cpumask: fix memory leak and cpumask corruption
PATCH 1/1 cpumask: fix memory leak and cpumask corruption
From: Hiroshi Shimamoto <[email protected]>
On CONFIG_CPUMASK_OFFSTACK enabled kernel, when exiting smp_call_function_many() without calling arch_send_call_function_ipi() allbutself should be freed.
Also, the memory for allbutself shouldn't be freed when arch_send_call_function_ipi() is called. The memory region will be referenced in generic_smp_call_function_interrupt(). And the memory will be freed at rcu_free_call_data().
--- kernel/smp.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-)
kernel/smp.c +6 -2
@@ -88,6 +88,7 @@ static void rcu_free_call_data(struct rcu_head *head)struct call_function_data *data; data = container_of(head, struct call_function_data, rcu_head); +free_cpumask_var (data->cpumask);kfree (data); }
@@ -347,7 +348,7 @@ void smp_call_function_many(const struct cpumask *mask,* into a targetted single call instead since it's faster. */ if (!num_cpus) -return ; + goto out;else if (num_cpus ==1 ) { cpu =cpumask_first (allbutself);smp_call_function_single (cpu, func, info, wait);
@@ -382,9 +383,12 @@ void smp_call_function_many(const struct cpumask *mask,/* optionally wait for the CPUs to complete */ if (wait) {csd_flag_wait (&data->csd); -if (unlikely (slowpath)) +if (unlikely (slowpath)) {smp_call_function_mask_quiesce_stack (allbutself); +free_cpumask_var (allbutself); + } } +return ; out:free_cpumask_var (allbutself); }
Signature · 1 line
1.5.6
Quoted 1 line · On Friday 24 October 2008 15:59:59 Hiroshi Shimamoto wrote:
From: Hiroshi Shimamoto <[email protected]>
Hi Hiroshi,
Thanks for looking at this!
Quoted 3 lines
On
CONFIG_CPUMASK_OFFSTACKenabled kernel, when exitingsmp_call_function_many()without callingarch_send_call_function_ipi()allbutself should be freed.
That bit's OK, changing the return to "goto out;".
Quoted 4 lines
Also, the memory for allbutself shouldn't be freed when
arch_send_call_function_ipi()is called. The memory region will be referenced ingeneric_smp_call_function_interrupt(). And the memory will be freed atrcu_free_call_data().
As your next patch shows, this should be solved a different way. I'll comment there.
Cheers,
Rusty.