Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1530816

[PATCH 18/22] zram: Convert to hotplug state machine

From Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Newsgroups linux.kernel
Subject [PATCH 18/22] zram: Convert to hotplug state machine
Date 2016-11-27 00:20 +0100
Message-ID <sHUqf-4EY-45@gated-at.bofh.it> (permalink)
References <sHUqd-4EY-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Anna-Maria Gleixner <anna-maria@linutronix.de>

Install the callbacks via the state machine with multi instance support and let
the core invoke the callbacks on the already online CPUs.

Cc: Minchan Kim <minchan@kernel.org>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
[bigeasy: wire up the multi instance stuff]
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/block/zram/zcomp.c    | 76 ++++++++++++++-----------------------------
 drivers/block/zram/zcomp.h    |  5 +--
 drivers/block/zram/zram_drv.c |  9 +++++
 include/linux/cpuhotplug.h    |  1 +
 4 files changed, 38 insertions(+), 53 deletions(-)

diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 4b5cd3a7b2b6..12046f4f00e4 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -160,82 +160,56 @@ int zcomp_decompress(struct zcomp_strm *zstrm,
 			dst, &dst_len);
 }
 
-static int __zcomp_cpu_notifier(struct zcomp *comp,
-		unsigned long action, unsigned long cpu)
+int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
 {
+	struct zcomp *comp = hlist_entry(node, struct zcomp, node);
 	struct zcomp_strm *zstrm;
 
-	switch (action) {
-	case CPU_UP_PREPARE:
-		if (WARN_ON(*per_cpu_ptr(comp->stream, cpu)))
-			break;
-		zstrm = zcomp_strm_alloc(comp);
-		if (IS_ERR_OR_NULL(zstrm)) {
-			pr_err("Can't allocate a compression stream\n");
-			return NOTIFY_BAD;
-		}
-		*per_cpu_ptr(comp->stream, cpu) = zstrm;
-		break;
-	case CPU_DEAD:
-	case CPU_UP_CANCELED:
-		zstrm = *per_cpu_ptr(comp->stream, cpu);
-		if (!IS_ERR_OR_NULL(zstrm))
-			zcomp_strm_free(zstrm);
-		*per_cpu_ptr(comp->stream, cpu) = NULL;
-		break;
-	default:
-		break;
+	if (WARN_ON(*per_cpu_ptr(comp->stream, cpu)))
+		return 0;
+
+	zstrm = zcomp_strm_alloc(comp);
+	if (IS_ERR_OR_NULL(zstrm)) {
+		pr_err("Can't allocate a compression stream\n");
+		return -ENOMEM;
 	}
-	return NOTIFY_OK;
+	*per_cpu_ptr(comp->stream, cpu) = zstrm;
+	return 0;
 }
 
-static int zcomp_cpu_notifier(struct notifier_block *nb,
-		unsigned long action, void *pcpu)
+int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node)
 {
-	unsigned long cpu = (unsigned long)pcpu;
-	struct zcomp *comp = container_of(nb, typeof(*comp), notifier);
+	struct zcomp *comp = hlist_entry(node, struct zcomp, node);
+	struct zcomp_strm *zstrm;
 
-	return __zcomp_cpu_notifier(comp, action, cpu);
+	zstrm = *per_cpu_ptr(comp->stream, cpu);
+	if (!IS_ERR_OR_NULL(zstrm))
+		zcomp_strm_free(zstrm);
+	*per_cpu_ptr(comp->stream, cpu) = NULL;
+	return 0;
 }
 
 static int zcomp_init(struct zcomp *comp)
 {
-	unsigned long cpu;
 	int ret;
 
-	comp->notifier.notifier_call = zcomp_cpu_notifier;
-
 	comp->stream = alloc_percpu(struct zcomp_strm *);
 	if (!comp->stream)
 		return -ENOMEM;
 
-	cpu_notifier_register_begin();
-	for_each_online_cpu(cpu) {
-		ret = __zcomp_cpu_notifier(comp, CPU_UP_PREPARE, cpu);
-		if (ret == NOTIFY_BAD)
-			goto cleanup;
-	}
-	__register_cpu_notifier(&comp->notifier);
-	cpu_notifier_register_done();
+	ret = cpuhp_state_add_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
+	if (ret < 0)
+		goto cleanup;
 	return 0;
 
 cleanup:
-	for_each_online_cpu(cpu)
-		__zcomp_cpu_notifier(comp, CPU_UP_CANCELED, cpu);
-	cpu_notifier_register_done();
-	return -ENOMEM;
+	free_percpu(comp->stream);
+	return ret;
 }
 
 void zcomp_destroy(struct zcomp *comp)
 {
-	unsigned long cpu;
-
-	cpu_notifier_register_begin();
-	for_each_online_cpu(cpu)
-		__zcomp_cpu_notifier(comp, CPU_UP_CANCELED, cpu);
-	__unregister_cpu_notifier(&comp->notifier);
-	cpu_notifier_register_done();
-
+	cpuhp_state_remove_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
 	free_percpu(comp->stream);
 	kfree(comp);
 }
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index 478cac2ed465..41c1002a7d7d 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -19,11 +19,12 @@ struct zcomp_strm {
 /* dynamic per-device compression frontend */
 struct zcomp {
 	struct zcomp_strm * __percpu *stream;
-	struct notifier_block notifier;
-
 	const char *name;
+	struct hlist_node node;
 };
 
+int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node);
+int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node);
 ssize_t zcomp_available_show(const char *comp, char *buf);
 bool zcomp_available_algorithm(const char *comp);
 
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 04365b17ee67..511c35fd5c6f 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -30,6 +30,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/sysfs.h>
+#include <linux/cpuhotplug.h>
 
 #include "zram_drv.h"
 
@@ -1436,15 +1437,22 @@ static void destroy_devices(void)
 	idr_for_each(&zram_index_idr, &zram_remove_cb, NULL);
 	idr_destroy(&zram_index_idr);
 	unregister_blkdev(zram_major, "zram");
+	cpuhp_remove_multi_state(CPUHP_ZCOMP_PREPARE);
 }
 
 static int __init zram_init(void)
 {
 	int ret;
 
+	ret = cpuhp_setup_state_multi(CPUHP_ZCOMP_PREPARE, "block/zram:prepare",
+				      zcomp_cpu_up_prepare, zcomp_cpu_dead);
+	if (ret < 0)
+		return ret;
+
 	ret = class_register(&zram_control_class);
 	if (ret) {
 		pr_err("Unable to register zram-control class\n");
+		cpuhp_remove_multi_state(CPUHP_ZCOMP_PREPARE);
 		return ret;
 	}
 
@@ -1452,6 +1460,7 @@ static int __init zram_init(void)
 	if (zram_major <= 0) {
 		pr_err("Unable to get major number\n");
 		class_unregister(&zram_control_class);
+		cpuhp_remove_multi_state(CPUHP_ZCOMP_PREPARE);
 		return -EBUSY;
 	}
 
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 71c6822dd5be..22acee76cf4c 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -69,6 +69,7 @@ enum cpuhp_state {
 	CPUHP_MM_ZSWP_MEM_PREPARE,
 	CPUHP_MM_ZSWP_POOL_PREPARE,
 	CPUHP_KVM_PPC_BOOK3S_PREPARE,
+	CPUHP_ZCOMP_PREPARE,
 	CPUHP_TIMERS_DEAD,
 	CPUHP_NOTF_ERR_INJ_PREPARE,
 	CPUHP_MIPS_SOC_PREPARE,
-- 
2.10.2

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

cpu hotplug: convert more drivers (batch #6 and last) Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
  [PATCH 01/22] cpufreq/acpi-cpufreq: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 01/22] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Viresh Kumar <viresh.kumar@linaro.org> - 2016-11-28 06:20 +0100
      Re: [PATCH 01/22] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-28 10:50 +0100
        [PATCH 01/22 v2] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-28 11:00 +0100
          Re: [PATCH 01/22 v2] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Viresh Kumar <viresh.kumar@linaro.org> - 2016-11-28 11:00 +0100
          Re: [PATCH 01/22 v2] cpufreq/acpi-cpufreq: Convert to hotplug state machine "Rafael J. Wysocki" <rafael@kernel.org> - 2016-11-28 13:50 +0100
  [PATCH 13/22] iommu/vt-d: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] iommu/vt-d: Convert to hotplug state machine tip-bot for Anna-Maria Gleixner <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 11/22] mm/zswap: Convert dst-mem to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] mm/zswap: Convert dst-mem to hotplug state  machine tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 19/22] soc/fsl/qbman: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] soc/fsl/qbman: Convert to hotplug state machine tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 04/22] idle/intel: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 04/22] idle/intel: Convert to hotplug state machine Thomas Gleixner <tglx@linutronix.de> - 2016-11-28 18:40 +0100
      Re: [PATCH 04/22] idle/intel: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-29 10:50 +0100
        [PATCH 04/22 v2] idle/intel: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-29 11:00 +0100
  [PATCH 07/22] mm/vmstat: Drop get_online_cpus() from init_cpu_node_state/vmstat_cpu_dead() Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 07/22] mm/vmstat: Drop get_online_cpus() from  init_cpu_node_state/vmstat_cpu_dead() Michal Hocko <mhocko@kernel.org> - 2016-11-28 10:30 +0100
    [tip:smp/hotplug] mm/vmstat: Drop get_online_cpus() from  init_cpu_node_state/vmstat_cpu_dead() tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 03/22] idle/intel: Remove superfluous SMP fuction call Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
  [PATCH 06/22] tracing/rb: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] tracing/rb: Convert to hotplug state machine tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
      [linux-next] tracing/rb: NULL pointer dereference at  trace_rb_cpu_prepare() Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> - 2016-12-07 12:20 +0100
        [PATCH] tracing/rb: init the CPU mask on allocation Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-12-07 14:40 +0100
          [tip:smp/hotplug] tracing/rb: Init the CPU mask on allocation tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-07 14:50 +0100
          Re: [PATCH] tracing/rb: init the CPU mask on allocation Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> - 2016-12-07 15:40 +0100
  [PATCH 16/22] arm64/cpuinfo: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 16/22] arm64/cpuinfo: Convert to hotplug state machine Suzuki K Poulose <suzuki.poulose@arm.com> - 2016-11-29 18:30 +0100
    [tip:smp/hotplug] arm64/cpuinfo: Convert to hotplug state machine tip-bot for Anna-Maria Gleixner <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 22/22] Remove obsolete cpu hotplug register / unregister functions Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
  [PATCH 18/22] zram: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] zram: Convert to hotplug state machine tip-bot for Anna-Maria Gleixner <tipbot@zytor.com> - 2016-12-02 01:20 +0100

csiph-web