diff options
author | Omar Sandoval <osandov@fb.com> | 2018-08-22 00:54:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-22 13:52:46 -0400 |
commit | bf53183164dbba00b342df7d2215b33007ed83ed (patch) | |
tree | 679d8cf52528ddbcffbbf773703fae7fa3225a61 /fs/proc/kcore.c | |
parent | a8dd9c4df18edc873d244790d163564a5d17626b (diff) |
proc/kcore: don't grab lock for memory hotplug notifier
The memory hotplug notifier kcore_callback() only needs kclist_lock to
prevent races with __kcore_update_ram(), but we can easily eliminate that
race by using an atomic xchg() in __kcore_update_ram(). This is
preparation for converting kclist_lock to an rwsem.
Link: http://lkml.kernel.org/r/0a4bc89f4dbde8b5b2ea309f7b4fb6a85fe29df2.1531953780.git.osandov@fb.com
Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Bhupesh Sharma <bhsharma@redhat.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: James Morse <james.morse@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc/kcore.c')
-rw-r--r-- | fs/proc/kcore.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index b0b9a76f28d6..e83f15a4f66d 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -118,7 +118,7 @@ static void __kcore_update_ram(struct list_head *list) | |||
118 | LIST_HEAD(garbage); | 118 | LIST_HEAD(garbage); |
119 | 119 | ||
120 | write_lock(&kclist_lock); | 120 | write_lock(&kclist_lock); |
121 | if (kcore_need_update) { | 121 | if (xchg(&kcore_need_update, 0)) { |
122 | list_for_each_entry_safe(pos, tmp, &kclist_head, list) { | 122 | list_for_each_entry_safe(pos, tmp, &kclist_head, list) { |
123 | if (pos->type == KCORE_RAM | 123 | if (pos->type == KCORE_RAM |
124 | || pos->type == KCORE_VMEMMAP) | 124 | || pos->type == KCORE_VMEMMAP) |
@@ -127,7 +127,6 @@ static void __kcore_update_ram(struct list_head *list) | |||
127 | list_splice_tail(list, &kclist_head); | 127 | list_splice_tail(list, &kclist_head); |
128 | } else | 128 | } else |
129 | list_splice(list, &garbage); | 129 | list_splice(list, &garbage); |
130 | kcore_need_update = 0; | ||
131 | proc_root_kcore->size = get_kcore_size(&nphdr, &size); | 130 | proc_root_kcore->size = get_kcore_size(&nphdr, &size); |
132 | write_unlock(&kclist_lock); | 131 | write_unlock(&kclist_lock); |
133 | 132 | ||
@@ -593,9 +592,8 @@ static int __meminit kcore_callback(struct notifier_block *self, | |||
593 | switch (action) { | 592 | switch (action) { |
594 | case MEM_ONLINE: | 593 | case MEM_ONLINE: |
595 | case MEM_OFFLINE: | 594 | case MEM_OFFLINE: |
596 | write_lock(&kclist_lock); | ||
597 | kcore_need_update = 1; | 595 | kcore_need_update = 1; |
598 | write_unlock(&kclist_lock); | 596 | break; |
599 | } | 597 | } |
600 | return NOTIFY_OK; | 598 | return NOTIFY_OK; |
601 | } | 599 | } |