diff options
author | Richard Weinberger <richard@nod.at> | 2016-08-18 08:57:17 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-06 12:30:20 -0400 |
commit | e6d4989a9ad1ccc343f29578a461612ed80fc6c5 (patch) | |
tree | 97b092d2f0505c61d15cf4f2025fddb0c5f6c614 | |
parent | 017c59c042d01fc84cae7a8ea475861e702c77ab (diff) |
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>
-rw-r--r-- | include/linux/cpuhotplug.h | 1 | ||||
-rw-r--r-- | include/linux/relay.h | 6 | ||||
-rw-r--r-- | kernel/cpu.c | 6 | ||||
-rw-r--r-- | 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 { | |||
21 | CPUHP_PROFILE_PREPARE, | 21 | CPUHP_PROFILE_PREPARE, |
22 | CPUHP_X2APIC_PREPARE, | 22 | CPUHP_X2APIC_PREPARE, |
23 | CPUHP_SMPCFD_PREPARE, | 23 | CPUHP_SMPCFD_PREPARE, |
24 | CPUHP_RELAY_PREPARE, | ||
24 | CPUHP_RCUTREE_PREP, | 25 | CPUHP_RCUTREE_PREP, |
25 | CPUHP_NOTIFY_PREPARE, | 26 | CPUHP_NOTIFY_PREPARE, |
26 | CPUHP_TIMERS_DEAD, | 27 | 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, | |||
288 | */ | 288 | */ |
289 | extern const struct file_operations relay_file_operations; | 289 | extern const struct file_operations relay_file_operations; |
290 | 290 | ||
291 | #ifdef CONFIG_RELAY | ||
292 | int relay_prepare_cpu(unsigned int cpu); | ||
293 | #else | ||
294 | #define relay_prepare_cpu NULL | ||
295 | #endif | ||
296 | |||
291 | #endif /* _LINUX_RELAY_H */ | 297 | #endif /* _LINUX_RELAY_H */ |
292 | 298 | ||
diff --git a/kernel/cpu.c b/kernel/cpu.c index d14ae4438e8e..0c0d4b2ddd1c 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/tick.h> | 23 | #include <linux/tick.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/smpboot.h> | 25 | #include <linux/smpboot.h> |
26 | #include <linux/relay.h> | ||
26 | 27 | ||
27 | #include <trace/events/power.h> | 28 | #include <trace/events/power.h> |
28 | #define CREATE_TRACE_POINTS | 29 | #define CREATE_TRACE_POINTS |
@@ -1272,6 +1273,11 @@ static struct cpuhp_step cpuhp_bp_states[] = { | |||
1272 | .startup.single = smpcfd_prepare_cpu, | 1273 | .startup.single = smpcfd_prepare_cpu, |
1273 | .teardown.single = smpcfd_dead_cpu, | 1274 | .teardown.single = smpcfd_dead_cpu, |
1274 | }, | 1275 | }, |
1276 | [CPUHP_RELAY_PREPARE] = { | ||
1277 | .name = "relay:prepare", | ||
1278 | .startup.single = relay_prepare_cpu, | ||
1279 | .teardown.single = NULL, | ||
1280 | }, | ||
1275 | [CPUHP_RCUTREE_PREP] = { | 1281 | [CPUHP_RCUTREE_PREP] = { |
1276 | .name = "RCU/tree:prepare", | 1282 | .name = "RCU/tree:prepare", |
1277 | .startup.single = rcutree_prepare_cpu, | 1283 | .startup.single = 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, | |||
513 | chan->cb = cb; | 513 | chan->cb = cb; |
514 | } | 514 | } |
515 | 515 | ||
516 | /** | 516 | int relay_prepare_cpu(unsigned int cpu) |
517 | * relay_hotcpu_callback - CPU hotplug callback | ||
518 | * @nb: notifier block | ||
519 | * @action: hotplug action to take | ||
520 | * @hcpu: CPU number | ||
521 | * | ||
522 | * Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD) | ||
523 | */ | ||
524 | static int relay_hotcpu_callback(struct notifier_block *nb, | ||
525 | unsigned long action, | ||
526 | void *hcpu) | ||
527 | { | 517 | { |
528 | unsigned int hotcpu = (unsigned long)hcpu; | ||
529 | struct rchan *chan; | 518 | struct rchan *chan; |
530 | struct rchan_buf *buf; | 519 | struct rchan_buf *buf; |
531 | 520 | ||
532 | switch(action) { | 521 | mutex_lock(&relay_channels_mutex); |
533 | case CPU_UP_PREPARE: | 522 | list_for_each_entry(chan, &relay_channels, list) { |
534 | case CPU_UP_PREPARE_FROZEN: | 523 | if ((buf = *per_cpu_ptr(chan->buf, cpu))) |
535 | mutex_lock(&relay_channels_mutex); | 524 | continue; |
536 | list_for_each_entry(chan, &relay_channels, list) { | 525 | buf = relay_open_buf(chan, cpu); |
537 | if ((buf = *per_cpu_ptr(chan->buf, hotcpu))) | 526 | if (!buf) { |
538 | continue; | 527 | pr_err("relay: cpu %d buffer creation failed\n", cpu); |
539 | buf = relay_open_buf(chan, hotcpu); | 528 | mutex_unlock(&relay_channels_mutex); |
540 | if (!buf) { | 529 | return -ENOMEM; |
541 | printk(KERN_ERR | ||
542 | "relay_hotcpu_callback: cpu %d buffer " | ||
543 | "creation failed\n", hotcpu); | ||
544 | mutex_unlock(&relay_channels_mutex); | ||
545 | return notifier_from_errno(-ENOMEM); | ||
546 | } | ||
547 | *per_cpu_ptr(chan->buf, hotcpu) = buf; | ||
548 | } | 530 | } |
549 | mutex_unlock(&relay_channels_mutex); | 531 | *per_cpu_ptr(chan->buf, cpu) = buf; |
550 | break; | ||
551 | case CPU_DEAD: | ||
552 | case CPU_DEAD_FROZEN: | ||
553 | /* No need to flush the cpu : will be flushed upon | ||
554 | * final relay_flush() call. */ | ||
555 | break; | ||
556 | } | 532 | } |
557 | return NOTIFY_OK; | 533 | mutex_unlock(&relay_channels_mutex); |
534 | return 0; | ||
558 | } | 535 | } |
559 | 536 | ||
560 | /** | 537 | /** |
@@ -1387,12 +1364,3 @@ const struct file_operations relay_file_operations = { | |||
1387 | .splice_read = relay_file_splice_read, | 1364 | .splice_read = relay_file_splice_read, |
1388 | }; | 1365 | }; |
1389 | EXPORT_SYMBOL_GPL(relay_file_operations); | 1366 | EXPORT_SYMBOL_GPL(relay_file_operations); |
1390 | |||
1391 | static __init int relay_init(void) | ||
1392 | { | ||
1393 | |||
1394 | hotcpu_notifier(relay_hotcpu_callback, 0); | ||
1395 | return 0; | ||
1396 | } | ||
1397 | |||
1398 | early_initcall(relay_init); | ||