* [PATCH v2 1/1] of: reform prom_update_property function
From: Dong Aisheng @ 2012-06-25 6:28 UTC (permalink / raw)
To: linux-kernel; +Cc: devicetree-discuss, rob.herring, paulus, linuxppc-dev
From: Dong Aisheng <dong.aisheng@linaro.org>
prom_update_property() currently fails if the property doesn't
actually exist yet which isn't what we want. Change to add-or-update
instead of update-only, then we can remove a lot duplicated lines.
Suggested-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
---
ChangeLog v1->v2:
* keep reconfig.c behavior the same as before after changes
---
arch/powerpc/platforms/85xx/p1022_ds.c | 8 +-------
arch/powerpc/platforms/pseries/mobility.c | 8 +-------
arch/powerpc/platforms/pseries/reconfig.c | 16 ++++++----------
drivers/of/base.c | 15 +++++++++++----
fs/proc/proc_devtree.c | 5 +++++
include/linux/of.h | 3 +--
6 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index f700c81..d66631c 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -348,13 +348,7 @@ void __init p1022_ds_pic_init(void)
*/
static void __init disable_one_node(struct device_node *np, struct property *new)
{
- struct property *old;
-
- old = of_find_property(np, new->name, NULL);
- if (old)
- prom_update_property(np, new, old);
- else
- prom_add_property(np, new);
+ prom_update_property(np, new);
}
/* TRUE if there is a "video=fslfb" command-line parameter. */
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 029a562..dd30b12 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
const char *name, u32 vd, char *value)
{
struct property *new_prop = *prop;
- struct property *old_prop;
int more = 0;
/* A negative 'vd' value indicates that only part of the new property
@@ -117,12 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
}
if (!more) {
- old_prop = of_find_property(dn, new_prop->name, NULL);
- if (old_prop)
- prom_update_property(dn, new_prop, old_prop);
- else
- prom_add_property(dn, new_prop);
-
+ prom_update_property(dn, new_prop);
new_prop = NULL;
}
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 7b3bf76..db1b7b1 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize)
unsigned char *value;
char *name, *end, *next_prop;
int rc, length;
- struct property *newprop, *oldprop;
+ struct property *newprop;
buf = parse_node(buf, bufsize, &np);
end = buf + bufsize;
@@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize)
if (!next_prop)
return -EINVAL;
+ if (!strlen(name)
+ return -ENODEV;
+
newprop = new_property(name, length, value, NULL);
if (!newprop)
return -ENOMEM;
@@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize)
if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
slb_set_size(*(int *)value);
- oldprop = of_find_property(np, name,NULL);
- if (!oldprop) {
- if (strlen(name))
- return prom_add_property(np, newprop);
- return -ENODEV;
- }
-
upd_value.node = np;
upd_value.property = newprop;
pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
- rc = prom_update_property(np, newprop, oldprop);
+ rc = prom_update_property(np, newprop);
if (rc)
return rc;
@@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize)
rc = pSeries_reconfig_notify(action, value);
if (rc) {
- prom_update_property(np, oldprop, newprop);
+ prom_update_property(np, newprop);
return rc;
}
}
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d9bfd49..a14f109 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1051,7 +1051,8 @@ int prom_remove_property(struct device_node *np, struct property *prop)
}
/*
- * prom_update_property - Update a property in a node.
+ * prom_update_property - Update a property in a node, if the property does
+ * not exist, add it.
*
* Note that we don't actually remove it, since we have given out
* who-knows-how-many pointers to the data using get-property.
@@ -1059,13 +1060,19 @@ int prom_remove_property(struct device_node *np, struct property *prop)
* and add the new property to the property list
*/
int prom_update_property(struct device_node *np,
- struct property *newprop,
- struct property *oldprop)
+ struct property *newprop)
{
- struct property **next;
+ struct property **next, *oldprop;
unsigned long flags;
int found = 0;
+ if (!newprop->name)
+ return -EINVAL;
+
+ oldprop = of_find_property(np, newprop->name, NULL);
+ if (!oldprop)
+ return prom_add_property(np, newprop);
+
write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 927cbd1..df7dd08 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -101,6 +101,11 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde,
{
struct proc_dir_entry *ent;
+ if (!oldprop) {
+ proc_device_tree_add_prop(pde, newprop);
+ return;
+ }
+
for (ent = pde->subdir; ent != NULL; ent = ent->next)
if (ent->data == oldprop)
break;
diff --git a/include/linux/of.h b/include/linux/of.h
index 2ec1083..b27c871 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -260,8 +260,7 @@ extern int of_machine_is_compatible(const char *compat);
extern int prom_add_property(struct device_node* np, struct property* prop);
extern int prom_remove_property(struct device_node *np, struct property *prop);
extern int prom_update_property(struct device_node *np,
- struct property *newprop,
- struct property *oldprop);
+ struct property *newprop);
#if defined(CONFIG_OF_DYNAMIC)
/* For updating the device tree at runtime */
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/4] powerpc: IOMMU fault injection
From: Anton Blanchard @ 2012-06-25 4:26 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
In-Reply-To: <20120625142353.0a92791a@kryten>
Add the ability to inject IOMMU faults. We enable this per device
via a fail_iommu sysfs property, similar to fault injection on other
subsystems.
An example:
# lspci
...
0003:01:00.1 Ethernet controller: Emulex Corporation OneConnect 10Gb NIC (be3) (rev 02)
To inject one error to this device:
echo 1 > /sys/bus/pci/devices/0003:01:00.1/fail_iommu
echo 1 > /sys/kernel/debug/fail_iommu/probability
echo 1 > /sys/kernel/debug/fail_iommu/times
As feared, the first failure injected on the be3 results in an
unrecoverable error, taking down both functions of the card
permanently:
be2net 0003:01:00.1: Unrecoverable error in the card
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/iommu.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/iommu.c 2012-06-08 09:01:02.785709100 +1000
+++ linux-build/arch/powerpc/kernel/iommu.c 2012-06-08 09:01:07.489784856 +1000
@@ -33,7 +33,9 @@
#include <linux/bitmap.h>
#include <linux/iommu-helper.h>
#include <linux/crash_dump.h>
+#include <linux/fault-inject.h>
#include <asm/io.h>
+#include <asm/vio.h>
#include <asm/prom.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
@@ -58,6 +60,94 @@ static int __init setup_iommu(char *str)
__setup("iommu=", setup_iommu);
+#ifdef CONFIG_FAIL_IOMMU
+
+static DECLARE_FAULT_ATTR(fail_iommu);
+
+static int __init setup_fail_iommu(char *str)
+{
+ return setup_fault_attr(&fail_iommu, str);
+}
+__setup("fail_iommu=", setup_fail_iommu);
+
+static bool should_fail_iommu(struct device *dev)
+{
+ return dev->archdata.fail_iommu && should_fail(&fail_iommu, 1);
+}
+
+static int __init fail_iommu_debugfs(void)
+{
+ struct dentry *dir = fault_create_debugfs_attr("fail_iommu",
+ NULL, &fail_iommu);
+
+ return IS_ERR(dir) ? PTR_ERR(dir) : 0;
+}
+late_initcall(fail_iommu_debugfs);
+
+static ssize_t fail_iommu_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", dev->archdata.fail_iommu);
+}
+
+static ssize_t fail_iommu_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int i;
+
+ if (count > 0 && sscanf(buf, "%d", &i) > 0)
+ dev->archdata.fail_iommu = (i == 0) ? 0 : 1;
+
+ return count;
+}
+
+static DEVICE_ATTR(fail_iommu, S_IRUGO|S_IWUSR, fail_iommu_show,
+ fail_iommu_store);
+
+static int fail_iommu_bus_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+
+ if (action == BUS_NOTIFY_ADD_DEVICE) {
+ if (device_create_file(dev, &dev_attr_fail_iommu))
+ pr_warn("Unable to create IOMMU fault injection sysfs "
+ "entries\n");
+ } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+ device_remove_file(dev, &dev_attr_fail_iommu);
+ }
+
+ return 0;
+}
+
+static struct notifier_block fail_iommu_bus_notifier = {
+ .notifier_call = fail_iommu_bus_notify
+};
+
+static int __init fail_iommu_setup(void)
+{
+#ifdef CONFIG_PCI
+ bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier);
+#endif
+#ifdef CONFIG_IBMVIO
+ bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier);
+#endif
+
+ return 0;
+}
+/*
+ * Must execute after PCI and VIO subsystem have initialised but before
+ * devices are probed.
+ */
+arch_initcall(fail_iommu_setup);
+#else
+static inline bool should_fail_iommu(struct device *dev)
+{
+ return false;
+}
+#endif
+
static unsigned long iommu_range_alloc(struct device *dev,
struct iommu_table *tbl,
unsigned long npages,
@@ -83,6 +173,9 @@ static unsigned long iommu_range_alloc(s
return DMA_ERROR_CODE;
}
+ if (should_fail_iommu(dev))
+ return DMA_ERROR_CODE;
+
if (handle && *handle)
start = *handle;
else
Index: linux-build/arch/powerpc/include/asm/device.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/device.h 2012-06-08 09:01:02.765708778 +1000
+++ linux-build/arch/powerpc/include/asm/device.h 2012-06-08 09:01:07.489784856 +1000
@@ -34,6 +34,9 @@ struct dev_archdata {
#ifdef CONFIG_EEH
struct eeh_dev *edev;
#endif
+#ifdef CONFIG_FAIL_IOMMU
+ int fail_iommu;
+#endif
};
struct pdev_archdata {
Index: linux-build/arch/powerpc/Kconfig.debug
===================================================================
--- linux-build.orig/arch/powerpc/Kconfig.debug 2012-06-08 09:01:02.753708585 +1000
+++ linux-build/arch/powerpc/Kconfig.debug 2012-06-08 09:01:07.489784856 +1000
@@ -331,4 +331,13 @@ config STRICT_DEVMEM
If you are unsure, say Y.
+config FAIL_IOMMU
+ bool "Fault-injection capability for IOMMU"
+ depends on FAULT_INJECTION
+ help
+ Provide fault-injection capability for IOMMU. Each device can
+ be selectively enabled via the fail_iommu property.
+
+ If you are unsure, say N.
+
endmenu
^ permalink raw reply
* [PATCH 3/4] powerpc: call dma_debug_add_bus for PCI and VIO buses
From: Anton Blanchard @ 2012-06-25 4:25 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
In-Reply-To: <20120625142353.0a92791a@kryten>
The DMA API debug code has hooks to verify all DMA entries have been
freed at time of hot unplug. We need to call dma_debug_add_bus for
this to work.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/vio.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vio.c 2012-06-08 09:16:53.856359566 +1000
+++ linux-build/arch/powerpc/kernel/vio.c 2012-06-08 09:17:43.625089518 +1000
@@ -37,8 +37,6 @@
#include <asm/page.h>
#include <asm/hvcall.h>
-static struct bus_type vio_bus_type;
-
static struct vio_dev vio_bus_device = { /* fake "parent" device */
.name = "vio",
.type = "",
@@ -1580,7 +1578,7 @@ static int vio_hotplug(struct device *de
return 0;
}
-static struct bus_type vio_bus_type = {
+struct bus_type vio_bus_type = {
.name = "vio",
.dev_attrs = vio_dev_attrs,
.uevent = vio_hotplug,
Index: linux-build/arch/powerpc/kernel/dma.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/dma.c 2012-06-08 09:12:47.356758198 +1000
+++ linux-build/arch/powerpc/kernel/dma.c 2012-06-08 09:17:43.625089518 +1000
@@ -11,6 +11,8 @@
#include <linux/gfp.h>
#include <linux/memblock.h>
#include <linux/export.h>
+#include <linux/pci.h>
+#include <asm/vio.h>
#include <asm/bug.h>
#include <asm/abs_addr.h>
#include <asm/machdep.h>
@@ -205,7 +207,13 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask)
static int __init dma_init(void)
{
- dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+#ifdef CONFIG_PCI
+ dma_debug_add_bus(&pci_bus_type);
+#endif
+#ifdef CONFIG_IBMVIO
+ dma_debug_add_bus(&vio_bus_type);
+#endif
return 0;
}
Index: linux-build/arch/powerpc/include/asm/vio.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/vio.h 2012-06-08 09:12:47.344758025 +1000
+++ linux-build/arch/powerpc/include/asm/vio.h 2012-06-08 09:17:43.625089518 +1000
@@ -44,6 +44,8 @@
*/
#define VIO_CMO_MIN_ENT 1562624
+extern struct bus_type vio_bus_type;
+
struct iommu_table;
/*
^ permalink raw reply
* [PATCH 2/4] powerpc: vio: Separate vio bus probe and device probe
From: Anton Blanchard @ 2012-06-25 4:24 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
In-Reply-To: <20120625142353.0a92791a@kryten>
Similar to PCI, separate the bus probe from device probe. This allows
us to attach bus notifiers for DMA debug and IOMMU fault injection
before devices have been probed.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/vio.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vio.c 2012-06-08 09:14:19.282098456 +1000
+++ linux-build/arch/powerpc/kernel/vio.c 2012-06-08 09:16:53.856359566 +1000
@@ -1497,12 +1497,18 @@ static int __init vio_bus_init(void)
if (firmware_has_feature(FW_FEATURE_CMO))
vio_cmo_bus_init();
+ return 0;
+}
+postcore_initcall(vio_bus_init);
+
+static int __init vio_device_init(void)
+{
vio_bus_scan_register_devices("vdevice");
vio_bus_scan_register_devices("ibm,platform-facilities");
return 0;
}
-__initcall(vio_bus_init);
+device_initcall(vio_device_init);
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
^ permalink raw reply
* [PATCH 1/4] powerpc: vio: Remove dma not supported warnings
From: Anton Blanchard @ 2012-06-25 4:23 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
During boot we see a number of these warnings:
vio 30000000: Warning: IOMMU dma not supported: mask 0xffffffffffffffff, table unavailable
The reason for this is that we set IOMMU properties for all VIO
devices even if they are not DMA capable.
Only set DMA ops, table and mask for devices with a DMA window.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/vio.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vio.c 2012-06-08 14:02:05.548512941 +1000
+++ linux-build/arch/powerpc/kernel/vio.c 2012-06-25 13:49:54.349806390 +1000
@@ -1397,21 +1397,27 @@ struct vio_dev *vio_register_device_node
viodev->name = of_node->name;
viodev->dev.of_node = of_node_get(of_node);
- if (firmware_has_feature(FW_FEATURE_CMO))
- vio_cmo_set_dma_ops(viodev);
- else
- set_dma_ops(&viodev->dev, &dma_iommu_ops);
- set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev));
set_dev_node(&viodev->dev, of_node_to_nid(of_node));
/* init generic 'struct device' fields: */
viodev->dev.parent = &vio_bus_device.dev;
viodev->dev.bus = &vio_bus_type;
viodev->dev.release = vio_dev_release;
- /* needed to ensure proper operation of coherent allocations
- * later, in case driver doesn't set it explicitly */
- dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
- dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
+
+ if (of_get_property(viodev->dev.of_node, "ibm,my-dma-window", NULL)) {
+ if (firmware_has_feature(FW_FEATURE_CMO))
+ vio_cmo_set_dma_ops(viodev);
+ else
+ set_dma_ops(&viodev->dev, &dma_iommu_ops);
+
+ set_iommu_table_base(&viodev->dev,
+ vio_build_iommu_table(viodev));
+
+ /* needed to ensure proper operation of coherent allocations
+ * later, in case driver doesn't set it explicitly */
+ dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
+ dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
+ }
/* register with generic device framework */
if (device_register(&viodev->dev)) {
^ permalink raw reply
* [PATCH V3 1/2] PCI: retrieve host bridge by PCI bus
From: Gavin Shan @ 2012-06-25 3:10 UTC (permalink / raw)
To: linux-pci, linuxppc-dev; +Cc: bhelgaas, Gavin Shan
With current implementation, there is one function to retrieve
the corresponding host bridge (struct pci_host_bridge) according
to the given PCI device (struct pci_dev) and that function has
been declared as "static". Further, we don't have the public
function to retrieve host bridge from PCI bus yet. The function
is useful somewhere.
The additional information like minimal resource alignment for I/O
and MMIO bars of p2p bridges will be put into the PCI host bridge.
The patch introduces the public function pci_bus_host_bridge() to
retrieve the corresponding PCI host bridge according to the specified
PCI bus, then accessing the information regarding the minimal resource
alignment for I/O and MMIO bars of p2p bridges.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
Reviewed-by: Richard Yang <weiyang@linux.vnet.ibm.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/pci/host-bridge.c | 13 +++++++++++++
include/linux/pci.h | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index a68dc61..b95f0ce 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -27,6 +27,19 @@ static struct pci_host_bridge *find_pci_host_bridge(struct pci_dev *dev)
return to_pci_host_bridge(bus->bridge);
}
+struct pci_host_bridge *pci_bus_host_bridge(struct pci_bus *bus)
+{
+ struct pci_bus *b = bus;
+
+ /* Find the PCI root bus */
+ while (b->parent)
+ b = b->parent;
+
+ return to_pci_host_bridge(b->bridge);
+}
+
+EXPORT_SYMBOL(pci_bus_host_bridge);
+
void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
void (*release_fn)(struct pci_host_bridge *),
void *release_data)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index fefb4e1..6d5bb1c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -656,7 +656,7 @@ void pcibios_update_irq(struct pci_dev *, int irq);
void pci_fixup_cardbus(struct pci_bus *);
/* Generic PCI functions used internally */
-
+struct pci_host_bridge *pci_bus_host_bridge(struct pci_bus *bus);
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res);
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 2/2] PCI: minimal alignment for bars of P2P bridges
From: Gavin Shan @ 2012-06-25 3:10 UTC (permalink / raw)
To: linux-pci, linuxppc-dev; +Cc: bhelgaas, Gavin Shan
In-Reply-To: <1340593821-19011-1-git-send-email-shangw@linux.vnet.ibm.com>
On some powerpc platforms, device BARs need to be assigned to separate
"segments" of the address space in order for the error isolation and HW
virtualization mechanisms (EEH) to work properly. Those "segments" have
a minimum size that can be fairly large (16M). In order to be able to
use the generic resource assignment code rather than re-inventing our
own, we chose to group devices by bus. That way, a simple change of the
minimum alignment requirements of resources assigned to PCI to PCI (P2P)
bridges is enough to ensure that all BARs for devices below those bridges
will fit into contiguous sets of segments and there will be no overlap.
This patch provides a way for the host bridge to override the default
alignment values used by the resource allocation code for that purpose.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
Reviewed-by: Richard Yang <weiyang@linux.vnet.ibm.com>
---
drivers/pci/probe.c | 5 +++++
drivers/pci/setup-bus.c | 28 +++++++++++++++++++++-------
include/linux/pci.h | 8 ++++++++
3 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 658ac97..a196529 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -431,6 +431,11 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
if (bridge) {
INIT_LIST_HEAD(&bridge->windows);
bridge->bus = b;
+
+ /* Set minimal alignment shift of P2P bridges */
+ bridge->io_align_shift = PCI_DEFAULT_IO_ALIGN_SHIFT;
+ bridge->mem_align_shift = PCI_DEFAULT_MEM_ALIGN_SHIFT;
+ bridge->pmem_align_shift = PCI_DEFAULT_PMEM_ALIGN_SHIFT;
}
return bridge;
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8fa2d4b..7c3e90d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -706,10 +706,12 @@ static resource_size_t calculate_memsize(resource_size_t size,
static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
resource_size_t add_size, struct list_head *realloc_head)
{
+ struct pci_host_bridge *phb;
struct pci_dev *dev;
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
unsigned long size = 0, size0 = 0, size1 = 0;
resource_size_t children_add_size = 0;
+ resource_size_t io_align;
if (!b_res)
return;
@@ -735,13 +737,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
children_add_size += get_res_add_size(realloc_head, r);
}
}
+
+ phb = pci_bus_host_bridge(bus);
+ io_align = (1 << phb->io_align_shift);
+
size0 = calculate_iosize(size, min_size, size1,
- resource_size(b_res), 4096);
+ resource_size(b_res), io_align);
if (children_add_size > add_size)
add_size = children_add_size;
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
calculate_iosize(size, min_size, add_size + size1,
- resource_size(b_res), 4096);
+ resource_size(b_res), io_align);
if (!size0 && !size1) {
if (b_res->start || b_res->end)
dev_info(&bus->self->dev, "disabling bridge window "
@@ -751,11 +757,11 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
return;
}
/* Alignment of the IO window is always 4K */
- b_res->start = 4096;
+ b_res->start = io_align;
b_res->end = b_res->start + size0 - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
if (size1 > size0 && realloc_head) {
- add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
+ add_to_list(realloc_head, bus->self, b_res, size1-size0, io_align);
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
"%pR to [bus %02x-%02x] add_size %lx\n", b_res,
bus->secondary, bus->subordinate, size1-size0);
@@ -778,6 +784,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
resource_size_t add_size,
struct list_head *realloc_head)
{
+ struct pci_host_bridge *phb;
struct pci_dev *dev;
resource_size_t min_align, align, size, size0, size1;
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
@@ -785,10 +792,17 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
struct resource *b_res = find_free_bus_resource(bus, type);
unsigned int mem64_mask = 0;
resource_size_t children_add_size = 0;
+ int mem_align_shift;
if (!b_res)
return 0;
+ phb = pci_bus_host_bridge(bus);
+ if (type & IORESOURCE_PREFETCH)
+ mem_align_shift = phb->pmem_align_shift;
+ else
+ mem_align_shift = phb->mem_align_shift;
+
memset(aligns, 0, sizeof(aligns));
max_order = 0;
size = 0;
@@ -818,8 +832,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
#endif
/* For bridges size != alignment */
align = pci_resource_alignment(dev, r);
- order = __ffs(align) - 20;
- if (order > 11) {
+ order = __ffs(align) - mem_align_shift;
+ if (order > (11 - (mem_align_shift - 20))) {
dev_warn(&dev->dev, "disabling BAR %d: %pR "
"(bad alignment %#llx)\n", i, r,
(unsigned long long) align);
@@ -846,7 +860,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
for (order = 0; order <= max_order; order++) {
resource_size_t align1 = 1;
- align1 <<= (order + 20);
+ align1 <<= (order + mem_align_shift);
if (!align)
min_align = align1;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6d5bb1c..ed55e58 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -376,9 +376,17 @@ struct pci_host_bridge_window {
resource_size_t offset; /* bus address + offset = CPU address */
};
+/* Default shits for P2P I/O and MMIO bar minimal alignment shifts */
+#define PCI_DEFAULT_IO_ALIGN_SHIFT 12 /* 4KB */
+#define PCI_DEFAULT_MEM_ALIGN_SHIFT 20 /* 1MB */
+#define PCI_DEFAULT_PMEM_ALIGN_SHIFT 20 /* 1MB */
+
struct pci_host_bridge {
struct device dev;
struct pci_bus *bus; /* root bus */
+ int io_align_shift; /* P2P I/O bar minimal alignment shift */
+ int mem_align_shift; /* P2P MMIO bar minimal alignment shift */
+ int pmem_align_shift; /* P2P prefetchable MMIO bar minimal alignment shift */
struct list_head windows; /* pci_host_bridge_windows */
void (*release_fn)(struct pci_host_bridge *);
void *release_data;
--
1.7.9.5
^ permalink raw reply related
* [PATCH] powerpc: Add VDSO version of getcpu
From: Anton Blanchard @ 2012-06-25 1:55 UTC (permalink / raw)
To: benh, paulus; +Cc: linuxppc-dev
We had a request for a fast method of getting CPU and NUMA node IDs
from userspace. Ben suggested we use SPRG3 which is userspace
readable. This is a quick hack to try that out.
I have a glibc patch to implement sched_getcpu using this. Testing
on a POWER7:
baseline: 538 cycles
vdso: 30 cycles
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Outstanding issues:
- Do we have any KVM issues?
- This will only work with 64 bit kernels for now, do we need to come up
with a scheme for 32 bit?
- Implement 32 bit userspace version (running on 64 bit kernels)
Index: linux-build/arch/powerpc/include/asm/reg.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/reg.h 2012-06-25 10:05:52.193076424 +1000
+++ linux-build/arch/powerpc/include/asm/reg.h 2012-06-25 10:09:02.932316659 +1000
@@ -491,6 +491,7 @@
#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
+#define SPRN_USPRG3 0x103 /* SPRG3 userspace read */
#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
@@ -753,14 +754,14 @@
* 64-bit server:
* - SPRG0 unused (reserved for HV on Power4)
* - SPRG2 scratch for exception vectors
- * - SPRG3 unused (user visible)
+ * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
* - HSPRG0 stores PACA in HV mode
* - HSPRG1 scratch for "HV" exceptions
*
* 64-bit embedded
* - SPRG0 generic exception scratch
* - SPRG2 TLB exception stack
- * - SPRG3 unused (user visible)
+ * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
* - SPRG4 unused (user visible)
* - SPRG6 TLB miss scratch (user visible, sorry !)
* - SPRG7 critical exception scratch
Index: linux-build/arch/powerpc/kernel/vdso.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso.c 2012-06-25 10:05:52.229077036 +1000
+++ linux-build/arch/powerpc/kernel/vdso.c 2012-06-25 10:12:50.256171890 +1000
@@ -706,6 +706,25 @@ static void __init vdso_setup_syscall_ma
}
}
+#ifdef CONFIG_PPC64
+int __cpuinit vdso_getcpu_init(void)
+{
+ unsigned long cpu, node;
+
+ /*
+ * SPRG3 contains the CPU in the bottom 32 bits and the NUMA node in the
+ * top 32 bits.
+ */
+ cpu = get_cpu();
+ node = cpu_to_node(cpu);
+ mtspr(SPRN_SPRG3, cpu | (node << 32));
+ put_cpu();
+
+ return 0;
+}
+/* We need to call this before SMP init */
+early_initcall(vdso_getcpu_init);
+#endif
static int __init vdso_init(void)
{
Index: linux-build/arch/powerpc/kernel/vdso64/Makefile
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso64/Makefile 2012-06-25 10:05:52.209076696 +1000
+++ linux-build/arch/powerpc/kernel/vdso64/Makefile 2012-06-25 10:05:53.737102674 +1000
@@ -1,6 +1,6 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
+obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
# Build rules
Index: linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso64/vdso64.lds.S 2012-06-25 10:05:52.217076832 +1000
+++ linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S 2012-06-25 10:05:53.737102674 +1000
@@ -146,6 +146,7 @@ VERSION
__kernel_sync_dicache;
__kernel_sync_dicache_p5;
__kernel_sigtramp_rt64;
+ __kernel_getcpu;
local: *;
};
Index: linux-build/arch/powerpc/kernel/vdso64/getcpu.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-build/arch/powerpc/kernel/vdso64/getcpu.S 2012-06-25 10:09:11.796467121 +1000
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <asm/ppc_asm.h>
+#include <asm/vdso.h>
+
+ .text
+/*
+ * Exact prototype of getcpu
+ *
+ * int __kernel_getcpu(unsigned *cpu, unsigned *node);
+ *
+ */
+V_FUNCTION_BEGIN(__kernel_getcpu)
+ .cfi_startproc
+ mfspr r5,SPRN_USPRG3
+ cmpdi cr0,r3,0
+ cmpdi cr1,r4,0
+ srdi r6,r5,32
+ beq cr0,1f
+ stw r5,0(r3)
+1: beq cr1,2f
+ stw r6,0(r4)
+2: crclr cr0*4+so
+ li r3,0 /* always success */
+ blr
+ .cfi_endproc
+V_FUNCTION_END(__kernel_getcpu)
Index: linux-build/arch/powerpc/kernel/smp.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/smp.c 2012-06-25 10:05:52.197076492 +1000
+++ linux-build/arch/powerpc/kernel/smp.c 2012-06-25 10:13:54.897266908 +1000
@@ -48,6 +48,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#endif
+#include <asm/vdso.h>
#include <asm/debug.h>
#ifdef DEBUG
@@ -570,6 +571,8 @@ void __devinit start_secondary(void *unu
#ifdef CONFIG_PPC64
if (system_state == SYSTEM_RUNNING)
vdso_data->processorCount++;
+
+ vdso_getcpu_init();
#endif
ipi_call_lock();
notify_cpu_starting(cpu);
Index: linux-build/arch/powerpc/include/asm/vdso.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/vdso.h 2012-06-25 10:05:52.181076220 +1000
+++ linux-build/arch/powerpc/include/asm/vdso.h 2012-06-25 10:05:53.737102674 +1000
@@ -22,6 +22,8 @@ extern unsigned long vdso64_rt_sigtramp;
extern unsigned long vdso32_sigtramp;
extern unsigned long vdso32_rt_sigtramp;
+int __cpuinit vdso_getcpu_init(void);
+
#else /* __ASSEMBLY__ */
#ifdef __VDSO64__
^ permalink raw reply
* [PATCH -v4 6/6] fault-injection: add notifier error injection testing scripts
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
To: linux-kernel, akpm
Cc: Greg KH, Akinobu Mita, Rafael J. Wysocki, linux-mm,
Paul Mackerras, Pavel Machek, Américo Wang, linux-pm,
linuxppc-dev
In-Reply-To: <1340463502-15341-1-git-send-email-akinobu.mita@gmail.com>
This adds two testing scripts with notifier error injection
* tools/testing/fault-injection/cpu-notifier.sh is testing script for
CPU notifier error handling by using cpu-notifier-error-inject.ko.
1. Offline all hot-pluggable CPUs in preparation for testing
2. Test CPU hot-add error handling by injecting notifier errors
3. Online all hot-pluggable CPUs in preparation for testing
4. Test CPU hot-remove error handling by injecting notifier errors
* tools/testing/fault-injection/memory-notifier.sh is doing the similar
thing for memory hotplug notifier.
1. Offline 10% of hot-pluggable memory in preparation for testing
2. Test memory hot-add error handling by injecting notifier errors
3. Online all hot-pluggable memory in preparation for testing
4. Test memory hot-remove error handling by injecting notifier errors
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
Cc: Greg KH <greg@kroah.com>
Cc: linux-mm@kvack.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang <xiyou.wangcong@gmail.com>
---
* v4
- add -r option for memory-notifier.sh to specify percent of offlining
memory blocks
tools/testing/fault-injection/cpu-notifier.sh | 169 +++++++++++++++++++++
tools/testing/fault-injection/memory-notifier.sh | 176 ++++++++++++++++++++++
2 files changed, 345 insertions(+)
create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
create mode 100755 tools/testing/fault-injection/memory-notifier.sh
diff --git a/tools/testing/fault-injection/cpu-notifier.sh b/tools/testing/fault-injection/cpu-notifier.sh
new file mode 100755
index 0000000..af93630
--- /dev/null
+++ b/tools/testing/fault-injection/cpu-notifier.sh
@@ -0,0 +1,169 @@
+#!/bin/bash
+
+#
+# list all hot-pluggable CPUs
+#
+hotpluggable_cpus()
+{
+ local state=${1:-.\*}
+
+ for cpu in /sys/devices/system/cpu/cpu*; do
+ if [ -f $cpu/online ] && grep -q $state $cpu/online; then
+ echo ${cpu##/*/cpu}
+ fi
+ done
+}
+
+hotplaggable_offline_cpus()
+{
+ hotpluggable_cpus 0
+}
+
+hotpluggable_online_cpus()
+{
+ hotpluggable_cpus 1
+}
+
+cpu_is_online()
+{
+ grep -q 1 /sys/devices/system/cpu/cpu$1/online
+}
+
+cpu_is_offline()
+{
+ grep -q 0 /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu()
+{
+ echo 1 > /sys/devices/system/cpu/cpu$1/online
+}
+
+remove_cpu()
+{
+ echo 0 > /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu_expect_success()
+{
+ local cpu=$1
+
+ if ! add_cpu $cpu; then
+ echo $FUNCNAME $cpu: unexpected fail >&2
+ elif ! cpu_is_online $cpu; then
+ echo $FUNCNAME $cpu: unexpected offline >&2
+ fi
+}
+
+add_cpu_expect_fail()
+{
+ local cpu=$1
+
+ if add_cpu $cpu 2> /dev/null; then
+ echo $FUNCNAME $cpu: unexpected success >&2
+ elif ! cpu_is_offline $cpu; then
+ echo $FUNCNAME $cpu: unexpected online >&2
+ fi
+}
+
+remove_cpu_expect_success()
+{
+ local cpu=$1
+
+ if ! remove_cpu $cpu; then
+ echo $FUNCNAME $cpu: unexpected fail >&2
+ elif ! cpu_is_offline $cpu; then
+ echo $FUNCNAME $cpu: unexpected offline >&2
+ fi
+}
+
+remove_cpu_expect_fail()
+{
+ local cpu=$1
+
+ if remove_cpu $cpu 2> /dev/null; then
+ echo $FUNCNAME $cpu: unexpected success >&2
+ elif ! cpu_is_online $cpu; then
+ echo $FUNCNAME $cpu: unexpected offline >&2
+ fi
+}
+
+if [ $UID != 0 ]; then
+ echo must be run as root >&2
+ exit 1
+fi
+
+error=-12
+priority=0
+
+while getopts e:hp: opt; do
+ case $opt in
+ e)
+ error=$OPTARG
+ ;;
+ h)
+ echo "Usage $0 [ -e errno ] [ -p notifier-priority ]"
+ exit
+ ;;
+ p)
+ priority=$OPTARG
+ ;;
+ esac
+done
+
+if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+ echo "error code must be -4095 <= errno < 0" >&2
+ exit 1
+fi
+
+DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+
+if [ ! -d "$DEBUGFS" ]; then
+ echo debugfs is not mounted >&2
+ exit 1
+fi
+
+/sbin/modprobe -r cpu-notifier-error-inject
+/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
+
+NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
+
+if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+ echo cpu-notifier-error-inject module is not available >&2
+ exit 1
+fi
+
+#
+# Offline all hot-pluggable CPUs
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+for cpu in `hotpluggable_online_cpus`; do
+ remove_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-add error handling (offline => online)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+for cpu in `hotplaggable_offline_cpus`; do
+ add_cpu_expect_fail $cpu
+done
+
+#
+# Online all hot-pluggable CPUs
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+for cpu in `hotplaggable_offline_cpus`; do
+ add_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-remove error handling (online => offline)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+for cpu in `hotpluggable_online_cpus`; do
+ remove_cpu_expect_fail $cpu
+done
+
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+/sbin/modprobe -r cpu-notifier-error-inject
diff --git a/tools/testing/fault-injection/memory-notifier.sh b/tools/testing/fault-injection/memory-notifier.sh
new file mode 100755
index 0000000..843cba7
--- /dev/null
+++ b/tools/testing/fault-injection/memory-notifier.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+#
+# list all hot-pluggable memory
+#
+hotpluggable_memory()
+{
+ local state=${1:-.\*}
+
+ for memory in /sys/devices/system/memory/memory*; do
+ if grep -q 1 $memory/removable &&
+ grep -q $state $memory/state; then
+ echo ${memory##/*/memory}
+ fi
+ done
+}
+
+hotplaggable_offline_memory()
+{
+ hotpluggable_memory offline
+}
+
+hotpluggable_online_memory()
+{
+ hotpluggable_memory online
+}
+
+memory_is_online()
+{
+ grep -q online /sys/devices/system/memory/memory$1/state
+}
+
+memory_is_offline()
+{
+ grep -q offline /sys/devices/system/memory/memory$1/state
+}
+
+add_memory()
+{
+ echo online > /sys/devices/system/memory/memory$1/state
+}
+
+remove_memory()
+{
+ echo offline > /sys/devices/system/memory/memory$1/state
+}
+
+add_memory_expect_success()
+{
+ local memory=$1
+
+ if ! add_memory $memory; then
+ echo $FUNCNAME $memory: unexpected fail >&2
+ elif ! memory_is_online $memory; then
+ echo $FUNCNAME $memory: unexpected offline >&2
+ fi
+}
+
+add_memory_expect_fail()
+{
+ local memory=$1
+
+ if add_memory $memory 2> /dev/null; then
+ echo $FUNCNAME $memory: unexpected success >&2
+ elif ! memory_is_offline $memory; then
+ echo $FUNCNAME $memory: unexpected online >&2
+ fi
+}
+
+remove_memory_expect_success()
+{
+ local memory=$1
+
+ if ! remove_memory $memory; then
+ echo $FUNCNAME $memory: unexpected fail >&2
+ elif ! memory_is_offline $memory; then
+ echo $FUNCNAME $memory: unexpected offline >&2
+ fi
+}
+
+remove_memory_expect_fail()
+{
+ local memory=$1
+
+ if remove_memory $memory 2> /dev/null; then
+ echo $FUNCNAME $memory: unexpected success >&2
+ elif ! memory_is_online $memory; then
+ echo $FUNCNAME $memory: unexpected offline >&2
+ fi
+}
+
+if [ $UID != 0 ]; then
+ echo must be run as root >&2
+ exit 1
+fi
+
+error=-12
+priority=0
+ratio=10
+
+while getopts e:hp:r: opt; do
+ case $opt in
+ e)
+ error=$OPTARG
+ ;;
+ h)
+ echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]"
+ exit
+ ;;
+ p)
+ priority=$OPTARG
+ ;;
+ r)
+ ratio=$OPTARG
+ ;;
+ esac
+done
+
+if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+ echo "error code must be -4095 <= errno < 0" >&2
+ exit 1
+fi
+
+DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+
+if [ ! -d "$DEBUGFS" ]; then
+ echo debugfs is not mounted >&2
+ exit 1
+fi
+
+/sbin/modprobe -r memory-notifier-error-inject
+/sbin/modprobe -q memory-notifier-error-inject priority=$priority
+
+NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory
+
+if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+ echo memory-notifier-error-inject module is not available >&2
+ exit 1
+fi
+
+#
+# Offline $ratio percent of hot-pluggable memory
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
+for memory in `hotpluggable_online_memory`; do
+ if [ $((RANDOM % 100)) -lt $ratio ]; then
+ remove_memory_expect_success $memory
+ fi
+done
+
+#
+# Test memory hot-add error handling (offline => online)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
+for memory in `hotplaggable_offline_memory`; do
+ add_memory_expect_fail $memory
+done
+
+#
+# Online all hot-pluggable memory
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
+for memory in `hotplaggable_offline_memory`; do
+ add_memory_expect_success $memory
+done
+
+#
+# Test memory hot-remove error handling (online => offline)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
+for memory in `hotpluggable_online_memory`; do
+ remove_memory_expect_fail $memory
+done
+
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
+/sbin/modprobe -r memory-notifier-error-inject
--
1.7.10.2
^ permalink raw reply related
* [PATCH -v4 5/6] powerpc: pSeries reconfig notifier error injection module
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
To: linux-kernel, akpm; +Cc: linuxppc-dev, Paul Mackerras, Akinobu Mita
In-Reply-To: <1340463502-15341-1-git-send-email-akinobu.mita@gmail.com>
This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks. It is controlled through debugfs interface
under /sys/kernel/debug/notifier-error-inject/pSeries-reconfig
If the notifier call chain should be failed with some events
notified, write the error code to "actions/<notifier event>/error".
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
* v4
- update modules to follow new interface
lib/Kconfig.debug | 17 +++++++++
lib/Makefile | 2 +
lib/pSeries-reconfig-notifier-error-inject.c | 51 ++++++++++++++++++++++++++
3 files changed, 70 insertions(+)
create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7cceddc..8f8e226 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1166,6 +1166,23 @@ config MEMORY_NOTIFIER_ERROR_INJECT
If unsure, say N.
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
+ tristate "pSeries reconfig notifier error injection module"
+ depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+ help
+ This option provides the ability to inject artifical errors to
+ pSeries reconfig notifier chain callbacks. It is controlled
+ through debugfs interface under
+ /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/
+
+ If the notifier call chain should be failed with some events
+ notified, write the error code to "actions/<notifier event>/error".
+
+ To compile this code as a module, choose M here: the module will
+ be called memory-notifier-error-inject.
+
+ If unsure, say N.
+
config FAULT_INJECTION
bool "Fault-injection framework"
depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index a867aa5..d055cb1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -94,6 +94,8 @@ obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
+obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \
+ pSeries-reconfig-notifier-error-inject.o
lib-$(CONFIG_GENERIC_BUG) += bug.o
diff --git a/lib/pSeries-reconfig-notifier-error-inject.c b/lib/pSeries-reconfig-notifier-error-inject.c
new file mode 100644
index 0000000..7f7c98d
--- /dev/null
+++ b/lib/pSeries-reconfig-notifier-error-inject.c
@@ -0,0 +1,51 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/pSeries_reconfig.h>
+
+#include "notifier-error-inject.h"
+
+static int priority;
+module_param(priority, int, 0);
+MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority");
+
+static struct notifier_err_inject reconfig_err_inject = {
+ .actions = {
+ { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_ADD) },
+ { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_REMOVE) },
+ { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_ADD) },
+ { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+ {}
+ }
+};
+
+static struct dentry *dir;
+
+static int err_inject_init(void)
+{
+ int err;
+
+ dir = notifier_err_inject_init("pSeries-reconfig",
+ notifier_err_inject_dir, &reconfig_err_inject, priority);
+ if (IS_ERR(dir))
+ return PTR_ERR(dir);
+
+ err = pSeries_reconfig_notifier_register(&reconfig_err_inject.nb);
+ if (err)
+ debugfs_remove_recursive(dir);
+
+ return err;
+}
+
+static void err_inject_exit(void)
+{
+ pSeries_reconfig_notifier_unregister(&reconfig_err_inject.nb);
+ debugfs_remove_recursive(dir);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_DESCRIPTION("pSeries reconfig notifier error injection module");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
--
1.7.10.2
^ permalink raw reply related
* [PATCH -v4 1/6] fault-injection: notifier error injection
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
To: linux-kernel, akpm
Cc: Greg KH, Akinobu Mita, Rafael J. Wysocki, linux-mm,
Paul Mackerras, Pavel Machek, linux-pm, linuxppc-dev
In-Reply-To: <1340463502-15341-1-git-send-email-akinobu.mita@gmail.com>
The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks. It is useful to test the
error handling of notifier call chain failures.
This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
Cc: Greg KH <greg@kroah.com>
Cc: linux-mm@kvack.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman <michael@ellerman.id.au>
---
* v4
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
(e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
$DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)
lib/Kconfig.debug | 11 +++++
lib/Makefile | 1 +
lib/notifier-error-inject.c | 112 +++++++++++++++++++++++++++++++++++++++++++
lib/notifier-error-inject.h | 24 ++++++++++
4 files changed, 148 insertions(+)
create mode 100644 lib/notifier-error-inject.c
create mode 100644 lib/notifier-error-inject.h
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ff5bdee..c848758 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1084,6 +1084,17 @@ config LKDTM
Documentation on how to use the module can be found in
Documentation/fault-injection/provoke-crashes.txt
+config NOTIFIER_ERROR_INJECTION
+ tristate "Notifier error injection"
+ depends on DEBUG_KERNEL
+ select DEBUG_FS
+ help
+ This option provides the ability to inject artifical errors to
+ specified notifier chain callbacks. It is useful to test the error
+ handling of notifier call chain failures.
+
+ Say N if unsure.
+
config CPU_NOTIFIER_ERROR_INJECT
tristate "CPU notifier error injection module"
depends on HOTPLUG_CPU && DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 8c31a0c..23fba9e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_AUDIT_GENERIC) += audit.o
obj-$(CONFIG_SWIOTLB) += swiotlb.o
obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o
obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
+obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
lib-$(CONFIG_GENERIC_BUG) += bug.o
diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
new file mode 100644
index 0000000..44b92cb
--- /dev/null
+++ b/lib/notifier-error-inject.c
@@ -0,0 +1,112 @@
+#include <linux/module.h>
+
+#include "notifier-error-inject.h"
+
+static int debugfs_errno_set(void *data, u64 val)
+{
+ *(int *)data = clamp_t(int, val, -MAX_ERRNO, 0);
+ return 0;
+}
+
+static int debugfs_errno_get(void *data, u64 *val)
+{
+ *val = *(int *)data;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
+ "%lld\n");
+
+static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+ struct dentry *parent, int *value)
+{
+ return debugfs_create_file(name, mode, parent, value, &fops_errno);
+}
+
+static int notifier_err_inject_callback(struct notifier_block *nb,
+ unsigned long val, void *p)
+{
+ int err = 0;
+ struct notifier_err_inject *err_inject =
+ container_of(nb, struct notifier_err_inject, nb);
+ struct notifier_err_inject_action *action;
+
+ for (action = err_inject->actions; action->name; action++) {
+ if (action->val == val) {
+ err = action->error;
+ break;
+ }
+ }
+ if (err)
+ pr_info("Injecting error (%d) to %s\n", err, action->name);
+
+ return notifier_from_errno(err);
+}
+
+struct dentry *notifier_err_inject_dir;
+EXPORT_SYMBOL_GPL(notifier_err_inject_dir);
+
+struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent,
+ struct notifier_err_inject *err_inject, int priority)
+{
+ struct notifier_err_inject_action *action;
+ mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+ struct dentry *dir;
+ struct dentry *actions_dir;
+
+ err_inject->nb.notifier_call = notifier_err_inject_callback;
+ err_inject->nb.priority = priority;
+
+ dir = debugfs_create_dir(name, parent);
+ if (!dir)
+ return ERR_PTR(-ENOMEM);
+
+ actions_dir = debugfs_create_dir("actions", dir);
+ if (!actions_dir)
+ goto fail;
+
+ for (action = err_inject->actions; action->name; action++) {
+ struct dentry *action_dir;
+
+ action_dir = debugfs_create_dir(action->name, actions_dir);
+ if (!action_dir)
+ goto fail;
+
+ /*
+ * Create debugfs r/w file containing action->error. If
+ * notifier call chain is called with action->val, it will
+ * fail with the error code
+ */
+ if (!debugfs_create_errno("error", mode, action_dir,
+ &action->error))
+ goto fail;
+ }
+ return dir;
+fail:
+ debugfs_remove_recursive(dir);
+ return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL_GPL(notifier_err_inject_init);
+
+static int __init err_inject_init(void)
+{
+ notifier_err_inject_dir =
+ debugfs_create_dir("notifier-error-inject", NULL);
+
+ if (!notifier_err_inject_dir)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __exit err_inject_exit(void)
+{
+ debugfs_remove_recursive(notifier_err_inject_dir);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_DESCRIPTION("Notifier error injection module");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
diff --git a/lib/notifier-error-inject.h b/lib/notifier-error-inject.h
new file mode 100644
index 0000000..99b3b6f
--- /dev/null
+++ b/lib/notifier-error-inject.h
@@ -0,0 +1,24 @@
+#include <linux/atomic.h>
+#include <linux/debugfs.h>
+#include <linux/notifier.h>
+
+struct notifier_err_inject_action {
+ unsigned long val;
+ int error;
+ const char *name;
+};
+
+#define NOTIFIER_ERR_INJECT_ACTION(action) \
+ .name = #action, .val = (action),
+
+struct notifier_err_inject {
+ struct notifier_block nb;
+ struct notifier_err_inject_action actions[];
+ /* The last slot must be terminated with zero sentinel */
+};
+
+extern struct dentry *notifier_err_inject_dir;
+
+extern struct dentry *notifier_err_inject_init(const char *name,
+ struct dentry *parent, struct notifier_err_inject *err_inject,
+ int priority);
--
1.7.10.2
^ permalink raw reply related
* [PATCH -v4 0/6] notifier error injection
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
To: linux-kernel, akpm
Cc: Greg KH, Akinobu Mita, Rafael J. Wysocki, linux-mm,
Paul Mackerras, Pavel Machek, Américo Wang, linux-pm,
linuxppc-dev
This provides kernel modules that can be used to test the error handling
of notifier call chain failures by injecting artifical errors to the
following notifier chain callbacks.
* CPU notifier
* PM notifier
* memory hotplug notifier
* powerpc pSeries reconfig notifier
Example: Inject CPU offline error (-1 == -EPERM)
# cd /sys/kernel/debug/notifier-error-inject/cpu
# echo -1 > actions/CPU_DOWN_PREPARE/error
# echo 0 > /sys/devices/system/cpu/cpu1/online
bash: echo: write error: Operation not permitted
There are also handy shell scripts to test CPU and memory hotplug notifier.
Note that these tests didn't detect error handling bugs on my machine but
I still think this feature is usefull to test the code path which is rarely
executed.
Changelog:
* v4 (It is about 11 months since v3)
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
(e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
$DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)
- update modules to follow new interface
- add -r option for memory-notifier.sh to specify percent of offlining
memory blocks
* v3
- rewrite to be kernel modules instead of initializing at late_initcall()s
(it makes the diffstat look different but most code remains unchanged)
- export err_inject_notifier_block_{init,cleanup} for modules
- export pSeries_reconfig_notifier_{,un}register symbols for a module
- notifier priority can be specified as a module parameter
- add testing scripts in tools/testing/fault-injection
* v2
- "PM: Improve error code of pm_notifier_call_chain()" is now in -next
- "debugfs: add debugfs_create_int" is dropped
- put a comment in err_inject_notifier_block_init()
- only allow valid errno to be injected (-MAX_ERRNO <= errno <= 0)
- improve Kconfig help text
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION visible even if PM_DEBUG is disabled
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION default if PM_DEBUG is enabled
Akinobu Mita (6):
fault-injection: notifier error injection
cpu: rewrite cpu-notifier-error-inject module
PM: PM notifier error injection module
memory: memory notifier error injection module
powerpc: pSeries reconfig notifier error injection module
fault-injection: add notifier error injection testing scripts
lib/Kconfig.debug | 91 ++++++++++-
lib/Makefile | 5 +
lib/cpu-notifier-error-inject.c | 63 +++-----
lib/memory-notifier-error-inject.c | 48 ++++++
lib/notifier-error-inject.c | 112 ++++++++++++++
lib/notifier-error-inject.h | 24 +++
lib/pSeries-reconfig-notifier-error-inject.c | 51 +++++++
lib/pm-notifier-error-inject.c | 49 ++++++
tools/testing/fault-injection/cpu-notifier.sh | 169 +++++++++++++++++++++
tools/testing/fault-injection/memory-notifier.sh | 176 ++++++++++++++++++++++
10 files changed, 748 insertions(+), 40 deletions(-)
create mode 100644 lib/memory-notifier-error-inject.c
create mode 100644 lib/notifier-error-inject.c
create mode 100644 lib/notifier-error-inject.h
create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c
create mode 100644 lib/pm-notifier-error-inject.c
create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
create mode 100755 tools/testing/fault-injection/memory-notifier.sh
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
Cc: Greg KH <greg@kroah.com>
Cc: linux-mm@kvack.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang <xiyou.wangcong@gmail.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
--
1.7.10.2
^ permalink raw reply
* [PATCH 03/12] powerpc: remove km_type definitions
From: Cong Wang @ 2012-06-23 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: Andrew Morton, linuxppc-dev, Paul Mackerras, Cong Wang
In-Reply-To: <1340445863-16111-1-git-send-email-amwang@redhat.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
arch/powerpc/include/asm/kmap_types.h | 31 +------------------------------
1 files changed, 1 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h
index bca8fdc..5acabbd 100644
--- a/arch/powerpc/include/asm/kmap_types.h
+++ b/arch/powerpc/include/asm/kmap_types.h
@@ -10,36 +10,7 @@
* 2 of the License, or (at your option) any later version.
*/
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_PPC_SYNC_PAGE,
- KM_PPC_SYNC_ICACHE,
- KM_KDB,
- KM_TYPE_NR
-};
-
-/*
- * This is a temporary build fix that (so they say on lkml....) should no longer
- * be required after 2.6.33, because of changes planned to the kmap code.
- * Let's try to remove this cruft then.
- */
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define KM_NMI (-1)
-#define KM_NMI_PTE (-1)
-#define KM_IRQ_PTE (-1)
-#endif
+#define KM_TYPE_NR 16
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KMAP_TYPES_H */
--
1.7.7.6
^ permalink raw reply related
* Help with Freescale QE ATM driver (FUA)
From: Bill F @ 2012-06-22 19:14 UTC (permalink / raw)
To: linuxppc-dev
Hi,
Have you used the Freescale QUICC Engine (QE) ATM mode with a Linux
based product ?
I am currently using the "fua" driver obtained from Freescale
MPC8360E_PB_K26_20081112-LTIB.iso CDROM image. The "fua" driver was
written for kernel 2.6.22 (2007) and I have ported it forward to
kernel 3.3 (2012). My board has an MPC8358 and SUNI PHY. I am
testing the fua driver with the atm-tools and aburst, and using a
loopback cable.
The ported fua driver is able to open an ATM connection and send and
receive messages. I can use awrite and aread to send and receive
ascii characters.
Problems:
* If I open three or more ATM connections, all ATM transfers stop,
and the ethernet driver (ucc_geth) also stops working. To recover I
have to reboot. Urg.
* UBR transfers seem to be treated as if they are a 100 Mbps CBR
connection. I was expecting UBR to fill all of the unused bandwidth.
* I'm finding and fixing a lot of minor bugs that crash the driver.
My other reference is the mpc8360 SAR driver
(http://mpc8360sar.sourceforge.net) which is even older (patches
against kernel 2.6.11).
If someone on this list is sitting on an updated fua driver or similar
QE ATM driver, could you send me the code. Better yet, can I help you
push it out to a github or similar repo ?
Thanks,
Bill
^ permalink raw reply
* Re: [PATCH] MIPS: fix bug.h MIPS build regression
From: David Daney @ 2012-06-22 17:54 UTC (permalink / raw)
To: Ralf Baechle
Cc: Linux MIPS Mailing List, Linux-sh list, linux-kernel,
Linuxppc-dev, Paul Mundt, Geert Uytterhoeven, Chris Zankel,
Yoichi Yuasa
In-Reply-To: <20120620161249.GB29196@linux-mips.org>
On 06/20/2012 09:12 AM, Ralf Baechle wrote:
> On Wed, Jun 20, 2012 at 03:27:59PM +0900, Yoichi Yuasa wrote:
>
>> Commit: 3777808873b0c49c5cf27e44c948dfb02675d578 breaks all MIPS builds.
>
> Thanks, fix applied.
>
Where was it applied?
It doesn't show up in linux-next for 20120622, which is where it is needed.
David Daney
^ permalink raw reply
* Re: [PATCH] powerpc: Fix BPF_JIT code to link with multiple TOCs
From: matt @ 2012-06-22 9:01 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, amodra
In-Reply-To: <1340337027-22110-1-git-send-email-michael@ellerman.id.au>
Whee! Let's try that again with MUA configured better...
On 2012-06-22 04:50, Michael Ellerman wrote:
> If the kernel is big enough (eg. allyesconfig), the linker may need
> to
> switch TOCs when calling from the BPF JIT code out to the external
> helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()).
>
> In order to do that we need to leave space after the bl for the
> linker
> to insert a reload of our TOC pointer.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Oops, x2, and
Acked-by: Matt Evans <matt@ozlabs.org>
:-)
> ---
> arch/powerpc/net/bpf_jit_64.S | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/net/bpf_jit_64.S
> b/arch/powerpc/net/bpf_jit_64.S
> index 55ba385..7d3a3b5 100644
> --- a/arch/powerpc/net/bpf_jit_64.S
> +++ b/arch/powerpc/net/bpf_jit_64.S
> @@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset:
> mr r4, r_addr; \
> li r6, SIZE; \
> bl skb_copy_bits; \
> + nop; \
> /* R3 = 0 on success */ \
> addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
> ld r0, 16(r1); \
> @@ -156,6 +157,7 @@ bpf_slow_path_byte_msh:
> mr r4, r_addr; \
> li r5, SIZE; \
> bl bpf_internal_load_pointer_neg_helper; \
> + nop; \
> /* R3 != 0 on success */ \
> addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
> ld r0, 16(r1); \
^ permalink raw reply
* Re: [PATCH] powerpc: Fix BPF_JIT code to link with multiple TOCs
From: matt @ 2012-06-22 8:58 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, matt, amodra
In-Reply-To: <1340337027-22110-1-git-send-email-michael@ellerman.id.au>
On 2012-06-22 04:50, Michael Ellerman wrote:
> If the kernel is big enough (eg. allyesconfig), the linker may need
> to
> switch TOCs when calling from the BPF JIT code out to the external
> helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()).
>
> In order to do that we need to leave space after the bl for the
> linker
> to insert a reload of our TOC pointer.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Oops..!
Acked-by: Matt Evans <matt@ozlabs.org>
> ---
> arch/powerpc/net/bpf_jit_64.S | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/net/bpf_jit_64.S
> b/arch/powerpc/net/bpf_jit_64.S
> index 55ba385..7d3a3b5 100644
> --- a/arch/powerpc/net/bpf_jit_64.S
> +++ b/arch/powerpc/net/bpf_jit_64.S
> @@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset:
> mr r4, r_addr; \
> li r6, SIZE; \
> bl skb_copy_bits; \
> + nop; \
> /* R3 = 0 on success */ \
> addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
> ld r0, 16(r1); \
> @@ -156,6 +157,7 @@ bpf_slow_path_byte_msh:
> mr r4, r_addr; \
> li r5, SIZE; \
> bl bpf_internal_load_pointer_neg_helper; \
> + nop; \
> /* R3 != 0 on success */ \
> addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
> ld r0, 16(r1); \
^ permalink raw reply
* [PATCH] powerpc: Turn on BPF_JIT in ppc64_defconfig
From: Michael Ellerman @ 2012-06-22 3:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: matt, amodra
Matt added BPF_JIT support in commit 0ca87f05, but currently none of our
defconfigs build it. Turn that sucker on.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/configs/ppc64_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index c1442a3..a637ee7 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -489,3 +489,4 @@ CONFIG_VIRTUALIZATION=y
CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=y
CONFIG_VHOST_NET=m
+CONFIG_BPF_JIT=y
--
1.7.9.5
^ permalink raw reply related
* [PATCH] powerpc: Fix BPF_JIT code to link with multiple TOCs
From: Michael Ellerman @ 2012-06-22 3:50 UTC (permalink / raw)
To: linuxppc-dev; +Cc: matt, amodra
If the kernel is big enough (eg. allyesconfig), the linker may need to
switch TOCs when calling from the BPF JIT code out to the external
helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()).
In order to do that we need to leave space after the bl for the linker
to insert a reload of our TOC pointer.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/net/bpf_jit_64.S | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
index 55ba385..7d3a3b5 100644
--- a/arch/powerpc/net/bpf_jit_64.S
+++ b/arch/powerpc/net/bpf_jit_64.S
@@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset:
mr r4, r_addr; \
li r6, SIZE; \
bl skb_copy_bits; \
+ nop; \
/* R3 = 0 on success */ \
addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
ld r0, 16(r1); \
@@ -156,6 +157,7 @@ bpf_slow_path_byte_msh:
mr r4, r_addr; \
li r5, SIZE; \
bl bpf_internal_load_pointer_neg_helper; \
+ nop; \
/* R3 != 0 on success */ \
addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
ld r0, 16(r1); \
--
1.7.9.5
^ permalink raw reply related
* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Michael Ellerman @ 2012-06-22 0:39 UTC (permalink / raw)
To: Alan Modra; +Cc: linux-next, ppc-dev, linux-kernel, Stephen Rothwell
In-Reply-To: <20120621114354.GG20973@bubble.grove.modra.org>
On Thu, 2012-06-21 at 21:13 +0930, Alan Modra wrote:
> On Thu, Jun 21, 2012 at 08:18:39PM +0930, Alan Modra wrote:
> > Linker bug. That's not a sibling call, but a normal function return
> > via an out-of-line register restore function.
>
> I couldn't see how this might be occurring, then I remembered the
> kernel has this horrible practise of using ld -r to package object
> files. So linker generated functions might be munged together with
> other functions. Does this help? (It won't if the kernel is
> providing its own save/restore functions.)
The kernel does provide its own AIUI.
cheers
^ permalink raw reply
* Re: [PATCH] kernel panic during kernel module load (powerpc specific part)
From: roger blofeld @ 2012-06-21 15:27 UTC (permalink / raw)
To: ext Benjamin Herrenschmidt, paulus, Steffen Rumler
Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4FCF6B1D.50009@nsn.com>
--- On Wed, 6/6/12, Steffen Rumler <steffen.rumler.ext@nsn.com> wrote:=0A=
=0A> From: Steffen Rumler <steffen.rumler.ext@nsn.com>=0A> Subject: [PATCH]=
kernel panic during kernel module load (powerpc specific part)=0A> To: "ex=
t Benjamin Herrenschmidt" <benh@kernel.crashing.org>, paulus@samba.org=0A> =
Cc: "Wrobel Heinz-R39252" <r39252@freescale.com>, "Michael Ellerman" <micha=
el@ellerman.id.au>, "linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozl=
abs.org>=0A> Date: Wednesday, June 6, 2012, 7:37 AM=0A> Hi,=0A> =0A> The pa=
tch below is intended to fix the following problem.=0A> =0A> According to t=
he PowerPC EABI specification, the GPR r11 is=0A> assigned=0A> the dedicate=
d function to point to the previous stack=0A> frame.=0A> In the powerpc-spe=
cific kernel module loader, do_plt_call()=0A> (in arch/powerpc/kernel/modul=
e_32.c), the GPR r11 is also=0A> used=0A> to generate trampoline code.=0A> =
=0A> This combination crashes the kernel, in the following case:=0A> =0A> =
=A0 + The compiler has been generated the prologue and=0A> epilogue,=0A> =
=A0 =A0 which is part of the .text section.=0A> =A0 + The compiler has been=
generated the code for the=0A> module init entry point,=0A> =A0 =A0 part o=
f the .init.text section (in the case it=0A> is marked with __init).=0A> =
=A0 + By returning from the module init entry point, the=0A> epilogue is ca=
lled by doing=0A> =A0 =A0 a branch instruction.=0A> =A0 + If the epilogue i=
s too far away, a relative branch=0A> instruction cannot be applied.=0A> =
=A0 =A0 Instead trampoline code is generated in=0A> do_plt_call(), in order=
to jump via register.=0A> =A0 =A0 Unfortunately the code generated by=0A> =
do_plt_call() destroys the content of GPR r11.=0A> =A0 + Because GPR r11 do=
es not more keep the right stack=0A> frame pointer,=0A> =A0 =A0 the kernel =
crashes right after the epilogue.=0A> =0A> The fix just uses GPR r12 instea=
d of GPR r11 for generating=0A> the trampoline code.=0A> According to the s=
tatements from Freescale, this is also=0A> save from EABI perspective.=0A> =
=0A> I've tested the fix for kernel 2.6.33 on MPC8541.=0A> =0A> Signed-off-=
by: Steffen Rumler <steffen.rumler.ext@nsn.com>=0A> ---=0A> =0A> --- orig/a=
rch/powerpc/kernel/module_32.c=A0=A0=A0=0A> 2012-06-06 16:04:28.956446788 +=
0200=0A> +++ new/arch/powerpc/kernel/module_32.c=A0=A0=A0=0A> =A0=A0=A0 201=
2-06-06 16:04:17.746290683 +0200=0A> @@ -187,8 +187,8 @@=0A> =0A> static i=
nline int entry_matches(struct ppc_plt_entry=0A> *entry, Elf32_Addr val)=0A=
> {=0A> -=A0=A0=A0 if (entry->jump[0] =3D=3D 0x3d600000 +=0A> ((val + 0x80=
00) >> 16)=0A> -=A0=A0=A0 =A0 =A0 &&=0A> entry->jump[1] =3D=3D 0x396b0000 +=
(val & 0xffff))=0A> +=A0=A0=A0 if (entry->jump[0] =3D=3D 0x3d800000 +=0A> =
((val + 0x8000) >> 16)=0A> +=A0=A0=A0 =A0 =A0 &&=0A> entry->jump[1] =3D=3D =
0x398c0000 + (val & 0xffff))=0A> =A0=A0=A0 =A0=A0=A0 return 1;=0A> =A0=A0=
=A0 return 0;=0A> }=0A> @@ -215,10 +215,9 @@=0A> =A0=A0=A0 =A0=A0=A0 entr=
y++;=0A> =A0=A0=A0 }=0A> =0A> -=A0=A0=A0 /* Stolen from Paul Mackerras as =
well...=0A> */=0A> -=A0=A0=A0 entry->jump[0] =3D=0A> 0x3d600000+((val+0x800=
0)>>16);=A0=A0=A0 /*=0A> lis r11,sym@ha */=0A> -=A0=A0=A0 entry->jump[1] =
=3D 0x396b0000 +=0A> (val&0xffff);=A0=A0=A0 /* addi r11,r11,sym@l*/=0A> -=
=A0=A0=A0 entry->jump[2] =3D=0A> 0x7d6903a6;=A0=A0=A0 =A0=A0=A0=0A> =A0=A0=
=A0 /* mtctr r11 */=0A> +=A0=A0=A0 entry->jump[0] =3D=0A> 0x3d800000+((val+=
0x8000)>>16); /* lis r12,sym@ha */=0A> +=A0=A0=A0 entry->jump[1] =3D 0x398c=
0000 +=0A> (val&0xffff);=A0 =A0=A0=A0/* addi=0A> r12,r12,sym@l*/=0A> +=A0=
=A0=A0 entry->jump[2] =3D 0x7d8903a6;=A0=0A> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0=0A> =A0 /* mtctr r12 */=0A> =A0=A0=A0 entry->jump[3] =3D=0A> 0x4e80042=
0;=A0=A0=A0 =A0=A0=A0=0A> =A0=A0=A0 /* bctr */=0A> =0A> =A0=A0=A0 DEBUGP("=
Initialized plt for 0x%x at=0A> %p\n", val, entry);=0A> ___________________=
____________________________=0A> Linuxppc-dev mailing list=0A> Linuxppc-dev=
@lists.ozlabs.org=0A> https://lists.ozlabs.org/listinfo/linuxppc-dev=0A> =
=0A=0AHi,=0A=0AShouldn't the corresponding ftrace code be updated to match?=
Perhaps like the following (untested) patch:=0A=0ASigned-off-by: Roger Blo=
feld <blofeldus@yahoo.com>=0A---=0A=0A--- a/arch/powerpc/kernel/ftrace.c=0A=
+++ b/arch/powerpc/kernel/ftrace.c=0A@@ -245,9 +245,9 @@ __ftrace_make_nop(=
struct module *mod,=0A =0A =09/*=0A =09 * On PPC32 the trampoline looks lik=
e:=0A-=09 * 0x3d, 0x60, 0x00, 0x00 lis r11,sym@ha=0A-=09 * 0x39, 0x6b, 0=
x00, 0x00 addi r11,r11,sym@l=0A-=09 * 0x7d, 0x69, 0x03, 0xa6 mtctr r11=
=0A+=09 * 0x3d, 0x80, 0x00, 0x00 lis r12,sym@ha=0A+=09 * 0x39, 0x8c, 0x0=
0, 0x00 addi r12,r12,sym@l=0A+=09 * 0x7d, 0x89, 0x03, 0xa6 mtctr r12=0A =
=09 * 0x4e, 0x80, 0x04, 0x20 bctr=0A =09 */=0A =0A@@ -262,9 +262,9 @@ __f=
trace_make_nop(struct module *mod,=0A =09pr_devel(" %08x %08x ", jmp[0], jm=
p[1]);=0A =0A =09/* verify that this is what we expect it to be */=0A-=09if=
(((jmp[0] & 0xffff0000) !=3D 0x3d600000) ||=0A-=09 ((jmp[1] & 0xffff000=
0) !=3D 0x396b0000) ||=0A-=09 (jmp[2] !=3D 0x7d6903a6) ||=0A+=09if (((jm=
p[0] & 0xffff0000) !=3D 0x3d800000) ||=0A+=09 ((jmp[1] & 0xffff0000) !=
=3D 0x398c0000) ||=0A+=09 (jmp[2] !=3D 0x7d8903a6) ||=0A =09 (jmp[3] =
!=3D 0x4e800420)) {=0A =09=09printk(KERN_ERR "Not a trampoline\n");=0A =09=
=09return -EINVAL;=0A
^ permalink raw reply
* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Alan Modra @ 2012-06-21 11:43 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linux-next, ppc-dev, linux-kernel, Stephen Rothwell
In-Reply-To: <20120621104839.GE20973@bubble.grove.modra.org>
On Thu, Jun 21, 2012 at 08:18:39PM +0930, Alan Modra wrote:
> Linker bug. That's not a sibling call, but a normal function return
> via an out-of-line register restore function.
I couldn't see how this might be occurring, then I remembered the
kernel has this horrible practise of using ld -r to package object
files. So linker generated functions might be munged together with
other functions. Does this help? (It won't if the kernel is
providing its own save/restore functions.)
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.387
diff -u -p -r1.387 elf64-ppc.c
@@ -6494,9 +6494,10 @@ ppc64_elf_func_desc_adjust (bfd *obfd AT
/* Provide any missing _save* and _rest* functions. */
htab->sfpr->size = 0;
- for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
- if (!sfpr_define (info, &funcs[i]))
- return FALSE;
+ if (!info->relocatable)
+ for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
+ if (!sfpr_define (info, &funcs[i]))
+ return FALSE;
elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply
* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Alan Modra @ 2012-06-21 10:48 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linux-next, ppc-dev, linux-kernel, Stephen Rothwell
In-Reply-To: <1340264307.1998.20.camel@concordia>
On Thu, Jun 21, 2012 at 05:38:27PM +1000, Michael Ellerman wrote:
> On Thu, 2012-06-21 at 17:07 +1000, Michael Ellerman wrote:
> > On Thu, 2012-06-21 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> > > On Thu, 2012-06-21 at 15:36 +1000, Michael Ellerman wrote:
> > > >
> > > > powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text+0x89b990):
> > > > sibling call optimization to `_restgpr0_28' does not allow automatic multiple TOCs;
> > > > recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `_restgpr0_28' extern
> > > >
Linker bug. That's not a sibling call, but a normal function return
via an out-of-line register restore function. Will fix. I'm a bit
surprised to see this with gcc-4.6 though. Or does this gcc-4.6 have
some of my recent mainline gcc patches enabling out-of-line
save/restore functions for -Os?
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply
* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Michael Ellerman @ 2012-06-21 7:38 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Stephen Rothwell, linux-next, ppc-dev, linux-kernel, amodra
In-Reply-To: <1340262473.1998.19.camel@concordia>
On Thu, 2012-06-21 at 17:07 +1000, Michael Ellerman wrote:
> On Thu, 2012-06-21 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> > On Thu, 2012-06-21 at 15:36 +1000, Michael Ellerman wrote:
> > >=20
> > > powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.te=
xt+0x89b990):=20
> > > sibling call optimization to `_restgpr0_28' does not allow au=
tomatic multiple TOCs;
> > > recompile with -mminimal-toc or -fno-optimize-sibling-calls, =
or make `_restgpr0_28' extern
> > >=20
> > Can you show the full build command that triggers the above ?
>=20
> Well that would be a few MBs of log, but here's an excerpt:
>=20
> make -f scripts/Makefile.build obj=3Dnet/openvswitch
> /opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc -m64 =
-Wp,-MD,net/openvswitch/.vport-netdev.o.d -nostdinc -isystem /opt/cross/gc=
c-4.6.3-nolibc/powerpc64-linux/lib/gcc/powerpc64-linux/4.6.3/include -I/hom=
e/michael/src/kmk/next/arch/powerpc/include -Iarch/powerpc/include/generate=
d -Iinclude -include /home/michael/src/kmk/next/include/linux/kconfig.h -D=
__KERNEL__ -Iarch/powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs =
-fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno=
-format-security -fno-delete-null-pointer-checks -Os -msoft-float -pipe -Ia=
rch/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtune=3Dpower7 -=
mtune=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-at-a-time -fn=
o-dwarf2-cfi-asm -mno-string -mno-sched-epilog -Wa,-maltivec -fno-reorder-b=
locks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-than=3D2048 -f=
no-stack-protector -Wno-unused-but-set-variable -g -femit-struct-debug-base=
only -pg -fno-inline-functions-called-once -Wdeclaration-after-statement -W=
no-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -=
fprofile-arcs -ftest-coverage -D"KBUILD_STR(s)=3D#s" -D"KBUILD_BASENAME=
=3DKBUILD_STR(vport_netdev)" -D"KBUILD_MODNAME=3DKBUILD_STR(openvswitch)" =
-c -o net/openvswitch/.tmp_vport-netdev.o net/openvswitch/vport-netdev.c
> if [ "-pg" =3D "-pg" ]; then set -e ; perl /home/michael/src/kmk/next/s=
cripts/recordmcount.pl "powerpc" "little" "64" "/opt/cross/gcc-4.6-nolibc/p=
owerpc64-linux/bin/powerpc64-linux-objdump" "/opt/cross/gcc-4.6-nolibc/powe=
rpc64-linux/bin/powerpc64-linux-objcopy" "/opt/cross/gcc-4.6-nolibc/powerpc=
64-linux/bin/powerpc64-linux-gcc -m64 -Wall -Wundef -Wstrict-prototypes -Wn=
o-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-decl=
aration -Wno-format-security -fno-delete-null-pointer-checks -Os -msoft-flo=
at -pipe -Iarch/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtun=
e=3Dpower7 -mtune=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-a=
t-a-time -fno-dwarf2-cfi-asm -mno-string -mno-sched-epilog -Wa,-maltivec -f=
no-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-th=
an=3D2048 -fno-stack-protector -Wno-unused-but-set-variable -g -femit-str=
uct-debug-baseonly -pg -fno-inline-functions-called-once -Wdeclaration-aft=
er-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_H=
AVE_ASM_GOTO" "/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linu=
x-ld -m elf64ppc" "/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-=
linux-nm --synthetic" "" "" "0" "net/openvswitch/vport-netdev.o"; fi;
Just for the record it's not the FTRACE stuff (-pg):
/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc -m64 -W=
p,-MD,net/openvswitch/.vport-netdev.o.d -nostdinc -isystem /opt/cross/gcc-=
4.6.3-nolibc/powerpc64-linux/lib/gcc/powerpc64-linux/4.6.3/include -I/home/=
michael/src/kmk/next/arch/powerpc/include -Iarch/powerpc/include/generated =
-Iinclude -include /home/michael/src/kmk/next/include/linux/kconfig.h -D__=
KERNEL__ -Iarch/powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -f=
no-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-f=
ormat-security -fno-delete-null-pointer-checks -Os -msoft-float -pipe -Iarc=
h/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtune=3Dpower7 -mt=
une=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-at-a-time -fno-=
dwarf2-cfi-asm -mno-string -Wa,-maltivec -fno-reorder-blocks -fno-ipa-cp-cl=
one -fno-partial-inlining -Wframe-larger-than=3D2048 -fno-stack-protector -=
Wno-unused-but-set-variable -fomit-frame-pointer -g -femit-struct-debug-bas=
eonly -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-=
pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -fpr=
ofile-arcs -ftest-coverage -D"KBUILD_STR(s)=3D#s" -D"KBUILD_BASENAME=3DK=
BUILD_STR(vport_netdev)" -D"KBUILD_MODNAME=3DKBUILD_STR(openvswitch)" -c -=
o net/openvswitch/.tmp_vport-netdev.o net/openvswitch/vport-netdev.c
And same error.
cheers
^ permalink raw reply
* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Gabriel Paubert @ 2012-06-21 7:29 UTC (permalink / raw)
To: Michael Ellerman
Cc: Stephen Rothwell, linux-next, ppc-dev, linux-kernel, Alan Modra
In-Reply-To: <1340256961.1998.11.camel@concordia>
On Thu, Jun 21, 2012 at 03:36:01PM +1000, Michael Ellerman wrote:
> On Wed, 2012-06-20 at 17:50 +1000, Stephen Rothwell wrote:
> > Hi all,
> >
> > After merging the final tree, today's linux-next build (powerpc
> > allyesconfig) failed like this:
> >
> > powerpc64-linux-ld: arch/powerpc/net/built-in.o: In function `bpf_slow_path_word':
> > (.text+0x90): sibling call optimization to `skb_copy_bits' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `skb_copy_bits' extern
>
>
> Those seem to be caused because we don't have a nop after the call,
> meaning we can't patch the TOC pointer on the way back. Adding a nop
> fixes those.
>
> But, then I get 32,410 variants of this:
>
> powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text+0x89b990):
> sibling call optimization to `_restgpr0_28' does not allow automatic multiple TOCs;
> recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `_restgpr0_28' extern
>
>
These functions should not need a TOC in the first place. There is
code in the linker (for 64 bit only: bfd/elf64-ppc.c) to automatically
generate them whenever they are needed.
I suspect you compile with -Os. But I don't think you can use
these functions when doing a sibling call since restgpr0_nn
implies a return to the caller. restgpr1_nn would be different...
> And those are generated calls so I don't see how we can fix them.
>
> > I started building with gcc 4.6.3/binutils 2.22 today. gcc
> > 4.6.0/binutils 2.21 do not produce this error, it produces this instead
> > (which has been happening for a long time):
> >
> > powerpc64-linux-ld: TOC section size exceeds 64k
>
>
> So presumably there's some new error checking that we're hitting, I
> imagine it was always broken, but now it's being more explicit.
I'm not so sure. I suspect gcc, but upgrading gcc and binutils at the
same time may not be the wisest...
Gabriel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox