lkml.org 
[lkml]   [2008]   [Feb]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 1/2] workqueues: shrink cpu_populated_map when CPU dies
    When cpu_populated_map was introduced, it was supposed that cwq->thread can
    survive after CPU_DEAD, that is why we never shrink cpu_populated_map.

    This is not very nice, we can safely remove the already dead CPU from the map.
    The only required change is that destroy_workqueue() must hold the hotplug lock
    until it destroys all cwq->thread's, to protect the cpu_populated_map. We could
    make the local copy of cpu mask and drop the lock, but sizeof(cpumask_t) may be
    very large.

    Also, fix the comment near queue_work(). Unless _cpu_down() happens we do
    guarantee the cpu-affinity of the work_struct, and we have users which rely on
    this.

    Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>

    --- 25/kernel/workqueue.c~2_WQ_CPU_MAP 2008-02-15 16:59:18.000000000 +0300
    +++ 25/kernel/workqueue.c 2008-02-16 19:33:03.000000000 +0300
    @@ -158,8 +158,8 @@ static void __queue_work(struct cpu_work
    *
    * Returns 0 if @work was already on a queue, non-zero otherwise.
    *
    - * We queue the work to the CPU it was submitted, but there is no
    - * guarantee that it will be processed by that CPU.
    + * We queue the work to the CPU it was submitted, but if CPU dies
    + * it can be processed by another CPU.
    */
    int queue_work(struct workqueue_struct *wq, struct work_struct *work)
    {
    @@ -813,12 +813,12 @@ void destroy_workqueue(struct workqueue_
    spin_lock(&workqueue_lock);
    list_del(&wq->list);
    spin_unlock(&workqueue_lock);
    - put_online_cpus();

    for_each_cpu_mask(cpu, *cpu_map) {
    cwq = per_cpu_ptr(wq->cpu_wq, cpu);
    cleanup_workqueue_thread(cwq, cpu);
    }
    + put_online_cpus();

    free_percpu(wq->cpu_wq);
    kfree(wq);
    @@ -836,7 +836,6 @@ static int __devinit workqueue_cpu_callb
    action &= ~CPU_TASKS_FROZEN;

    switch (action) {
    -
    case CPU_UP_PREPARE:
    cpu_set(cpu, cpu_populated_map);
    }
    @@ -864,6 +863,12 @@ static int __devinit workqueue_cpu_callb
    }
    }

    + switch (action) {
    + case CPU_UP_CANCELED:
    + case CPU_DEAD:
    + cpu_clear(cpu, cpu_populated_map);
    + }
    +
    return NOTIFY_OK;
    }



    \
     
     \ /
      Last update: 2008-02-16 18:23    [W:0.022 / U:120.820 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site