LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Freescale P2020 CPU Freeze over PCIe abort signal
From: Eran Liberty @ 2010-10-18 11:44 UTC (permalink / raw)
  To: tiejun.chen; +Cc: linuxppc-dev, linux-pci
In-Reply-To: <4CBC18D8.5060804@windriver.com>

tiejun.chen wrote:
> AFAIK we can set one bit on PEX_ERR_DISR to detect PCI Express completion
> time-out. If so one interrupt should be issued. But I'm not sure if this can fix
> your issue.
>
> Tiejun
>   
As I understand the problem, this will not help me as the CPU itself is 
on hold waiting for the assembly line to complete. It may give me enough 
to spot the faulty situation and crash the system... but I am aiming for 
an Enterprise grade product.  Crash/oops is not something I want to put 
into the system if I do not absolutely have to and I do have a hardware 
watch-dog that will pull me out if I do.

So just for the fun of it I am going to follow up on this PEX_ERR_DISR, 
but I do not see how it will help.

-- Liberty

^ permalink raw reply

* Parsing DTS file
From: Guillaume Dargaud @ 2010-10-18 12:13 UTC (permalink / raw)
  To: linuxppc-dev

Hello all,
I'm sure there's a standard way of doing this: I'd like to access some info 
from the DTS file from a usermode program (things like address of device, 
etc...)
What is the best way to do this ? Write a parser ? Or query the running kernel 
somehow ?
-- 
Guillaume Dargaud
http://www.gdargaud.net/

^ permalink raw reply

* [PATCH -mm 1/2] RapidIO: Fix maximum port number in tsi57x EM initialization
From: Alexandre Bounine @ 2010-10-18 14:03 UTC (permalink / raw)
  To: akpm, linux-kernel, linuxppc-dev; +Cc: Alexandre Bounine, Thomas Moll

Replace hardcoded maximum port number with actual reported number of
switch ports.

Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Thomas Moll <thomas.moll@sysgo.com>
Cc: Micha Nelissen <micha@neli.hopto.org>
---
 drivers/rapidio/switches/tsi57x.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c
index d9e9492..2003fb6 100644
--- a/drivers/rapidio/switches/tsi57x.c
+++ b/drivers/rapidio/switches/tsi57x.c
@@ -166,7 +166,8 @@ tsi57x_em_init(struct rio_dev *rdev)
 
 	pr_debug("TSI578 %s [%d:%d]\n", __func__, destid, hopcount);
 
-	for (portnum = 0; portnum < 16; portnum++) {
+	for (portnum = 0;
+	     portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) {
 		/* Make sure that Port-Writes are enabled (for all ports) */
 		rio_mport_read_config_32(mport, destid, hopcount,
 				TSI578_SP_MODE(portnum), &regval);
-- 
1.7.3.1

^ permalink raw reply related

* [PATCH -mm 2/2] RapidIO: Fix destructive port EM initialization for Tsi568
From: Alexandre Bounine @ 2010-10-18 14:03 UTC (permalink / raw)
  To: akpm, linux-kernel, linuxppc-dev; +Cc: Alexandre Bounine, Thomas Moll
In-Reply-To: <1287410600-24783-1-git-send-email-alexandre.bounine@idt.com>

Replaces possibly damaging broadcast writes into the per-port SP_MODE
registers with individual writes for each port. This will preserve
individual port configurations in case if ports are configured differently.

Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Thomas Moll <thomas.moll@sysgo.com>
Cc: Micha Nelissen <micha@neli.hopto.org>
---
 drivers/rapidio/switches/tsi568.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c
index f7fd789..b9a389b 100644
--- a/drivers/rapidio/switches/tsi568.c
+++ b/drivers/rapidio/switches/tsi568.c
@@ -29,7 +29,7 @@
 #define SPP_ROUTE_CFG_DESTID(n)	(0x11070 + 0x100*n)
 #define SPP_ROUTE_CFG_PORT(n)	(0x11074 + 0x100*n)
 
-#define TSI568_SP_MODE_BC	0x10004
+#define TSI568_SP_MODE(n)	(0x11004 + 0x100*n)
 #define  TSI568_SP_MODE_PW_DIS	0x08000000
 
 static int
@@ -117,14 +117,19 @@ tsi568_em_init(struct rio_dev *rdev)
 	u16 destid = rdev->rswitch->destid;
 	u8 hopcount = rdev->rswitch->hopcount;
 	u32 regval;
+	int portnum;
 
 	pr_debug("TSI568 %s [%d:%d]\n", __func__, destid, hopcount);
 
 	/* Make sure that Port-Writes are disabled (for all ports) */
-	rio_mport_read_config_32(mport, destid, hopcount,
-			TSI568_SP_MODE_BC, &regval);
-	rio_mport_write_config_32(mport, destid, hopcount,
-			TSI568_SP_MODE_BC, regval | TSI568_SP_MODE_PW_DIS);
+	for (portnum = 0;
+	     portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) {
+		rio_mport_read_config_32(mport, destid, hopcount,
+				TSI568_SP_MODE(portnum), &regval);
+		rio_mport_write_config_32(mport, destid, hopcount,
+				TSI568_SP_MODE(portnum),
+				regval | TSI568_SP_MODE_PW_DIS);
+	}
 
 	return 0;
 }
-- 
1.7.3.1

^ permalink raw reply related

* Re: Parsing DTS file
From: David Gibson @ 2010-10-18 14:14 UTC (permalink / raw)
  To: Guillaume Dargaud; +Cc: linuxppc-dev
In-Reply-To: <201010181413.58302.dargaud@lpsc.in2p3.fr>

On Mon, Oct 18, 2010 at 02:13:58PM +0200, Guillaume Dargaud wrote:
> Hello all,
> I'm sure there's a standard way of doing this: I'd like to access some info 
> from the DTS file from a usermode program (things like address of device, 
> etc...)
> What is the best way to do this ? Write a parser ? Or query the running kernel 
> somehow ?

Um.. this question doesn't seem to make a lot of sense.  What's the
context in which you're trying to do this.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: BUG: dead loop in PowerPC hcall tracepoint (Was: [LTP] [PATCH v2] Add ftrace-stress-test to LTP)
From: Steven Rostedt @ 2010-10-18 14:25 UTC (permalink / raw)
  To: Li Zefan
  Cc: ltp-list, Peter Zijlstra, linuxppc-dev, LKML, Paul Mackerras,
	Anton Blanchard, Ingo Molnar, subrata
In-Reply-To: <4CBBBCB0.8070406@cn.fujitsu.com>

On Mon, 2010-10-18 at 11:19 +0800, Li Zefan wrote:

> This is a dead loop:
> 
> trace_hcall_entry() -> trace_clock_global() -> trace_hcall_entry() ..
> 
> And this is a PPC specific bug. Hope some ppc guys will fix it?
> Or we kill trace_clock_global() if no one actually uses it..

trace_clock_global() is used by many. I use it (and recommend using it)
on boxes where the TSC is horribly out of sync, and the trace needs
synchronization between CPUs.

The trace_hcall_entry and exit has wrappers already. Just add recursion
protection there.

Perhaps something like this:

(Not compiled nor ran)

+static DEFINE_PER_CPU(hcall_trace_disable);
+
 void hcall_tracepoint_regfunc(void)
 {
 	hcall_tracepoint_refcount++;
 }

 void hcall_tracepoint_unregfunc(void)
 {
 	hcall_tracepoint_refcount--;
 }

+int __trace_disable_check(void)
+{
+	if (!hcall_tracepoint_refcount)
+		return 1;
+
+	if (get_cpu_var(hcall_trace_disable)) {
+		put_cpu_var(hcall_trace_disable);
+		return 1;
+	}
+
+	__get_cpu_var(hcall_trace_disable)++;
+
+	return 0;
+}
+
+void __trace_disable_put(void)
+{
+	__get_cpu_var(hcall_trace_disable)--;
+	put_cpu_var(hcall_trace_disable);
+}
+
 void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
 {
+	int trace_disable;
+
+	if (__trace_disable_check())
+		return;
+
 	trace_hcall_entry(opcode, args);
+	__trace_disable_put();
 }

 void __trace_hcall_exit(long opcode, unsigned long retval,
 			unsigned long *retbuf)
 {
+	if (__trace_disable_check())
+		return;
+
 	trace_hcall_exit(opcode, retval, retbuf);
+	__trace_disable_put();
 }

-- Steve

^ permalink raw reply

* RE: Parsing DTS file
From: Ivo Schenk @ 2010-10-18 15:22 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <201010181413.58302.dargaud@lpsc.in2p3.fr>

>Hello all,
>I'm sure there's a standard way of doing this: I'd like to access some =
info=20
>from the DTS file from a usermode program (things like address of =
device,=20
>etc...)
>What is the best way to do this ? Write a parser ? Or query the running =
kernel=20
>somehow ?

Compile your kernel with CONFIG_PROC_DEVICETREE, then you can access all =
entries via filesystem:

[root@t:~] # ll /proc/device-tree/

-r--r--r--  1 root root  4 Oct 18 17:17 #address-cells
-r--r--r--  1 root root  4 Oct 18 17:17 #size-cells
dr-xr-xr-x  2 root root  0 Oct 18 17:17 chosen
-r--r--r--  1 root root 13 Oct 18 17:17 compatible
dr-xr-xr-x  3 root root  0 Oct 18 17:17 cpus
-r--r--r--  1 root root 13 Oct 18 17:17 dtb-revision
-r--r--r--  1 root root  4 Oct 18 17:17 interrupt-parent
dr-xr-xr-x  8 root root  0 Oct 18 17:17 localbus
dr-xr-xr-x  2 root root  0 Oct 18 17:17 memory
-r--r--r--  1 root root  5 Oct 18 17:17 model
-r--r--r--  1 root root  1 Oct 18 17:17 name
dr-xr-xr-x  2 root root  0 Oct 18 17:17 pci@f0000d00
-r--r--r--  1 root root  9 Oct 18 17:17 serialno
dr-xr-xr-x 32 root root  0 Oct 18 17:17 soc5200@f0000000

--=20
Ivo Schenk
http://www.delphin.de/

Delphin Technology AG
Sitz der Gesellschaft: Bergisch Gladbach
Registergericht: Amtsgericht Koeln, HRB 47544
Vorstand: Ursula Renner (Vorsitzende), Frank Ringsdorf
Vorsitzender des Aufsichtsrats: Peter Renner

^ permalink raw reply

* Re: [PATCH 1/2] P4080/eLBC: Make Freescale elbc interrupt common to elbc devices
From: Scott Wood @ 2010-10-18 16:06 UTC (permalink / raw)
  To: tiejun.chen
  Cc: B07421, dedekind1, dwmw2, B25806, linuxppc-dev, linux-mtd, akpm,
	B11780
In-Reply-To: <4CBC0B95.9010300@windriver.com>

On Mon, 18 Oct 2010 16:55:49 +0800
"tiejun.chen" <tiejun.chen@windriver.com> wrote:

> Looks you always iounmap(fsl_lbc_ctrl_dev->regs) on position 'err' but here
> of_iomap() is already failed you should skip iounmap() fsl_lbc_ctrl_dev->regs
> again. So you should improve that as the following on 'err', or layout 'err' in
> gain.
> ------
> 	if(fsl_lbc_ctrl_dev->regs)
> 		iounmap(fsl_lbc_ctrl_dev->regs);
> 

It looks like iounmap(NULL) is a no-op, just like kfree(NULL).

-Scott

^ permalink raw reply

* Re: CONFIG_FEC is not good for mpc8xx ethernet?
From: Scott Wood @ 2010-10-18 16:42 UTC (permalink / raw)
  To: tiejun.chen; +Cc: ppcdev
In-Reply-To: <4CBC080A.7030005@windriver.com>

On Mon, 18 Oct 2010 16:40:42 +0800
"tiejun.chen" <tiejun.chen@windriver.com> wrote:

> Shawn Jin wrote:
> > Hi,
> > 
> > My target is a mpc875 based board and has FEC ethernet. The phy is
> > AM79C874. I have the following configuration for the network support.
> > 
> > CONFIG_PHYLIB=y
> > CONFIG_NET_ETHERNET=y
> > CONFIG_MII=y
> > CONFIG_FS_ENET=y
> > CONFIG_FS_ENET_HAS_FEC=y
> > CONFIG_FS_ENET_MDIO_FEC=y
> > 
> > However I found that the phy support (AM79C874) is actually in
> > drivers/net/fec.c which is compiled only when CONFIG_FEC=y. However
> 
> The phy driver should not be embedded into the NIC driver in theory.

Right, those are handled by drivers/net/phy/.

> I think you should include the phy driver, mdio-bitbang.c, which should be
> support AMD79C874.

On MPC8xx you want drivers/net/fs_enet/mii-fec.c.  This is just the
MDIO driver; it doesn't handle any particular PHY.  I don't know if
there is a driver specifically for AM79C874, though the generic PHY
support may be good enough.

-Scott

^ permalink raw reply

* [PATCH 4/7] ppc/cell: beat dma ops cleanup
From: Nishanth Aravamudan @ 2010-10-18 17:27 UTC (permalink / raw)
  To: nacc
  Cc: cbe-oss-dev, Arnd Bergmann, linux-kernel, miltonm, Paul Mackerras,
	linuxppc-dev, David S. Miller
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

direct_dma_ops is the default pci dma ops.

No need to call a function to get the pci dma ops, we know they are the
dma_direct_ops.

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/platforms/cell/beat_iommu.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c
index beec405..3ce6855 100644
--- a/arch/powerpc/platforms/cell/beat_iommu.c
+++ b/arch/powerpc/platforms/cell/beat_iommu.c
@@ -76,7 +76,7 @@ static void __init celleb_init_direct_mapping(void)
 
 static void celleb_dma_dev_setup(struct device *dev)
 {
-	dev->archdata.dma_ops = get_pci_dma_ops();
+	set_dma_ops(dev, &dma_direct_ops);
 	set_dma_offset(dev, celleb_dma_direct_offset);
 }
 
@@ -106,7 +106,6 @@ static struct notifier_block celleb_of_bus_notifier = {
 static int __init celleb_init_iommu(void)
 {
 	celleb_init_direct_mapping();
-	set_pci_dma_ops(&dma_direct_ops);
 	ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
 	bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier);
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 6/7] ppc/pseries: iommu cleanup
From: Nishanth Aravamudan @ 2010-10-18 17:27 UTC (permalink / raw)
  To: nacc
  Cc: devicetree-discuss, linux-kernel, miltonm, Paul Mackerras,
	Anton Blanchard, linuxppc-dev
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

No need to initialize per-cpu pointer to NULL, it is the default.

Direct dma ops and no setup are the defaults, no need to set for
iommu-off.

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/powerpc/platforms/pseries/iommu.c |    9 ++-------
 1 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index a77bcae..9184db3 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -140,7 +140,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	return ret;
 }
 
-static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
+static DEFINE_PER_CPU(u64 *, tce_page);
 
 static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 				     long npages, unsigned long uaddr,
@@ -589,13 +589,8 @@ static struct notifier_block iommu_reconfig_nb = {
 /* These are called very early. */
 void iommu_init_early_pSeries(void)
 {
-	if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL)) {
-		/* Direct I/O, IOMMU off */
-		ppc_md.pci_dma_dev_setup = NULL;
-		ppc_md.pci_dma_bus_setup = NULL;
-		set_pci_dma_ops(&dma_direct_ops);
+	if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL))
 		return;
-	}
 
 	if (firmware_has_feature(FW_FEATURE_LPAR)) {
 		if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/7] ppc/pasemi: clean up pasemi iommu table initializations
From: Nishanth Aravamudan @ 2010-10-18 17:27 UTC (permalink / raw)
  To: nacc
  Cc: linuxppc-dev, miltonm, linux-kernel, Paul Mackerras,
	Olof Johansson, Yinghai Lu
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

No need for empty helpers with iommu off, the ppc_md hooks are optional.

The direct_dma_ops are the default pci_dma_ops, so no need to set in the
them iommu off case.

No need to set the device tree device_node pci node iommu pointer, its
only used for dlpar remove.

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Acked-by: Olof Johansson <olof@lixom.net>
---
 arch/powerpc/platforms/pasemi/iommu.c |   19 +------------------
 1 files changed, 1 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 1f9fb2c..14943ef 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -156,20 +156,12 @@ static void iommu_table_iobmap_setup(void)
 
 static void pci_dma_bus_setup_pasemi(struct pci_bus *bus)
 {
-	struct device_node *dn;
-
 	pr_debug("pci_dma_bus_setup, bus %p, bus->self %p\n", bus, bus->self);
 
 	if (!iommu_table_iobmap_inited) {
 		iommu_table_iobmap_inited = 1;
 		iommu_table_iobmap_setup();
 	}
-
-	dn = pci_bus_to_OF_node(bus);
-
-	if (dn)
-		PCI_DN(dn)->iommu_table = &iommu_table_iobmap;
-
 }
 
 
@@ -192,9 +184,6 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
 	set_iommu_table_base(&dev->dev, &iommu_table_iobmap);
 }
 
-static void pci_dma_bus_setup_null(struct pci_bus *b) { }
-static void pci_dma_dev_setup_null(struct pci_dev *d) { }
-
 int __init iob_init(struct device_node *dn)
 {
 	unsigned long tmp;
@@ -251,14 +240,8 @@ void __init iommu_init_early_pasemi(void)
 	iommu_off = of_chosen &&
 			of_get_property(of_chosen, "linux,iommu-off", NULL);
 #endif
-	if (iommu_off) {
-		/* Direct I/O, IOMMU off */
-		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_null;
-		ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_null;
-		set_pci_dma_ops(&dma_direct_ops);
-
+	if (iommu_off)
 		return;
-	}
 
 	iob_init(NULL);
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 5/7] ppc/dart: iommu table cleanup
From: Nishanth Aravamudan @ 2010-10-18 17:27 UTC (permalink / raw)
  To: nacc
  Cc: linux-kernel, miltonm, André Goddard Rosa, Paul Mackerras,
	Tejun Heo, linuxppc-dev
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

No need to set the device tree device_node pci node iommu pointer, its
only used for dlpar remove.

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
---
 arch/powerpc/sysdev/dart_iommu.c |    9 +--------
 1 files changed, 1 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 17cf15e..8e9e06a 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -312,17 +312,10 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev)
 
 static void pci_dma_bus_setup_dart(struct pci_bus *bus)
 {
-	struct device_node *dn;
-
 	if (!iommu_table_dart_inited) {
 		iommu_table_dart_inited = 1;
 		iommu_table_dart_setup();
 	}
-
-	dn = pci_bus_to_OF_node(bus);
-
-	if (dn)
-		PCI_DN(dn)->iommu_table = &iommu_table_dart;
 }
 
 static bool dart_device_on_pcie(struct device *dev)
@@ -373,7 +366,7 @@ void __init iommu_init_early_dart(void)
 	if (dn == NULL) {
 		dn = of_find_compatible_node(NULL, "dart", "u4-dart");
 		if (dn == NULL)
-			goto bail;
+			return;	/* use default direct_dma_ops */
 		dart_is_u4 = 1;
 	}
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/7] ppc/vio: use dma ops helpers
From: Nishanth Aravamudan @ 2010-10-18 17:26 UTC (permalink / raw)
  To: nacc; +Cc: linux-kernel, miltonm, Paul Mackerras, Brian King, linuxppc-dev
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

Use the set_dma_ops helper. Instead of modifying vio_dma_mapping_ops,
just create a trivial wrapper for dma_supported.

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
---
 arch/powerpc/kernel/vio.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index d692989..3c3083f 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -602,6 +602,11 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
 	vio_cmo_dealloc(viodev, alloc_size);
 }
 
+static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask)
+{
+        return dma_iommu_ops.dma_supported(dev, mask);
+}
+
 struct dma_map_ops vio_dma_mapping_ops = {
 	.alloc_coherent = vio_dma_iommu_alloc_coherent,
 	.free_coherent  = vio_dma_iommu_free_coherent,
@@ -609,6 +614,7 @@ struct dma_map_ops vio_dma_mapping_ops = {
 	.unmap_sg       = vio_dma_iommu_unmap_sg,
 	.map_page       = vio_dma_iommu_map_page,
 	.unmap_page     = vio_dma_iommu_unmap_page,
+	.dma_supported  = vio_dma_iommu_dma_supported,
 
 };
 
@@ -860,8 +866,7 @@ static void vio_cmo_bus_remove(struct vio_dev *viodev)
 
 static void vio_cmo_set_dma_ops(struct vio_dev *viodev)
 {
-	vio_dma_mapping_ops.dma_supported = dma_iommu_ops.dma_supported;
-	viodev->dev.archdata.dma_ops = &vio_dma_mapping_ops;
+	set_dma_ops(&viodev->dev, &vio_dma_mapping_ops);
 }
 
 /**
@@ -1246,7 +1251,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
 	if (firmware_has_feature(FW_FEATURE_CMO))
 		vio_cmo_set_dma_ops(viodev);
 	else
-		viodev->dev.archdata.dma_ops = &dma_iommu_ops;
+		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));
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 7/7] ppc64 iommu: use coherent_dma_mask for alloc_coherent
From: Nishanth Aravamudan @ 2010-10-18 17:27 UTC (permalink / raw)
  To: nacc; +Cc: linux-kernel, miltonm, Paul Mackerras, Brian King, linuxppc-dev
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

The IOMMU code has been passing the dma-mask instead of the
coherent_dma_mask to the iommu allocator.  Coherent allocations should
be made using the coherent_dma_mask.

Also update the vio code to ensure the coherent_dma_mask is set. Without
this change drivers, such as ibmvscsi, fail to load with the corrected
dma_iommu_alloc_coherent().

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
---
We currently don't check the mask other than to warn when its being set,
so I don't think this is stable material.
---
 arch/powerpc/kernel/dma-iommu.c |    2 +-
 arch/powerpc/kernel/vio.c       |    4 ++++
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 6e54a0f..e755415 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -19,7 +19,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
 				      dma_addr_t *dma_handle, gfp_t flag)
 {
 	return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
-				    dma_handle, device_to_mask(dev), flag,
+				    dma_handle, dev->coherent_dma_mask, flag,
 				    dev_to_node(dev));
 }
 
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 3c3083f..f15b3df 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1259,6 +1259,10 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
 	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));
 
 	/* register with generic device framework */
 	if (device_register(&viodev->dev)) {
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/7] microblaze: pci-common cleanup
From: Nishanth Aravamudan @ 2010-10-18 17:26 UTC (permalink / raw)
  To: nacc
  Cc: Michal Simek, linux-kernel, miltonm, Jesse Barnes,
	microblaze-uclinux, linuxppc-dev, Bjorn Helgaas
In-Reply-To: <1287422825-14999-1-git-send-email-nacc@us.ibm.com>

Use set_dma_ops and remove now used-once oddly named temp pointer sd.

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Cc: benh@kernel.crashing.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/microblaze/pci/pci-common.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 55ef532..9631e1d 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -1075,8 +1075,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
 		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
-		struct dev_archdata *sd = &dev->dev.archdata;
-
 		/* Setup OF node pointer in archdata */
 		dev->dev.of_node = pci_device_to_OF_node(dev);
 
@@ -1086,8 +1084,8 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
 		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
 
 		/* Hook up default DMA ops */
-		sd->dma_ops = pci_dma_ops;
-		sd->dma_data = (void *)PCI_DRAM_OFFSET;
+		set_dma_ops(&dev->dev, pci_dma_ops);
+		dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;
 
 		/* Read default IRQs and fixup if necessary */
 		pci_read_irq_line(dev);
-- 
1.7.1

^ permalink raw reply related

* Re: Freescale P2020 CPU Freeze over PCIe abort signal
From: Eran Liberty @ 2010-10-18 18:00 UTC (permalink / raw)
  Cc: linuxppc-dev, linux-pci
In-Reply-To: <4CBB4D80.3030007@extricom.com>

Eran Liberty wrote:
> This should probably go to the Freescale support, as it feels like a 
> hardware issue yet the end result is a very frozen Linux kernel so I 
> post here first...
>
> I have a programmable FPGA PCIe device connected to a Freescale's 
> P2020 PCIe port. As part of the bring-up tests, we are testing two 
> faulty scenarios:
> 1. The FPGA totally ignores the PCIe transaction.
> 2. The FPGA return a transaction abort.
>
> Both are plausible PCIe behavior and their should be outcome is 
> documented in the PCIe spec. The first should be terminated by the 
> transaction requestor timeout mechanism and raise an error, the second 
> should abort the transaction and raise and error.
>
> In P2020 if I do any of those the CPU is left hung over the transaction.
>
> something like:
> in_le32(addr)
>
> is turned into:
> 7c 00 04 ac     sync   7c 00 4c 2c     lwbrx   r0,0,r9
> 0c 00 00 00     twi     0,r0,0
> 4c 00 01 2c     isync
>
> assembly code, where in r9 (in this example) hold an address which is 
> physically mapped into the PCIe resource space.
>
> The CPU will hang over the load instruction.
>
> Just for the fun of it, I have wrote my own assembly function omitting 
> everything but the load instruction; still freeze.
> Replace "lwbrx" with a simple "lwz"; still freeze.
>
> It looks like the CPU snoozes till the PCIe transaction is done with 
> no timeouts, ignoring any abort signal.
>
> I am going to:
> A. Try to reach the Freescale support.
> B. Asked the FPGA designed to give me a new behavior that will stall 
> the PCIe transaction replay for 10 sec, but after those return ok.
> C. report back here with either A or B.
>
> If you have any ideas I would love to hear them.
>
> -- Liberty
>
Some more info:

As said the the FPGA designer provided me a PCIe device that will stall 
its response to a variable amount of time. The CPU became un-frozen 
after this amount of time. More over, we have found that in that period 
till it un-froze the PCIe core did a retry to that transaction over and 
over every 40 ms. This gave me the bright idea to look for the word 
"retry" in the Freescale documentation which rewarded me with these 
registers:

------------------------------------------------------- snip 
-------------------------------------------------------
16.3.2.3        PCI Express Outbound Completion Timeout Register
                (PEX_OTB_CPL_TOR)
The PCI Express outbound completion timeout register, shown in Figure 
16-4, contains the maximum wait
time for a response to come back as a result of an outbound non-posted 
request before a timeout condition
occurs.
 Offset 
0x00C                                                                                                
Access: Read/Write
         0   1              5     7   
8                                                                                      
31
     R
        TD            
—                                                            TC
     W
 Reset 0     0  0  0   0   0   0  0   0   0   0   1    0  0   0  0    
1   1  1    1   1  1   1   1   1  1   1   1  1  1   1  1
            Figure 16-4. PCI Express Outbound Completion Timeout 
Register (PEX_OTB_CPL_TOR)
Table 16-6 describes the PCI Express outbound completion timeout 
register fields.
                                 Table 16-6. PEX_OTB_CPL_TOR Field 
Descriptions
  Bits     Name                                                     
Description
   0        TD     Timeout disable. This bit controls the 
enabling/disabling of the timeout function.
                   0 Enable completion timeout
                   1 Disable completion timeout
  1–7        —     Reserved
 8–31       TC     Timeout counter. This is the value that is used to 
load the response counter of the completion timeout.
                   One TC unit is 8× the PCI Express controller clock 
period; that is, one TC unit is 20 ns at 400 MHz, and 30
                   ns at 266.66 MHz.
                   The following are examples of timeout periods based 
on different TC settings:
                   0x00_0000 Reserved
                   0x10_FFFF 22.28 ms at 400 MHz controller clock; 33.34 
ms at 266.66 MHz controller clock
                   0xFF_FFFF 335.54 ms at 400 MHz controller clock; 
503.31 ms at 266.66 MHz controller clock


16.3.2.4       PCI Express Configuration Retry Timeout Register
               (PEX_CONF_RTY_TOR)
The PCI Express configuration retry timeout register, shown in Figure 
16-5, contains the maximum time
period during which retries of configuration transactions which resulted 
in a CRS response occur.
 Offset 
0x010                                                                               
Access: Read/Write
         0  1     3   
4                                                                                     
31
     R
        RD     —                                                 TC
     W
 Reset 0    0  0  0  0   1  0  0  0  0   0  0   0  0  0  0   1  1  1  1  
1  1   1   1 1 1   1  1   1 1   1  1
           Figure 16-5. PCI Express Configuration Retry Timeout Register 
(PEX_CONF_RTY_TOR)
                            QorIQ P2020 Integrated Processor Reference 
Manual, Rev. 0
16-12                                                                                   
Freescale Semiconductor
                                                                                                 
PCI Express Interface Controller
Table 16-7 describes the PCI Express configuration retry timeout 
register fields.
                            Table 16-7. PEX_CONF_RTY_TOR Field Descriptions
  Bits  Name                                                     Description
   0     RD    Retry disable. This bit disables the retry of a 
configuration transaction that receives a CRS status response
               packet.
               0 Enable retry of a configuration transaction in response 
to receiving a CRS status response until the timeout
                  counter (defined by the PEX_CONF_RTY_TOR[TC] field) 
has expired.
               1 Disable retry of a configuration transaction regardless 
of receiving a CRS status response.
  1–3     —    Reserved
 4–31    TC    Timeout counter. This is the value that is used to load 
the CRS response counter.
               One TC unit is 8× the PCI Express controller clock 
period; that is, one TC unit is 20 ns at 400 MHz and 30 ns
               at 266.66 MHz.
               Timeout period based on different TC settings:
               0x000_0000        Reserved
               0x400_FFFF        1.34 s at 400 MHz controller clock, 
2.02 s at 266.66 MHz controller clock
               0xFFF_FFFF        5.37 s at 400 MHz controller clock, 
8.05 s at 266.66 MHz controller clock
------------------------------------------------------- snap 
-------------------------------------------------------

Now this is all nice on the paper, but what the P2020 seems to be doing 
in reality is
1. never expire
2. do re-tries even in the non configuration access

I am going to try to disable completion timeout and see if I get better 
behavior.

-- Liberty

^ permalink raw reply

* RE: msi_bitmap.c question
From: Tirumala Marri @ 2010-10-18 18:04 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1287102354.4194.15.camel@concordia>

> >
> > I am trying to resubmit a patch for MSI support for ppc4xx devices.
> > One of the review feedback was not to use the bit map as it is only
> > for the devices which don=92t have hard wired mapping between interrupt
> > controller interrupts and MSI number. For example intr-ctrl0
> interrupt
> > 20 goes to MSI-0, interrupt 21 goes to MSI-1 ..etc. But when I
> checked
> > freescale SoCs and cell SoCs they have interrupts hard wired to MSI
> > interrupts.
> >
> >
> >
> > Why do they have to use the bitmap and create irqhost, even though
> > they are one-to-one mapped between interrupt controller numbers and
> > MSI ?
>
> I'm not quite sure I understand your question.
>
> The MSI bitmap and the irq_host are two different things.
>
> The MSI bitmap is basically an allocator for hardware numbers that can
> be used for MSI. On some interrupt controllers that might be any
> interrupt that's not used, on others there are restrictions on which
> numbers can be used for MSI, it depends. So it's possible you don't
> need to use that code, but I don't know how your hardware works.
>
> The irq_host is the struct that controls mapping hardware irq numbers
> into linux irq numbers. The cell MSI code has no restrictions on what
> the MSI value is, so it just uses the Linux irq number directly using
> irq_create_direct_mapping().
>

Mike, thanks. Could please you clarify your statement
" The cell MSI code has no restrictions on what  the MSI value is ".
If MSIs are one to one mapped to system interrupt controller
Interrupts, why do we need to create new irq_host? Isn't passing
Interrupt controllers irq_host instance not enough ?

Also when is cascade is needed?

Regards,
Marri

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: pacman @ 2010-10-18 19:10 UTC (permalink / raw)
  To: Mel Gorman; +Cc: linux-mm, Andrew Morton, linuxppc-dev, linux-kernel
In-Reply-To: <20101018113331.GB30667@csn.ul.ie>

Mel Gorman writes:
> 
> A bit but I still don't know why it would cause corruption. Maybe this is still
> a caching issue but the difference in timing between list_add and list_add_tail
> is enough to hide the bug. It's also possible there are some registers
> ioremapped after the memmap array and reading them is causing some
> problem.

I've been doing a lot more tests and I'm sure that 6dda9d55 is not really
responsible. It just happens to provoke the bug in my particular setup.
Whatever it is, it's very sensitive to small changes.

At the end of free_all_bootmem, the free list for order 9 has 4 entries.
Which one is at the head of the list depends on whether 6dda9d55 is applied
or not. If page number 130048 is at the head of the list, it gets used fairly
soon, and everything's fine. The alternative is that page number 64512 is at
the head of the list, so it gets used fairly soon, and corruption occurs.

> 
> Andrew, what is the right thing to do here? We could flail around looking
> for explanations as to why the bug causes a user buffer corruption but never
> get an answer or do we go with this patch, preferably before 2.6.36 releases?

I've been flailing around quite a bit. Here's my latest result:

Since I can view the corruption with md5sum /sbin/e2fsck, I know it's in a
clean cached page. So I made an extra copy of /sbin/e2fsck, which won't be
loaded into memory during boot. So now after the corruption happens, I can
  cmp -l /sbin/e2fsck good-e2fsck
for a quick look at the changed bytes. Much easier than provoking a segfault
under gdb.

Then I got really creative and wrote a cmp replacement which mmaps the files
and reports the physical addresses from /proc/self/pagemap of the pages that
don't match. And the consistent result is that physical pages 64604 and 64609
(both in the range of the order=9 64512) have wrong contents. And the
corruption is always a single word 128 bytes after the start of the page.
Physical addresses 0x0fc5c080 and 0x0fc61080 are hit every time.

The values of the corrupted words, observed in 5 consecutive boots, were:
  at 0fc5c080   at 0fc61080
  -----------   -----------
  c3540000      92510000
  565c0000      23590000
  c85b0000      97580000
  d15f0000      9e5c0000
  d95b0000      a8580000

The low 16 bits are all 0 and the upper 16 bits seem randomly distributed.
But look at the differences:

  c3540000 - 92510000 = 31030000
  565c0000 - 23590000 = 33030000
  c85b0000 - 97580000 = 31030000
  d15f0000 - 9e5c0000 = 33030000
  d95b0000 - a8580000 = 31030000

This means something... but I don't know what.

In a completely different method of investigation, I went back a few stable
kernels, got 2.6.33.7 and applied 6dda9d55 to it, thinking that if 6dda9d55
only reveals a pre-existing bug, I could bisect it using 6dda9d55 as a
bug-revealing assistant. The bug appeared when running 2.6.33.7 with 6dda9d55
applied. That was discouraging.

>This patch fixes the problem by ensuring we are not reading a possibly
>invalid location of memory. It's not clear why the read causes
>corruption but one way or the other it is a buggy read.

At least that part of the explanation is wrong. Where's the buggy read?
The action taken by the 6dda9d55 version of __free_one_page looks perfectly
legitimate to me. Page numbers:

[129024       ] [130048       ]   order=10
[129024 129536] [130048 130560]   order=9

130048 is being freed. 130560 is not free. 129024 (the higher_buddy) is
already free at order=10. So 130048 is being pushed to the tail of the free
list, on the speculation that 130560 might soon be free and then the whole
thing will form an order=11 free page, the only problem being that order=11
is too high so that later merge will never happen. It's not useful, and maybe
not conceptually valid to say that 129024 is the buddy of 130048, but it is
an existing page, and the only way it wouldn't be is if the total memory size
was not a multiple of 1<<(MAX_ORDER-1) pages

-- 
Alan Curry

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: Andrew Morton @ 2010-10-18 19:37 UTC (permalink / raw)
  To: Mel Gorman; +Cc: linux-mm, pacman, linuxppc-dev, linux-kernel
In-Reply-To: <20101018113331.GB30667@csn.ul.ie>

On Mon, 18 Oct 2010 12:33:31 +0100
Mel Gorman <mel@csn.ul.ie> wrote:

> A bit but I still don't know why it would cause corruption. Maybe this is still
> a caching issue but the difference in timing between list_add and list_add_tail
> is enough to hide the bug. It's also possible there are some registers
> ioremapped after the memmap array and reading them is causing some
> problem.
> 
> Andrew, what is the right thing to do here? We could flail around looking
> for explanations as to why the bug causes a user buffer corruption but never
> get an answer or do we go with this patch, preferably before 2.6.36 releases?

Well, you've spotted a bug so I'd say we fix it asap.

It's a bit of a shame that we lose the only known way of reproducing a
different bug, but presumably that will come back and bite someone else
one day, and we'll fix it then :(

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: Benjamin Herrenschmidt @ 2010-10-18 20:59 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Yinghai Lu, linux-kernel, linux-mm, pacman, KOSAKI Motohiro,
	Andrew Morton, linuxppc-dev, Christoph Lameter
In-Reply-To: <20101013144044.GS30667@csn.ul.ie>

On Wed, 2010-10-13 at 15:40 +0100, Mel Gorman wrote:
> 
> This is somewhat contrived but I can see how it might happen even on one
> CPU particularly if the L1 cache is virtual and is loose about checking
> physical tags.
> 
> > How sensitive/vulnerable is PPC32 to such things?
> > 
> 
> I can not tell you specifically but if the above scenario is in any way
> plausible, I believe it would depend on what sort of L1 cache the CPU
> has. Maybe this particular version has a virtual cache with no physical
> tagging and is depending on the OS not to make virtual aliasing mistakes.

Nah, ppc doesn't have problems with cache aliases, it all looks
physically tagged to the programmer (tho there's subtleties but none
that explains the reported behaviour).

Looks like real memory corruption to me.

Cheers,
Ben.

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: Benjamin Herrenschmidt @ 2010-10-18 21:02 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Mel Gorman, linux-mm, pacman, linuxppc-dev, linux-kernel
In-Reply-To: <20101018123750.ef7d6d48.akpm@linux-foundation.org>

On Mon, 2010-10-18 at 12:37 -0700, Andrew Morton wrote:
> Well, you've spotted a bug so I'd say we fix it asap.
> 
> It's a bit of a shame that we lose the only known way of reproducing a
> different bug, but presumably that will come back and bite someone
> else
> one day, and we'll fix it then :(

Well, I can always revert that and run some experiments here, provided I
can reproduce the problem at all ...

Cheers,
Ben.

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: Benjamin Herrenschmidt @ 2010-10-18 21:10 UTC (permalink / raw)
  To: pacman; +Cc: Mel Gorman, linux-mm, Andrew Morton, linuxppc-dev, linux-kernel
In-Reply-To: <20101018191034.21165.qmail@kosh.dhis.org>

On Mon, 2010-10-18 at 14:10 -0500, pacman@kosh.dhis.org wrote:

> I've been flailing around quite a bit. Here's my latest result:
> 
> Since I can view the corruption with md5sum /sbin/e2fsck, I know it's in a
> clean cached page. So I made an extra copy of /sbin/e2fsck, which won't be
> loaded into memory during boot. So now after the corruption happens, I can
>   cmp -l /sbin/e2fsck good-e2fsck
> for a quick look at the changed bytes. Much easier than provoking a segfault
> under gdb.
> 
> Then I got really creative and wrote a cmp replacement which mmaps the files
> and reports the physical addresses from /proc/self/pagemap of the pages that
> don't match. And the consistent result is that physical pages 64604 and 64609
> (both in the range of the order=9 64512) have wrong contents. And the
> corruption is always a single word 128 bytes after the start of the page.
> Physical addresses 0x0fc5c080 and 0x0fc61080 are hit every time.

 .../...

You can do something fun... like a timer interrupt that peeks at those
physical addresses from the linear mapping for example, and try to find
out "when" they get set to the wrong value (you should observe the load
from disk, then the corruption, unless they end up being loaded
incorrectly (ie. dma coherency problem ?) ...

>From there, you might be able to close onto the culprit a bit more, for
example, try using the DABR register to set data access breakpoints
shortly before the corruption spot. AFAIK, On those old 32-bit CPUs, you
can set whether you want it to break on a real or a virtual address.

You can also sprinkle tests for the page content through the code if
that doesn't work to try to "close in" on the culprit (for example if
it's a case of stray DMA, like a network driver bug or such).

Cheers,
Ben.


> The values of the corrupted words, observed in 5 consecutive boots, were:
>   at 0fc5c080   at 0fc61080
>   -----------   -----------
>   c3540000      92510000
>   565c0000      23590000
>   c85b0000      97580000
>   d15f0000      9e5c0000
>   d95b0000      a8580000
> 
> The low 16 bits are all 0 and the upper 16 bits seem randomly distributed.
> But look at the differences:
> 
>   c3540000 - 92510000 = 31030000
>   565c0000 - 23590000 = 33030000
>   c85b0000 - 97580000 = 31030000
>   d15f0000 - 9e5c0000 = 33030000
>   d95b0000 - a8580000 = 31030000
> 
> This means something... but I don't know what.
> 
> In a completely different method of investigation, I went back a few stable
> kernels, got 2.6.33.7 and applied 6dda9d55 to it, thinking that if 6dda9d55
> only reveals a pre-existing bug, I could bisect it using 6dda9d55 as a
> bug-revealing assistant. The bug appeared when running 2.6.33.7 with 6dda9d55
> applied. That was discouraging.
> 
> >This patch fixes the problem by ensuring we are not reading a possibly
> >invalid location of memory. It's not clear why the read causes
> >corruption but one way or the other it is a buggy read.
> 
> At least that part of the explanation is wrong. Where's the buggy read?
> The action taken by the 6dda9d55 version of __free_one_page looks perfectly
> legitimate to me. Page numbers:
> 
> [129024       ] [130048       ]   order=10
> [129024 129536] [130048 130560]   order=9
> 
> 130048 is being freed. 130560 is not free. 129024 (the higher_buddy) is
> already free at order=10. So 130048 is being pushed to the tail of the free
> list, on the speculation that 130560 might soon be free and then the whole
> thing will form an order=11 free page, the only problem being that order=11
> is too high so that later merge will never happen. It's not useful, and maybe
> not conceptually valid to say that 129024 is the buddy of 130048, but it is
> an existing page, and the only way it wouldn't be is if the total memory size
> was not a multiple of 1<<(MAX_ORDER-1) pages
> 
> -- 
> Alan Curry
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: pacman @ 2010-10-18 21:33 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Mel Gorman, linux-mm, Andrew Morton, linuxppc-dev, linux-kernel
In-Reply-To: <1287436205.2341.14.camel@pasglop>

Benjamin Herrenschmidt writes:
> 
> You can do something fun... like a timer interrupt that peeks at those
> physical addresses from the linear mapping for example, and try to find
> out "when" they get set to the wrong value (you should observe the load
> from disk, then the corruption, unless they end up being loaded
> incorrectly (ie. dma coherency problem ?) ...

I'm headed toward something like that. Maybe not a timer, maybe a "check it
every time the kernel is entered". But first I have to work out exactly when
the disk load completes so I know when to start checking.

> 
> >From there, you might be able to close onto the culprit a bit more, for
> example, try using the DABR register to set data access breakpoints
> shortly before the corruption spot. AFAIK, On those old 32-bit CPUs, you
> can set whether you want it to break on a real or a virtual address.

I thought of that, but as far as I can tell, this CPU doesn't have DABR.
/proc/cpuinfo
processor	: 0
cpu		: 7447/7457
clock		: 999.999990MHz
revision	: 1.1 (pvr 8002 0101)
bogomips	: 66.66
timebase	: 33333333
platform	: CHRP
model		: Pegasos2
machine		: CHRP Pegasos2
Memory		: 512 MB

My next thought was: right after the correct value appears in memory, unmap
the page from the kernel and let it Oops when it tries to write there. Then I
found out that the kernel is using BATs instead of page tables for its own
view of memory. Booting with "nobats" completely changes the memory usage
pattern (probably because it's allocating a lot of pages to hold PTEs that it
didn't need before)

> 
> You can also sprinkle tests for the page content through the code if
> that doesn't work to try to "close in" on the culprit (for example if
> it's a case of stray DMA, like a network driver bug or such).

No network drivers are loaded when this happens.

-- 
Alan Curry

^ permalink raw reply

* Re: PROBLEM: memory corrupting bug, bisected to 6dda9d55
From: Thomas Gleixner @ 2010-10-18 21:55 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Helmut Grohne, Mel Gorman, LKML, linux-mm, pacman, linuxppc-dev
In-Reply-To: <20101018123750.ef7d6d48.akpm@linux-foundation.org>

On Mon, 18 Oct 2010, Andrew Morton wrote:

> On Mon, 18 Oct 2010 12:33:31 +0100
> Mel Gorman <mel@csn.ul.ie> wrote:
> 
> > A bit but I still don't know why it would cause corruption. Maybe this is still
> > a caching issue but the difference in timing between list_add and list_add_tail
> > is enough to hide the bug. It's also possible there are some registers
> > ioremapped after the memmap array and reading them is causing some
> > problem.
> > 
> > Andrew, what is the right thing to do here? We could flail around looking
> > for explanations as to why the bug causes a user buffer corruption but never
> > get an answer or do we go with this patch, preferably before 2.6.36 releases?
> 
> Well, you've spotted a bug so I'd say we fix it asap.
> 
> It's a bit of a shame that we lose the only known way of reproducing a
> different bug, but presumably that will come back and bite someone else
> one day, and we'll fix it then :(

I might be completely one off as usual, but this thing reminds me of a
bug I stared at yesterday night:

    http://permalink.gmane.org/gmane.linux.kernel/1049605

Reporter Cc'ed

Thanks,

	tglx

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox