Skip to content

Commit

Permalink
relayfs: Convert to hotplug state machine
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Richard Weinberger <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: [email protected]
Cc: Andrew Morton <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
  • Loading branch information
richardweinberger authored and KAGA-KOKO committed Sep 6, 2016
1 parent 017c59c commit e6d4989
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 45 deletions.
1 change: 1 addition & 0 deletions include/linux/cpuhotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions include/linux/relay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

6 changes: 6 additions & 0 deletions kernel/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1272,6 +1273,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
.startup.single = smpcfd_prepare_cpu,
.teardown.single = smpcfd_dead_cpu,
},
[CPUHP_RELAY_PREPARE] = {
.name = "relay:prepare",
.startup.single = relay_prepare_cpu,
.teardown.single = NULL,
},
[CPUHP_RCUTREE_PREP] = {
.name = "RCU/tree:prepare",
.startup.single = rcutree_prepare_cpu,
Expand Down
58 changes: 13 additions & 45 deletions kernel/relay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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);

0 comments on commit e6d4989

Please sign in to comment.