lkml.org 
[lkml]   [2017]   [Apr]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch V2 02/24] stop_machine: Provide stop_machine_cpuslocked()
    From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

    Some call sites of stop_machine() are within a get_online_cpus() protected
    region.

    stop_machine() calls get_online_cpus() as well, which is possible in the
    current implementation but prevents converting the hotplug locking to a
    percpu rwsem.

    Provide stop_machine_cpuslocked() to avoid nested calls to get_online_cpus().

    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

    ---
    include/linux/stop_machine.h | 26 +++++++++++++++++++++++---
    kernel/stop_machine.c | 5 +++--
    2 files changed, 26 insertions(+), 5 deletions(-)

    --- a/include/linux/stop_machine.h
    +++ b/include/linux/stop_machine.h
    @@ -116,15 +116,29 @@ static inline int try_stop_cpus(const st
    * @fn() runs.
    *
    * This can be thought of as a very heavy write lock, equivalent to
    - * grabbing every spinlock in the kernel. */
    + * grabbing every spinlock in the kernel.
    + *
    + * Protects against CPU hotplug.
    + */
    int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);

    +/**
    + * stop_machine_cpuslocked: freeze the machine on all CPUs and run this function
    + * @fn: the function to run
    + * @data: the data ptr for the @fn()
    + * @cpus: the cpus to run the @fn() on (NULL = any online cpu)
    + *
    + * Same as above. Must be called from with in a get_online_cpus() protected
    + * region. Avoids nested calls to get_online_cpus().
    + */
    +int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);
    +
    int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
    const struct cpumask *cpus);
    #else /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */

    -static inline int stop_machine(cpu_stop_fn_t fn, void *data,
    - const struct cpumask *cpus)
    +static inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data,
    + const struct cpumask *cpus)
    {
    unsigned long flags;
    int ret;
    @@ -134,6 +148,12 @@ static inline int stop_machine(cpu_stop_
    return ret;
    }

    +static inline int stop_machine(cpu_stop_fn_t fn, void *data,
    + const struct cpumask *cpus)
    +{
    + return stop_machine_cpuslocked(fn, data, cpus);
    +}
    +
    static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
    const struct cpumask *cpus)
    {
    --- a/kernel/stop_machine.c
    +++ b/kernel/stop_machine.c
    @@ -552,7 +552,8 @@ static int __init cpu_stop_init(void)
    }
    early_initcall(cpu_stop_init);

    -static int __stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus)
    +int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data,
    + const struct cpumask *cpus)
    {
    struct multi_stop_data msdata = {
    .fn = fn,
    @@ -591,7 +592,7 @@ int stop_machine(cpu_stop_fn_t fn, void

    /* No CPUs can come up or down during this. */
    get_online_cpus();
    - ret = __stop_machine(fn, data, cpus);
    + ret = stop_machine_cpuslocked(fn, data, cpus);
    put_online_cpus();
    return ret;
    }

    \
     
     \ /
      Last update: 2017-04-18 21:49    [W:5.859 / U:0.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site