Skip to content

Commit

Permalink
powerpc/numa: Update numa code use walk_drmem_lmbs
Browse files Browse the repository at this point in the history
Update code in powerpc/numa.c to use the walk_drmem_lmbs()
routine instead of parsing the device tree directly. This is
in anticipation of introducing a new ibm,dynamic-memory-v2
property with a different format. This will allow the numa code
to use a single initialization routine per-LMB irregardless of
the device tree format.

Additionally, to support additional routines in numa.c that need
to look up LMB information, an late_init routine is added to drmem.c
to allocate the array of LMB information. This LMB array will provide
per-LMB information to separate the LMB data from the device tree
format.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
nfont authored and mpe committed Jan 16, 2018
1 parent 6c6ea53 commit 514a9cb
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 172 deletions.
4 changes: 4 additions & 0 deletions arch/powerpc/include/asm/drmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ static inline u32 drmem_lmb_size(void)
return drmem_info->lmb_size;
}

u64 drmem_lmb_memory_max(void);
void __init walk_drmem_lmbs(struct device_node *dn,
void (*func)(struct drmem_lmb *, const __be32 **));

#ifdef CONFIG_PPC_PSERIES
void __init walk_drmem_lmbs_early(unsigned long node,
void (*func)(struct drmem_lmb *, const __be32 **));
Expand Down
100 changes: 99 additions & 1 deletion arch/powerpc/mm/drmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@
static struct drmem_lmb_info __drmem_info;
struct drmem_lmb_info *drmem_info = &__drmem_info;

#ifdef CONFIG_PPC_PSERIES
u64 drmem_lmb_memory_max(void)
{
struct drmem_lmb *last_lmb;

last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1];
return last_lmb->base_addr + drmem_lmb_size();
}

static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
const __be32 **prop)
{
Expand Down Expand Up @@ -52,6 +59,7 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
}
}

#ifdef CONFIG_PPC_PSERIES
void __init walk_drmem_lmbs_early(unsigned long node,
void (*func)(struct drmem_lmb *, const __be32 **))
{
Expand All @@ -74,3 +82,93 @@ void __init walk_drmem_lmbs_early(unsigned long node,
}

#endif

static int __init init_drmem_lmb_size(struct device_node *dn)
{
const __be32 *prop;
int len;

if (drmem_info->lmb_size)
return 0;

prop = of_get_property(dn, "ibm,lmb-size", &len);
if (!prop || len < dt_root_size_cells * sizeof(__be32)) {
pr_info("Could not determine LMB size\n");
return -1;
}

drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop);
return 0;
}

/*
* Returns the property linux,drconf-usable-memory if
* it exists (the property exists only in kexec/kdump kernels,
* added by kexec-tools)
*/
static const __be32 *of_get_usable_memory(struct device_node *dn)
{
const __be32 *prop;
u32 len;

prop = of_get_property(dn, "linux,drconf-usable-memory", &len);
if (!prop || len < sizeof(unsigned int))
return NULL;

return prop;
}

void __init walk_drmem_lmbs(struct device_node *dn,
void (*func)(struct drmem_lmb *, const __be32 **))
{
const __be32 *prop, *usm;

if (init_drmem_lmb_size(dn))
return;

usm = of_get_usable_memory(dn);

prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
if (prop)
__walk_drmem_v1_lmbs(prop, usm, func);
}

static void __init init_drmem_v1_lmbs(const __be32 *prop)
{
struct drmem_lmb *lmb;

drmem_info->n_lmbs = of_read_number(prop++, 1);

drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
GFP_KERNEL);
if (!drmem_info->lmbs)
return;

for_each_drmem_lmb(lmb)
read_drconf_v1_cell(lmb, &prop);
}

static int __init drmem_init(void)
{
struct device_node *dn;
const __be32 *prop;

dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
if (!dn) {
pr_info("No dynamic reconfiguration memory found\n");
return 0;
}

if (init_drmem_lmb_size(dn)) {
of_node_put(dn);
return 0;
}

prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
if (prop)
init_drmem_v1_lmbs(prop);

of_node_put(dn);
return 0;
}
late_initcall(drmem_init);
Loading

0 comments on commit 514a9cb

Please sign in to comment.