linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Cell xmon helpers
@ 2006-10-12 12:03 Michael Ellerman
  2006-10-12 12:03 ` [PATCH 1/2] Add support for stopping spus from xmon Michael Ellerman
  2006-10-12 12:03 ` [PATCH 2/2] Add support for dumping spu info " Michael Ellerman
  0 siblings, 2 replies; 12+ messages in thread
From: Michael Ellerman @ 2006-10-12 12:03 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, cbe-oss-dev

The following two patches add three commands to xmon for stopping,
restarting and dumping info about spus from xmon.

For the folks on linuxppc-dev, these patches depend on another patch
which isn't in the powerpc tree yet AFAIK, you can get it here:
http://kernel.org/pub/linux/kernel/people/arnd/patches/2.6.17-arnd8/broken-out/spu-add-attributes.diff

cheers

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-12 12:03 [PATCH 0/2] Cell xmon helpers Michael Ellerman
@ 2006-10-12 12:03 ` Michael Ellerman
  2006-10-12 16:18   ` Linas Vepstas
                     ` (2 more replies)
  2006-10-12 12:03 ` [PATCH 2/2] Add support for dumping spu info " Michael Ellerman
  1 sibling, 3 replies; 12+ messages in thread
From: Michael Ellerman @ 2006-10-12 12:03 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, cbe-oss-dev

This patch adds support for stopping, and restarting, spus
from xmon. We use the spu master runcntl bit to stop execution,
this is apparently the "right" way to control spu execution and
spufs will be changed in the future to use this bit.

Testing has shown that to restart execution we have to turn the
master runcntl bit on and also rewrite the spu runcntl bit, even
if it is already set to 1 (running).

Stopping spus is triggered by the xmon command 'ss' - "spus stop"
perhaps. Restarting them is triggered via 'sr'. Restart doesn't
start execution on spus unless they were running prior to being
stopped by xmon.

Walking the spu->full_list in xmon after a panic, would mean
corruption of any spu struct would make all the others
inaccessible. To avoid this, and also to make the next patch
easier, we cache pointers to all spus during boot.

We attempt to catch and recover from errors while stopping and
restarting the spus, but as with most xmon functionality there are
no guarantees that performing these operations won't crash xmon
itself.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/platforms/cell/spu_base.c |    4 
 arch/powerpc/xmon/xmon.c               |  142 ++++++++++++++++++++++++++++++++-
 include/asm-powerpc/xmon.h             |    2 
 3 files changed, 146 insertions(+), 2 deletions(-)

Index: to-merge/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/cell/spu_base.c
+++ to-merge/arch/powerpc/platforms/cell/spu_base.c
@@ -38,6 +38,7 @@
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
 #include <asm/mmu_context.h>
+#include <asm/xmon.h>
 
 #include "interrupt.h"
 
@@ -914,6 +915,9 @@ static int __init init_spu_base(void)
 			break;
 		}
 	}
+
+	xmon_register_spus(&spu_full_list);
+
 	return ret;
 }
 module_init(init_spu_base);
Index: to-merge/arch/powerpc/xmon/xmon.c
===================================================================
--- to-merge.orig/arch/powerpc/xmon/xmon.c
+++ to-merge/arch/powerpc/xmon/xmon.c
@@ -35,6 +35,8 @@
 #include <asm/rtas.h>
 #include <asm/sstep.h>
 #include <asm/bug.h>
+#include <asm/spu.h>
+#include <asm/spu_priv1.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
@@ -145,6 +147,8 @@ static void xmon_print_symbol(unsigned l
 			      const char *after);
 static const char *getvecname(unsigned long vec);
 
+static int do_spu_cmd(void);
+
 int xmon_no_auto_backtrace;
 
 extern int print_insn_powerpc(unsigned long, unsigned long, int);
@@ -207,8 +211,12 @@ Commands:\n\
   mi	show information about memory allocation\n\
   p 	call a procedure\n\
   r	print registers\n\
-  s	single step\n\
-  S	print special registers\n\
+  s	single step\n"
+#ifdef CONFIG_PPC_CELL
+"  ss	stop execution on all spus\n\
+  sr	restore execution on stopped spus\n"
+#endif
+"  S	print special registers\n\
   t	print backtrace\n\
   x	exit monitor and recover\n\
   X	exit monitor and dont recover\n"
@@ -516,6 +524,7 @@ int xmon(struct pt_regs *excp)
 		xmon_save_regs(&regs);
 		excp = &regs;
 	}
+
 	return xmon_core(excp, 0);
 }
 EXPORT_SYMBOL(xmon);
@@ -808,6 +817,8 @@ cmds(struct pt_regs *excp)
 			cacheflush();
 			break;
 		case 's':
+			if (do_spu_cmd() == 0)
+				break;
 			if (do_step(excp))
 				return cmd;
 			break;
@@ -2630,3 +2641,130 @@ void __init xmon_setup(void)
 	if (xmon_early)
 		debugger(NULL);
 }
+
+#ifdef CONFIG_PPC_CELL
+
+struct spu_info {
+	struct spu *spu;
+	u64 saved_mfc_sr1_RW;
+	u32 saved_spu_runcntl_RW;
+	u8 stopped_ok;
+};
+
+#define XMON_NUM_SPUS	16	/* Enough for current hardware */
+
+static struct spu_info spu_info[XMON_NUM_SPUS];
+
+void xmon_register_spus(struct list_head *list)
+{
+	struct spu *spu;
+
+	list_for_each_entry(spu, list, full_list) {
+		if (spu->number >= XMON_NUM_SPUS) {
+			WARN_ON(1);
+			continue;
+		}
+
+		spu_info[spu->number].spu = spu;
+		spu_info[spu->number].stopped_ok = 0;
+	}
+}
+
+static void stop_spus(void)
+{
+	struct spu *spu;
+	int i;
+	u64 tmp;
+
+	for (i = 0; i < XMON_NUM_SPUS; i++) {
+		if (!spu_info[i].spu)
+			continue;
+
+		if (setjmp(bus_error_jmp) == 0) {
+			catch_memory_errors = 1;
+			sync();
+
+			spu = spu_info[i].spu;
+
+			spu_info[i].saved_spu_runcntl_RW =
+				in_be32(&spu->problem->spu_runcntl_RW);
+
+			tmp = spu_mfc_sr1_get(spu);
+			spu_info[i].saved_mfc_sr1_RW = tmp;
+
+			tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
+			spu_mfc_sr1_set(spu, tmp);
+
+			sync();
+			__delay(200);
+
+			spu_info[i].stopped_ok = 1;
+			printf("Stopped spu %.2d\n", i);
+		} else {
+			catch_memory_errors = 0;
+			printf("*** Error stopping spu %.2d\n", i);
+		}
+		catch_memory_errors = 0;
+	}
+}
+
+static void restart_spus(void)
+{
+	struct spu *spu;
+	int i;
+
+	for (i = 0; i < XMON_NUM_SPUS; i++) {
+		if (!spu_info[i].spu)
+			continue;
+
+		if (!spu_info[i].stopped_ok) {
+			printf("*** Error, spu %d was not successfully stopped"
+					", not restarting\n", i);
+			continue;
+		}
+
+		if (setjmp(bus_error_jmp) == 0) {
+			catch_memory_errors = 1;
+			sync();
+
+			spu = spu_info[i].spu;
+			spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
+			out_be32(&spu->problem->spu_runcntl_RW,
+					spu_info[i].saved_spu_runcntl_RW);
+
+			sync();
+			__delay(200);
+
+			printf("Restarted spu %.2d\n", i);
+		} else {
+			catch_memory_errors = 0;
+			printf("*** Error restarting spu %.2d\n", i);
+		}
+		catch_memory_errors = 0;
+	}
+}
+
+static int do_spu_cmd(void)
+{
+	int cmd;
+
+	cmd = inchar();
+	switch (cmd) {
+	case 's':
+		stop_spus();
+		break;
+	case 'r':
+		restart_spus();
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+#else /* ! CONFIG_PPC_CELL */
+static int do_spu_cmd(void)
+{
+	return -1;
+}
+#endif
Index: to-merge/include/asm-powerpc/xmon.h
===================================================================
--- to-merge.orig/include/asm-powerpc/xmon.h
+++ to-merge/include/asm-powerpc/xmon.h
@@ -14,8 +14,10 @@
 
 #ifdef CONFIG_XMON
 extern void xmon_setup(void);
+extern void xmon_register_spus(struct list_head *list);
 #else
 static inline void xmon_setup(void) { };
+static inline void xmon_register_spus(struct list_head *list) { };
 #endif
 
 #endif /* __KERNEL __ */

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/2] Add support for dumping spu info from xmon
  2006-10-12 12:03 [PATCH 0/2] Cell xmon helpers Michael Ellerman
  2006-10-12 12:03 ` [PATCH 1/2] Add support for stopping spus from xmon Michael Ellerman
@ 2006-10-12 12:03 ` Michael Ellerman
  2006-10-12 17:42   ` [Cbe-oss-dev] " Geoff Levand
  1 sibling, 1 reply; 12+ messages in thread
From: Michael Ellerman @ 2006-10-12 12:03 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, cbe-oss-dev

This patch adds a command to xmon for dumping information about
spu structs. The command is 'sf' for "spu fields" perhaps, and
takes the spu number as an argument. This is the same value as the
spu->number field, or the "phys-id" value of a context when it is
bound to a physical spu.

We try to catch memory errors as we dump each field, hopefully this
will make the command reasonably robust, but YMMV. If people see a
need we can easily add more fields to the dump in future.

Output looks something like this:

0:mon> sf 0
Dumping spu fields at address c00000001ffd9e80:
  number                  = 0x0
  name                    = spe
  devnode->full_name      = /cpus/PowerPC,BE@0/spes/spe@0
  nid                     = 0x0
  local_store_phys        = 0x20000000000
  local_store             = 0xd0000800801e0000
  ls_size                 = 0x0
  isrc                    = 0x4
  node                    = 0x0
  flags                   = 0x0
  dar                     = 0x0
  dsisr                   = 0x0
  class_0_pending         = 0
  irqs[0]                 = 0x16
  irqs[1]                 = 0x17
  irqs[2]                 = 0x24
  slb_replace             = 0x0
  pid                     = 0
  prio                    = 0
  mm                      = 0x0000000000000000
  ctx                     = 0x0000000000000000
  rq                      = 0x0000000000000000
  timestamp               = 0x0000000000000000
  problem_phys            = 0x20000040000
  problem                 = 0xd000080080220000
  problem->spu_runcntl_RW = 0x0
  problem->spu_status_R   = 0x0
  problem->spu_npc_RW     = 0x0
  priv1                   = 0xd000080080240000
  priv1->mfc_sr1_RW       = 0x33
  priv2                   = 0xd000080080250000


Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/xmon/xmon.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

Index: to-merge/arch/powerpc/xmon/xmon.c
===================================================================
--- to-merge.orig/arch/powerpc/xmon/xmon.c
+++ to-merge/arch/powerpc/xmon/xmon.c
@@ -214,7 +214,8 @@ Commands:\n\
   s	single step\n"
 #ifdef CONFIG_PPC_CELL
 "  ss	stop execution on all spus\n\
-  sr	restore execution on stopped spus\n"
+  sr	restore execution on stopped spus\n\
+  sf #	dump spu fields for spu # (in hex)\n"
 #endif
 "  S	print special registers\n\
   t	print backtrace\n\
@@ -2744,8 +2745,67 @@ static void restart_spus(void)
 	}
 }
 
+#define DUMP_WIDTH	23
+#define DUMP_FIELD(obj, format, field)					\
+do {									\
+	if (setjmp(bus_error_jmp) == 0) {				\
+		catch_memory_errors = 1;				\
+		sync();							\
+		printf("  %-*s = "format"\n", DUMP_WIDTH,		\
+				#field, obj->field);			\
+		sync();							\
+		__delay(200);						\
+	} else {							\
+		catch_memory_errors = 0;				\
+		printf("  %-*s = *** Error reading field.\n",		\
+					DUMP_WIDTH, #field);		\
+	}								\
+	catch_memory_errors = 0;					\
+} while (0)
+
+static void dump_spu_fields(struct spu *spu)
+{
+	printf("Dumping spu fields at address %p:\n", spu);
+
+	DUMP_FIELD(spu, "0x%x", number);
+	DUMP_FIELD(spu, "%s", name);
+	DUMP_FIELD(spu, "%s", devnode->full_name);
+	DUMP_FIELD(spu, "0x%x", nid);
+	DUMP_FIELD(spu, "0x%lx", local_store_phys);
+	DUMP_FIELD(spu, "0x%p", local_store);
+	DUMP_FIELD(spu, "0x%lx", ls_size);
+	DUMP_FIELD(spu, "0x%x", isrc);
+	DUMP_FIELD(spu, "0x%x", node);
+	DUMP_FIELD(spu, "0x%lx", flags);
+	DUMP_FIELD(spu, "0x%lx", dar);
+	DUMP_FIELD(spu, "0x%lx", dsisr);
+	DUMP_FIELD(spu, "%d", class_0_pending);
+	DUMP_FIELD(spu, "0x%lx", irqs[0]);
+	DUMP_FIELD(spu, "0x%lx", irqs[1]);
+	DUMP_FIELD(spu, "0x%lx", irqs[2]);
+	DUMP_FIELD(spu, "0x%x", slb_replace);
+	DUMP_FIELD(spu, "%d", pid);
+	DUMP_FIELD(spu, "%d", prio);
+	DUMP_FIELD(spu, "0x%p", mm);
+	DUMP_FIELD(spu, "0x%p", ctx);
+	DUMP_FIELD(spu, "0x%p", rq);
+	DUMP_FIELD(spu, "0x%p", timestamp);
+	DUMP_FIELD(spu, "0x%lx", problem_phys);
+	DUMP_FIELD(spu, "0x%p", problem);
+	DUMP_FIELD(spu, "0x%x", problem->spu_runcntl_RW);
+	DUMP_FIELD(spu, "0x%x", problem->spu_status_R);
+	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
+	DUMP_FIELD(spu, "0x%p", priv1);
+
+	if (spu->priv1)
+		DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW);
+
+	DUMP_FIELD(spu, "0x%p", priv2);
+}
+
 static int do_spu_cmd(void)
 {
+	unsigned long num = 0;
 	int cmd;
 
 	cmd = inchar();
@@ -2756,6 +2816,12 @@ static int do_spu_cmd(void)
 	case 'r':
 		restart_spus();
 		break;
+	case 'f':
+		if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu)
+			dump_spu_fields(spu_info[num].spu);
+		else
+			printf("*** Error: invalid spu number\n");
+		break;
 	default:
 		return -1;
 	}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-12 12:03 ` [PATCH 1/2] Add support for stopping spus from xmon Michael Ellerman
@ 2006-10-12 16:18   ` Linas Vepstas
  2006-10-18  7:13     ` Michael Ellerman
  2006-10-13  3:10   ` Haren Myneni
  2006-10-13  3:18   ` Luke Browning
  2 siblings, 1 reply; 12+ messages in thread
From: Linas Vepstas @ 2006-10-12 16:18 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

On Thu, Oct 12, 2006 at 10:03:08PM +1000, Michael Ellerman wrote:
> 
>  arch/powerpc/platforms/cell/spu_base.c |    4 
>  arch/powerpc/xmon/xmon.c               |  142 ++++++++++++++++++++++++++++++++-
>  include/asm-powerpc/xmon.h             |    2 
>  3 files changed, 146 insertions(+), 2 deletions(-)

The next patch adds another 60 lines to xmon.c, which 
is already a bit too big. Perhaps you could instead
put this code in "xmon/cell.c" or something like that?

--linas

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Cbe-oss-dev] [PATCH 2/2] Add support for dumping spu info from xmon
  2006-10-12 12:03 ` [PATCH 2/2] Add support for dumping spu info " Michael Ellerman
@ 2006-10-12 17:42   ` Geoff Levand
  2006-10-18  6:56     ` Michael Ellerman
  0 siblings, 1 reply; 12+ messages in thread
From: Geoff Levand @ 2006-10-12 17:42 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

Michael Ellerman wrote:
> This patch adds a command to xmon for dumping information about
> spu structs. The command is 'sf' for "spu fields" perhaps, and
> takes the spu number as an argument. This is the same value as the
> spu->number field, or the "phys-id" value of a context when it is
> bound to a physical spu.

> +static void dump_spu_fields(struct spu *spu)
> +{
...
> +	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
> +	DUMP_FIELD(spu, "0x%p", priv1);
> +
> +	if (spu->priv1)
> +		DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW);
> +
> +	DUMP_FIELD(spu, "0x%p", priv2);

Just to let you know, I've been doing some work to abstract the platform
specific parts out of the spu support to better support running on a
hypervisor.  It shouldn't make much difference, but maybe I'll try to set
something up like this for you:
 
	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
	DUMP_FIELD(spu, "0x%p", priv2);
	spu_dump_platform_fields(spu);

-Geoff

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-12 12:03 ` [PATCH 1/2] Add support for stopping spus from xmon Michael Ellerman
  2006-10-12 16:18   ` Linas Vepstas
@ 2006-10-13  3:10   ` Haren Myneni
  2006-10-18  7:16     ` Michael Ellerman
  2006-10-13  3:18   ` Luke Browning
  2 siblings, 1 reply; 12+ messages in thread
From: Haren Myneni @ 2006-10-13  3:10 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

Michael Ellerman wrote:

>This patch adds support for stopping, and restarting, spus
>from xmon. We use the spu master runcntl bit to stop execution,
>this is apparently the "right" way to control spu execution and
>spufs will be changed in the future to use this bit.
>
>Testing has shown that to restart execution we have to turn the
>master runcntl bit on and also rewrite the spu runcntl bit, even
>if it is already set to 1 (running).
>
>Stopping spus is triggered by the xmon command 'ss' - "spus stop"
>perhaps. Restarting them is triggered via 'sr'. Restart doesn't
>start execution on spus unless they were running prior to being
>stopped by xmon.
>
>Walking the spu->full_list in xmon after a panic, would mean
>corruption of any spu struct would make all the others
>inaccessible. To avoid this, and also to make the next patch
>easier, we cache pointers to all spus during boot.
>
>We attempt to catch and recover from errors while stopping and
>restarting the spus, but as with most xmon functionality there are
>no guarantees that performing these operations won't crash xmon
>itself.
>
>  
>
I think, kdump also need stop_spus() functionality when the dump support 
is included on cell. If so, how about both stop_spus() and start_spus() 
in platforms/cell/.

Thanks
Haren

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-12 12:03 ` [PATCH 1/2] Add support for stopping spus from xmon Michael Ellerman
  2006-10-12 16:18   ` Linas Vepstas
  2006-10-13  3:10   ` Haren Myneni
@ 2006-10-13  3:18   ` Luke Browning
  2006-10-18  7:14     ` Michael Ellerman
  2 siblings, 1 reply; 12+ messages in thread
From: Luke Browning @ 2006-10-13  3:18 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linuxppc-dev, linuxppc-dev-bounces+lukebrowning=us.ibm.com,
	Arnd Bergmann, cbe-oss-dev

[-- Attachment #1: Type: text/plain, Size: 7685 bytes --]

linuxppc-dev-bounces+lukebrowning=us.ibm.com@ozlabs.org wrote on 
10/12/2006 09:03:08 AM:

> This patch adds support for stopping, and restarting, spus
> from xmon. We use the spu master runcntl bit to stop execution,
> this is apparently the "right" way to control spu execution and
> spufs will be changed in the future to use this bit.
> 
> Testing has shown that to restart execution we have to turn the
> master runcntl bit on and also rewrite the spu runcntl bit, even
> if it is already set to 1 (running).
> 
> Stopping spus is triggered by the xmon command 'ss' - "spus stop"
> perhaps. Restarting them is triggered via 'sr'. Restart doesn't
> start execution on spus unless they were running prior to being
> stopped by xmon.
> 
> Walking the spu->full_list in xmon after a panic, would mean
> corruption of any spu struct would make all the others
> inaccessible. To avoid this, and also to make the next patch
> easier, we cache pointers to all spus during boot.

The spe affinity code drop created an array of spu pointers that
is indexed by spu->number.  We have a couple of other fields in
there that are needed for multiple spu scheduling operations. 
Maybe, you can use this array.  The name of the arry is lspu[]
for logical spus.

> 
> We attempt to catch and recover from errors while stopping and
> restarting the spus, but as with most xmon functionality there are
> no guarantees that performing these operations won't crash xmon
> itself.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> ---
> 
>  arch/powerpc/platforms/cell/spu_base.c |    4 
>  arch/powerpc/xmon/xmon.c               |  142 
> ++++++++++++++++++++++++++++++++-
>  include/asm-powerpc/xmon.h             |    2 
>  3 files changed, 146 insertions(+), 2 deletions(-)
> 
> Index: to-merge/arch/powerpc/platforms/cell/spu_base.c
> ===================================================================
> --- to-merge.orig/arch/powerpc/platforms/cell/spu_base.c
> +++ to-merge/arch/powerpc/platforms/cell/spu_base.c
> @@ -38,6 +38,7 @@
>  #include <asm/spu.h>
>  #include <asm/spu_priv1.h>
>  #include <asm/mmu_context.h>
> +#include <asm/xmon.h>
> 
>  #include "interrupt.h"
> 
> @@ -914,6 +915,9 @@ static int __init init_spu_base(void)
>           break;
>        }
>     }
> +
> +   xmon_register_spus(&spu_full_list);
> +
>     return ret;
>  }
>  module_init(init_spu_base);
> Index: to-merge/arch/powerpc/xmon/xmon.c
> ===================================================================
> --- to-merge.orig/arch/powerpc/xmon/xmon.c
> +++ to-merge/arch/powerpc/xmon/xmon.c
> @@ -35,6 +35,8 @@
>  #include <asm/rtas.h>
>  #include <asm/sstep.h>
>  #include <asm/bug.h>
> +#include <asm/spu.h>
> +#include <asm/spu_priv1.h>
> 
>  #ifdef CONFIG_PPC64
>  #include <asm/hvcall.h>
> @@ -145,6 +147,8 @@ static void xmon_print_symbol(unsigned l
>                 const char *after);
>  static const char *getvecname(unsigned long vec);
> 
> +static int do_spu_cmd(void);
> +
>  int xmon_no_auto_backtrace;
> 
>  extern int print_insn_powerpc(unsigned long, unsigned long, int);
> @@ -207,8 +211,12 @@ Commands:\n\
>    mi   show information about memory allocation\n\
>    p    call a procedure\n\
>    r   print registers\n\
> -  s   single step\n\
> -  S   print special registers\n\
> +  s   single step\n"
> +#ifdef CONFIG_PPC_CELL
> +"  ss   stop execution on all spus\n\
> +  sr   restore execution on stopped spus\n"
> +#endif
> +"  S   print special registers\n\
>    t   print backtrace\n\
>    x   exit monitor and recover\n\
>    X   exit monitor and dont recover\n"
> @@ -516,6 +524,7 @@ int xmon(struct pt_regs *excp)
>        xmon_save_regs(&regs);
>        excp = &regs;
>     }
> +
>     return xmon_core(excp, 0);
>  }
>  EXPORT_SYMBOL(xmon);
> @@ -808,6 +817,8 @@ cmds(struct pt_regs *excp)
>           cacheflush();
>           break;
>        case 's':
> +         if (do_spu_cmd() == 0)
> +            break;
>           if (do_step(excp))
>              return cmd;
>           break;
> @@ -2630,3 +2641,130 @@ void __init xmon_setup(void)
>     if (xmon_early)
>        debugger(NULL);
>  }
> +
> +#ifdef CONFIG_PPC_CELL
> +
> +struct spu_info {
> +   struct spu *spu;
> +   u64 saved_mfc_sr1_RW;
> +   u32 saved_spu_runcntl_RW;
> +   u8 stopped_ok;
> +};
> +
> +#define XMON_NUM_SPUS   16   /* Enough for current hardware */
> +
> +static struct spu_info spu_info[XMON_NUM_SPUS];
> +
> +void xmon_register_spus(struct list_head *list)
> +{
> +   struct spu *spu;
> +
> +   list_for_each_entry(spu, list, full_list) {
> +      if (spu->number >= XMON_NUM_SPUS) {
> +         WARN_ON(1);
> +         continue;
> +      }
> +
> +      spu_info[spu->number].spu = spu;
> +      spu_info[spu->number].stopped_ok = 0;
> +   }
> +}
> +
> +static void stop_spus(void)
> +{
> +   struct spu *spu;
> +   int i;
> +   u64 tmp;
> +
> +   for (i = 0; i < XMON_NUM_SPUS; i++) {
> +      if (!spu_info[i].spu)
> +         continue;
> +
> +      if (setjmp(bus_error_jmp) == 0) {
> +         catch_memory_errors = 1;
> +         sync();
> +
> +         spu = spu_info[i].spu;
> +
> +         spu_info[i].saved_spu_runcntl_RW =
> +            in_be32(&spu->problem->spu_runcntl_RW);
> +
> +         tmp = spu_mfc_sr1_get(spu);
> +         spu_info[i].saved_mfc_sr1_RW = tmp;
> +
> +         tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
> +         spu_mfc_sr1_set(spu, tmp);
> +
> +         sync();
> +         __delay(200);
> +
> +         spu_info[i].stopped_ok = 1;
> +         printf("Stopped spu %.2d\n", i);
> +      } else {
> +         catch_memory_errors = 0;
> +         printf("*** Error stopping spu %.2d\n", i);
> +      }
> +      catch_memory_errors = 0;
> +   }
> +}
> +
> +static void restart_spus(void)
> +{
> +   struct spu *spu;
> +   int i;
> +
> +   for (i = 0; i < XMON_NUM_SPUS; i++) {
> +      if (!spu_info[i].spu)
> +         continue;
> +
> +      if (!spu_info[i].stopped_ok) {
> +         printf("*** Error, spu %d was not successfully stopped"
> +               ", not restarting\n", i);
> +         continue;
> +      }
> +
> +      if (setjmp(bus_error_jmp) == 0) {
> +         catch_memory_errors = 1;
> +         sync();
> +
> +         spu = spu_info[i].spu;
> +         spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
> +         out_be32(&spu->problem->spu_runcntl_RW,
> +               spu_info[i].saved_spu_runcntl_RW);
> +
> +         sync();
> +         __delay(200);
> +
> +         printf("Restarted spu %.2d\n", i);
> +      } else {
> +         catch_memory_errors = 0;
> +         printf("*** Error restarting spu %.2d\n", i);
> +      }
> +      catch_memory_errors = 0;
> +   }
> +}
> +
> +static int do_spu_cmd(void)
> +{
> +   int cmd;
> +
> +   cmd = inchar();
> +   switch (cmd) {
> +   case 's':
> +      stop_spus();
> +      break;
> +   case 'r':
> +      restart_spus();
> +      break;
> +   default:
> +      return -1;
> +   }
> +
> +   return 0;
> +}
> +#else /* ! CONFIG_PPC_CELL */
> +static int do_spu_cmd(void)
> +{
> +   return -1;
> +}
> +#endif
> Index: to-merge/include/asm-powerpc/xmon.h
> ===================================================================
> --- to-merge.orig/include/asm-powerpc/xmon.h
> +++ to-merge/include/asm-powerpc/xmon.h
> @@ -14,8 +14,10 @@
> 
>  #ifdef CONFIG_XMON
>  extern void xmon_setup(void);
> +extern void xmon_register_spus(struct list_head *list);
>  #else
>  static inline void xmon_setup(void) { };
> +static inline void xmon_register_spus(struct list_head *list) { };
>  #endif
> 
>  #endif /* __KERNEL __ */
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

[-- Attachment #2: Type: text/html, Size: 11975 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Cbe-oss-dev] [PATCH 2/2] Add support for dumping spu info from xmon
  2006-10-12 17:42   ` [Cbe-oss-dev] " Geoff Levand
@ 2006-10-18  6:56     ` Michael Ellerman
  2006-11-10  9:11       ` Geoff Levand
  0 siblings, 1 reply; 12+ messages in thread
From: Michael Ellerman @ 2006-10-18  6:56 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

[-- Attachment #1: Type: text/plain, Size: 1629 bytes --]

On Thu, 2006-10-12 at 10:42 -0700, Geoff Levand wrote:
> Michael Ellerman wrote:
> > This patch adds a command to xmon for dumping information about
> > spu structs. The command is 'sf' for "spu fields" perhaps, and
> > takes the spu number as an argument. This is the same value as the
> > spu->number field, or the "phys-id" value of a context when it is
> > bound to a physical spu.
> 
> > +static void dump_spu_fields(struct spu *spu)
> > +{
> ...
> > +	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
> > +	DUMP_FIELD(spu, "0x%p", priv1);
> > +
> > +	if (spu->priv1)
> > +		DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW);
> > +
> > +	DUMP_FIELD(spu, "0x%p", priv2);
> 
> Just to let you know, I've been doing some work to abstract the platform
> specific parts out of the spu support to better support running on a
> hypervisor.  It shouldn't make much difference, but maybe I'll try to set
> something up like this for you:
>  
> 	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
> 	DUMP_FIELD(spu, "0x%p", priv2);
> 	spu_dump_platform_fields(spu);

We already have the spu_priv1_ops abstracted out, is that not enough? I
decided to check explicitly for the priv1 pointer because calling the
hypervisor from a panicked kernel is risky at best. Although I haven't
seen how you guys implement hypervisor calls, so perhaps it's not so
bad.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-12 16:18   ` Linas Vepstas
@ 2006-10-18  7:13     ` Michael Ellerman
  0 siblings, 0 replies; 12+ messages in thread
From: Michael Ellerman @ 2006-10-18  7:13 UTC (permalink / raw)
  To: Linas Vepstas; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

[-- Attachment #1: Type: text/plain, Size: 1082 bytes --]

On Thu, 2006-10-12 at 11:18 -0500, Linas Vepstas wrote:
> On Thu, Oct 12, 2006 at 10:03:08PM +1000, Michael Ellerman wrote:
> > 
> >  arch/powerpc/platforms/cell/spu_base.c |    4 
> >  arch/powerpc/xmon/xmon.c               |  142 ++++++++++++++++++++++++++++++++-
> >  include/asm-powerpc/xmon.h             |    2 
> >  3 files changed, 146 insertions(+), 2 deletions(-)
> 
> The next patch adds another 60 lines to xmon.c, which 
> is already a bit too big. Perhaps you could instead
> put this code in "xmon/cell.c" or something like that?

I did originally, but that requires exporting several globals from
xmon.c, which struck me as even less pleasant.

I looked at some way of wrapping the if(setjmp) .. logic into a
function, but I couldn't come up with anything neat in the little time I
had.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-13  3:18   ` Luke Browning
@ 2006-10-18  7:14     ` Michael Ellerman
  0 siblings, 0 replies; 12+ messages in thread
From: Michael Ellerman @ 2006-10-18  7:14 UTC (permalink / raw)
  To: Luke Browning; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

[-- Attachment #1: Type: text/plain, Size: 1907 bytes --]

On Fri, 2006-10-13 at 01:18 -0200, Luke Browning wrote:
> 
> linuxppc-dev-bounces+lukebrowning=us.ibm.com@ozlabs.org wrote on
> 10/12/2006 09:03:08 AM:
> 
> > This patch adds support for stopping, and restarting, spus
> > from xmon. We use the spu master runcntl bit to stop execution,
> > this is apparently the "right" way to control spu execution and
> > spufs will be changed in the future to use this bit.
> > 
> > Testing has shown that to restart execution we have to turn the
> > master runcntl bit on and also rewrite the spu runcntl bit, even
> > if it is already set to 1 (running).
> > 
> > Stopping spus is triggered by the xmon command 'ss' - "spus stop"
> > perhaps. Restarting them is triggered via 'sr'. Restart doesn't
> > start execution on spus unless they were running prior to being
> > stopped by xmon.
> > 
> > Walking the spu->full_list in xmon after a panic, would mean
> > corruption of any spu struct would make all the others
> > inaccessible. To avoid this, and also to make the next patch
> > easier, we cache pointers to all spus during boot.
> 
> The spe affinity code drop created an array of spu pointers that 
> is indexed by spu->number.  We have a couple of other fields in 
> there that are needed for multiple spu scheduling operations.   
> Maybe, you can use this array.  The name of the arry is lspu[] 
> for logical spus. 

I'll have a look at it, but part of the rationale for xmon keeping its
own array is that there should be no code during normal kernel operation
that touches that array, and therefore less chance that a programming
error will corrupt the array.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add support for stopping spus from xmon
  2006-10-13  3:10   ` Haren Myneni
@ 2006-10-18  7:16     ` Michael Ellerman
  0 siblings, 0 replies; 12+ messages in thread
From: Michael Ellerman @ 2006-10-18  7:16 UTC (permalink / raw)
  To: Haren Myneni; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

[-- Attachment #1: Type: text/plain, Size: 1931 bytes --]

On Thu, 2006-10-12 at 20:10 -0700, Haren Myneni wrote:
> Michael Ellerman wrote:
> 
> >This patch adds support for stopping, and restarting, spus
> >from xmon. We use the spu master runcntl bit to stop execution,
> >this is apparently the "right" way to control spu execution and
> >spufs will be changed in the future to use this bit.
> >
> >Testing has shown that to restart execution we have to turn the
> >master runcntl bit on and also rewrite the spu runcntl bit, even
> >if it is already set to 1 (running).
> >
> >Stopping spus is triggered by the xmon command 'ss' - "spus stop"
> >perhaps. Restarting them is triggered via 'sr'. Restart doesn't
> >start execution on spus unless they were running prior to being
> >stopped by xmon.
> >
> >Walking the spu->full_list in xmon after a panic, would mean
> >corruption of any spu struct would make all the others
> >inaccessible. To avoid this, and also to make the next patch
> >easier, we cache pointers to all spus during boot.
> >
> >We attempt to catch and recover from errors while stopping and
> >restarting the spus, but as with most xmon functionality there are
> >no guarantees that performing these operations won't crash xmon
> >itself.
> >
> >  
> >
> I think, kdump also need stop_spus() functionality when the dump support 
> is included on cell. If so, how about both stop_spus() and start_spus() 
> in platforms/cell/.

Good point. We haven't got that far with kdump on cell so I hadn't
thought of it. We won't need start_spus(), but we will need something to
stop spus for kdump. I'll leave it for now, but keep it in mind for when
we get kdump going on cell.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Cbe-oss-dev] [PATCH 2/2] Add support for dumping spu info from xmon
  2006-10-18  6:56     ` Michael Ellerman
@ 2006-11-10  9:11       ` Geoff Levand
  0 siblings, 0 replies; 12+ messages in thread
From: Geoff Levand @ 2006-11-10  9:11 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev

Michael Ellerman wrote:
> On Thu, 2006-10-12 at 10:42 -0700, Geoff Levand wrote:
>> Michael Ellerman wrote:
>> > This patch adds a command to xmon for dumping information about
>> > spu structs. The command is 'sf' for "spu fields" perhaps, and
>> > takes the spu number as an argument. This is the same value as the
>> > spu->number field, or the "phys-id" value of a context when it is
>> > bound to a physical spu.
>> 
>> > +static void dump_spu_fields(struct spu *spu)
>> > +{
>> ...
>> > +	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
>> > +	DUMP_FIELD(spu, "0x%p", priv1);
>> > +
>> > +	if (spu->priv1)
>> > +		DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW);
>> > +
>> > +	DUMP_FIELD(spu, "0x%p", priv2);
>> 
>> Just to let you know, I've been doing some work to abstract the platform
>> specific parts out of the spu support to better support running on a
>> hypervisor.  It shouldn't make much difference, but maybe I'll try to set
>> something up like this for you:
>>  
>> 	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
>> 	DUMP_FIELD(spu, "0x%p", priv2);
>> 	spu_dump_platform_fields(spu);
> 
> We already have the spu_priv1_ops abstracted out, is that not enough? I
> decided to check explicitly for the priv1 pointer because calling the
> hypervisor from a panicked kernel is risky at best. Although I haven't
> seen how you guys implement hypervisor calls, so perhaps it's not so
> bad.

Michael,

I tried to set this up as above, but unfortunately, your DUMP_FIELD is
setup in such a way that it is not easy to change to use from outside
xmon.c, so I left spu_dump_platform_fields() (I put it in spu_priv1_mmio.c)
empty.  We'll need to work on something usable here, or make some other way
to abstract those platform specific spu variables.

I'll re-post my abstract spu management routines patch again soon with
this xmon support added.

-Geoff

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2006-11-10  9:11 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-12 12:03 [PATCH 0/2] Cell xmon helpers Michael Ellerman
2006-10-12 12:03 ` [PATCH 1/2] Add support for stopping spus from xmon Michael Ellerman
2006-10-12 16:18   ` Linas Vepstas
2006-10-18  7:13     ` Michael Ellerman
2006-10-13  3:10   ` Haren Myneni
2006-10-18  7:16     ` Michael Ellerman
2006-10-13  3:18   ` Luke Browning
2006-10-18  7:14     ` Michael Ellerman
2006-10-12 12:03 ` [PATCH 2/2] Add support for dumping spu info " Michael Ellerman
2006-10-12 17:42   ` [Cbe-oss-dev] " Geoff Levand
2006-10-18  6:56     ` Michael Ellerman
2006-11-10  9:11       ` Geoff Levand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).