From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753873AbcKZXQ1 (ORCPT ); Sat, 26 Nov 2016 18:16:27 -0500 Received: from Galois.linutronix.de ([146.0.238.70]:43546 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753341AbcKZXOh (ORCPT ); Sat, 26 Nov 2016 18:14:37 -0500 From: Sebastian Andrzej Siewior To: linux-kernel@vger.kernel.org Cc: rt@linutronix.de, tglx@linutronix.de, Anna-Maria Gleixner , Minchan Kim , Nitin Gupta , Sergey Senozhatsky , Sebastian Andrzej Siewior Subject: [PATCH 18/22] zram: Convert to hotplug state machine Date: Sun, 27 Nov 2016 00:13:46 +0100 Message-Id: <20161126231350.10321-19-bigeasy@linutronix.de> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161126231350.10321-1-bigeasy@linutronix.de> References: <20161126231350.10321-1-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Anna-Maria Gleixner 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 Cc: Nitin Gupta Cc: Sergey Senozhatsky [bigeasy: wire up the multi instance stuff] Signed-off-by: Anna-Maria Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Thomas Gleixner --- 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); } =20 -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 =3D hlist_entry(node, struct zcomp, node); struct zcomp_strm *zstrm; =20 - switch (action) { - case CPU_UP_PREPARE: - if (WARN_ON(*per_cpu_ptr(comp->stream, cpu))) - break; - zstrm =3D 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) =3D zstrm; - break; - case CPU_DEAD: - case CPU_UP_CANCELED: - zstrm =3D *per_cpu_ptr(comp->stream, cpu); - if (!IS_ERR_OR_NULL(zstrm)) - zcomp_strm_free(zstrm); - *per_cpu_ptr(comp->stream, cpu) =3D NULL; - break; - default: - break; + if (WARN_ON(*per_cpu_ptr(comp->stream, cpu))) + return 0; + + zstrm =3D 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) =3D zstrm; + return 0; } =20 -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 =3D (unsigned long)pcpu; - struct zcomp *comp =3D container_of(nb, typeof(*comp), notifier); + struct zcomp *comp =3D hlist_entry(node, struct zcomp, node); + struct zcomp_strm *zstrm; =20 - return __zcomp_cpu_notifier(comp, action, cpu); + zstrm =3D *per_cpu_ptr(comp->stream, cpu); + if (!IS_ERR_OR_NULL(zstrm)) + zcomp_strm_free(zstrm); + *per_cpu_ptr(comp->stream, cpu) =3D NULL; + return 0; } =20 static int zcomp_init(struct zcomp *comp) { - unsigned long cpu; int ret; =20 - comp->notifier.notifier_call =3D zcomp_cpu_notifier; - comp->stream =3D alloc_percpu(struct zcomp_strm *); if (!comp->stream) return -ENOMEM; =20 - cpu_notifier_register_begin(); - for_each_online_cpu(cpu) { - ret =3D __zcomp_cpu_notifier(comp, CPU_UP_PREPARE, cpu); - if (ret =3D=3D NOTIFY_BAD) - goto cleanup; - } - __register_cpu_notifier(&comp->notifier); - cpu_notifier_register_done(); + ret =3D cpuhp_state_add_instance(CPUHP_ZCOMP_PREPARE, &comp->node); + if (ret < 0) + goto cleanup; return 0; =20 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; } =20 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; }; =20 +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); =20 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 #include #include +#include =20 #include "zram_drv.h" =20 @@ -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); } =20 static int __init zram_init(void) { int ret; =20 + ret =3D cpuhp_setup_state_multi(CPUHP_ZCOMP_PREPARE, "block/zram:prepare", + zcomp_cpu_up_prepare, zcomp_cpu_dead); + if (ret < 0) + return ret; + ret =3D 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; } =20 @@ -1452,6 +1460,7 @@ static int __init zram_init(void) if (zram_major <=3D 0) { pr_err("Unable to get major number\n"); class_unregister(&zram_control_class); + cpuhp_remove_multi_state(CPUHP_ZCOMP_PREPARE); return -EBUSY; } =20 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, --=20 2.10.2