Re: [PATCH v2 1/3] Kernel DLPAR Infrastructure

2009-11-25 Thread Paul Mackerras
Nathan Fontenot writes:

 The Dynamic Logical Partitioning capabilities of the powerpc pseries platform
 allows for the addition and removal of resources (i.e. CPU's, memory, and PCI
 devices) from a partition. The removal of a resource involves
 removing the resource's node from the device tree and then returning the
 resource to firmware via the rtas set-indicator call.  To add a resource, it
 is first obtained from firmware via the rtas set-indicator call and then a
 new device tree node is created using the ibm,configure-coinnector rtas call
 and added to the device tree. 
 
 This patch provides the kernel DLPAR infrastructure in a new filed named
 dlpar.c.  The functionality provided is for acquiring and releasing a resource
 from firmware and the parsing of information returned from the
 ibm,configure-connector rtas call.  Additionally this exports the pSeries
 reconfiguration notifier chain so that it can be invoked when device tree 
 updates are made.
 
 Signed-off-by: Nathan Fontenot nf...@austin.ibm.com 

Acked-by: Paul Mackerras pau...@samba.org
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 1/3] Kernel DLPAR Infrastructure

2009-11-24 Thread Nathan Fontenot

The Dynamic Logical Partitioning capabilities of the powerpc pseries platform
allows for the addition and removal of resources (i.e. CPU's, memory, and PCI
devices) from a partition. The removal of a resource involves
removing the resource's node from the device tree and then returning the
resource to firmware via the rtas set-indicator call.  To add a resource, it
is first obtained from firmware via the rtas set-indicator call and then a
new device tree node is created using the ibm,configure-coinnector rtas call
and added to the device tree. 


This patch provides the kernel DLPAR infrastructure in a new filed named
dlpar.c.  The functionality provided is for acquiring and releasing a resource
from firmware and the parsing of information returned from the
ibm,configure-connector rtas call.  Additionally this exports the pSeries
reconfiguration notifier chain so that it can be invoked when device tree 
updates are made.


Signed-off-by: Nathan Fontenot nf...@austin.ibm.com 
---
arch/powerpc/include/asm/pSeries_reconfig.h |1 
arch/powerpc/platforms/pseries/Makefile |2 
arch/powerpc/platforms/pseries/dlpar.c  |  344 
arch/powerpc/platforms/pseries/reconfig.c   |2 
4 files changed, 347 insertions(+), 2 deletions(-)


Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ powerpc/arch/powerpc/platforms/pseries/dlpar.c  2009-11-25 
04:54:13.0 -0600
@@ -0,0 +1,344 @@
+/*
+ * Support for dynamic reconfiguration for PCI, Memory, and CPU
+ * Hotplug and Dynamic Logical Partitioning on RPA platforms.
+ *
+ * Copyright (C) 2009 Nathan Fontenot
+ * Copyright (C) 2009 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include linux/kernel.h
+#include linux/kref.h
+#include linux/notifier.h
+#include linux/proc_fs.h
+#include linux/spinlock.h
+#include linux/cpu.h
+
+#include asm/prom.h
+#include asm/machdep.h
+#include asm/uaccess.h
+#include asm/rtas.h
+#include asm/pSeries_reconfig.h
+
+struct cc_workarea {
+   u32 drc_index;
+   u32 zero;
+   u32 name_offset;
+   u32 prop_length;
+   u32 prop_offset;
+};
+
+static void dlpar_free_cc_property(struct property *prop)
+{
+   kfree(prop-name);
+   kfree(prop-value);
+   kfree(prop);
+}
+
+static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
+{
+   struct property *prop;
+   char *name;
+   char *value;
+
+   prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+   if (!prop)
+   return NULL;
+
+   name = (char *)ccwa + ccwa-name_offset;
+   prop-name = kstrdup(name, GFP_KERNEL);
+
+   prop-length = ccwa-prop_length;
+   value = (char *)ccwa + ccwa-prop_offset;
+   prop-value = kzalloc(prop-length, GFP_KERNEL);
+   if (!prop-value) {
+   dlpar_free_cc_property(prop);
+   return NULL;
+   }
+
+   memcpy(prop-value, value, prop-length);
+   return prop;
+}
+
+static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
+{
+   struct device_node *dn;
+   char *name;
+
+   dn = kzalloc(sizeof(*dn), GFP_KERNEL);
+   if (!dn)
+   return NULL;
+
+   /* The configure connector reported name does not contain a
+* preceeding '/', so we allocate a buffer large enough to
+* prepend this to the full_name.
+*/
+   name = (char *)ccwa + ccwa-name_offset;
+   dn-full_name = kmalloc(strlen(name) + 2, GFP_KERNEL);
+   if (!dn-full_name) {
+   kfree(dn);
+   return NULL;
+   }
+
+   sprintf(dn-full_name, /%s, name);
+   return dn;
+}
+
+static void dlpar_free_one_cc_node(struct device_node *dn)
+{
+   struct property *prop;
+
+   while (dn-properties) {
+   prop = dn-properties;
+   dn-properties = prop-next;
+   dlpar_free_cc_property(prop);
+   }
+
+   kfree(dn-full_name);
+   kfree(dn);
+}
+
+static void dlpar_free_cc_nodes(struct device_node *dn)
+{
+   if (dn-child)
+   dlpar_free_cc_nodes(dn-child);
+
+   if (dn-sibling)
+   dlpar_free_cc_nodes(dn-sibling);
+
+   dlpar_free_one_cc_node(dn);
+}
+
+#define NEXT_SIBLING1
+#define NEXT_CHILD  2
+#define NEXT_PROPERTY   3
+#define PREV_PARENT 4
+#define MORE_MEMORY 5
+#define CALL_AGAIN -2
+#define ERR_CFG_USE -9003
+
+struct device_node *dlpar_configure_connector(u32 drc_index)
+{
+   struct device_node *dn;
+   struct device_node *first_dn = NULL;
+   struct device_node *last_dn = NULL;
+   struct property *property;
+   struct property *last_property = NULL;
+   struct cc_workarea