[PATCH 3/3] ppc64-specific memory notifier support

Badari Pulavarty pbadari at us.ibm.com
Sat Mar 1 04:47:16 EST 2008


On Fri, 2008-02-29 at 12:03 +1100, Michael Ellerman wrote:
> On Thu, 2008-02-28 at 18:39 -0600, Nathan Lynch wrote:
> > Michael Ellerman wrote:
> > > On Thu, 2008-02-28 at 08:46 -0800, Badari Pulavarty wrote:
> > > > Hotplug memory notifier for ppc64. This gets invoked by writing
> > > > the device-node that needs to be removed to /proc/ppc64/ofdt.
> > > > We need to adjust the sections and remove sysfs entries by
> > > > calling __remove_pages(). Then call arch specific code to
> > > > get rid of htab mappings for the section of memory.
> > > > 
> > > > Signed-off-by: Badari Pulavarty <pbadari at us.ibm.com>
> > > > ---
> > > >  arch/powerpc/platforms/pseries/Makefile         |    1 
> > > >  arch/powerpc/platforms/pseries/hotplug-memory.c |   98 ++++++++++++++++++++++++
> > > >  2 files changed, 99 insertions(+)
> > > > 
> > > > Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
> > > > ===================================================================
> > > > --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> > > > +++ linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c	2008-02-28 08:20:14.000000000 -0800
> > > 
> > > > +
> > > > +static struct notifier_block pseries_smp_nb = {
> > > > +	.notifier_call = pseries_memory_notifier,
> > > > +};
> > > > +
> > > > +static int __init pseries_memory_hotplug_init(void)
> > > > +{
> > > > +	if (firmware_has_feature(FW_FEATURE_LPAR))
> > > > +		pSeries_reconfig_notifier_register(&pseries_smp_nb);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +arch_initcall(pseries_memory_hotplug_init);
> > > 
> > > This is going to fire on non-pseries LPAR platforms, like iSeries and
> > > PS3. Which is not what you want I think.
> > 
> > Well, the notifier will be registered, yes, but it will never be
> > called because that path is reachable only from a write to
> > /proc/ppc64/ofdt, which is not created on non-pseries.
> 
> Sure. Still seems better not to register it in the first place.
> 
> > Maybe it should be
> > 
> > machine_device_initcall(pseries, pseries_memory_hotplug_init);
> 
> I think so.
> 

Here is the latest for review. (just to make sure I didn't miss
anything).

Thanks,
Badari

Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.

Signed-off-by: Badari Pulavarty <pbadari at us.ibm.com>
---
 arch/powerpc/platforms/pseries/Makefile         |    1 
 arch/powerpc/platforms/pseries/hotplug-memory.c |   98 ++++++++++++++++++++++++
 2 files changed, 99 insertions(+)

Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c	2008-02-29 09:25:14.000000000 -0800
@@ -0,0 +1,98 @@
+/*
+ * pseries Memory Hotplug infrastructure.
+ *
+ * Copyright (C) 2008 Badari Pulavarty, IBM Corporation
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/prom.h>
+#include <asm/firmware.h>
+#include <asm/machdep.h>
+#include <asm/pSeries_reconfig.h>
+
+static int pseries_remove_memory(struct device_node *np)
+{
+	const char *type;
+	const unsigned int *my_index;
+	const unsigned int *regs;
+	u64 start_pfn, start;
+	struct zone *zone;
+	int ret = -EINVAL;
+
+	/*
+	 * Check to see if we are actually removing memory
+	 */
+	type = of_get_property(np, "device_type", NULL);
+	if (type == NULL || strcmp(type, "memory") != 0)
+		return 0;
+
+	/*
+	 * Find the memory index and size of the removing section
+	 */
+	my_index = of_get_property(np, "ibm,my-drc-index", NULL);
+	if (!my_index)
+		return ret;
+
+	regs = of_get_property(np, "reg", NULL);
+	if (!regs)
+		return ret;
+
+	start_pfn = section_nr_to_pfn(*my_index & 0xffff);
+	zone = page_zone(pfn_to_page(start_pfn));
+
+	/*
+	 * Remove section mappings and sysfs entries for the
+	 * section of the memory we are removing.
+	 *
+	 * NOTE: Ideally, this should be done in generic code like
+	 * remove_memory(). But remove_memory() gets called by writing
+	 * to sysfs "state" file and we can't remove sysfs entries
+	 * while writing to it. So we have to defer it to here.
+	 */
+	ret = __remove_pages(zone, start_pfn, regs[3] >> PAGE_SHIFT);
+	if (ret)
+		return ret;
+
+	/*
+	 * Remove htab bolted mappings for this section of memory
+	 */
+ 	start = (unsigned long)__va(start_pfn << PAGE_SHIFT);
+ 	ret = remove_section_mapping(start, start + regs[3]);
+	return ret;
+}
+
+static int pseries_memory_notifier(struct notifier_block *nb,
+				unsigned long action, void *node)
+{
+	int err = NOTIFY_OK;
+
+	switch (action) {
+	case PSERIES_RECONFIG_ADD:
+		break;
+	case PSERIES_RECONFIG_REMOVE:
+		if (pseries_remove_memory(node))
+			err = NOTIFY_BAD;
+		break;
+	default:
+		err = NOTIFY_DONE;
+		break;
+	}
+	return err;
+}
+
+static struct notifier_block pseries_mem_nb = {
+	.notifier_call = pseries_memory_notifier,
+};
+
+static int __init pseries_memory_hotplug_init(void)
+{
+	if (firmware_has_feature(FW_FEATURE_LPAR))
+		pSeries_reconfig_notifier_register(&pseries_mem_nb);
+
+	return 0;
+}
+machine_device_initcall(pseries, pseries_memory_hotplug_init);
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/Makefile
===================================================================
--- linux-2.6.25-rc2.orig/arch/powerpc/platforms/pseries/Makefile	2008-02-28 08:15:53.000000000 -0800
+++ linux-2.6.25-rc2/arch/powerpc/platforms/pseries/Makefile	2008-02-28 08:17:57.000000000 -0800
@@ -14,6 +14,7 @@ obj-$(CONFIG_PCI)	+= pci.o pci_dlpar.o
 obj-$(CONFIG_PCI_MSI)	+= msi.o
 
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug-cpu.o
+obj-$(CONFIG_MEMORY_HOTPLUG)	+= hotplug-memory.o
 
 obj-$(CONFIG_HVC_CONSOLE)	+= hvconsole.o
 obj-$(CONFIG_HVCS)		+= hvcserver.o





More information about the Linuxppc-dev mailing list