diff options
author | Sergey Senozhatsky <sergey.senozhatsky@gmail.com> | 2014-12-12 19:56:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-13 15:42:50 -0500 |
commit | b1b00a5b8a6cf32e3973507decf1216709b55072 (patch) | |
tree | 768a19295b08df9423ebae482949f3dbe35a4c23 /mm/zsmalloc.c | |
parent | 8c7f01025f7becd577bed9af93f974fc6798c5a3 (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.c | 39 |
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 | ||
884 | static void zs_exit(void) | 884 | static 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 | ||
901 | static int zs_init(void) | 897 | static 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 | ||
914 | static 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 | |||
922 | static 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; |
923 | fail: | ||
924 | zs_exit(); | ||
925 | return notifier_to_errno(ret); | ||
926 | } | 935 | } |
927 | 936 | ||
928 | static unsigned int get_maxobj_per_zspage(int size, int pages_per_zspage) | 937 | static unsigned int get_maxobj_per_zspage(int size, int pages_per_zspage) |