aboutsummaryrefslogtreecommitdiffstats
path: root/mm/zsmalloc.c
diff options
context:
space:
mode:
authorSergey Senozhatsky <sergey.senozhatsky@gmail.com>2014-12-12 19:56:56 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-13 15:42:50 -0500
commitb1b00a5b8a6cf32e3973507decf1216709b55072 (patch)
tree768a19295b08df9423ebae482949f3dbe35a4c23 /mm/zsmalloc.c
parent8c7f01025f7becd577bed9af93f974fc6798c5a3 (diff)
zsmalloc: fix zs_init cpu notifier error handling
Mahendran Ganesh reported that zpool-enabled zsmalloc should not call zpool_unregister_driver() from zs_init() if cpu notifier registration has failed, because error handling is performed before we register the driver via zpool_register_driver() call. Factor out cpu notifier registration and unregistration code and fix zs_init() error handling. link: http://lkml.iu.edu//hypermail/linux/kernel/1411.1/04156.html [akpm@linux-foundation.org: squash bogus gcc warning] [akpm@linux-foundation.org: use __init and __exit] Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Reported-by: Mahendran Ganesh <opensource.ganesh@gmail.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Nitin Gupta <ngupta@vflare.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/zsmalloc.c')
-rw-r--r--mm/zsmalloc.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index b3b57ef85830..5481c677e465 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -881,14 +881,10 @@ static struct notifier_block zs_cpu_nb = {
881 .notifier_call = zs_cpu_notifier 881 .notifier_call = zs_cpu_notifier
882}; 882};
883 883
884static void zs_exit(void) 884static void zs_unregister_cpu_notifier(void)
885{ 885{
886 int cpu; 886 int cpu;
887 887
888#ifdef CONFIG_ZPOOL
889 zpool_unregister_driver(&zs_zpool_driver);
890#endif
891
892 cpu_notifier_register_begin(); 888 cpu_notifier_register_begin();
893 889
894 for_each_online_cpu(cpu) 890 for_each_online_cpu(cpu)
@@ -898,31 +894,44 @@ static void zs_exit(void)
898 cpu_notifier_register_done(); 894 cpu_notifier_register_done();
899} 895}
900 896
901static int zs_init(void) 897static int zs_register_cpu_notifier(void)
902{ 898{
903 int cpu, ret; 899 int cpu, uninitialized_var(ret);
904 900
905 cpu_notifier_register_begin(); 901 cpu_notifier_register_begin();
906 902
907 __register_cpu_notifier(&zs_cpu_nb); 903 __register_cpu_notifier(&zs_cpu_nb);
908 for_each_online_cpu(cpu) { 904 for_each_online_cpu(cpu) {
909 ret = zs_cpu_notifier(NULL, CPU_UP_PREPARE, (void *)(long)cpu); 905 ret = zs_cpu_notifier(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
910 if (notifier_to_errno(ret)) { 906 if (notifier_to_errno(ret))
911 cpu_notifier_register_done(); 907 break;
912 goto fail;
913 }
914 } 908 }
915 909
916 cpu_notifier_register_done(); 910 cpu_notifier_register_done();
911 return notifier_to_errno(ret);
912}
917 913
914static void __exit zs_exit(void)
915{
918#ifdef CONFIG_ZPOOL 916#ifdef CONFIG_ZPOOL
919 zpool_register_driver(&zs_zpool_driver); 917 zpool_unregister_driver(&zs_zpool_driver);
920#endif 918#endif
919 zs_unregister_cpu_notifier();
920}
921
922static int __init zs_init(void)
923{
924 int ret = zs_register_cpu_notifier();
925
926 if (ret) {
927 zs_unregister_cpu_notifier();
928 return ret;
929 }
921 930
931#ifdef CONFIG_ZPOOL
932 zpool_register_driver(&zs_zpool_driver);
933#endif
922 return 0; 934 return 0;
923fail:
924 zs_exit();
925 return notifier_to_errno(ret);
926} 935}
927 936
928static unsigned int get_maxobj_per_zspage(int size, int pages_per_zspage) 937static unsigned int get_maxobj_per_zspage(int size, int pages_per_zspage)