numa: convert static memory to dynamically allocated memory for per node device
We use a static array to store struct node. In many cases, we don't have too many nodes, and some memory will be unused. Convert it to per-device dynamically allocated memory. Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Cc: David Rientjes <rientjes@google.com> Cc: Jiang Liu <liuj97@gmail.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
97d0da2204
Коммит
8732794b16
|
@ -607,7 +607,7 @@ static void register_nodes(void)
|
||||||
|
|
||||||
int sysfs_add_device_to_node(struct device *dev, int nid)
|
int sysfs_add_device_to_node(struct device *dev, int nid)
|
||||||
{
|
{
|
||||||
struct node *node = &node_devices[nid];
|
struct node *node = node_devices[nid];
|
||||||
return sysfs_create_link(&node->dev.kobj, &dev->kobj,
|
return sysfs_create_link(&node->dev.kobj, &dev->kobj,
|
||||||
kobject_name(&dev->kobj));
|
kobject_name(&dev->kobj));
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
|
||||||
|
|
||||||
void sysfs_remove_device_from_node(struct device *dev, int nid)
|
void sysfs_remove_device_from_node(struct device *dev, int nid)
|
||||||
{
|
{
|
||||||
struct node *node = &node_devices[nid];
|
struct node *node = node_devices[nid];
|
||||||
sysfs_remove_link(&node->dev.kobj, kobject_name(&dev->kobj));
|
sysfs_remove_link(&node->dev.kobj, kobject_name(&dev->kobj));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
|
EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
|
||||||
|
|
|
@ -306,7 +306,7 @@ void unregister_node(struct node *node)
|
||||||
device_unregister(&node->dev);
|
device_unregister(&node->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct node node_devices[MAX_NUMNODES];
|
struct node *node_devices[MAX_NUMNODES];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* register cpu under node
|
* register cpu under node
|
||||||
|
@ -323,15 +323,15 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid)
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = sysfs_create_link(&node_devices[nid].dev.kobj,
|
ret = sysfs_create_link(&node_devices[nid]->dev.kobj,
|
||||||
&obj->kobj,
|
&obj->kobj,
|
||||||
kobject_name(&obj->kobj));
|
kobject_name(&obj->kobj));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return sysfs_create_link(&obj->kobj,
|
return sysfs_create_link(&obj->kobj,
|
||||||
&node_devices[nid].dev.kobj,
|
&node_devices[nid]->dev.kobj,
|
||||||
kobject_name(&node_devices[nid].dev.kobj));
|
kobject_name(&node_devices[nid]->dev.kobj));
|
||||||
}
|
}
|
||||||
|
|
||||||
int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
|
int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
|
||||||
|
@ -345,10 +345,10 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sysfs_remove_link(&node_devices[nid].dev.kobj,
|
sysfs_remove_link(&node_devices[nid]->dev.kobj,
|
||||||
kobject_name(&obj->kobj));
|
kobject_name(&obj->kobj));
|
||||||
sysfs_remove_link(&obj->kobj,
|
sysfs_remove_link(&obj->kobj,
|
||||||
kobject_name(&node_devices[nid].dev.kobj));
|
kobject_name(&node_devices[nid]->dev.kobj));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -390,15 +390,15 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
|
||||||
continue;
|
continue;
|
||||||
if (page_nid != nid)
|
if (page_nid != nid)
|
||||||
continue;
|
continue;
|
||||||
ret = sysfs_create_link_nowarn(&node_devices[nid].dev.kobj,
|
ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
|
||||||
&mem_blk->dev.kobj,
|
&mem_blk->dev.kobj,
|
||||||
kobject_name(&mem_blk->dev.kobj));
|
kobject_name(&mem_blk->dev.kobj));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
|
return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
|
||||||
&node_devices[nid].dev.kobj,
|
&node_devices[nid]->dev.kobj,
|
||||||
kobject_name(&node_devices[nid].dev.kobj));
|
kobject_name(&node_devices[nid]->dev.kobj));
|
||||||
}
|
}
|
||||||
/* mem section does not span the specified node */
|
/* mem section does not span the specified node */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -431,10 +431,10 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
|
||||||
continue;
|
continue;
|
||||||
if (node_test_and_set(nid, *unlinked_nodes))
|
if (node_test_and_set(nid, *unlinked_nodes))
|
||||||
continue;
|
continue;
|
||||||
sysfs_remove_link(&node_devices[nid].dev.kobj,
|
sysfs_remove_link(&node_devices[nid]->dev.kobj,
|
||||||
kobject_name(&mem_blk->dev.kobj));
|
kobject_name(&mem_blk->dev.kobj));
|
||||||
sysfs_remove_link(&mem_blk->dev.kobj,
|
sysfs_remove_link(&mem_blk->dev.kobj,
|
||||||
kobject_name(&node_devices[nid].dev.kobj));
|
kobject_name(&node_devices[nid]->dev.kobj));
|
||||||
}
|
}
|
||||||
NODEMASK_FREE(unlinked_nodes);
|
NODEMASK_FREE(unlinked_nodes);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -500,7 +500,7 @@ static void node_hugetlb_work(struct work_struct *work)
|
||||||
|
|
||||||
static void init_node_hugetlb_work(int nid)
|
static void init_node_hugetlb_work(int nid)
|
||||||
{
|
{
|
||||||
INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work);
|
INIT_WORK(&node_devices[nid]->node_work, node_hugetlb_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int node_memory_callback(struct notifier_block *self,
|
static int node_memory_callback(struct notifier_block *self,
|
||||||
|
@ -517,7 +517,7 @@ static int node_memory_callback(struct notifier_block *self,
|
||||||
* when transitioning to/from memoryless state.
|
* when transitioning to/from memoryless state.
|
||||||
*/
|
*/
|
||||||
if (nid != NUMA_NO_NODE)
|
if (nid != NUMA_NO_NODE)
|
||||||
schedule_work(&node_devices[nid].node_work);
|
schedule_work(&node_devices[nid]->node_work);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM_GOING_ONLINE:
|
case MEM_GOING_ONLINE:
|
||||||
|
@ -558,9 +558,13 @@ int register_one_node(int nid)
|
||||||
struct node *parent = NULL;
|
struct node *parent = NULL;
|
||||||
|
|
||||||
if (p_node != nid)
|
if (p_node != nid)
|
||||||
parent = &node_devices[p_node];
|
parent = node_devices[p_node];
|
||||||
|
|
||||||
error = register_node(&node_devices[nid], nid, parent);
|
node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
|
||||||
|
if (!node_devices[nid])
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
error = register_node(node_devices[nid], nid, parent);
|
||||||
|
|
||||||
/* link cpu under this node */
|
/* link cpu under this node */
|
||||||
for_each_present_cpu(cpu) {
|
for_each_present_cpu(cpu) {
|
||||||
|
@ -581,7 +585,9 @@ int register_one_node(int nid)
|
||||||
|
|
||||||
void unregister_one_node(int nid)
|
void unregister_one_node(int nid)
|
||||||
{
|
{
|
||||||
unregister_node(&node_devices[nid]);
|
unregister_node(node_devices[nid]);
|
||||||
|
kfree(node_devices[nid]);
|
||||||
|
node_devices[nid] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct node {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct memory_block;
|
struct memory_block;
|
||||||
extern struct node node_devices[];
|
extern struct node *node_devices[];
|
||||||
typedef void (*node_registration_func_t)(struct node *);
|
typedef void (*node_registration_func_t)(struct node *);
|
||||||
|
|
||||||
extern int register_node(struct node *, int, struct node *);
|
extern int register_node(struct node *, int, struct node *);
|
||||||
|
|
|
@ -1800,7 +1800,7 @@ static void hugetlb_unregister_all_nodes(void)
|
||||||
* remove hstate attributes from any nodes that have them.
|
* remove hstate attributes from any nodes that have them.
|
||||||
*/
|
*/
|
||||||
for (nid = 0; nid < nr_node_ids; nid++)
|
for (nid = 0; nid < nr_node_ids; nid++)
|
||||||
hugetlb_unregister_node(&node_devices[nid]);
|
hugetlb_unregister_node(node_devices[nid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1845,7 +1845,7 @@ static void hugetlb_register_all_nodes(void)
|
||||||
int nid;
|
int nid;
|
||||||
|
|
||||||
for_each_node_state(nid, N_HIGH_MEMORY) {
|
for_each_node_state(nid, N_HIGH_MEMORY) {
|
||||||
struct node *node = &node_devices[nid];
|
struct node *node = node_devices[nid];
|
||||||
if (node->dev.id == nid)
|
if (node->dev.id == nid)
|
||||||
hugetlb_register_node(node);
|
hugetlb_register_node(node);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче