Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.26-rc1 /kernel/workqueue.c

Filename:/kernel/workqueue.c
Lines Added:16
Lines Deleted:14
Also changed in: (Previous) 2.6.25-git20  2.6.25-git19  2.6.25-git18  2.6.25-git17  2.6.25-git16  2.6.25-git15 
(Following) 2.6.26-rc2  2.6.26-rc3  2.6.26-rc4  2.6.26-rc5  2.6.26-rc6  2.6.26-rc7 

Location
[  2.6.26-rc1
  [  kernel
     o  workqueue.c

Patch

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index ff06611..29fc39f 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -158,8 +158,8 @@ static void __queue_work(struct cpu_workqueue_struct *cwq,
  *
  * 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 on which it was submitted, but if the CPU dies
+ * it can be processed by another CPU.
  */
 int queue_work(struct workqueue_struct *wq, struct work_struct *work)
 {
@@ -195,7 +195,6 @@ static void delayed_work_timer_fn(unsigned long __data)
 int queue_delayed_work(struct workqueue_struct *wq,
          struct delayed_work *dwork, unsigned long delay)
 {
-   timer_stats_timer_set_start_info(&dwork->timer);
    if (delay == 0)
       return queue_work(wq, &dwork->work);
 
@@ -223,6 +222,8 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
       BUG_ON(timer_pending(timer));
       BUG_ON(!list_empty(&work->entry));
 
+      timer_stats_timer_set_start_info(&dwork->timer);
+
       /* This stores cwq for the moment, for the timer_fn */
       set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id()));
       timer->expires = jiffies + delay;
@@ -246,7 +247,7 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
    if (cwq->run_depth > 3) {
       /* morton gets to eat his hat */
       printk("%s: recursion depth exceeded: %d\n",
-         __FUNCTION__, cwq->run_depth);
+         __func__, cwq->run_depth);
       dump_stack();
    }
    while (!list_empty(&cwq->worklist)) {
@@ -563,7 +564,6 @@ EXPORT_SYMBOL(schedule_work);
 int schedule_delayed_work(struct delayed_work *dwork,
                unsigned long delay)
 {
-   timer_stats_timer_set_start_info(&dwork->timer);
    return queue_delayed_work(keventd_wq, dwork, delay);
 }
 EXPORT_SYMBOL(schedule_delayed_work);
@@ -770,7 +770,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
 }
 EXPORT_SYMBOL_GPL(__create_workqueue_key);
 
-static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
+static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq)
 {
    /*
     * Our caller is either destroy_workqueue() or CPU_DEAD,
@@ -806,19 +806,16 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 void destroy_workqueue(struct workqueue_struct *wq)
 {
    const cpumask_t *cpu_map = wq_cpu_map(wq);
-   struct cpu_workqueue_struct *cwq;
    int cpu;
 
    get_online_cpus();
    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);
-   }
+   for_each_cpu_mask(cpu, *cpu_map)
+      cleanup_workqueue_thread(per_cpu_ptr(wq->cpu_wq, cpu));
+   put_online_cpus();
 
    free_percpu(wq->cpu_wq);
    kfree(wq);
@@ -836,7 +833,6 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
    action &= ~CPU_TASKS_FROZEN;
 
    switch (action) {
-
    case CPU_UP_PREPARE:
       cpu_set(cpu, cpu_populated_map);
    }
@@ -859,11 +855,17 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
       case CPU_UP_CANCELED:
          start_workqueue_thread(cwq, -1);
       case CPU_DEAD:
-         cleanup_workqueue_thread(cwq, cpu);
+         cleanup_workqueue_thread(cwq);
          break;
       }
    }
 
+   switch (action) {
+   case CPU_UP_CANCELED:
+   case CPU_DEAD:
+      cpu_clear(cpu, cpu_populated_map);
+   }
+
    return NOTIFY_OK;
 }
 


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.