powerpc/pseries: minor enhancements in dlpar_memory_remove_by_ic()
authorDaniel Henrique Barboza <danielhb413@gmail.com>
Wed, 12 May 2021 20:28:09 +0000 (17:28 -0300)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 23 May 2021 10:51:35 +0000 (20:51 +1000)
We don't need the 'lmbs_available' variable to count the valid LMBs and
to check if we have less than 'lmbs_to_remove'. We must ensure that the
entire LMB range must be removed, so we can error out immediately if any
LMB in the range is marked as reserved.

Add a couple of comments explaining the reasoning behind the differences
we have in this function in contrast to what it is done in its sister
function, dlpar_memory_remove_by_count().

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210512202809.95363-5-danielhb413@gmail.com
arch/powerpc/platforms/pseries/hotplug-memory.c

index 1c6e66f..36f6655 100644 (file)
@@ -517,7 +517,6 @@ static int dlpar_memory_remove_by_index(u32 drc_index)
 static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
 {
        struct drmem_lmb *lmb, *start_lmb, *end_lmb;
-       int lmbs_available = 0;
        int rc;
 
        pr_info("Attempting to hot-remove %u LMB(s) at %x\n",
@@ -530,18 +529,29 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
        if (rc)
                return -EINVAL;
 
-       /* Validate that there are enough LMBs to satisfy the request */
+       /*
+        * Validate that all LMBs in range are not reserved. Note that it
+        * is ok if they are !ASSIGNED since our goal here is to remove the
+        * LMB range, regardless of whether some LMBs were already removed
+        * by any other reason.
+        *
+        * This is a contrast to what is done in remove_by_count() where we
+        * check for both RESERVED and !ASSIGNED (via lmb_is_removable()),
+        * because we want to remove a fixed amount of LMBs in that function.
+        */
        for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
-               if (lmb->flags & DRCONF_MEM_RESERVED)
-                       break;
-
-               lmbs_available++;
+               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_remove)
-               return -EINVAL;
-
        for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
+               /*
+                * dlpar_remove_lmb() will error out if the LMB is already
+                * !ASSIGNED, but this case is a no-op for us.
+                */
                if (!(lmb->flags & DRCONF_MEM_ASSIGNED))
                        continue;