+ mm-memory_hotplug-fix-try_offline_node-v3.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     Subject: mm/memory_hotplug: Fix try_offline_node()
has been added to the -mm tree.  Its filename is
     mm-memory_hotplug-fix-try_offline_node-v3.patch

This patch should soon appear at
    http://ozlabs.org/~akpm/mmots/broken-out/mm-memory_hotplug-fix-try_offline_node-v3.patch
and later at
    http://ozlabs.org/~akpm/mmotm/broken-out/mm-memory_hotplug-fix-try_offline_node-v3.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

------------------------------------------------------
From: David Hildenbrand <david@xxxxxxxxxx>
Subject: mm/memory_hotplug: Fix try_offline_node()

Introduce and use for_each_memory_block(), which will run significantly
faster than walk_memory_blocks().

Link: http://lkml.kernel.org/r/20191102120221.7553-1-david@xxxxxxxxxx
Fixes: 60a5a19e7419 ("memory-hotplug: remove sysfs file of node")
Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") # visiable after d0dc12e86b319
Cc: Tang Chen <tangchen@xxxxxxxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: "Rafael J. Wysocki" <rafael@xxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Keith Busch <keith.busch@xxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: "Peter Zijlstra (Intel)" <peterz@xxxxxxxxxxxxx>
Cc: Jani Nikula <jani.nikula@xxxxxxxxx>
Cc: Nayna Jain <nayna@xxxxxxxxxxxxx>
Cc: Michal Hocko <mhocko@xxxxxxxx>
Cc: Oscar Salvador <osalvador@xxxxxxx>
Cc: Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx>
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>
Cc: Pavel Tatashin <pasha.tatashin@xxxxxxxxxx>
Signed-off-by: David Hildenbrand <david@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 drivers/base/memory.c  |   36 ++++++++++++++++++++++++++++++++++++
 drivers/base/node.c    |    9 ---------
 fs/sysfs/symlink.c     |   21 ---------------------
 include/linux/memory.h |    1 +
 include/linux/node.h   |    7 -------
 include/linux/sysfs.h  |    6 ------
 mm/memory_hotplug.c    |   17 +++++++++--------
 7 files changed, 46 insertions(+), 51 deletions(-)

--- a/drivers/base/memory.c~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/drivers/base/memory.c
@@ -872,3 +872,39 @@ int walk_memory_blocks(unsigned long sta
 	}
 	return ret;
 }
+
+struct for_each_memory_block_cb_data {
+	walk_memory_blocks_func_t func;
+	void *arg;
+};
+
+static int for_each_memory_block_cb(struct device *dev, void *data)
+{
+	struct memory_block *mem = to_memory_block(dev);
+	struct for_each_memory_block_cb_data *cb_data = data;
+
+	return cb_data->func(mem, cb_data->arg);
+}
+
+/**
+ * for_each_memory_block - walk through all present memory blocks
+ *
+ * @arg: argument passed to func
+ * @func: callback for each memory block walked
+ *
+ * This function walks through all present memory blocks, calling func on
+ * each memory block.
+ *
+ * In case func() returns an error, walking is aborted and the error is
+ * returned.
+ */
+int for_each_memory_block(void *arg, walk_memory_blocks_func_t func)
+{
+	struct for_each_memory_block_cb_data cb_data = {
+		.func = func,
+		.arg = arg,
+	};
+
+	return bus_for_each_dev(&memory_subsys, NULL, &cb_data,
+				for_each_memory_block_cb);
+}
--- a/drivers/base/node.c~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/drivers/base/node.c
@@ -836,15 +836,6 @@ int link_mem_sections(int nid, unsigned
 				  register_mem_sect_under_node);
 }
 
-bool memory_block_registered_under_node(struct memory_block *mem, int nid)
-{
-	if (mem->nid == nid)
-		return true;
-	/* memory blocks can span multiple nodes. Check against the link. */
-	return sysfs_link_exists(&mem->dev.kobj,
-				 kobject_name(&node_devices[nid]->dev.kobj));
-}
-
 #ifdef CONFIG_HUGETLBFS
 /*
  * Handle per node hstate attribute [un]registration on transistions
--- a/fs/sysfs/symlink.c~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/fs/sysfs/symlink.c
@@ -154,27 +154,6 @@ void sysfs_remove_link(struct kobject *k
 EXPORT_SYMBOL_GPL(sysfs_remove_link);
 
 /**
- *	sysfs_link_exists - test if a symlink exists in object's directory.
- *	@kobj:	object we're acting for.
- *	@name:	name of the symlink to test.
- */
-bool sysfs_link_exists(struct kobject *kobj, const char *name)
-{
-	struct kernfs_node *parent = NULL, *kn;
-
-	if (!kobj)
-		parent = sysfs_root_kn;
-	else
-		parent = kobj->sd;
-
-	kn = kernfs_find_and_get(parent, name);
-	kernfs_put(kn);
-
-	return kn != NULL;
-}
-EXPORT_SYMBOL_GPL(sysfs_link_exists);
-
-/**
  *	sysfs_rename_link_ns - rename symlink in object's directory.
  *	@kobj:	object we're acting for.
  *	@targ:	object we're pointing to.
--- a/include/linux/memory.h~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/include/linux/memory.h
@@ -119,6 +119,7 @@ extern struct memory_block *find_memory_
 typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *);
 extern int walk_memory_blocks(unsigned long start, unsigned long size,
 			      void *arg, walk_memory_blocks_func_t func);
+extern int for_each_memory_block(void *arg, walk_memory_blocks_func_t func);
 #define CONFIG_MEM_BLOCK_SIZE	(PAGES_PER_SECTION<<PAGE_SHIFT)
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 
--- a/include/linux/node.h~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/include/linux/node.h
@@ -138,8 +138,6 @@ extern void unregister_one_node(int nid)
 extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern void unregister_memory_block_under_nodes(struct memory_block *mem_blk);
-extern bool memory_block_registered_under_node(struct memory_block *mem,
-					       int nid);
 
 extern int register_memory_node_under_compute_node(unsigned int mem_nid,
 						   unsigned int cpu_nid,
@@ -173,11 +171,6 @@ static inline int unregister_cpu_under_n
 static inline void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
 {
 }
-static inline bool memory_block_registered_under_node(struct memory_block *mem,
-						      int nid)
-{
-	return true;
-}
 
 static inline void register_hugetlbfs_with_node(node_registration_func_t reg,
 						node_registration_func_t unreg)
--- a/include/linux/sysfs.h~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/include/linux/sysfs.h
@@ -265,7 +265,6 @@ int __must_check sysfs_create_link_nowar
 					  struct kobject *target,
 					  const char *name);
 void sysfs_remove_link(struct kobject *kobj, const char *name);
-bool sysfs_link_exists(struct kobject *kobj, const char *name);
 
 int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target,
 			 const char *old_name, const char *new_name,
@@ -421,11 +420,6 @@ static inline void sysfs_remove_link(str
 {
 }
 
-static inline bool sysfs_link_exists(struct kobject *kobj, const char *name)
-{
-	return true;
-}
-
 static inline int sysfs_rename_link_ns(struct kobject *k, struct kobject *t,
 				       const char *old_name,
 				       const char *new_name, const void *ns)
--- a/mm/memory_hotplug.c~mm-memory_hotplug-fix-try_offline_node-v3
+++ a/mm/memory_hotplug.c
@@ -1646,13 +1646,16 @@ static int check_cpu_on_node(pg_data_t *
 	return 0;
 }
 
-static int check_no_memblock_registered_under_node_cb(struct memory_block *mem,
-						      void *arg)
+static int check_no_memblock_for_node_cb(struct memory_block *mem, void *arg)
 {
+	int nid = *(int *)arg;
 
-	const int nid = *(int *)arg;
-
-	return memory_block_registered_under_node(mem, nid) ? -EEXIST : 0;
+	/*
+	 * If a memory block belongs to multiple nodes, the stored nid is not
+	 * reliable. However, such blocks are always online (e.g., cannot get
+	 * offlined) and, therefore, are still spanned by the node.
+	 */
+	return mem->nid == nid ? -EEXIST : 0;
 }
 
 /**
@@ -1666,7 +1669,6 @@ static int check_no_memblock_registered_
  */
 void try_offline_node(int nid)
 {
-	unsigned long end_pfn = section_nr_to_pfn(__highest_present_section_nr);
 	pg_data_t *pgdat = NODE_DATA(nid);
 	int rc;
 
@@ -1683,8 +1685,7 @@ void try_offline_node(int nid)
 	 * node. They will get spanned by the node once they get onlined.
 	 * However, they link to the node in sysfs and can get onlined later.
 	 */
-	rc = walk_memory_blocks(0, PFN_PHYS(end_pfn), &nid,
-				check_no_memblock_registered_under_node_cb);
+	rc = for_each_memory_block(&nid, check_no_memblock_for_node_cb);
 	if (rc)
 		return;
 
_

Patches currently in -mm which might be from david@xxxxxxxxxx are

mm-memory_hotplug-fix-try_offline_node.patch
mm-memory_hotplug-fix-try_offline_node-v3.patch
mm-memory_hotplug-export-generic_online_page.patch
hv_balloon-use-generic_online_page.patch
mm-memory_hotplug-remove-__online_page_free-and-__online_page_increment_counters.patch
mm-memory_hotplug-dont-access-uninitialized-memmaps-in-shrink_zone_span.patch
mm-memory_hotplug-shrink-zones-when-offlining-memory.patch
mm-memory_hotplug-poison-memmap-in-remove_pfn_range_from_zone.patch
mm-memory_hotplug-we-always-have-a-zone-in-find_smallestbiggest_section_pfn.patch
mm-memory_hotplug-dont-check-for-all-holes-in-shrink_zone_span.patch
mm-memory_hotplug-drop-local-variables-in-shrink_zone_span.patch
mm-memory_hotplug-cleanup-__remove_pages.patch
mm-page_allocc-dont-set-pages-pagereserved-when-offlining.patch
mm-page_isolationc-convert-skip_hwpoison-to-memory_offline.patch




[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux