lkml.org 
[lkml]   [2016]   [Aug]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 02/16] relayfs: Convert to hotplug state machine
    Date
    From: Richard Weinberger <richard@nod.at>

    Install the callbacks via the state machine. They are installed at run time but
    relay_prepare_cpu() does not need to be invoked by the boot CPU because
    relay_open() was not yet invoked and there are no pools that need to be created.

    Cc: Andrew Morton <akpm@linux-foundation.org>
    Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Richard Weinberger <richard@nod.at>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    ---
    include/linux/cpuhotplug.h | 1 +
    include/linux/relay.h | 6 +++++
    kernel/cpu.c | 6 +++++
    kernel/relay.c | 58 +++++++++++-----------------------------------
    4 files changed, 26 insertions(+), 45 deletions(-)

    diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
    index 9e6d10786e29..4c79f40fcebc 100644
    --- a/include/linux/cpuhotplug.h
    +++ b/include/linux/cpuhotplug.h
    @@ -21,6 +21,7 @@ enum cpuhp_state {
    CPUHP_PROFILE_PREPARE,
    CPUHP_X2APIC_PREPARE,
    CPUHP_SMPCFD_PREPARE,
    + CPUHP_RELAY_PREPARE,
    CPUHP_RCUTREE_PREP,
    CPUHP_NOTIFY_PREPARE,
    CPUHP_TIMERS_DEAD,
    diff --git a/include/linux/relay.h b/include/linux/relay.h
    index eb295e373b90..ecbb34a382b8 100644
    --- a/include/linux/relay.h
    +++ b/include/linux/relay.h
    @@ -288,5 +288,11 @@ static inline void subbuf_start_reserve(struct rchan_buf *buf,
    */
    extern const struct file_operations relay_file_operations;

    +#ifdef CONFIG_RELAY
    +int relay_prepare_cpu(unsigned int cpu);
    +#else
    +#define relay_prepare_cpu NULL
    +#endif
    +
    #endif /* _LINUX_RELAY_H */

    diff --git a/kernel/cpu.c b/kernel/cpu.c
    index c10eea6ea4dd..2a11381d5997 100644
    --- a/kernel/cpu.c
    +++ b/kernel/cpu.c
    @@ -23,6 +23,7 @@
    #include <linux/tick.h>
    #include <linux/irq.h>
    #include <linux/smpboot.h>
    +#include <linux/relay.h>

    #include <trace/events/power.h>
    #define CREATE_TRACE_POINTS
    @@ -1267,6 +1268,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
    .startup = smpcfd_prepare_cpu,
    .teardown = smpcfd_dead_cpu,
    },
    + [CPUHP_RELAY_PREPARE] = {
    + .name = "relay prepare",
    + .startup = relay_prepare_cpu,
    + .teardown = NULL,
    + },
    [CPUHP_RCUTREE_PREP] = {
    .name = "RCU-tree prepare",
    .startup = rcutree_prepare_cpu,
    diff --git a/kernel/relay.c b/kernel/relay.c
    index ed157378f6cb..fc9b4a4af463 100644
    --- a/kernel/relay.c
    +++ b/kernel/relay.c
    @@ -513,48 +513,25 @@ static void setup_callbacks(struct rchan *chan,
    chan->cb = cb;
    }

    -/**
    - * relay_hotcpu_callback - CPU hotplug callback
    - * @nb: notifier block
    - * @action: hotplug action to take
    - * @hcpu: CPU number
    - *
    - * Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD)
    - */
    -static int relay_hotcpu_callback(struct notifier_block *nb,
    - unsigned long action,
    - void *hcpu)
    +int relay_prepare_cpu(unsigned int cpu)
    {
    - unsigned int hotcpu = (unsigned long)hcpu;
    struct rchan *chan;
    struct rchan_buf *buf;

    - switch(action) {
    - case CPU_UP_PREPARE:
    - case CPU_UP_PREPARE_FROZEN:
    - mutex_lock(&relay_channels_mutex);
    - list_for_each_entry(chan, &relay_channels, list) {
    - if ((buf = *per_cpu_ptr(chan->buf, hotcpu)))
    - continue;
    - buf = relay_open_buf(chan, hotcpu);
    - if (!buf) {
    - printk(KERN_ERR
    - "relay_hotcpu_callback: cpu %d buffer "
    - "creation failed\n", hotcpu);
    - mutex_unlock(&relay_channels_mutex);
    - return notifier_from_errno(-ENOMEM);
    - }
    - *per_cpu_ptr(chan->buf, hotcpu) = buf;
    + mutex_lock(&relay_channels_mutex);
    + list_for_each_entry(chan, &relay_channels, list) {
    + if ((buf = *per_cpu_ptr(chan->buf, cpu)))
    + continue;
    + buf = relay_open_buf(chan, cpu);
    + if (!buf) {
    + pr_err("relay: cpu %d buffer creation failed\n", cpu);
    + mutex_unlock(&relay_channels_mutex);
    + return -ENOMEM;
    }
    - mutex_unlock(&relay_channels_mutex);
    - break;
    - case CPU_DEAD:
    - case CPU_DEAD_FROZEN:
    - /* No need to flush the cpu : will be flushed upon
    - * final relay_flush() call. */
    - break;
    + *per_cpu_ptr(chan->buf, cpu) = buf;
    }
    - return NOTIFY_OK;
    + mutex_unlock(&relay_channels_mutex);
    + return 0;
    }

    /**
    @@ -1387,12 +1364,3 @@ const struct file_operations relay_file_operations = {
    .splice_read = relay_file_splice_read,
    };
    EXPORT_SYMBOL_GPL(relay_file_operations);
    -
    -static __init int relay_init(void)
    -{
    -
    - hotcpu_notifier(relay_hotcpu_callback, 0);
    - return 0;
    -}
    -
    -early_initcall(relay_init);
    --
    2.9.3
    \
     
     \ /
      Last update: 2016-09-17 09:57    [W:4.527 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site