Skip to content

Commit 063b8b1

Browse files
nfontmpe
authored andcommitted
powerpc/pseries/memory-hotplug: Only update DT once per memory DLPAR request
The updates to powerpc numa and memory hotplug code now use the in-kernel LMB array instead of the device tree. This change allows the pseries memory DLPAR code to only update the device tree once after successfully handling a DLPAR request. Prior to the in-kernel LMB array, the numa code looked up the affinity for memory being added in the device tree, the code now looks this up in the LMB array. This change means the memory hotplug code can just update the affinity for an LMB in the LMB array instead of updating the device tree. This also provides a savings in kernel memory. When updating the device tree old properties are never free'ed since there is no usecount on properties. This behavior leads to a new copy of the property being allocated every time a LMB is added or removed (i.e. a request to add 100 LMBs creates 100 new copies of the property). With this update only a single new property is created when a DLPAR request completes successfully. Signed-off-by: Nathan Fontenot <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent 6977f95 commit 063b8b1

File tree

2 files changed

+21
-39
lines changed

2 files changed

+21
-39
lines changed

arch/powerpc/include/asm/drmem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,9 @@ void __init walk_drmem_lmbs_early(unsigned long node,
9999
void (*func)(struct drmem_lmb *, const __be32 **));
100100
#endif
101101

102+
static inline void invalidate_lmb_associativity_index(struct drmem_lmb *lmb)
103+
{
104+
lmb->aa_index = 0xffffffff;
105+
}
106+
102107
#endif /* _ASM_POWERPC_LMB_H */

arch/powerpc/platforms/pseries/hotplug-memory.c

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ static u32 find_aa_index(struct device_node *dr_node,
163163
return aa_index;
164164
}
165165

166-
static u32 lookup_lmb_associativity_index(struct drmem_lmb *lmb)
166+
static int update_lmb_associativity_index(struct drmem_lmb *lmb)
167167
{
168168
struct device_node *parent, *lmb_node, *dr_node;
169169
struct property *ala_prop;
@@ -203,43 +203,14 @@ static u32 lookup_lmb_associativity_index(struct drmem_lmb *lmb)
203203
aa_index = find_aa_index(dr_node, ala_prop, lmb_assoc);
204204

205205
dlpar_free_cc_nodes(lmb_node);
206-
return aa_index;
207-
}
208-
209-
static int dlpar_add_device_tree_lmb(struct drmem_lmb *lmb)
210-
{
211-
int rc, aa_index;
212-
213-
lmb->flags |= DRCONF_MEM_ASSIGNED;
214206

215-
aa_index = lookup_lmb_associativity_index(lmb);
216207
if (aa_index < 0) {
217-
pr_err("Couldn't find associativity index for drc index %x\n",
218-
lmb->drc_index);
219-
return aa_index;
208+
pr_err("Could not find LMB associativity\n");
209+
return -1;
220210
}
221211

222212
lmb->aa_index = aa_index;
223-
224-
rtas_hp_event = true;
225-
rc = drmem_update_dt();
226-
rtas_hp_event = false;
227-
228-
return rc;
229-
}
230-
231-
static int dlpar_remove_device_tree_lmb(struct drmem_lmb *lmb)
232-
{
233-
int rc;
234-
235-
lmb->flags &= ~DRCONF_MEM_ASSIGNED;
236-
lmb->aa_index = 0xffffffff;
237-
238-
rtas_hp_event = true;
239-
rc = drmem_update_dt();
240-
rtas_hp_event = false;
241-
242-
return rc;
213+
return 0;
243214
}
244215

245216
static struct memory_block *lmb_to_memblock(struct drmem_lmb *lmb)
@@ -428,7 +399,9 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb)
428399
/* Update memory regions for memory remove */
429400
memblock_remove(lmb->base_addr, block_sz);
430401

431-
dlpar_remove_device_tree_lmb(lmb);
402+
invalidate_lmb_associativity_index(lmb);
403+
lmb->flags &= ~DRCONF_MEM_ASSIGNED;
404+
432405
return 0;
433406
}
434407

@@ -688,10 +661,8 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
688661
if (lmb->flags & DRCONF_MEM_ASSIGNED)
689662
return -EINVAL;
690663

691-
rc = dlpar_add_device_tree_lmb(lmb);
664+
rc = update_lmb_associativity_index(lmb);
692665
if (rc) {
693-
pr_err("Couldn't update device tree for drc index %x\n",
694-
lmb->drc_index);
695666
dlpar_release_drc(lmb->drc_index);
696667
return rc;
697668
}
@@ -704,14 +675,14 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
704675
/* Add the memory */
705676
rc = add_memory(nid, lmb->base_addr, block_sz);
706677
if (rc) {
707-
dlpar_remove_device_tree_lmb(lmb);
678+
invalidate_lmb_associativity_index(lmb);
708679
return rc;
709680
}
710681

711682
rc = dlpar_online_lmb(lmb);
712683
if (rc) {
713684
remove_memory(nid, lmb->base_addr, block_sz);
714-
dlpar_remove_device_tree_lmb(lmb);
685+
invalidate_lmb_associativity_index(lmb);
715686
} else {
716687
lmb->flags |= DRCONF_MEM_ASSIGNED;
717688
}
@@ -958,6 +929,12 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
958929
break;
959930
}
960931

932+
if (!rc) {
933+
rtas_hp_event = true;
934+
rc = drmem_update_dt();
935+
rtas_hp_event = false;
936+
}
937+
961938
unlock_device_hotplug();
962939
return rc;
963940
}

0 commit comments

Comments
 (0)