diff options
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 17 | 
1 files changed, 16 insertions, 1 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 47cdd7e76f2b..67e526b6ae81 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c  | |||
| @@ -685,6 +685,7 @@ EXPORT_SYMBOL(schedule_delayed_work_on); | |||
| 685 | int schedule_on_each_cpu(work_func_t func) | 685 | int schedule_on_each_cpu(work_func_t func) | 
| 686 | { | 686 | { | 
| 687 | int cpu; | 687 | int cpu; | 
| 688 | int orig = -1; | ||
| 688 | struct work_struct *works; | 689 | struct work_struct *works; | 
| 689 | 690 | ||
| 690 | works = alloc_percpu(struct work_struct); | 691 | works = alloc_percpu(struct work_struct); | 
| @@ -692,14 +693,28 @@ int schedule_on_each_cpu(work_func_t func) | |||
| 692 | return -ENOMEM; | 693 | return -ENOMEM; | 
| 693 | 694 | ||
| 694 | get_online_cpus(); | 695 | get_online_cpus(); | 
| 696 | |||
| 697 | /* | ||
| 698 | * When running in keventd don't schedule a work item on | ||
| 699 | * itself. Can just call directly because the work queue is | ||
| 700 | * already bound. This also is faster. | ||
| 701 | */ | ||
| 702 | if (current_is_keventd()) | ||
| 703 | orig = raw_smp_processor_id(); | ||
| 704 | |||
| 695 | for_each_online_cpu(cpu) { | 705 | for_each_online_cpu(cpu) { | 
| 696 | struct work_struct *work = per_cpu_ptr(works, cpu); | 706 | struct work_struct *work = per_cpu_ptr(works, cpu); | 
| 697 | 707 | ||
| 698 | INIT_WORK(work, func); | 708 | INIT_WORK(work, func); | 
| 699 | schedule_work_on(cpu, work); | 709 | if (cpu != orig) | 
| 710 | schedule_work_on(cpu, work); | ||
| 700 | } | 711 | } | 
| 712 | if (orig >= 0) | ||
| 713 | func(per_cpu_ptr(works, orig)); | ||
| 714 | |||
| 701 | for_each_online_cpu(cpu) | 715 | for_each_online_cpu(cpu) | 
| 702 | flush_work(per_cpu_ptr(works, cpu)); | 716 | flush_work(per_cpu_ptr(works, cpu)); | 
| 717 | |||
| 703 | put_online_cpus(); | 718 | put_online_cpus(); | 
| 704 | free_percpu(works); | 719 | free_percpu(works); | 
| 705 | return 0; | 720 | return 0; | 
