* 'hwpoison-2.6.32' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6: HWPOISON: fix invalid page count in printk output HWPOISON: Allow schedule_on_each_cpu() from keventd HWPOISON: fix/proc/meminfo alignment HWPOISON: fix oops on ksm pages HWPOISON: Fix page count leak in hwpoison late kill in do_swap_page HWPOISON: return early on non-LRU pages HWPOISON: Add brief hwpoison description to Documentation HWPOISON: Clean up PR_MCE_KILL interface
Showing the changes to kernel/workqueue.c (1 of 6 files). Show all
Unified · Split
| @@ -685,21 +685,38 @@ EXPORT_SYMBOL(schedule_delayed_work_on); · 684 unmodified lines | ||
| 685 | 685 | int schedule_on_each_cpu(work_func_t func) |
| 686 | 686 | { |
| 687 | 687 | int cpu; |
| 688 | + int orig = -1; | |
| 688 | 689 | struct work_struct *works; |
| 689 | 690 | |
| 690 | 691 | works = alloc_percpu(struct work_struct); |
| 691 | 692 | if (!works) |
| 692 | 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 | 707 | get_online_cpus(); |
| 695 | 708 | for_each_online_cpu(cpu) { |
| 696 | 709 | struct work_struct *work = per_cpu_ptr(works, cpu); |
| 697 | 710 | |
| 711 | + if (cpu == orig) | |
| 712 | + continue; | |
| 698 | 713 | INIT_WORK(work, func); |
| 699 | 714 | schedule_work_on(cpu, work); |
| 700 | 715 | } |
| 701 | − for_each_online_cpu(cpu) | |
| 702 | − flush_work(per_cpu_ptr(works, cpu)); | |
| 716 | + for_each_online_cpu(cpu) { | |
| 717 | + if (cpu != orig) | |
| 718 | + flush_work(per_cpu_ptr(works, cpu)); | |
| 719 | + } | |
| 703 | 720 | put_online_cpus(); |
| 704 | 721 | free_percpu(works); |
| 705 | 722 | return 0; |