Commit a4a00b45 authored by Muchun Song's avatar Muchun Song Committed by Andrew Morton
Browse files

mm: hugetlb: eliminate memory-less nodes handling

The memory-notify-based approach aims to handle meory-less nodes, however,
it just adds the complexity of code as pointed by David in thread [1]. 
The handling of memory-less nodes is introduced by commit 4faf8d95
("hugetlb: handle memory hot-plug events").  >From its commit message, we
cannot find any necessity of handling this case.  So, we can simply
register/unregister sysfs entries in register_node/unregister_node to
simlify the code.

BTW, hotplug callback added because in hugetlb_register_all_nodes() we
register sysfs nodes only for N_MEMORY nodes, seeing commit 9b5e5d0f,
which said it was a preparation for handling memory-less nodes via memory
hotplug.  Since we want to remove memory hotplug, so make sure we only
register per-node sysfs for online (N_ONLINE) nodes in
hugetlb_register_all_nodes().

https://lore.kernel.org/linux-mm/60933ffc-b850-976c-78a0-0ee6e0ea9ef0@redhat.com/ [1]
Link: https://lkml.kernel.org/r/20220914072603.60293-3-songmuchun@bytedance.com


Suggested-by: default avatarDavid Hildenbrand <david@redhat.com>
Signed-off-by: default avatarMuchun Song <songmuchun@bytedance.com>
Acked-by: default avatarDavid Hildenbrand <david@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent b958d4d0
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/pm_runtime.h>
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/hugetlb.h>

static struct bus_type node_subsys = {
	.name = "node",
@@ -608,10 +609,12 @@ static int register_node(struct node *node, int num)
	node->dev.groups = node_dev_groups;
	error = device_register(&node->dev);

	if (error)
	if (error) {
		put_device(&node->dev);
	else
	} else {
		hugetlb_register_node(node);
		compaction_register_node(node);
	}

	return error;
}
@@ -625,6 +628,7 @@ static int register_node(struct node *node, int num)
 */
void unregister_node(struct node *node)
{
	hugetlb_unregister_node(node);
	compaction_unregister_node(node);
	node_remove_accesses(node);
	node_remove_caches(node);
+14 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
struct ctl_table;
struct user_struct;
struct mmu_gather;
struct node;

#ifndef is_hugepd
typedef struct { unsigned long pd; } hugepd_t;
@@ -935,6 +936,11 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
}
#endif

#ifdef CONFIG_NUMA
void hugetlb_register_node(struct node *node);
void hugetlb_unregister_node(struct node *node);
#endif

#else	/* CONFIG_HUGETLB_PAGE */
struct hstate {};

@@ -1109,6 +1115,14 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
				   pte_t *ptep, pte_t pte)
{
}

static inline void hugetlb_register_node(struct node *node)
{
}

static inline void hugetlb_unregister_node(struct node *node)
{
}
#endif	/* CONFIG_HUGETLB_PAGE */

static inline spinlock_t *huge_pte_lock(struct hstate *h,
+29 −41
Original line number Diff line number Diff line
@@ -3871,24 +3871,8 @@ static int hugetlb_sysfs_add_hstate(struct hstate *h, struct kobject *parent,
	return 0;
}

static void __init hugetlb_sysfs_init(void)
{
	struct hstate *h;
	int err;

	hugepages_kobj = kobject_create_and_add("hugepages", mm_kobj);
	if (!hugepages_kobj)
		return;

	for_each_hstate(h) {
		err = hugetlb_sysfs_add_hstate(h, hugepages_kobj,
					 hstate_kobjs, &hstate_attr_group);
		if (err)
			pr_err("HugeTLB: Unable to add hstate %s", h->name);
	}
}

#ifdef CONFIG_NUMA
static bool hugetlb_sysfs_initialized __ro_after_init;

/*
 * node_hstate/s - associate per node hstate attributes, via their kobjects,
@@ -3944,7 +3928,7 @@ static struct hstate *kobj_to_node_hstate(struct kobject *kobj, int *nidp)
 * Unregister hstate attributes from a single node device.
 * No-op if no hstate attributes attached.
 */
static void hugetlb_unregister_node(struct node *node)
void hugetlb_unregister_node(struct node *node)
{
	struct hstate *h;
	struct node_hstate *nhs = &node_hstates[node->dev.id];
@@ -3974,12 +3958,15 @@ static void hugetlb_unregister_node(struct node *node)
 * Register hstate attributes for a single node device.
 * No-op if attributes already registered.
 */
static void hugetlb_register_node(struct node *node)
void hugetlb_register_node(struct node *node)
{
	struct hstate *h;
	struct node_hstate *nhs = &node_hstates[node->dev.id];
	int err;

	if (!hugetlb_sysfs_initialized)
		return;

	if (nhs->hugepages_kobj)
		return;		/* already allocated */

@@ -4001,23 +3988,6 @@ static void hugetlb_register_node(struct node *node)
	}
}

static int __meminit hugetlb_memory_callback(struct notifier_block *self,
					     unsigned long action, void *arg)
{
	struct memory_notify *mnb = arg;
	int nid = mnb->status_change_nid;

	if (nid == NUMA_NO_NODE)
		return NOTIFY_DONE;

	if (action == MEM_GOING_ONLINE)
		hugetlb_register_node(node_devices[nid]);
	else if (action == MEM_CANCEL_ONLINE || action == MEM_OFFLINE)
		hugetlb_unregister_node(node_devices[nid]);

	return NOTIFY_OK;
}

/*
 * hugetlb init time:  register hstate attributes for all registered node
 * devices of nodes that have memory.  All on-line nodes should have
@@ -4027,11 +3997,8 @@ static void __init hugetlb_register_all_nodes(void)
{
	int nid;

	get_online_mems();
	hotplug_memory_notifier(hugetlb_memory_callback, 0);
	for_each_node_state(nid, N_MEMORY)
	for_each_online_node(nid)
		hugetlb_register_node(node_devices[nid]);
	put_online_mems();
}
#else	/* !CONFIG_NUMA */

@@ -4055,6 +4022,28 @@ static inline __init void hugetlb_cma_check(void)
}
#endif

static void __init hugetlb_sysfs_init(void)
{
	struct hstate *h;
	int err;

	hugepages_kobj = kobject_create_and_add("hugepages", mm_kobj);
	if (!hugepages_kobj)
		return;

	for_each_hstate(h) {
		err = hugetlb_sysfs_add_hstate(h, hugepages_kobj,
					 hstate_kobjs, &hstate_attr_group);
		if (err)
			pr_err("HugeTLB: Unable to add hstate %s", h->name);
	}

#ifdef CONFIG_NUMA
	hugetlb_sysfs_initialized = true;
#endif
	hugetlb_register_all_nodes();
}

static int __init hugetlb_init(void)
{
	int i;
@@ -4109,7 +4098,6 @@ static int __init hugetlb_init(void)
	report_hugepages();

	hugetlb_sysfs_init();
	hugetlb_register_all_nodes();
	hugetlb_cgroup_file_init();

#ifdef CONFIG_SMP