On 05/03/2012 08:25 PM, Gilad Ben-Yossef wrote: > Introduce schedule_on_each_cpu_mask function to schedule a work > item on each online CPU which is included in the mask provided. > > Then re-implement schedule_on_each_cpu on top of the new function. > > This function should be prefered to schedule_on_each_cpu in > any case where some of the CPUs, especially on a big multi-core > system, might not have actual work to perform in order to save > needless wakeups and schedules. > > Signed-off-by: Gilad Ben-Yossef <gilad@xxxxxxxxxxxxx> > /** > - * schedule_on_each_cpu - execute a function synchronously on each online CPU > + * schedule_on_each_cpu_mask - execute a function synchronously on each > + * online CPU which is specified in the supplied cpumask > * @func: the function to call > + * @mask: the cpu mask > * > - * schedule_on_each_cpu() executes @func on each online CPU using the > - * system workqueue and blocks until all CPUs have completed. > - * schedule_on_each_cpu() is very slow. > + * schedule_on_each_cpu_mask() executes @func on each online CPU which > + * is part of the @mask using the * system workqueue and blocks until ^^^ stray character? > + * all CPUs have completed > + * schedule_on_each_cpu_mask() is very slow. > * > * RETURNS: > * 0 on success, -errno on failure. > */ > -int schedule_on_each_cpu(work_func_t func) > +int schedule_on_each_cpu_mask(work_func_t func, const struct cpumask *mask) > { > int cpu; > struct work_struct __percpu *works; > > works = alloc_percpu(struct work_struct); > - if (!works) > + if (unlikely(!works)) > return -ENOMEM; > > get_online_cpus(); > > - for_each_online_cpu(cpu) { > + for_each_cpu_and(cpu, mask, cpu_online_mask) { > struct work_struct *work = per_cpu_ptr(works, cpu); > > INIT_WORK(work, func); > schedule_work_on(cpu, work); > } > > - for_each_online_cpu(cpu) > + for_each_cpu_and(cpu, mask, cpu_online_mask) > flush_work(per_cpu_ptr(works, cpu)); > Given that cpu hotplug is not a frequent operation, I think mask will be a subset of cpu_online_mask most of the time (also, one example is from schedule_on_each_cpu_cond() introduced in 3/6, which is already under get/put_online_cpus(). So can we optimize something (the 'and' operations perhaps) based on that? May be something by using: if (likely(cpumask_subset(mask, cpu_online_mask)) > put_online_cpus(); > free_percpu(works); > + > return 0; > } > Regards, Srivatsa S. Bhat -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>