mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
[PATCH] schedule_on_each_cpu(): reduce kmalloc() size
schedule_on_each_cpu() presently does a large kmalloc - 96 kbytes on 1024 CPU 64-bit. Rework it so that we do one 8192-byte allocation and then a pile of tiny ones, via alloc_percpu(). This has a much higher chance of success (100% in the current VM). This also has the effect of reducing the memory requirements from NR_CPUS*n to num_possible_cpus()*n. Cc: Christoph Lameter <clameter@engr.sgi.com> Cc: Andi Kleen <ak@muc.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
232acbcf53
commit
b61367732f
1 changed files with 20 additions and 8 deletions
|
@ -428,22 +428,34 @@ int schedule_delayed_work_on(int cpu,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int schedule_on_each_cpu(void (*func) (void *info), void *info)
|
/**
|
||||||
|
* schedule_on_each_cpu - call a function on each online CPU from keventd
|
||||||
|
* @func: the function to call
|
||||||
|
* @info: a pointer to pass to func()
|
||||||
|
*
|
||||||
|
* Returns zero on success.
|
||||||
|
* Returns -ve errno on failure.
|
||||||
|
*
|
||||||
|
* Appears to be racy against CPU hotplug.
|
||||||
|
*
|
||||||
|
* schedule_on_each_cpu() is very slow.
|
||||||
|
*/
|
||||||
|
int schedule_on_each_cpu(void (*func)(void *info), void *info)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
struct work_struct *work;
|
struct work_struct *works;
|
||||||
|
|
||||||
work = kmalloc(NR_CPUS * sizeof(struct work_struct), GFP_KERNEL);
|
works = alloc_percpu(struct work_struct);
|
||||||
|
if (!works)
|
||||||
if (!work)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
INIT_WORK(work + cpu, func, info);
|
INIT_WORK(per_cpu_ptr(works, cpu), func, info);
|
||||||
__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
|
__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
|
||||||
work + cpu);
|
per_cpu_ptr(works, cpu));
|
||||||
}
|
}
|
||||||
flush_workqueue(keventd_wq);
|
flush_workqueue(keventd_wq);
|
||||||
kfree(work);
|
free_percpu(works);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue