Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6d4989a authored by Richard Weinberger's avatar Richard Weinberger Committed by Thomas Gleixner
Browse files

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: default avatarRichard Weinberger <richard@nod.at>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: default avatarSebastian 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: default avatarThomas Gleixner <tglx@linutronix.de>
parent 017c59c0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
+6 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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
@@ -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,
+13 −45
Original line number Diff line number Diff line
@@ -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)))
		if ((buf = *per_cpu_ptr(chan->buf, cpu)))
			continue;
			buf = relay_open_buf(chan, hotcpu);
		buf = relay_open_buf(chan, cpu);
		if (!buf) {
				printk(KERN_ERR
					"relay_hotcpu_callback: cpu %d buffer "
					"creation failed\n", hotcpu);
			pr_err("relay: cpu %d buffer creation failed\n", cpu);
			mutex_unlock(&relay_channels_mutex);
				return notifier_from_errno(-ENOMEM);
			return -ENOMEM;
		}
			*per_cpu_ptr(chan->buf, hotcpu) = buf;
		*per_cpu_ptr(chan->buf, cpu) = buf;
	}
	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;
	}
	return NOTIFY_OK;
	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);