Re: [PATCH v2 5/6] powerpc/pseries: Add CPU dlpar add functionality

2015-12-01 Thread Nathan Fontenot
On 11/25/2015 11:13 PM, Michael Ellerman wrote:
> On Tue, 2015-10-27 at 13:27 -0500, Nathan Fontenot wrote:
> 
>> Add the ability to hotplug add cpus via rtas hotplug events by either
>> specifying the drc index of the CPU to add, or providing a count of the
>> number of CPUs to add.
> 
> So I just tried running this on my system, without doing anything on the HMC.
> 
> I have:
> 
>   # lsprop /proc/device-tree/cpus/ibm,drc-indexes 
>   /proc/device-tree/cpus/ibm,drc-indexes
>0002 1000 1002
> 
> So I think that says I have two cpus.
> 
> The first one is already added:
> 
>   /proc/device-tree/cpus/PowerPC,POWER6@0/ibm,my-drc-index
>1000 (268435456)
> 
> But can I add the second one?
> 
>   # echo "cpu add count 1" > dlpar 
>   RTAS: event: 34, Type: Platform Error, Severity: 2
>   pseries-hotplug-cpu: Failed to acquire DRC, rc: -5, drc index: 1002
>   pseries-hotplug-cpu: CPU hot-add failed, removing any added CPUs
>   -bash: echo: write error: Invalid argument
> 
> 
> Seems not. But I'm not clear why?

The add request is failing because rtas call to acquire the resource is failing.
I have seen this on many systems lately. Previously one could add and remove
CPUs (and memory) by running the drmgr command on an LPAR manually and
everything would work. It seems there are now systems (not sure if its a
firmware or HMC update) that will only allow the rtas call to acquire the 
resource to succeed when the request is initiated from the HMC.

I can provide a patch for drmgr that uses the new sysfs interface so you
can drive the dlpar operations from the hmc.

> 
> Adding by index doesn't work either:
> 
>   # echo "cpu add index 1002" > dlpar
>   pseries-hotplug-cpu: Failed to acquire DRC, rc: -1, drc index: 989682
>   -bash: echo: write error: Invalid argument
> 
> That's a little confusing, drc index is hex obviously.
> 
>   [root@p6-10-P5-E0 kernel]# echo "cpu add index 0x1002" > dlpar 
>   RTAS: event: 35, Type: Platform Error, Severity: 2
>   pseries-hotplug-cpu: Failed to acquire DRC, rc: -5, drc index: 1002
>   -bash: echo: write error: Invalid argument
> 
> 
> So that's probably all PEBKAC, but if we can make it more intutive that would 
> be good.

I wrote the interface to take the drc index value in the format specified, so
without the 0x it assumes decimal. Should be a better error message in this 
case.

-Nathan

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 5/6] powerpc/pseries: Add CPU dlpar add functionality

2015-11-25 Thread Michael Ellerman
On Tue, 2015-10-27 at 13:27 -0500, Nathan Fontenot wrote:

> Add the ability to hotplug add cpus via rtas hotplug events by either
> specifying the drc index of the CPU to add, or providing a count of the
> number of CPUs to add.

So I just tried running this on my system, without doing anything on the HMC.

I have:

  # lsprop /proc/device-tree/cpus/ibm,drc-indexes 
  /proc/device-tree/cpus/ibm,drc-indexes
 0002 1000 1002

So I think that says I have two cpus.

The first one is already added:

  /proc/device-tree/cpus/PowerPC,POWER6@0/ibm,my-drc-index
 1000 (268435456)

But can I add the second one?

  # echo "cpu add count 1" > dlpar 
  RTAS: event: 34, Type: Platform Error, Severity: 2
  pseries-hotplug-cpu: Failed to acquire DRC, rc: -5, drc index: 1002
  pseries-hotplug-cpu: CPU hot-add failed, removing any added CPUs
  -bash: echo: write error: Invalid argument


Seems not. But I'm not clear why?

Adding by index doesn't work either:

  # echo "cpu add index 1002" > dlpar
  pseries-hotplug-cpu: Failed to acquire DRC, rc: -1, drc index: 989682
  -bash: echo: write error: Invalid argument

That's a little confusing, drc index is hex obviously.

  [root@p6-10-P5-E0 kernel]# echo "cpu add index 0x1002" > dlpar 
  RTAS: event: 35, Type: Platform Error, Severity: 2
  pseries-hotplug-cpu: Failed to acquire DRC, rc: -5, drc index: 1002
  -bash: echo: write error: Invalid argument


So that's probably all PEBKAC, but if we can make it more intutive that would 
be good.

cheers

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 5/6] powerpc/pseries: Add CPU dlpar add functionality

2015-10-27 Thread Nathan Fontenot
Add the ability to hotplug add cpus via rtas hotplug events by either
specifying the drc index of the CPU to add, or providing a count of the
number of CPUs to add.

Signed-off-by: Nathan Fontenot 
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c |   94 ++
 1 file changed, 94 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 635f0ba..8ec52c0 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -679,6 +679,92 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
return rc;
 }
 
+static u32 *dlpar_cpus_to_add(u32 cpus_to_add)
+{
+   struct device_node *parent;
+   u32 *cpu_drcs;
+   int cpus_found = 0;
+   int i, index, rc;
+
+   cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL);
+   if (!cpu_drcs)
+   return NULL;
+
+   parent = of_find_node_by_path("/cpus");
+   if (!parent) {
+   kfree(cpu_drcs);
+   return NULL;
+   }
+
+   /* Search the ibm,drc-indexes array for possible CPU drcs to
+* add. Note that the format of the ibm,drc-indexes array is
+* the number of entries in the array followed by the array
+* of drc values so we start looking at index = 1.
+*/
+   i = 0;
+   index = 1;
+   while (cpus_found < cpus_to_add) {
+   u32 drc;
+
+   rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
+   index++, );
+   if (rc)
+   break;
+
+   if (dlpar_cpu_exists(parent, drc))
+   continue;
+
+   cpu_drcs[i++] = drc;
+   cpus_found++;
+   }
+
+   of_node_put(parent);
+
+   if (cpus_found < cpus_to_add) {
+   pr_warn("Failed to find enough CPUs (%d of %d) to add\n",
+   cpus_found, cpus_to_add);
+   kfree(cpu_drcs);
+   cpu_drcs = NULL;
+   }
+
+   return cpu_drcs;
+}
+
+static int dlpar_cpu_add_by_count(u32 cpus_to_add)
+{
+   u32 *cpu_drcs;
+   int cpus_added = 0;
+   int i, rc;
+
+   pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add);
+
+   cpu_drcs = dlpar_cpus_to_add(cpus_to_add);
+   if (!cpu_drcs)
+   return -EINVAL;
+
+   for (i = 0; i < cpus_to_add; i++) {
+   rc = dlpar_cpu_add(cpu_drcs[i]);
+   if (rc)
+   break;
+
+   cpus_added++;
+   }
+
+   if (cpus_added < cpus_to_add) {
+   pr_warn("CPU hot-add failed, removing any added CPUs\n");
+
+   for (i = 0; i < cpus_added; i++)
+   dlpar_cpu_remove_by_index(cpu_drcs[i]);
+
+   rc = -EINVAL;
+   } else {
+   rc = 0;
+   }
+
+   kfree(cpu_drcs);
+   return rc;
+}
+
 int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
 {
u32 count, drc_index;
@@ -698,6 +784,14 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
else
rc = -EINVAL;
break;
+   case PSERIES_HP_ELOG_ACTION_ADD:
+   if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
+   rc = dlpar_cpu_add_by_count(count);
+   else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
+   rc = dlpar_cpu_add(drc_index);
+   else
+   rc = -EINVAL;
+   break;
default:
pr_err("Invalid action (%d) specified\n", hp_elog->action);
rc = -EINVAL;

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev