diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-02-24 17:55:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-24 20:46:53 -0500 |
commit | 3fc21924100b13f73c734d0ce8dfcfe913fcf7a8 (patch) | |
tree | 3d9f46a4936f591e5e306cf909e44fe6012efe89 | |
parent | b5d24fda9c3dce51fcb4eee459550a458eaaf1e2 (diff) |
mm: validate device_hotplug is held for memory hotplug
mem_hotplug_begin() assumes that it can set mem_hotplug.active_writer
and run the hotplug process without racing another thread. Validate
this assumption with a lockdep assertion.
Link: http://lkml.kernel.org/r/148693886229.16345.1770484669403334689.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Reported-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Toshi Kani <toshi.kani@hpe.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Logan Gunthorpe <logang@deltatee.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/base/core.c | 5 | ||||
-rw-r--r-- | include/linux/device.h | 1 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 2 |
3 files changed, 8 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 8c25e68e67d7..3050e6f99403 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -638,6 +638,11 @@ int lock_device_hotplug_sysfs(void) | |||
638 | return restart_syscall(); | 638 | return restart_syscall(); |
639 | } | 639 | } |
640 | 640 | ||
641 | void assert_held_device_hotplug(void) | ||
642 | { | ||
643 | lockdep_assert_held(&device_hotplug_lock); | ||
644 | } | ||
645 | |||
641 | #ifdef CONFIG_BLOCK | 646 | #ifdef CONFIG_BLOCK |
642 | static inline int device_is_not_partition(struct device *dev) | 647 | static inline int device_is_not_partition(struct device *dev) |
643 | { | 648 | { |
diff --git a/include/linux/device.h b/include/linux/device.h index bd684fc8ec1d..a48a7ff70164 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -1139,6 +1139,7 @@ static inline bool device_supports_offline(struct device *dev) | |||
1139 | extern void lock_device_hotplug(void); | 1139 | extern void lock_device_hotplug(void); |
1140 | extern void unlock_device_hotplug(void); | 1140 | extern void unlock_device_hotplug(void); |
1141 | extern int lock_device_hotplug_sysfs(void); | 1141 | extern int lock_device_hotplug_sysfs(void); |
1142 | void assert_held_device_hotplug(void); | ||
1142 | extern int device_offline(struct device *dev); | 1143 | extern int device_offline(struct device *dev); |
1143 | extern int device_online(struct device *dev); | 1144 | extern int device_online(struct device *dev); |
1144 | extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); | 1145 | extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index d67787d10ff0..92a242af5a91 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -126,6 +126,8 @@ void put_online_mems(void) | |||
126 | 126 | ||
127 | void mem_hotplug_begin(void) | 127 | void mem_hotplug_begin(void) |
128 | { | 128 | { |
129 | assert_held_device_hotplug(); | ||
130 | |||
129 | mem_hotplug.active_writer = current; | 131 | mem_hotplug.active_writer = current; |
130 | 132 | ||
131 | memhp_lock_acquire(); | 133 | memhp_lock_acquire(); |