Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 138484
b: refs/heads/master
c: 0f16ef7
h: refs/heads/master
v: v3
  • Loading branch information
Nathan Fontenot authored and Benjamin Herrenschmidt committed Feb 23, 2009
1 parent 2c3b965 commit db7da37
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f52862f4070fb930e407d466aa82d8efcc98c9ed
refs/heads/master: 0f16ef7fd3880575b59d0b0f0c9a2ef96e057522
139 changes: 73 additions & 66 deletions trunk/arch/powerpc/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -1012,57 +1012,32 @@ early_param("numa", early_numa);

#ifdef CONFIG_MEMORY_HOTPLUG
/*
* Validate the node associated with the memory section we are
* trying to add.
*/
int valid_hot_add_scn(int *nid, unsigned long start, u32 lmb_size,
unsigned long scn_addr)
{
nodemask_t nodes;

if (*nid < 0 || !node_online(*nid))
*nid = any_online_node(NODE_MASK_ALL);

if ((scn_addr >= start) && (scn_addr < (start + lmb_size))) {
nodes_setall(nodes);
while (NODE_DATA(*nid)->node_spanned_pages == 0) {
node_clear(*nid, nodes);
*nid = any_online_node(nodes);
}

return 1;
}

return 0;
}

/*
* Find the node associated with a hot added memory section represented
* by the ibm,dynamic-reconfiguration-memory node.
* Find the node associated with a hot added memory section for
* memory represented in the device tree by the property
* ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory.
*/
static int hot_add_drconf_scn_to_nid(struct device_node *memory,
unsigned long scn_addr)
{
const u32 *dm;
unsigned int n, rc;
unsigned int drconf_cell_cnt, rc;
unsigned long lmb_size;
int default_nid = any_online_node(NODE_MASK_ALL);
int nid;
struct assoc_arrays aa;
int nid = -1;

n = of_get_drconf_memory(memory, &dm);
if (!n)
return default_nid;;
drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
if (!drconf_cell_cnt)
return -1;

lmb_size = of_get_lmb_size(memory);
if (!lmb_size)
return default_nid;
return -1;

rc = of_get_assoc_arrays(memory, &aa);
if (rc)
return default_nid;
return -1;

for (; n != 0; --n) {
for (; drconf_cell_cnt != 0; --drconf_cell_cnt) {
struct of_drconf_cell drmem;

read_drconf_cell(&drmem, &dm);
Expand All @@ -1073,15 +1048,57 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
|| !(drmem.flags & DRCONF_MEM_ASSIGNED))
continue;

if ((scn_addr < drmem.base_addr)
|| (scn_addr >= (drmem.base_addr + lmb_size)))
continue;

nid = of_drconf_to_nid_single(&drmem, &aa);
break;
}

return nid;
}

/*
* Find the node associated with a hot added memory section for memory
* represented in the device tree as a node (i.e. memory@XXXX) for
* each lmb.
*/
int hot_add_node_scn_to_nid(unsigned long scn_addr)
{
struct device_node *memory = NULL;
int nid = -1;

while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
unsigned long start, size;
int ranges;
const unsigned int *memcell_buf;
unsigned int len;

memcell_buf = of_get_property(memory, "reg", &len);
if (!memcell_buf || len <= 0)
continue;

/* ranges in cell */
ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);

while (ranges--) {
start = read_n_cells(n_mem_addr_cells, &memcell_buf);
size = read_n_cells(n_mem_size_cells, &memcell_buf);

if ((scn_addr < start) || (scn_addr >= (start + size)))
continue;

nid = of_node_to_nid_single(memory);
break;
}

if (valid_hot_add_scn(&nid, drmem.base_addr, lmb_size,
scn_addr))
return nid;
of_node_put(memory);
if (nid >= 0)
break;
}

BUG(); /* section address should be found above */
return 0;
return nid;
}

/*
Expand All @@ -1092,7 +1109,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
int hot_add_scn_to_nid(unsigned long scn_addr)
{
struct device_node *memory = NULL;
int nid;
int nid, found = 0;

if (!numa_enabled || (min_common_depth < 0))
return any_online_node(NODE_MASK_ALL);
Expand All @@ -1101,35 +1118,25 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
if (memory) {
nid = hot_add_drconf_scn_to_nid(memory, scn_addr);
of_node_put(memory);
return nid;
} else {
nid = hot_add_node_scn_to_nid(scn_addr);
}

while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
unsigned long start, size;
int ranges;
const unsigned int *memcell_buf;
unsigned int len;

memcell_buf = of_get_property(memory, "reg", &len);
if (!memcell_buf || len <= 0)
continue;
if (nid < 0 || !node_online(nid))
nid = any_online_node(NODE_MASK_ALL);

/* ranges in cell */
ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
ha_new_range:
start = read_n_cells(n_mem_addr_cells, &memcell_buf);
size = read_n_cells(n_mem_size_cells, &memcell_buf);
nid = of_node_to_nid_single(memory);
if (NODE_DATA(nid)->node_spanned_pages)
return nid;

if (valid_hot_add_scn(&nid, start, size, scn_addr)) {
of_node_put(memory);
return nid;
for_each_online_node(nid) {
if (NODE_DATA(nid)->node_spanned_pages) {
found = 1;
break;
}

if (--ranges) /* process all ranges in cell */
goto ha_new_range;
}
BUG(); /* section address should be found above */
return 0;

BUG_ON(!found);
return nid;
}

#endif /* CONFIG_MEMORY_HOTPLUG */

0 comments on commit db7da37

Please sign in to comment.