diff options
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 21 | 
1 files changed, 19 insertions, 2 deletions
| diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 47cdd7e76f2b..12328147132c 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -685,21 +685,38 @@ 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); | 
| 691 | if (!works) | 692 | if (!works) | 
| 692 | return -ENOMEM; | 693 | return -ENOMEM; | 
| 693 | 694 | ||
| 695 | /* | ||
| 696 | * when running in keventd don't schedule a work item on itself. | ||
| 697 | * Can just call directly because the work queue is already bound. | ||
| 698 | * This also is faster. | ||
| 699 | * Make this a generic parameter for other workqueues? | ||
| 700 | */ | ||
| 701 | if (current_is_keventd()) { | ||
| 702 | orig = raw_smp_processor_id(); | ||
| 703 | INIT_WORK(per_cpu_ptr(works, orig), func); | ||
| 704 | func(per_cpu_ptr(works, orig)); | ||
| 705 | } | ||
| 706 | |||
| 694 | get_online_cpus(); | 707 | get_online_cpus(); | 
| 695 | for_each_online_cpu(cpu) { | 708 | for_each_online_cpu(cpu) { | 
| 696 | struct work_struct *work = per_cpu_ptr(works, cpu); | 709 | struct work_struct *work = per_cpu_ptr(works, cpu); | 
| 697 | 710 | ||
| 711 | if (cpu == orig) | ||
| 712 | continue; | ||
| 698 | INIT_WORK(work, func); | 713 | INIT_WORK(work, func); | 
| 699 | schedule_work_on(cpu, work); | 714 | schedule_work_on(cpu, work); | 
| 700 | } | 715 | } | 
| 701 | for_each_online_cpu(cpu) | 716 | for_each_online_cpu(cpu) { | 
| 702 | flush_work(per_cpu_ptr(works, cpu)); | 717 | if (cpu != orig) | 
| 718 | flush_work(per_cpu_ptr(works, cpu)); | ||
| 719 | } | ||
| 703 | put_online_cpus(); | 720 | put_online_cpus(); | 
| 704 | free_percpu(works); | 721 | free_percpu(works); | 
| 705 | return 0; | 722 | return 0; | 
