From: John Jacques <john.jacq...@lsi.com> When we do a reset (core, not chip or system), the core that is doing the reset has to tell all the other cores to reset. To do this, we call smp_call_function_single(). In this case the function specified in smp_call_function_single() doesn't return. The "wait" parameter (third argument, described as '@wait: If true, wait until function has completed on other CPUs.') doesn't work as described without the patch.
Signen-off-by: John Jacques <john.jacq...@lsi.com> --- kernel/smp.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/kernel/smp.c b/kernel/smp.c index d5f3238..040b2b1 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -17,14 +17,14 @@ static struct { struct list_head queue; raw_spinlock_t lock; -} call_function __cacheline_aligned_in_smp = - { +} call_function __cacheline_aligned_in_smp = { .queue = LIST_HEAD_INIT(call_function.queue), .lock = __RAW_SPIN_LOCK_UNLOCKED(call_function.lock), }; enum { CSD_FLAG_LOCK = 0x01, + CSD_FLAG_NOWAIT = 0x02, }; struct call_function_data { @@ -268,6 +268,8 @@ void generic_smp_call_function_single_interrupt(void) while (!list_empty(&list)) { struct call_single_data *data; + void (*func)(void *); + void *info; data = list_entry(list.next, struct call_single_data, list); list_del(&data->list); @@ -278,12 +280,21 @@ void generic_smp_call_function_single_interrupt(void) * so save them away before making the call: */ data_flags = data->flags; - - data->func(data->info); + func = data->func; + info = data->info; /* + * Unlock before calling func so that func never has + * to return. + * * Unlocked CSDs are valid through generic_exec_single(): */ + if ((data_flags & CSD_FLAG_LOCK) && + (data_flags & CSD_FLAG_NOWAIT)) + csd_unlock(data); + + func(info); + if (data_flags & CSD_FLAG_LOCK) csd_unlock(data); } @@ -337,6 +348,9 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info, csd_lock(data); + if (!wait) + data->flags |= CSD_FLAG_NOWAIT; + data->func = func; data->info = info; generic_exec_single(cpu, data, wait); @@ -672,7 +686,7 @@ EXPORT_SYMBOL(nr_cpu_ids); /* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ void __init setup_nr_cpu_ids(void) { - nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; + nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask), NR_CPUS) + 1; } /* Called by boot processor to activate the rest. */ -- 1.7.9.5 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto