From: Daniel Henrique Barboza <hidden> Date: 2021-06-22 13:43:01
Hi,
These are a couple of cleanups for the dlpar_memory_add* functions
that are similar to those I did a month or so ago in
dlpar_memory_remove_by_count and dlpar_memory_remove_by_ic.
Daniel Henrique Barboza (3):
powerpc/pseries: skip reserved LMBs in dlpar_memory_add_by_count()
powerpc/pseries: break early in dlpar_memory_add_by_count() loops
powerpc/pseries: fail quicker in dlpar_memory_add_by_ic()
.../platforms/pseries/hotplug-memory.c | 34 ++++++++++++-------
1 file changed, 21 insertions(+), 13 deletions(-)
--
2.31.1
From: Daniel Henrique Barboza <hidden> Date: 2021-06-22 13:42:37
The function is counting reserved LMBs as available to be added, but
they aren't. This will cause the function to miscalculate the available
LMBs and can trigger errors later on when executing dlpar_add_lmb().
Signed-off-by: Daniel Henrique Barboza <redacted>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 3 +++
1 file changed, 3 insertions(+)
@@ -683,6 +683,9 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)/* Validate that there are enough LMBs to satisfy the request */for_each_drmem_lmb(lmb){+if(lmb->flags&DRCONF_MEM_RESERVED)+continue;+if(!(lmb->flags&DRCONF_MEM_ASSIGNED))lmbs_available++;
From: Daniel Henrique Barboza <hidden> Date: 2021-06-22 13:43:25
After a successful dlpar_add_lmb() call the LMB is marked as reserved.
Later on, depending whether we added enough LMBs or not, we rely on
the marked LMBs to see which ones might need to be removed, and we
remove the reservation of all of them.
These are done in for_each_drmem_lmb() loops without any break
condition. This means that we're going to check all LMBs of the partition
even after going through all the reserved ones.
This patch adds break conditions in both loops to avoid this. The
'lmbs_added' variable was renamed to 'lmbs_reserved', and it's now
being decremented each time a lmb reservation is removed, indicating
if there are still marked LMBs to be processed.
Signed-off-by: Daniel Henrique Barboza <redacted>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
@@ -673,7 +673,7 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add){structdrmem_lmb*lmb;intlmbs_available=0;-intlmbs_added=0;+intlmbs_reserved=0;intrc;pr_info("Attempting to hot-add %d LMB(s)\n",lmbs_to_add);
@@ -714,13 +714,12 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)*requestedLMBscannotbeadded.*/drmem_mark_lmb_reserved(lmb);--lmbs_added++;-if(lmbs_added==lmbs_to_add)+lmbs_reserved++;+if(lmbs_reserved==lmbs_to_add)break;}-if(lmbs_added!=lmbs_to_add){+if(lmbs_reserved!=lmbs_to_add){pr_err("Memory hot-add failed, removing any added LMBs\n");for_each_drmem_lmb(lmb){
@@ -735,6 +734,10 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)dlpar_release_drc(lmb->drc_index);drmem_remove_lmb_reservation(lmb);+lmbs_reserved--;++if(lmbs_reserved==0)+break;}rc=-EINVAL;}else{
@@ -745,6 +748,10 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)pr_debug("Memory at %llx (drc index %x) was hot-added\n",lmb->base_addr,lmb->drc_index);drmem_remove_lmb_reservation(lmb);+lmbs_reserved--;++if(lmbs_reserved==0)+break;}rc=0;}
From: Daniel Henrique Barboza <hidden> Date: 2021-06-22 13:43:48
The validation done at the start of dlpar_memory_add_by_ic() is an all
of nothing scenario - if any LMBs in the range is marked as RESERVED we
can fail right away.
We then can remove the 'lmbs_available' var and its check with
'lmbs_to_add' since the whole LMB range was already validated in the
previous step.
Signed-off-by: Daniel Henrique Barboza <redacted>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
@@ -796,7 +796,6 @@ static int dlpar_memory_add_by_index(u32 drc_index)staticintdlpar_memory_add_by_ic(u32lmbs_to_add,u32drc_index){structdrmem_lmb*lmb,*start_lmb,*end_lmb;-intlmbs_available=0;intrc;pr_info("Attempting to hot-add %u LMB(s) at index %x\n",
@@ -811,15 +810,14 @@ static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index)/* Validate that the LMBs in this range are not reserved */for_each_drmem_lmb_in_range(lmb,start_lmb,end_lmb){-if(lmb->flags&DRCONF_MEM_RESERVED)-break;--lmbs_available++;+/* Fail immediately if the whole range can't be hot-added */+if(lmb->flags&DRCONF_MEM_RESERVED){+pr_err("Memory at %llx (drc index %x) is reserved\n",+lmb->base_addr,lmb->drc_index);+return-EINVAL;+}}-if(lmbs_available<lmbs_to_add)-return-EINVAL;-for_each_drmem_lmb_in_range(lmb,start_lmb,end_lmb){if(lmb->flags&DRCONF_MEM_ASSIGNED)continue;
Le 22/06/2021 à 15:39, Daniel Henrique Barboza a écrit :
The function is counting reserved LMBs as available to be added, but
they aren't. This will cause the function to miscalculate the available
LMBs and can trigger errors later on when executing dlpar_add_lmb().
Indeed I'm wondering if dlpar_add_lmb() would fail in that case, so that's even better to check for that flag earlier.
Reviewed-by: Laurent Dufour <redacted>
@@ -683,6 +683,9 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)/* Validate that there are enough LMBs to satisfy the request */for_each_drmem_lmb(lmb){+if(lmb->flags&DRCONF_MEM_RESERVED)+continue;+if(!(lmb->flags&DRCONF_MEM_ASSIGNED))lmbs_available++;
Le 22/06/2021 à 15:39, Daniel Henrique Barboza a écrit :
After a successful dlpar_add_lmb() call the LMB is marked as reserved.
Later on, depending whether we added enough LMBs or not, we rely on
the marked LMBs to see which ones might need to be removed, and we
remove the reservation of all of them.
These are done in for_each_drmem_lmb() loops without any break
condition. This means that we're going to check all LMBs of the partition
even after going through all the reserved ones.
This patch adds break conditions in both loops to avoid this. The
'lmbs_added' variable was renamed to 'lmbs_reserved', and it's now
being decremented each time a lmb reservation is removed, indicating
if there are still marked LMBs to be processed.
@@ -673,7 +673,7 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add){structdrmem_lmb*lmb;intlmbs_available=0;-intlmbs_added=0;+intlmbs_reserved=0;intrc;pr_info("Attempting to hot-add %d LMB(s)\n",lmbs_to_add);
@@ -714,13 +714,12 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)*requestedLMBscannotbeadded.*/drmem_mark_lmb_reserved(lmb);--lmbs_added++;-if(lmbs_added==lmbs_to_add)+lmbs_reserved++;+if(lmbs_reserved==lmbs_to_add)break;}-if(lmbs_added!=lmbs_to_add){+if(lmbs_reserved!=lmbs_to_add){pr_err("Memory hot-add failed, removing any added LMBs\n");for_each_drmem_lmb(lmb){
@@ -735,6 +734,10 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)dlpar_release_drc(lmb->drc_index);drmem_remove_lmb_reservation(lmb);+lmbs_reserved--;++if(lmbs_reserved==0)+break;}rc=-EINVAL;}else{
@@ -745,6 +748,10 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)pr_debug("Memory at %llx (drc index %x) was hot-added\n",lmb->base_addr,lmb->drc_index);drmem_remove_lmb_reservation(lmb);+lmbs_reserved--;++if(lmbs_reserved==0)+break;}rc=0;}
Le 22/06/2021 à 15:39, Daniel Henrique Barboza a écrit :
The validation done at the start of dlpar_memory_add_by_ic() is an all
of nothing scenario - if any LMBs in the range is marked as RESERVED we
can fail right away.
We then can remove the 'lmbs_available' var and its check with
'lmbs_to_add' since the whole LMB range was already validated in the
previous step.
@@ -796,7 +796,6 @@ static int dlpar_memory_add_by_index(u32 drc_index)staticintdlpar_memory_add_by_ic(u32lmbs_to_add,u32drc_index){structdrmem_lmb*lmb,*start_lmb,*end_lmb;-intlmbs_available=0;intrc;pr_info("Attempting to hot-add %u LMB(s) at index %x\n",
@@ -811,15 +810,14 @@ static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index)/* Validate that the LMBs in this range are not reserved */for_each_drmem_lmb_in_range(lmb,start_lmb,end_lmb){-if(lmb->flags&DRCONF_MEM_RESERVED)-break;--lmbs_available++;+/* Fail immediately if the whole range can't be hot-added */+if(lmb->flags&DRCONF_MEM_RESERVED){+pr_err("Memory at %llx (drc index %x) is reserved\n",+lmb->base_addr,lmb->drc_index);+return-EINVAL;+}}-if(lmbs_available<lmbs_to_add)-return-EINVAL;-for_each_drmem_lmb_in_range(lmb,start_lmb,end_lmb){if(lmb->flags&DRCONF_MEM_ASSIGNED)continue;
From: Michael Ellerman <hidden> Date: 2021-06-25 06:25:19
On Tue, 22 Jun 2021 10:39:20 -0300, Daniel Henrique Barboza wrote:
These are a couple of cleanups for the dlpar_memory_add* functions
that are similar to those I did a month or so ago in
dlpar_memory_remove_by_count and dlpar_memory_remove_by_ic.
Daniel Henrique Barboza (3):
powerpc/pseries: skip reserved LMBs in dlpar_memory_add_by_count()
powerpc/pseries: break early in dlpar_memory_add_by_count() loops
powerpc/pseries: fail quicker in dlpar_memory_add_by_ic()
[...]
From: Michael Ellerman <hidden> Date: 2021-06-25 06:25:37
On Tue, 22 Jun 2021 10:39:22 -0300, Daniel Henrique Barboza wrote:
After a successful dlpar_add_lmb() call the LMB is marked as reserved.
Later on, depending whether we added enough LMBs or not, we rely on
the marked LMBs to see which ones might need to be removed, and we
remove the reservation of all of them.
These are done in for_each_drmem_lmb() loops without any break
condition. This means that we're going to check all LMBs of the partition
even after going through all the reserved ones.
[...]