relayfs: Convert to hotplug state machine
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 <richard@nod.at> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: rt@linutronix.de Cc: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/r/20160818125731.27256-3-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
017c59c042
commit
e6d4989a9a
@ -21,6 +21,7 @@ enum cpuhp_state {
|
|||||||
CPUHP_PROFILE_PREPARE,
|
CPUHP_PROFILE_PREPARE,
|
||||||
CPUHP_X2APIC_PREPARE,
|
CPUHP_X2APIC_PREPARE,
|
||||||
CPUHP_SMPCFD_PREPARE,
|
CPUHP_SMPCFD_PREPARE,
|
||||||
|
CPUHP_RELAY_PREPARE,
|
||||||
CPUHP_RCUTREE_PREP,
|
CPUHP_RCUTREE_PREP,
|
||||||
CPUHP_NOTIFY_PREPARE,
|
CPUHP_NOTIFY_PREPARE,
|
||||||
CPUHP_TIMERS_DEAD,
|
CPUHP_TIMERS_DEAD,
|
||||||
|
@ -288,5 +288,11 @@ static inline void subbuf_start_reserve(struct rchan_buf *buf,
|
|||||||
*/
|
*/
|
||||||
extern const struct file_operations relay_file_operations;
|
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 */
|
#endif /* _LINUX_RELAY_H */
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <linux/tick.h>
|
#include <linux/tick.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/smpboot.h>
|
#include <linux/smpboot.h>
|
||||||
|
#include <linux/relay.h>
|
||||||
|
|
||||||
#include <trace/events/power.h>
|
#include <trace/events/power.h>
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
@ -1272,6 +1273,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
|
|||||||
.startup.single = smpcfd_prepare_cpu,
|
.startup.single = smpcfd_prepare_cpu,
|
||||||
.teardown.single = smpcfd_dead_cpu,
|
.teardown.single = smpcfd_dead_cpu,
|
||||||
},
|
},
|
||||||
|
[CPUHP_RELAY_PREPARE] = {
|
||||||
|
.name = "relay:prepare",
|
||||||
|
.startup.single = relay_prepare_cpu,
|
||||||
|
.teardown.single = NULL,
|
||||||
|
},
|
||||||
[CPUHP_RCUTREE_PREP] = {
|
[CPUHP_RCUTREE_PREP] = {
|
||||||
.name = "RCU/tree:prepare",
|
.name = "RCU/tree:prepare",
|
||||||
.startup.single = rcutree_prepare_cpu,
|
.startup.single = rcutree_prepare_cpu,
|
||||||
|
@ -513,48 +513,25 @@ static void setup_callbacks(struct rchan *chan,
|
|||||||
chan->cb = cb;
|
chan->cb = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int relay_prepare_cpu(unsigned int cpu)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
unsigned int hotcpu = (unsigned long)hcpu;
|
|
||||||
struct rchan *chan;
|
struct rchan *chan;
|
||||||
struct rchan_buf *buf;
|
struct rchan_buf *buf;
|
||||||
|
|
||||||
switch(action) {
|
mutex_lock(&relay_channels_mutex);
|
||||||
case CPU_UP_PREPARE:
|
list_for_each_entry(chan, &relay_channels, list) {
|
||||||
case CPU_UP_PREPARE_FROZEN:
|
if ((buf = *per_cpu_ptr(chan->buf, cpu)))
|
||||||
mutex_lock(&relay_channels_mutex);
|
continue;
|
||||||
list_for_each_entry(chan, &relay_channels, list) {
|
buf = relay_open_buf(chan, cpu);
|
||||||
if ((buf = *per_cpu_ptr(chan->buf, hotcpu)))
|
if (!buf) {
|
||||||
continue;
|
pr_err("relay: cpu %d buffer creation failed\n", cpu);
|
||||||
buf = relay_open_buf(chan, hotcpu);
|
mutex_unlock(&relay_channels_mutex);
|
||||||
if (!buf) {
|
return -ENOMEM;
|
||||||
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_unlock(&relay_channels_mutex);
|
*per_cpu_ptr(chan->buf, cpu) = buf;
|
||||||
break;
|
|
||||||
case CPU_DEAD:
|
|
||||||
case CPU_DEAD_FROZEN:
|
|
||||||
/* No need to flush the cpu : will be flushed upon
|
|
||||||
* final relay_flush() call. */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
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,
|
.splice_read = relay_file_splice_read,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(relay_file_operations);
|
EXPORT_SYMBOL_GPL(relay_file_operations);
|
||||||
|
|
||||||
static __init int relay_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
hotcpu_notifier(relay_hotcpu_callback, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
early_initcall(relay_init);
|
|
||||||
|
Loading…
Reference in New Issue
Block a user