LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v3] [POWERPC] 85xx: Add basic Uniprocessor MPC8572 DS port
From: Segher Boessenkool @ 2007-09-13 22:30 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <96A13129-D16E-440D-B317-29BED85852D9@kernel.crashing.org>

>>>>> +		PowerPC,8572@0 {
>>>>
>>>> Maybe it would be good to use "PowerPC,e500" instead -- it would
>>>> make it easier to probe for the actual CPU type, that way.  Not
>>>> that Linux uses the name/compatible here at all ;-)
>>>
>>> I thought about this, not sure what the best solution is.
>>
>> Since the CPU cores on all these SoCs are identical (well, there
>> might be a few revisions, or different cache sizes or such -- minor
>> differences that can be probed for separately), it probably is a
>> good idea to name them in the tree instead of having each client
>> have its own table.
>>
>> Or is there anything about the CPU that can be derived from "8572"
>> but not from "e500"?
>
> Only in so much that we need something that states what the actual 
> processor is.

You mean, something needs to say "8572"?  I think the "soc" node
would be best for that.

It's all not terribly important, just something to think about.

>>>> And then there's the pci_bridge thing we're discussing on IRC, of
>>>> course -- basically, get rid of the pci_bridge pseudo-node, and
>>>> move the interrupt-map for the south-bridge devices into the
>>>> south-bridge node.
>>>
>>> Leaving the interrupt-map in the PHB because that works and moving 
>>> it down has issues.
>>
>> Okay, fair enough.  Are you looking at resolving those kernel issues?
>
> No.  I've had enough of this device tree foo for a while :)

Heh okay :-)

> [I'm happy to test any patches related to this, if someone else comes 
> up with them]

Well I don't know what the problem is ("it doesn't work" doesn't
say much), and don't have your hardware to test.  Maybe we can do
it on IRC again ;-)


Segher

^ permalink raw reply

* Re: [PATCH] PowerPC: usb ehci of_platform bindings for Sequoia 440EPx
From: Segher Boessenkool @ 2007-09-13 22:36 UTC (permalink / raw)
  To: Valentine Barshak; +Cc: linuxppc-dev
In-Reply-To: <20070913182453.GA26541@ru.mvista.com>

> EHCI OF bindings for PowerPC 440EPx Sequoia.

Those aren't bindings, they are examples.  Bindings are pieces
of documentation that describe what device-specific properties
mean what, what standard properties are required with what
values, etc.

Examples are good to have, of course.

One thing you really need to document is what "ehci-be-desc"
and friends mean.  I can give you one comment already: for
devices that are usually little-endian, but an implementation
implements registers as big-endian, precedent is to show that
in the device tree by including an (empty) "big-endian" property,
rather than inventing new "compatible" values.


Segher

^ permalink raw reply

* Re: [PATCH 04/22] [POWERPC] Update mpc7448hpc2 device tree to be compatible for tsi109 chip
From: Segher Boessenkool @ 2007-09-13 22:54 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <11897176851400-git-send-email-galak@kernel.crashing.org>

> Update mpc7448hpc2 device tree to be compatible for tsi109 chip.

Do all those boards have a tsi109?  If not, this patch is
incorrect.  If they do, is tsi109 actually backward-compatible
to tsi108?  That is, will a driver that knows about tsi108
only work correctly on a tsi109?

Also, all those names really should have a manufacturer
prefix ("XXX,...").


Segher

^ permalink raw reply

* Re: Flash on ep8248e standard motherboards
From: Erik Christiansen @ 2007-09-14  0:46 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <46E944BE.1010007@qstreams.com>

On Thu, Sep 13, 2007 at 10:10:06AM -0400, Ben Warren wrote:
> >  
> MIRRORX16 is the correct type for Spansion GL series NOR flash. AMD spun 
> off their flash business a while ago and renamed it Spansion. If you 
> look on the datasheet you'll see that Spansion calls the GL technology 
> 'MirrorBit', and in all likelihood the device has a 16-bit data bus. The 
> AMD algorithm may work but the MIRRORX16 definitely will.

Yes, the "Flash Organisation" section of the ep8248e manual shows two
16-bit devices. (That's what seemed erroneous in the BDI2000 config file
supplied with the card. ;-)

Many thanks for putting me on the right track w.r.t. CHIPTYPE. It'll
save me trying all the wrong guesses first.

Regards,
Erik

^ permalink raw reply

* Re: oftree and external connected devices
From: David Gibson @ 2007-09-14  1:22 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20070913132913.GA9031@lixom.net>

On Thu, Sep 13, 2007 at 08:29:13AM -0500, Olof Johansson wrote:
> On Thu, Sep 13, 2007 at 01:26:26PM +0200, Juergen Beisert wrote:
> > Hi,
> > 
> > I'm using an MPC5200B based system with various external connected devices to 
> > its LocalPlusBus. On other architectures I would register them as platform 
> > devices (no chance to autodetect these devices). But on PowerPC architecture?
> 
> If it's a special case of something that it's unlikely that you'll reuse
> the driver for, I'd say go ahead with a platform driver. There's nothing in the
> PPC kernel that stops it from working.
> 
> We're just trying to avoid it for common devices that platforms might share,
> and instead of describing hardware in the platform devices setup, describe it
> in the device tree instead.
> 
> So it depends on how much work you want to invest in it, and if you're
> planning on ever submitting the driver upstream. If you are, going
> with a simple device tree definiton would be best (the kernel side,
> to move a platform driver to instead be an of_platform driver is easy,
> and can be done afterwards).
> 
> > Is the oftree description also intended to describe these kind of external 
> > devices, or only SoC's internal devices? If its also intended for external 
> > devices, how to do so? Are there any examples? I didn't find anything useful 
> > yet.
> 
> It can be used to describe on-board or off-board devices alike.

And should be used to describe any devices that can't otherwise be
probed, whether they're on-board or not.

-- 
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: Patches added to powerpc.git for-2.6.24 branch
From: Michael Neuling @ 2007-09-14  1:43 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18153.30975.926456.819248@cargo.ozlabs.ibm.com>

Paulus,

Could you take this as well for 2.6.24?

  Remove barriers from the SLB shadow buffer update
  http://patchwork.ozlabs.org/linuxppc/patch?id=13116

Mikey

In message <18153.30975.926456.819248@cargo.ozlabs.ibm.com> you wrote:
> David Gibson (2):
>       [POWERPC] Move bootwrapper's strchr() and strncmp() from .h to string.S
>       [POWERPC] Document and implement an improved flash device binding for p
owerpc
> 
> Geert Uytterhoeven (1):
>       [POWERPC] PS3: Add new LV1 error codes
> 
> Geoff Levand (1):
>       [POWERPC] PS3: Enhance storage probe debug output
> 
> Jeremy Kerr (1):
>       [POWERPC] PS3: Fix CONFIG_SMP=n, CONFIG_KEXEC=y build
> 
> Josh Boyer (6):
>       [POWERPC] Remove dtc build cruft from DTS files
>       [POWERPC] Fix bus probe on Bamboo board
>       [POWERPC] Walnut DTS
>       [POWERPC] Walnut defconfig
>       [POWERPC] Walnut board support
>       [POWERPC] Walnut zImage wrapper
> 
> Kumar Gala (3):
>       [POWERPC] Remove old includes from arch/ppc
>       [POWERPC] Copy over headers from arch/ppc to arch/powerpc that we need
>       [POWERPC] Stop include asm-ppc when building ARCH=powerpc for ppc32
> 
> Linas Vepstas (4):
>       [POWERPC] IOMMU virtual merge is no longer experimental
>       [POWERPC] prom_init whitespace cleanup, typo fix
>       [POWERPC] prom.c whitespace cleanup
>       [POWERPC] setup_64.c and prom.c comment cleanup
> 
> Michael Ellerman (5):
>       [POWERPC] Add an optional device_node pointer to the irq_host
>       [POWERPC] Invert null match behaviour for irq_hosts
>       [POWERPC] Provide a default irq_host match, which matches on an exact o
f_node
>       [POWERPC] Initialise hwirq for legacy irqs
>       [POWERPC] Export virq mapping via debugfs
> 
> Olof Johansson (10):
>       [POWERPC] Export new __io{re,un}map_at() symbols
>       [POWERPC] pasemi: Add pasemi_pci_getcfgaddr()
>       [POWERPC] pasemi: Add workaround for erratum 5945
>       [POWERPC] pasemi: Export more SPRs to sysfs when CONFIG_DEBUG_KERNEL=y
>       [POWERPC] pasemi: Print more information at machine check
>       [POWERPC] pasemi: Move pasemi_idle_init() to late_initcall()
>       [POWERPC] Remove unused platform_machine_check()
>       [POWERPC] Move lowlevel runlatch calls under cpu feature control
>       [POWERPC] Remove warning in arch/powerpc/kernel/sysfs.c
>       [POWERPC] Add workaround for MPICs with broken register reads
> 
> Scott Wood (5):
>       [POWERPC] bootwrapper: flatdevtree fixes
>       [POWERPC] bootwrapper: Add strtoull()
>       [POWERPC] bootwrapper: Add get_path()
>       [POWERPC] bootwrapper: Only print MAC addresses when the node is actual
ly present
>       [POWERPC] Check _PAGE_RW and _PAGE_PRESENT on kernel addresses
> 
> Valentine Barshak (4):
>       [POWERPC] PowerPC 440EPx: Sequoia device tree
>       [POWERPC] PowerPC 440EPx: Sequoia defconfig
>       [POWERPC] PowerPC 440EPx: Sequoia board support
>       [POWERPC] PowerPC 440EPx: Sequoia bootwrapper
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
> 

^ permalink raw reply

* Re: [PATCH 2/9] 8xx: Infrastructure code cleanup.
From: David Gibson @ 2007-09-14  4:09 UTC (permalink / raw)
  To: Vitaly Bordug; +Cc: linuxppc-dev
In-Reply-To: <20070913121640.5764f656@localhost.localdomain>

On Thu, Sep 13, 2007 at 12:16:40PM +0400, Vitaly Bordug wrote:
[snip]
> > This looks bogus.  You're replacing the old crap immr_map() functions,
> > which ioremap()ed the registers every time, with a much simpler
> > version which uses an established-once mapping of the register
> > region.  AFAICT, anywah.
> > 
> > So far, so good - but your immr_unmap() still does an iounmap() which
> > is surely wrong - it should now be a no-op, leaving the mpc8xx_immr
> > mapping intact.  You probably get away with it by accident, because I
> > imagine attempting to unmap an unaligned chunk of the region will just
> > fail.
> >
> 
> yes, it should do nop instead of iounmap. 
> > In fact, with this patch in place, I'd like to see another patch which
> > removes all calls to immr_map() and immr_unmap(), simply accessing the
> > common mapping directly.
> > 
> Sorry, but originally, that stuff was created to get rid of BSP
> ifdefs in drivers. For PQ family, it is a common practice to have
> single driver handling all 3 CPU families, which use the same logic,
> but immr structure differs a little bit.
> 
> At this point it's clear case-by-case ioremapping does not have firm
> benefit, but getting back to the way it was is useless either.  In
> ideal world, we'd have all those stuff put into dts and have
> specific drivers be a shim layer between core hw and IO drivers.

Err.. I don't understand what you're getting at.  As the code stands
after Scott's cleanup, the map() and unmap() calls can certainly be
trivially removed, regardless of the history for them.

And, yes, the drivers should certainly uses addresses from the device
tree, rather than that revolting structure covering all the inbuilt
device retgisters.

-- 
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

* [PATCH 2/2] fsl/embedded6xx: don't cast the result of of_get_property
From: Jeremy Kerr @ 2007-09-14  5:46 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189748800.165136.731062325870.1.gpush@pokey>

Use a temporary variable of the correct type instead.

Also, this allows us to check the return value in ls_uarts_init, to
avoid dereferencing a null pointer if required properties aren't
present.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/embedded6xx/ls_uart.c |   14 +++++++++-----
 arch/powerpc/sysdev/fsl_soc.c                |   18 ++++++++++--------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c
index d0bee9f..9d4b40c 100644
--- a/arch/powerpc/platforms/embedded6xx/ls_uart.c
+++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -103,20 +103,24 @@ static void __init ls_uart_init(void)
 static int __init ls_uarts_init(void)
 {
 	struct device_node *avr;
-	phys_addr_t phys_addr;
+	const u32 *avr_clock_prop, *phys_addr;
 	int len;
 
 	avr = of_find_node_by_path("/soc10x/serial@80004500");
 	if (!avr)
 		return -EINVAL;
 
-	avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);
-	phys_addr = ((u32*)of_get_property(avr, "reg", &len))[0];
+	phys_addr = of_get_property(avr, "reg", &len);
+	avr_clock_prop = of_get_property(avr, "clock-frequency", &len);
 
-	if (!avr_clock || !phys_addr)
+	if (!avr_clock_prop || !phys_addr)
 		return -EINVAL;
 
-	avr_addr = ioremap(phys_addr, 32);
+	avr_clock = *avr_clock_prop;
+	if (!avr_clock || !phys_addr[0])
+		return -EINVAL;
+
+	avr_addr = ioremap(phys_addr[0], 32);
 	if (!avr_addr)
 		return -EFAULT;
 
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 1cf29c9..564d5e5 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -673,6 +673,7 @@ static int __init fs_enet_of_init(void)
 		struct fs_platform_info fs_enet_data;
 		const unsigned int *id, *phy_addr, *phy_irq;
 		const void *mac_addr;
+		const u32 *clk;
 		const phandle *ph;
 		const char *model;
 
@@ -740,10 +741,10 @@ static int __init fs_enet_of_init(void)
                         goto unreg;
                 }
 
-		fs_enet_data.clk_rx = *((u32 *)of_get_property(np,
-						"rx-clock", NULL));
-		fs_enet_data.clk_tx = *((u32 *)of_get_property(np,
-						"tx-clock", NULL));
+		clk = of_get_property(np, "rx-clock", NULL);
+		fs_enet_data.clk_rx = *clk;
+		clk = of_get_property(np, "tx-clock", NULL);
+		fs_enet_data.clk_tx = *clk;
 
 		if (strstr(model, "FCC")) {
 			int fcc_index = *id - 1;
@@ -844,6 +845,7 @@ static int __init cpm_uart_of_init(void)
 		struct resource r[3];
 		struct fs_uart_platform_info cpm_uart_data;
 		const int *id;
+		const u32 *clk;
 		const char *model;
 
 		memset(r, 0, sizeof(r));
@@ -882,10 +884,10 @@ static int __init cpm_uart_of_init(void)
 		cpm_uart_data.tx_buf_size = 32;
 		cpm_uart_data.rx_num_fifo = 4;
 		cpm_uart_data.rx_buf_size = 32;
-		cpm_uart_data.clk_rx = *((u32 *)of_get_property(np,
-						"rx-clock", NULL));
-		cpm_uart_data.clk_tx = *((u32 *)of_get_property(np,
-						"tx-clock", NULL));
+		clk = of_get_property(np, "rx-clock", NULL);
+		cpm_uart_data.clk_rx = *clk;
+		clk = of_get_property(np, "tx-clock", NULL);
+		cpm_uart_data.clk_tx = *clk;
 
 		ret =
 		    platform_device_add_data(cpm_uart_dev, &cpm_uart_data,

^ permalink raw reply related

* [PATCH 1/2] cell: don't cast the result of of_get_property()
From: Jeremy Kerr @ 2007-09-14  5:46 UTC (permalink / raw)
  To: linuxppc-dev

The cast to u32 * isn't required, of_get_property returns a void *.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spu_manage.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index 0e14f53..1b01070 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -377,10 +377,10 @@ static int qs20_reg_memory[QS20_SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 };
 static struct spu *spu_lookup_reg(int node, u32 reg)
 {
 	struct spu *spu;
-	u32 *spu_reg;
+	const u32 *spu_reg;
 
 	list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
-		spu_reg = (u32*)of_get_property(spu_devnode(spu), "reg", NULL);
+		spu_reg = of_get_property(spu_devnode(spu), "reg", NULL);
 		if (*spu_reg == reg)
 			return spu;
 	}

^ permalink raw reply related

* rtc-ds1742.c should use resource_size_t for base address
From: David Gibson @ 2007-09-14  5:54 UTC (permalink / raw)
  To: Andrew Morton, Atsushi Nemoto; +Cc: linuxppc-dev, linux-kernel, rtc-linux

Currently the rtc driver, rtc-ds1742.c uses an unsigned long to store
the base mmio address of the NVRAM/RTC.  This breaks on systems like
PowerPC 440, which is a 32-bit core with 36-bit physical addresses: IO
on the system, including the RTC, is typically above the 4GB point,
and cannot fit into an unsigned long.

This patch fixes the problem by replacing the unsigned long with a
resource_size_t.  Tested on Ebony (PPC440) (with additional patches to
instantiate the ds1742 platform device appropriately).

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: working-2.6/drivers/rtc/rtc-ds1742.c
===================================================================
--- working-2.6.orig/drivers/rtc/rtc-ds1742.c	2007-09-14 15:43:31.000000000 +1000
+++ working-2.6/drivers/rtc/rtc-ds1742.c	2007-09-14 15:44:09.000000000 +1000
@@ -55,7 +55,7 @@ struct rtc_plat_data {
 	void __iomem *ioaddr_rtc;
 	size_t size_nvram;
 	size_t size;
-	unsigned long baseaddr;
+	resource_size_t baseaddr;
 	unsigned long last_jiffies;
 };
 

-- 
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

* [PATCH 19/25] spufs: Internal __spufs_get_foo() routines should take a spu_context *
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

The SPUFS attribute get routines take a void * because the generic attribute
code doesn't know what sort of data it's passing around.

However our internal __spufs_get_foo() routines can take a spu_context *
directly, which saves plonking it in and out of a void * again.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

---
 arch/powerpc/platforms/cell/spufs/file.c  |   40 ++++++++++++------------------
 arch/powerpc/platforms/cell/spufs/spufs.h |    2 -
 2 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 6095fb1..4cd34e5 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1085,9 +1085,8 @@ static void spufs_signal1_type_set(void *data, u64 val)
 	spu_release(ctx);
 }
 
-static u64 __spufs_signal1_type_get(void *data)
+static u64 __spufs_signal1_type_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	return ctx->ops->signal1_type_get(ctx);
 }
 
@@ -1097,7 +1096,7 @@ static u64 spufs_signal1_type_get(void *data)
 	u64 ret;
 
 	spu_acquire(ctx);
-	ret = __spufs_signal1_type_get(data);
+	ret = __spufs_signal1_type_get(ctx);
 	spu_release(ctx);
 
 	return ret;
@@ -1114,9 +1113,8 @@ static void spufs_signal2_type_set(void *data, u64 val)
 	spu_release(ctx);
 }
 
-static u64 __spufs_signal2_type_get(void *data)
+static u64 __spufs_signal2_type_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	return ctx->ops->signal2_type_get(ctx);
 }
 
@@ -1126,7 +1124,7 @@ static u64 spufs_signal2_type_get(void *data)
 	u64 ret;
 
 	spu_acquire(ctx);
-	ret = __spufs_signal2_type_get(data);
+	ret = __spufs_signal2_type_get(ctx);
 	spu_release(ctx);
 
 	return ret;
@@ -1629,9 +1627,8 @@ static void spufs_decr_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 __spufs_decr_get(void *data)
+static u64 __spufs_decr_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
 	return lscsa->decr.slot[0];
 }
@@ -1641,7 +1638,7 @@ static u64 spufs_decr_get(void *data)
 	struct spu_context *ctx = data;
 	u64 ret;
 	spu_acquire_saved(ctx);
-	ret = __spufs_decr_get(data);
+	ret = __spufs_decr_get(ctx);
 	spu_release_saved(ctx);
 	return ret;
 }
@@ -1659,9 +1656,8 @@ static void spufs_decr_status_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 __spufs_decr_status_get(void *data)
+static u64 __spufs_decr_status_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	if (ctx->csa.priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING)
 		return SPU_DECR_STATUS_RUNNING;
 	else
@@ -1673,7 +1669,7 @@ static u64 spufs_decr_status_get(void *data)
 	struct spu_context *ctx = data;
 	u64 ret;
 	spu_acquire_saved(ctx);
-	ret = __spufs_decr_status_get(data);
+	ret = __spufs_decr_status_get(ctx);
 	spu_release_saved(ctx);
 	return ret;
 }
@@ -1689,9 +1685,8 @@ static void spufs_event_mask_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 __spufs_event_mask_get(void *data)
+static u64 __spufs_event_mask_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
 	return lscsa->event_mask.slot[0];
 }
@@ -1701,16 +1696,15 @@ static u64 spufs_event_mask_get(void *data)
 	struct spu_context *ctx = data;
 	u64 ret;
 	spu_acquire_saved(ctx);
-	ret = __spufs_event_mask_get(data);
+	ret = __spufs_event_mask_get(ctx);
 	spu_release_saved(ctx);
 	return ret;
 }
 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
 			spufs_event_mask_set, "0x%llx\n")
 
-static u64 __spufs_event_status_get(void *data)
+static u64 __spufs_event_status_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	struct spu_state *state = &ctx->csa;
 	u64 stat;
 	stat = state->spu_chnlcnt_RW[0];
@@ -1725,7 +1719,7 @@ static u64 spufs_event_status_get(void *data)
 	u64 ret = 0;
 
 	spu_acquire_saved(ctx);
-	ret = __spufs_event_status_get(data);
+	ret = __spufs_event_status_get(ctx);
 	spu_release_saved(ctx);
 	return ret;
 }
@@ -1770,16 +1764,15 @@ static u64 spufs_id_get(void *data)
 }
 DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
 
-static u64 __spufs_object_id_get(void *data)
+static u64 __spufs_object_id_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	return ctx->object_id;
 }
 
 static u64 spufs_object_id_get(void *data)
 {
 	/* FIXME: Should there really be no locking here? */
-	return __spufs_object_id_get(data);
+	return __spufs_object_id_get((struct spu_context *)data);
 }
 
 static void spufs_object_id_set(void *data, u64 id)
@@ -1791,9 +1784,8 @@ static void spufs_object_id_set(void *data, u64 id)
 DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
 		spufs_object_id_set, "0x%llx\n");
 
-static u64 __spufs_lslr_get(void *data)
+static u64 __spufs_lslr_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	return ctx->csa.priv2.spu_lslr_RW;
 }
 
@@ -1803,7 +1795,7 @@ static u64 spufs_lslr_get(void *data)
 	u64 ret;
 
 	spu_acquire_saved(ctx);
-	ret = __spufs_lslr_get(data);
+	ret = __spufs_lslr_get(ctx);
 	spu_release_saved(ctx);
 
 	return ret;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 3dbffeb..f869a4b 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -296,7 +296,7 @@ struct spufs_coredump_reader {
 	char *name;
 	ssize_t (*read)(struct spu_context *ctx,
 			char __user *buffer, size_t size, loff_t *pos);
-	u64 (*get)(void *data);
+	u64 (*get)(struct spu_context *ctx);
 	size_t size;
 };
 extern struct spufs_coredump_reader spufs_coredump_read[];

^ permalink raw reply related

* [PATCH 09/25] cell: remove DEBUG for spu callbacks
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

We don't want SPE programs to be able to flood the kernel log by
invoking the SPE callback handler, so don't enable DEBUG for
spu_callbacks.c by default.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spu_callbacks.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
index ab39e22..dceb8b6 100644
--- a/arch/powerpc/platforms/cell/spu_callbacks.c
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -2,7 +2,7 @@
  * System call callback functions for SPUs
  */
 
-#define DEBUG
+#undef DEBUG
 
 #include <linux/kallsyms.h>
 #include <linux/module.h>

^ permalink raw reply related

* [PATCH 21/25] spufs: Combine spufs_coredump_calls with spufs_calls
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

Because spufs might be built as a module, we can't have other parts of the
kernel calling directly into it, we need stub routines that check first if the
module is loaded.

Currently we have two structures which hold callbacks for these stubs, the
syscalls are in spufs_calls and the coredump calls are in spufs_coredump_calls.
In both cases the logic for registering/unregistering is essentially the same,
so we can simplify things by combining the two.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

---
 arch/powerpc/platforms/cell/Makefile         |    2 
 arch/powerpc/platforms/cell/spu_coredump.c   |   83 ---------------------------
 arch/powerpc/platforms/cell/spu_syscalls.c   |   30 +++++++++
 arch/powerpc/platforms/cell/spufs/coredump.c |   10 ---
 arch/powerpc/platforms/cell/spufs/inode.c    |    6 -
 arch/powerpc/platforms/cell/spufs/spufs.h    |    4 +
 arch/powerpc/platforms/cell/spufs/syscalls.c |    2 
 include/asm-powerpc/spu.h                    |   12 ---
 8 files changed, 41 insertions(+), 108 deletions(-)

diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 40f78e9..61d12f1 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -19,7 +19,7 @@ spu-manage-$(CONFIG_PPC_CELLEB)		+= spu_manage.o
 spu-manage-$(CONFIG_PPC_CELL_NATIVE)	+= spu_manage.o
 
 obj-$(CONFIG_SPU_BASE)			+= spu_callbacks.o spu_base.o \
-					   spu_coredump.o spu_syscalls.o \
+					   spu_syscalls.o \
 					   $(spu-priv1-y) \
 					   $(spu-manage-y) \
 					   spufs/
diff --git a/arch/powerpc/platforms/cell/spu_coredump.c b/arch/powerpc/platforms/cell/spu_coredump.c
deleted file mode 100644
index 656a8c5..0000000
--- a/arch/powerpc/platforms/cell/spu_coredump.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SPU core dump code
- *
- * (C) Copyright 2006 IBM Corp.
- *
- * Author: Dwayne Grant McConnell <decimal@us.ibm.com>
- *
- * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/file.h>
-#include <linux/module.h>
-#include <linux/syscalls.h>
-
-#include <asm/spu.h>
-
-static struct spu_coredump_calls *spu_coredump_calls;
-static DEFINE_MUTEX(spu_coredump_mutex);
-
-int arch_notes_size(void)
-{
-	int ret;
-
-	mutex_lock(&spu_coredump_mutex);
-
-	if (spu_coredump_calls && try_module_get(spu_coredump_calls->owner)) {
-		ret = spu_coredump_calls->arch_notes_size();
-		module_put(spu_coredump_calls->owner);
-	} else {
-		ret = 0;
-	}
-
-	mutex_unlock(&spu_coredump_mutex);
-
-	return ret;
-}
-
-void arch_write_notes(struct file *file)
-{
-	mutex_lock(&spu_coredump_mutex);
-	if (spu_coredump_calls && try_module_get(spu_coredump_calls->owner)) {
-		spu_coredump_calls->arch_write_notes(file);
-		module_put(spu_coredump_calls->owner);
-	}
-	mutex_unlock(&spu_coredump_mutex);
-}
-
-int register_arch_coredump_calls(struct spu_coredump_calls *calls)
-{
-	int ret = 0;
-
-
-	mutex_lock(&spu_coredump_mutex);
-	if (spu_coredump_calls)
-		ret = -EBUSY;
-	else
-		spu_coredump_calls = calls;
-	mutex_unlock(&spu_coredump_mutex);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(register_arch_coredump_calls);
-
-void unregister_arch_coredump_calls(struct spu_coredump_calls *calls)
-{
-	BUG_ON(spu_coredump_calls != calls);
-
-	mutex_lock(&spu_coredump_mutex);
-	spu_coredump_calls = NULL;
-	mutex_unlock(&spu_coredump_mutex);
-}
-EXPORT_SYMBOL_GPL(unregister_arch_coredump_calls);
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index 76815c5..cf00251 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -2,6 +2,7 @@
  * SPU file system -- system call stubs
  *
  * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ * (C) Copyright 2006-2007, IBM Corporation
  *
  * Author: Arnd Bergmann <arndb@de.ibm.com>
  *
@@ -108,6 +109,35 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
 	return ret;
 }
 
+int arch_notes_size(void)
+{
+	struct spufs_calls *calls;
+	int ret;
+
+	calls = spufs_calls_get();
+	if (!calls)
+		return 0;
+
+	ret = calls->coredump_extra_notes_size();
+
+	spufs_calls_put(calls);
+
+	return ret;
+}
+
+void arch_write_notes(struct file *file)
+{
+	struct spufs_calls *calls;
+
+	calls = spufs_calls_get();
+	if (!calls)
+		return;
+
+	calls->coredump_extra_notes_write(file);
+
+	spufs_calls_put(calls);
+}
+
 int register_spu_syscalls(struct spufs_calls *calls)
 {
 	int ret = 0;
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index fc988fd..6c20e44 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -122,7 +122,7 @@ static struct spu_context *coredump_next_context(int *fd)
 	return ctx;
 }
 
-static int spufs_arch_notes_size(void)
+int spufs_coredump_extra_notes_size(void)
 {
 	struct spu_context *ctx;
 	int size = 0, rc, fd;
@@ -185,7 +185,7 @@ out:
 	free_page((unsigned long)buf);
 }
 
-static void spufs_arch_write_notes(struct file *file)
+void spufs_coredump_extra_notes_write(struct file *file)
 {
 	struct spu_context *ctx;
 	int fd, j;
@@ -200,9 +200,3 @@ static void spufs_arch_write_notes(struct file *file)
 		spu_release_saved(ctx);
 	}
 }
-
-struct spu_coredump_calls spufs_coredump_calls = {
-	.arch_notes_size = spufs_arch_notes_size,
-	.arch_write_notes = spufs_arch_write_notes,
-	.owner = THIS_MODULE,
-};
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index e210a4b..1109874 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -790,16 +790,11 @@ static int __init spufs_init(void)
 	ret = register_spu_syscalls(&spufs_calls);
 	if (ret)
 		goto out_fs;
-	ret = register_arch_coredump_calls(&spufs_coredump_calls);
-	if (ret)
-		goto out_syscalls;
 
 	spufs_init_isolated_loader();
 
 	return 0;
 
-out_syscalls:
-	unregister_spu_syscalls(&spufs_calls);
 out_fs:
 	unregister_filesystem(&spufs_type);
 out_sched:
@@ -815,7 +810,6 @@ static void __exit spufs_exit(void)
 {
 	spu_sched_exit();
 	spufs_exit_isolated_loader();
-	unregister_arch_coredump_calls(&spufs_coredump_calls);
 	unregister_spu_syscalls(&spufs_calls);
 	unregister_filesystem(&spufs_type);
 	kmem_cache_destroy(spufs_inode_cache);
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index f869a4b..c7b4e03 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -204,6 +204,10 @@ extern struct spufs_calls spufs_calls;
 long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
 long spufs_create(struct nameidata *nd, unsigned int flags,
 			mode_t mode, struct file *filp);
+/* ELF coredump callbacks for writing SPU ELF notes */
+extern int spufs_coredump_extra_notes_size(void);
+extern void spufs_coredump_extra_notes_write(struct file *file);
+
 extern const struct file_operations spufs_context_fops;
 
 /* gang management */
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 22b138d..2c34f71 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -84,5 +84,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
 struct spufs_calls spufs_calls = {
 	.create_thread = do_spu_create,
 	.spu_run = do_spu_run,
+	.coredump_extra_notes_size = spufs_coredump_extra_notes_size,
+	.coredump_extra_notes_write = spufs_coredump_extra_notes_write,
 	.owner = THIS_MODULE,
 };
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index eb1159c..f1b10a1 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -244,13 +244,8 @@ struct spufs_calls {
 					struct file *neighbor);
 	long (*spu_run)(struct file *filp, __u32 __user *unpc,
 						__u32 __user *ustatus);
-	struct module *owner;
-};
-
-/* coredump calls implemented in spufs */
-struct spu_coredump_calls {
-	asmlinkage int (*arch_notes_size)(void);
-	asmlinkage void (*arch_write_notes)(struct file *file);
+	int (*coredump_extra_notes_size)(void);
+	void (*coredump_extra_notes_write)(struct file *file);
 	struct module *owner;
 };
 
@@ -277,9 +272,6 @@ struct spu_coredump_calls {
 int register_spu_syscalls(struct spufs_calls *calls);
 void unregister_spu_syscalls(struct spufs_calls *calls);
 
-int register_arch_coredump_calls(struct spu_coredump_calls *calls);
-void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);
-
 int spu_add_sysdev_attr(struct sysdev_attribute *attr);
 void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
 

^ permalink raw reply related

* [PATCH 10/25] spusched: fix null pointer dereference in find_victim
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Christoph Hellwig <hch@lst.de>

find_victim can dereference a NULL pointer when iterating over the list
of victim spus because list_mutex only guarantees spu->ct to be stable,
but of course not to be non-NULL.

Also fix find_victim to not call spu_unbind_context without list_mutex
because that violates the above guarantee.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/sched.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 17806e0..4d257b3 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -594,7 +594,7 @@ static struct spu *find_victim(struct spu_context *ctx)
 		list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
 			struct spu_context *tmp = spu->ctx;
 
-			if (tmp->prio > ctx->prio &&
+			if (tmp && tmp->prio > ctx->prio &&
 			    (!victim || tmp->prio > victim->prio))
 				victim = spu->ctx;
 		}
@@ -626,9 +626,9 @@ static struct spu *find_victim(struct spu_context *ctx)
 
 			mutex_lock(&cbe_spu_info[node].list_mutex);
 			cbe_spu_info[node].nr_active--;
+			spu_unbind_context(spu, victim);
 			mutex_unlock(&cbe_spu_info[node].list_mutex);
 
-			spu_unbind_context(spu, victim);
 			victim->stats.invol_ctx_switch++;
 			spu->stats.invol_ctx_switch++;
 			mutex_unlock(&victim->state_mutex);

^ permalink raw reply related

* [PATCH 23/25] spufs: Handle errors in SPU coredump code, and support coredump to a pipe
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

Rework spufs_coredump_extra_notes_write() to check for and return errors.

If we're coredumping to a pipe we can't trust file->f_pos, we need to
maintain the foffset value passed to us. The cleanest way to do this is
to have the low level write routine increment foffset when we've
successfully written.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spu_syscalls.c   |    8 --
 arch/powerpc/platforms/cell/spufs/coredump.c |   89 ++++++++++++++++++---------
 arch/powerpc/platforms/cell/spufs/spufs.h    |    2 
 include/asm-powerpc/spu.h                    |    2 
 4 files changed, 67 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index d9b2fd2..0b69107 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -129,19 +129,17 @@ int elf_coredump_extra_notes_size(void)
 int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset)
 {
 	struct spufs_calls *calls;
+	int ret;
 
 	calls = spufs_calls_get();
 	if (!calls)
 		return 0;
 
-	calls->coredump_extra_notes_write(file);
+	ret = calls->coredump_extra_notes_write(file, foffset);
 
 	spufs_calls_put(calls);
 
-	/* Fudge foffset for now */
-	*foffset = file->f_pos;
-
-	return 0;
+	return ret;
 }
 
 int register_spu_syscalls(struct spufs_calls *calls)
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 6c20e44..6b8aef6 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -51,19 +51,34 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
  * These are the only things you should do on a core-file: use only these
  * functions to write out all the necessary info.
  */
-static int spufs_dump_write(struct file *file, const void *addr, int nr)
+static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
 {
-	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+	ssize_t written;
+
+	written = file->f_op->write(file, addr, nr, &file->f_pos);
+	*foffset += written;
+
+	if (written != nr)
+		return -EIO;
+
+	return 0;
 }
 
-static int spufs_dump_seek(struct file *file, loff_t off)
+static int spufs_dump_align(struct file *file, char *buf, loff_t new_off,
+			    loff_t *foffset)
 {
-	if (file->f_op->llseek) {
-		if (file->f_op->llseek(file, off, 0) != off)
-			return 0;
-	} else
-		file->f_pos = off;
-	return 1;
+	int rc, size;
+
+	size = min((loff_t)PAGE_SIZE, new_off - *foffset);
+	memset(buf, 0, size);
+
+	rc = 0;
+	while (rc == 0 && new_off > *foffset) {
+		size = min((loff_t)PAGE_SIZE, new_off - *foffset);
+		rc = spufs_dump_write(file, buf, size, foffset);
+	}
+
+	return rc;
 }
 
 static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
@@ -141,11 +156,11 @@ int spufs_coredump_extra_notes_size(void)
 	return size;
 }
 
-static void spufs_arch_write_note(struct spu_context *ctx, int i,
-				struct file *file, int dfd)
+static int spufs_arch_write_note(struct spu_context *ctx, int i,
+				  struct file *file, int dfd, loff_t *foffset)
 {
 	loff_t pos = 0;
-	int sz, rc, total = 0;
+	int sz, rc, nread, total = 0;
 	const int bufsz = PAGE_SIZE;
 	char *name;
 	char fullname[80], *buf;
@@ -153,7 +168,7 @@ static void spufs_arch_write_note(struct spu_context *ctx, int i,
 
 	buf = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!buf)
-		return;
+		return -ENOMEM;
 
 	name = spufs_coredump_read[i].name;
 	sz = spufs_coredump_read[i].size;
@@ -163,40 +178,60 @@ static void spufs_arch_write_note(struct spu_context *ctx, int i,
 	en.n_descsz = sz;
 	en.n_type = NT_SPU;
 
-	if (!spufs_dump_write(file, &en, sizeof(en)))
+	rc = spufs_dump_write(file, &en, sizeof(en), foffset);
+	if (rc)
 		goto out;
-	if (!spufs_dump_write(file, fullname, en.n_namesz))
+
+	rc = spufs_dump_write(file, fullname, en.n_namesz, foffset);
+	if (rc)
 		goto out;
-	if (!spufs_dump_seek(file, roundup((unsigned long)file->f_pos, 4)))
+
+	rc = spufs_dump_align(file, buf, roundup(*foffset, 4), foffset);
+	if (rc)
 		goto out;
 
 	do {
-		rc = do_coredump_read(i, ctx, buf, bufsz, &pos);
-		if (rc > 0) {
-			if (!spufs_dump_write(file, buf, rc))
+		nread = do_coredump_read(i, ctx, buf, bufsz, &pos);
+		if (nread > 0) {
+			rc = spufs_dump_write(file, buf, nread, foffset);
+			if (rc)
 				goto out;
-			total += rc;
+			total += nread;
 		}
-	} while (rc == bufsz && total < sz);
+	} while (nread == bufsz && total < sz);
+
+	if (nread < 0) {
+		rc = nread;
+		goto out;
+	}
+
+	rc = spufs_dump_align(file, buf, roundup(*foffset - total + sz, 4),
+			      foffset);
 
-	spufs_dump_seek(file, roundup((unsigned long)file->f_pos
-						- total + sz, 4));
 out:
 	free_page((unsigned long)buf);
+	return rc;
 }
 
-void spufs_coredump_extra_notes_write(struct file *file)
+int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset)
 {
 	struct spu_context *ctx;
-	int fd, j;
+	int fd, j, rc;
 
 	fd = 0;
 	while ((ctx = coredump_next_context(&fd)) != NULL) {
 		spu_acquire_saved(ctx);
 
-		for (j = 0; spufs_coredump_read[j].name != NULL; j++)
-			spufs_arch_write_note(ctx, j, file, fd);
+		for (j = 0; spufs_coredump_read[j].name != NULL; j++) {
+			rc = spufs_arch_write_note(ctx, j, file, fd, foffset);
+			if (rc) {
+				spu_release_saved(ctx);
+				return rc;
+			}
+		}
 
 		spu_release_saved(ctx);
 	}
+
+	return 0;
 }
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index c7b4e03..ca47b99 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -206,7 +206,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags,
 			mode_t mode, struct file *filp);
 /* ELF coredump callbacks for writing SPU ELF notes */
 extern int spufs_coredump_extra_notes_size(void);
-extern void spufs_coredump_extra_notes_write(struct file *file);
+extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset);
 
 extern const struct file_operations spufs_context_fops;
 
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index f1b10a1..b1accce 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -245,7 +245,7 @@ struct spufs_calls {
 	long (*spu_run)(struct file *filp, __u32 __user *unpc,
 						__u32 __user *ustatus);
 	int (*coredump_extra_notes_size)(void);
-	void (*coredump_extra_notes_write)(struct file *file);
+	int (*coredump_extra_notes_write)(struct file *file, loff_t *foffset);
 	struct module *owner;
 };
 

^ permalink raw reply related

* [PATCH 12/25] spufs: Remove ctx_info and ctx_info_list
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

Remove the ctx_info struct entirely, and also the ctx_info_list. This fixes
a race where two processes can clobber each other's ctx_info structs.

Instead of using the list, we just repeat the search through the file
descriptor table.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/coredump.c |   79 ++++++---------------------
 1 file changed, 19 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 99f8e0b..6663669 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -31,15 +31,6 @@
 
 #include "spufs.h"
 
-struct spufs_ctx_info {
-	struct list_head list;
-	int dfd;
-	int memsize; /* in bytes */
-	struct spu_context *ctx;
-};
-
-static LIST_HEAD(ctx_info_list);
-
 static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *buffer,
 				size_t size, loff_t *off)
 {
@@ -73,25 +64,17 @@ static int spufs_dump_seek(struct file *file, loff_t off)
 	return 1;
 }
 
-static void spufs_fill_memsize(struct spufs_ctx_info *ctx_info)
+static u64 ctx_ls_size(struct spu_context *ctx)
 {
-	struct spu_context *ctx;
-	unsigned long long lslr;
-
-	ctx = ctx_info->ctx;
-	lslr = ctx->csa.priv2.spu_lslr_RW;
-	ctx_info->memsize = lslr + 1;
+	return ctx->csa.priv2.spu_lslr_RW + 1;
 }
 
-static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
+static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
 {
-	int dfd, memsize, i, sz, total = 0;
+	int i, sz, total = 0;
 	char *name;
 	char fullname[80];
 
-	dfd = ctx_info->dfd;
-	memsize = ctx_info->memsize;
-
 	for (i = 0; spufs_coredump_read[i].name; i++) {
 		name = spufs_coredump_read[i].name;
 		sz = spufs_coredump_read[i].size;
@@ -101,7 +84,7 @@ static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
 		total += sizeof(struct elf_note);
 		total += roundup(strlen(fullname) + 1, 4);
 		if (!strcmp(name, "mem"))
-			total += roundup(memsize, 4);
+			total += roundup(ctx_ls_size(ctx), 4);
 		else
 			total += roundup(sz, 4);
 	}
@@ -109,25 +92,6 @@ static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
 	return total;
 }
 
-static int spufs_add_one_context(struct spu_context *ctx, int dfd)
-{
-	struct spufs_ctx_info *ctx_info;
-	int size;
-
-	ctx_info = kzalloc(sizeof(*ctx_info), GFP_KERNEL);
-	if (unlikely(!ctx_info))
-		return -ENOMEM;
-
-	ctx_info->dfd = dfd;
-	ctx_info->ctx = ctx;
-
-	spufs_fill_memsize(ctx_info);
-
-	size = spufs_ctx_note_size(ctx_info);
-	list_add(&ctx_info->list, &ctx_info_list);
-	return size;
-}
-
 /*
  * The additional architecture-specific notes for Cell are various
  * context files in the spu context.
@@ -171,7 +135,7 @@ static int spufs_arch_notes_size(void)
 
 	fd = 0;
 	while ((ctx = coredump_next_context(&fd)) != NULL) {
-		rc = spufs_add_one_context(ctx, fd);
+		rc = spufs_ctx_note_size(ctx, fd);
 		if (rc < 0)
 			break;
 
@@ -181,12 +145,11 @@ static int spufs_arch_notes_size(void)
 	return size;
 }
 
-static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i,
-				struct file *file)
+static void spufs_arch_write_note(struct spu_context *ctx, int i,
+				struct file *file, int dfd)
 {
-	struct spu_context *ctx;
 	loff_t pos = 0;
-	int sz, dfd, rc, total = 0;
+	int sz, rc, total = 0;
 	const int bufsz = PAGE_SIZE;
 	char *name;
 	char fullname[80], *buf;
@@ -196,18 +159,13 @@ static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i,
 	if (!buf)
 		return;
 
-	dfd = ctx_info->dfd;
 	name = spufs_coredump_read[i].name;
 
 	if (!strcmp(name, "mem"))
-		sz = ctx_info->memsize;
+		sz = ctx_ls_size(ctx);
 	else
 		sz = spufs_coredump_read[i].size;
 
-	ctx = ctx_info->ctx;
-	if (!ctx)
-		goto out;
-
 	sprintf(fullname, "SPU/%d/%s", dfd, name);
 	en.n_namesz = strlen(fullname) + 1;
 	en.n_descsz = sz;
@@ -237,16 +195,17 @@ out:
 
 static void spufs_arch_write_notes(struct file *file)
 {
-	int j;
-	struct spufs_ctx_info *ctx_info, *next;
+	struct spu_context *ctx;
+	int fd, j;
+
+	fd = 0;
+	while ((ctx = coredump_next_context(&fd)) != NULL) {
+		spu_acquire_saved(ctx);
 
-	list_for_each_entry_safe(ctx_info, next, &ctx_info_list, list) {
-		spu_acquire_saved(ctx_info->ctx);
 		for (j = 0; j < spufs_coredump_num_notes; j++)
-			spufs_arch_write_note(ctx_info, j, file);
-		spu_release_saved(ctx_info->ctx);
-		list_del(&ctx_info->list);
-		kfree(ctx_info);
+			spufs_arch_write_note(ctx, j, file, fd);
+
+		spu_release_saved(ctx);
 	}
 }
 

^ permalink raw reply related

* [PATCH 25/25] spufs: Add DEFINE_SPUFS_ATTRIBUTE()
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

This patch adds DEFINE_SPUFS_ATTRIBUTE(), a wraper around
DEFINE_SIMPLE_ATTRIBUTE which does the specified locking for the get
routine for us.

Unfortunately we need two get routines (a locked and unlocked version) to
support the coredump code. This patch hides one of those (the locked version)
inside the macro foo.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/file.c |  216 ++++++++++---------------------
 1 file changed, 76 insertions(+), 140 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 985c86b..b93a027 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1076,6 +1076,36 @@ static const struct file_operations spufs_signal2_nosched_fops = {
 	.mmap = spufs_signal2_mmap,
 };
 
+/*
+ * This is a wrapper around DEFINE_SIMPLE_ATTRIBUTE which does the
+ * work of acquiring (or not) the SPU context before calling through
+ * to the actual get routine. The set routine is called directly.
+ */
+#define SPU_ATTR_NOACQUIRE	0
+#define SPU_ATTR_ACQUIRE	1
+#define SPU_ATTR_ACQUIRE_SAVED	2
+
+#define DEFINE_SPUFS_ATTRIBUTE(__name, __get, __set, __fmt, __acquire)	\
+static u64 __##__get(void *data)					\
+{									\
+	struct spu_context *ctx = data;					\
+	u64 ret;							\
+									\
+	if (__acquire == SPU_ATTR_ACQUIRE) {				\
+		spu_acquire(ctx);					\
+		ret = __get(ctx);					\
+		spu_release(ctx);					\
+	} else if (__acquire == SPU_ATTR_ACQUIRE_SAVED)	{		\
+		spu_acquire_saved(ctx);					\
+		ret = __get(ctx);					\
+		spu_release_saved(ctx);					\
+	} else								\
+		ret = __get(ctx);					\
+									\
+	return ret;							\
+}									\
+DEFINE_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
+
 static void spufs_signal1_type_set(void *data, u64 val)
 {
 	struct spu_context *ctx = data;
@@ -1085,24 +1115,13 @@ static void spufs_signal1_type_set(void *data, u64 val)
 	spu_release(ctx);
 }
 
-static u64 __spufs_signal1_type_get(struct spu_context *ctx)
+static u64 spufs_signal1_type_get(struct spu_context *ctx)
 {
 	return ctx->ops->signal1_type_get(ctx);
 }
+DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
+		       spufs_signal1_type_set, "%llu", SPU_ATTR_ACQUIRE);
 
-static u64 spufs_signal1_type_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-
-	spu_acquire(ctx);
-	ret = __spufs_signal1_type_get(ctx);
-	spu_release(ctx);
-
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
-					spufs_signal1_type_set, "%llu");
 
 static void spufs_signal2_type_set(void *data, u64 val)
 {
@@ -1113,24 +1132,12 @@ static void spufs_signal2_type_set(void *data, u64 val)
 	spu_release(ctx);
 }
 
-static u64 __spufs_signal2_type_get(struct spu_context *ctx)
+static u64 spufs_signal2_type_get(struct spu_context *ctx)
 {
 	return ctx->ops->signal2_type_get(ctx);
 }
-
-static u64 spufs_signal2_type_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-
-	spu_acquire(ctx);
-	ret = __spufs_signal2_type_get(ctx);
-	spu_release(ctx);
-
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
-					spufs_signal2_type_set, "%llu");
+DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
+		       spufs_signal2_type_set, "%llu", SPU_ATTR_ACQUIRE);
 
 #if SPUFS_MMAP_4K
 static unsigned long spufs_mss_mmap_nopfn(struct vm_area_struct *vma,
@@ -1606,22 +1613,12 @@ static void spufs_npc_set(void *data, u64 val)
 	spu_release(ctx);
 }
 
-static u64 __spufs_npc_get(struct spu_context *ctx)
+static u64 spufs_npc_get(struct spu_context *ctx)
 {
 	return ctx->ops->npc_read(ctx);
 }
-
-static u64 spufs_npc_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-	spu_acquire(ctx);
-	ret = __spufs_npc_get(ctx);
-	spu_release(ctx);
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
-			"0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
+		       "0x%llx\n", SPU_ATTR_ACQUIRE);
 
 static void spufs_decr_set(void *data, u64 val)
 {
@@ -1632,23 +1629,13 @@ static void spufs_decr_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 __spufs_decr_get(struct spu_context *ctx)
+static u64 spufs_decr_get(struct spu_context *ctx)
 {
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
 	return lscsa->decr.slot[0];
 }
-
-static u64 spufs_decr_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-	spu_acquire_saved(ctx);
-	ret = __spufs_decr_get(ctx);
-	spu_release_saved(ctx);
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
-			"0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
+		       "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED);
 
 static void spufs_decr_status_set(void *data, u64 val)
 {
@@ -1661,25 +1648,16 @@ static void spufs_decr_status_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 __spufs_decr_status_get(struct spu_context *ctx)
+static u64 spufs_decr_status_get(struct spu_context *ctx)
 {
 	if (ctx->csa.priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING)
 		return SPU_DECR_STATUS_RUNNING;
 	else
 		return 0;
 }
-
-static u64 spufs_decr_status_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-	spu_acquire_saved(ctx);
-	ret = __spufs_decr_status_get(ctx);
-	spu_release_saved(ctx);
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
-			spufs_decr_status_set, "0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
+		       spufs_decr_status_set, "0x%llx\n",
+		       SPU_ATTR_ACQUIRE_SAVED);
 
 static void spufs_event_mask_set(void *data, u64 val)
 {
@@ -1690,25 +1668,17 @@ static void spufs_event_mask_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 __spufs_event_mask_get(struct spu_context *ctx)
+static u64 spufs_event_mask_get(struct spu_context *ctx)
 {
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
 	return lscsa->event_mask.slot[0];
 }
 
-static u64 spufs_event_mask_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-	spu_acquire_saved(ctx);
-	ret = __spufs_event_mask_get(ctx);
-	spu_release_saved(ctx);
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
-			spufs_event_mask_set, "0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
+		       spufs_event_mask_set, "0x%llx\n",
+		       SPU_ATTR_ACQUIRE_SAVED);
 
-static u64 __spufs_event_status_get(struct spu_context *ctx)
+static u64 spufs_event_status_get(struct spu_context *ctx)
 {
 	struct spu_state *state = &ctx->csa;
 	u64 stat;
@@ -1717,19 +1687,8 @@ static u64 __spufs_event_status_get(struct spu_context *ctx)
 		return state->spu_chnldata_RW[0];
 	return 0;
 }
-
-static u64 spufs_event_status_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret = 0;
-
-	spu_acquire_saved(ctx);
-	ret = __spufs_event_status_get(ctx);
-	spu_release_saved(ctx);
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
-			NULL, "0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
+		       NULL, "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED)
 
 static void spufs_srr0_set(void *data, u64 val)
 {
@@ -1740,44 +1699,32 @@ static void spufs_srr0_set(void *data, u64 val)
 	spu_release_saved(ctx);
 }
 
-static u64 spufs_srr0_get(void *data)
+static u64 spufs_srr0_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
-	u64 ret;
-	spu_acquire_saved(ctx);
-	ret = lscsa->srr0.slot[0];
-	spu_release_saved(ctx);
-	return ret;
+	return lscsa->srr0.slot[0];
 }
-DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
-			"0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
+		       "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED)
 
-static u64 spufs_id_get(void *data)
+static u64 spufs_id_get(struct spu_context *ctx)
 {
-	struct spu_context *ctx = data;
 	u64 num;
 
-	spu_acquire(ctx);
 	if (ctx->state == SPU_STATE_RUNNABLE)
 		num = ctx->spu->number;
 	else
 		num = (unsigned int)-1;
-	spu_release(ctx);
 
 	return num;
 }
-DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n",
+		       SPU_ATTR_ACQUIRE)
 
-static u64 __spufs_object_id_get(struct spu_context *ctx)
-{
-	return ctx->object_id;
-}
-
-static u64 spufs_object_id_get(void *data)
+static u64 spufs_object_id_get(struct spu_context *ctx)
 {
 	/* FIXME: Should there really be no locking here? */
-	return __spufs_object_id_get((struct spu_context *)data);
+	return ctx->object_id;
 }
 
 static void spufs_object_id_set(void *data, u64 id)
@@ -1786,26 +1733,15 @@ static void spufs_object_id_set(void *data, u64 id)
 	ctx->object_id = id;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
-		spufs_object_id_set, "0x%llx\n");
+DEFINE_SPUFS_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
+		       spufs_object_id_set, "0x%llx\n", SPU_ATTR_NOACQUIRE);
 
-static u64 __spufs_lslr_get(struct spu_context *ctx)
+static u64 spufs_lslr_get(struct spu_context *ctx)
 {
 	return ctx->csa.priv2.spu_lslr_RW;
 }
-
-static u64 spufs_lslr_get(void *data)
-{
-	struct spu_context *ctx = data;
-	u64 ret;
-
-	spu_acquire_saved(ctx);
-	ret = __spufs_lslr_get(ctx);
-	spu_release_saved(ctx);
-
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n")
+DEFINE_SPUFS_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n",
+		       SPU_ATTR_ACQUIRE_SAVED);
 
 static int spufs_info_open(struct inode *inode, struct file *file)
 {
@@ -2230,23 +2166,23 @@ struct tree_descr spufs_dir_nosched_contents[] = {
 struct spufs_coredump_reader spufs_coredump_read[] = {
 	{ "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])},
 	{ "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) },
-	{ "lslr", NULL, __spufs_lslr_get, 19 },
-	{ "decr", NULL, __spufs_decr_get, 19 },
-	{ "decr_status", NULL, __spufs_decr_status_get, 19 },
+	{ "lslr", NULL, spufs_lslr_get, 19 },
+	{ "decr", NULL, spufs_decr_get, 19 },
+	{ "decr_status", NULL, spufs_decr_status_get, 19 },
 	{ "mem", __spufs_mem_read, NULL, LS_SIZE, },
 	{ "signal1", __spufs_signal1_read, NULL, sizeof(u32) },
-	{ "signal1_type", NULL, __spufs_signal1_type_get, 19 },
+	{ "signal1_type", NULL, spufs_signal1_type_get, 19 },
 	{ "signal2", __spufs_signal2_read, NULL, sizeof(u32) },
-	{ "signal2_type", NULL, __spufs_signal2_type_get, 19 },
-	{ "event_mask", NULL, __spufs_event_mask_get, 19 },
-	{ "event_status", NULL, __spufs_event_status_get, 19 },
+	{ "signal2_type", NULL, spufs_signal2_type_get, 19 },
+	{ "event_mask", NULL, spufs_event_mask_get, 19 },
+	{ "event_status", NULL, spufs_event_status_get, 19 },
 	{ "mbox_info", __spufs_mbox_info_read, NULL, sizeof(u32) },
 	{ "ibox_info", __spufs_ibox_info_read, NULL, sizeof(u32) },
 	{ "wbox_info", __spufs_wbox_info_read, NULL, 4 * sizeof(u32)},
 	{ "dma_info", __spufs_dma_info_read, NULL, sizeof(struct spu_dma_info)},
 	{ "proxydma_info", __spufs_proxydma_info_read,
 			   NULL, sizeof(struct spu_proxydma_info)},
-	{ "object-id", NULL, __spufs_object_id_get, 19 },
-	{ "npc", NULL, __spufs_npc_get, 19 },
+	{ "object-id", NULL, spufs_object_id_get, 19 },
+	{ "npc", NULL, spufs_npc_get, 19 },
 	{ NULL },
 };

^ permalink raw reply related

* [PATCH 02/25] spufs: remove asmlinkage from do_spu_create
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

do_spu_create doesn't need the asmlinkage qualifier; remove it.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/syscalls.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 3d8c328..936e0a8 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -76,8 +76,8 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
 }
 #endif
 
-static asmlinkage long do_spu_create(const char __user *pathname,
-		unsigned int flags, mode_t mode, struct file *neighbor)
+static long do_spu_create(const char __user *pathname, unsigned int flags,
+		mode_t mode, struct file *neighbor)
 {
 	char *tmp;
 	int ret;

^ permalink raw reply related

* [PATCH 14/25] spufs: Use computed sizes/#defines rather than literals in SPU coredump code
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

The spufs_coredump_reader array contains the size of the data that will be
returned by the read routine. Currently these are specified as literals, and
though some are obvious, sizeof(u32) == 4, others are not, 69 * 8 ==  ???

Instead, use sizeof() whatever type is returned by each routine, or in
the case of spufs_mem_read() the #define LS_SIZE.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/file.c |   21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index a4a8770..18ddde8 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2231,23 +2231,24 @@ struct tree_descr spufs_dir_nosched_contents[] = {
 };
 
 struct spufs_coredump_reader spufs_coredump_read[] = {
-	{ "regs", __spufs_regs_read, NULL, 128 * 16 },
-	{ "fpcr", __spufs_fpcr_read, NULL, 16 },
+	{ "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])},
+	{ "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) },
 	{ "lslr", NULL, __spufs_lslr_get, 11 },
 	{ "decr", NULL, __spufs_decr_get, 11 },
 	{ "decr_status", NULL, __spufs_decr_status_get, 11 },
-	{ "mem", __spufs_mem_read, NULL, 256 * 1024, },
-	{ "signal1", __spufs_signal1_read, NULL, 4 },
+	{ "mem", __spufs_mem_read, NULL, LS_SIZE, },
+	{ "signal1", __spufs_signal1_read, NULL, sizeof(u32) },
 	{ "signal1_type", NULL, __spufs_signal1_type_get, 2 },
-	{ "signal2", __spufs_signal2_read, NULL, 4 },
+	{ "signal2", __spufs_signal2_read, NULL, sizeof(u32) },
 	{ "signal2_type", NULL, __spufs_signal2_type_get, 2 },
 	{ "event_mask", NULL, __spufs_event_mask_get, 8 },
 	{ "event_status", NULL, __spufs_event_status_get, 8 },
-	{ "mbox_info", __spufs_mbox_info_read, NULL, 4 },
-	{ "ibox_info", __spufs_ibox_info_read, NULL, 4 },
-	{ "wbox_info", __spufs_wbox_info_read, NULL, 16 },
-	{ "dma_info", __spufs_dma_info_read, NULL, 69 * 8 },
-	{ "proxydma_info", __spufs_proxydma_info_read, NULL, 35 * 8 },
+	{ "mbox_info", __spufs_mbox_info_read, NULL, sizeof(u32) },
+	{ "ibox_info", __spufs_ibox_info_read, NULL, sizeof(u32) },
+	{ "wbox_info", __spufs_wbox_info_read, NULL, 4 * sizeof(u32)},
+	{ "dma_info", __spufs_dma_info_read, NULL, sizeof(struct spu_dma_info)},
+	{ "proxydma_info", __spufs_proxydma_info_read,
+			   NULL, sizeof(struct spu_proxydma_info)},
 	{ "object-id", NULL, __spufs_object_id_get, 19 },
 	{ },
 };

^ permalink raw reply related

* [PATCH 04/25] spufs: make isolated loader properly aligned
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Sebastian Siewior <cbe-oss-dev@ml.breakpoint.cc>

According to the comment in spufs_init_isolated_loader(), the isolated
loader should be aligned on a 16 byte boundary.
ARCH_{KMALLOC,SLAB}_MINALIGN is not defined so only 8 byte alignment is
guaranteed.

This patch enforces alignment via __get_free_pages.

Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/inode.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index b3d0dd1..e210a4b 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -43,6 +43,7 @@
 
 static struct kmem_cache *spufs_inode_cache;
 char *isolated_loader;
+static int isolated_loader_size;
 
 static struct inode *
 spufs_alloc_inode(struct super_block *sb)
@@ -667,7 +668,8 @@ spufs_parse_options(char *options, struct inode *root)
 
 static void spufs_exit_isolated_loader(void)
 {
-	kfree(isolated_loader);
+	free_pages((unsigned long) isolated_loader,
+			get_order(isolated_loader_size));
 }
 
 static void
@@ -685,11 +687,12 @@ spufs_init_isolated_loader(void)
 	if (!loader)
 		return;
 
-	/* kmalloc should align on a 16 byte boundary..* */
-	isolated_loader = kmalloc(size, GFP_KERNEL);
+	/* the loader must be align on a 16 byte boundary */
+	isolated_loader = (char *)__get_free_pages(GFP_KERNEL, get_order(size));
 	if (!isolated_loader)
 		return;
 
+	isolated_loader_size = size;
 	memcpy(isolated_loader, loader, size);
 	printk(KERN_INFO "spufs: SPU isolation mode enabled\n");
 }

^ permalink raw reply related

* [PATCH 13/25] spufs: Call spu_acquire_saved() before calculating the SPU note sizes
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

It makes sense to stop the SPU processes as soon as possible. Also if we
dont acquire_saved() I think there's a possibility that the value in
csa.priv2.spu_lslr_RW won't be accurate.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/coredump.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 6663669..21283f6 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -135,7 +135,9 @@ static int spufs_arch_notes_size(void)
 
 	fd = 0;
 	while ((ctx = coredump_next_context(&fd)) != NULL) {
+		spu_acquire_saved(ctx);
 		rc = spufs_ctx_note_size(ctx, fd);
+		spu_release_saved(ctx);
 		if (rc < 0)
 			break;
 

^ permalink raw reply related

* [PATCH 06/25] cell: unify spufs syscall path
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.

This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later. We also add a mutex to protect the
spufs_calls struct, so that accesses to the calls don't race with
{,un}register_spu_calls.

Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.

Before:
	[jk@cell ~]$ time ./spu_create
	performing 65536 spu_create calls

	real    0m24.075s
	user    0m0.146s
	sys     0m23.925s

After:
	[jk@cell ~]$ time ./spu_create
	performing 65536 spu_create calls

	real    0m24.777s
	user    0m0.141s
	sys     0m24.631s

So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/Makefile         |    4 
 arch/powerpc/platforms/cell/spu_syscalls.c   |  117 +++++++++++++++++----------
 arch/powerpc/platforms/cell/spufs/spufs.h    |    1 
 arch/powerpc/platforms/cell/spufs/syscalls.c |   42 ---------
 include/asm-powerpc/spu.h                    |   14 ---
 5 files changed, 78 insertions(+), 100 deletions(-)

diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index f88a7c7..40f78e9 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -13,15 +13,13 @@ obj-$(CONFIG_PPC_CELL_NATIVE)		+= smp.o
 endif
 
 # needed only when building loadable spufs.ko
-spufs-modular-$(CONFIG_SPU_FS)		+= spu_syscalls.o
 spu-priv1-$(CONFIG_PPC_CELL_NATIVE)	+= spu_priv1_mmio.o
 
 spu-manage-$(CONFIG_PPC_CELLEB)		+= spu_manage.o
 spu-manage-$(CONFIG_PPC_CELL_NATIVE)	+= spu_manage.o
 
 obj-$(CONFIG_SPU_BASE)			+= spu_callbacks.o spu_base.o \
-					   spu_coredump.o \
-					   $(spufs-modular-m) \
+					   spu_coredump.o spu_syscalls.o \
 					   $(spu-priv1-y) \
 					   $(spu-manage-y) \
 					   spufs/
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index 027ac32..76815c5 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -22,42 +22,67 @@
 #include <linux/file.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
+#include <linux/mutex.h>
 
 #include <asm/spu.h>
 
-struct spufs_calls spufs_calls = {
-	.owner = NULL,
-};
+static struct spufs_calls *spufs_calls;
+DEFINE_MUTEX(spufs_calls_mutex);
 
-/* These stub syscalls are needed to have the actual implementation
- * within a loadable module. When spufs is built into the kernel,
- * this file is not used and the syscalls directly enter the fs code */
+#ifdef CONFIG_SPU_FS_MODULE
+
+static inline struct spufs_calls *spufs_calls_get(void)
+{
+	struct spufs_calls *calls = NULL;
+
+	mutex_lock(&spufs_calls_mutex);
+	if (spufs_calls && try_module_get(spufs_calls->owner))
+		calls = spufs_calls;
+	mutex_unlock(&spufs_calls_mutex);
+
+	return calls;
+}
+
+static inline void spufs_calls_put(struct spufs_calls *calls)
+{
+	BUG_ON(calls != spufs_calls);
+	module_put(calls->owner);
+}
+
+#else /* !defined CONFIG_SPU_FS_MODULE */
+
+static inline struct spufs_calls *spufs_calls_get(void)
+{
+	return spufs_calls;
+}
+
+static inline void spufs_calls_put(struct spufs_calls *calls) { }
+
+#endif /* CONFIG_SPU_FS_MODULE */
 
 asmlinkage long sys_spu_create(const char __user *name,
 		unsigned int flags, mode_t mode, int neighbor_fd)
 {
 	long ret;
-	struct module *owner = spufs_calls.owner;
 	struct file *neighbor;
 	int fput_needed;
+	struct spufs_calls *calls;
 
-	ret = -ENOSYS;
-	if (owner && try_module_get(owner)) {
-		if (flags & SPU_CREATE_AFFINITY_SPU) {
-			neighbor = fget_light(neighbor_fd, &fput_needed);
-			ret = -EBADF;
-			if (neighbor) {
-				ret = spufs_calls.create_thread(name, flags,
-								mode, neighbor);
-				fput_light(neighbor, fput_needed);
-			}
-		}
-		else {
-			ret = spufs_calls.create_thread(name, flags,
-							mode, NULL);
+	calls = spufs_calls_get();
+	if (!calls)
+		return -ENOSYS;
+
+	if (flags & SPU_CREATE_AFFINITY_SPU) {
+		ret = -EBADF;
+		neighbor = fget_light(neighbor_fd, &fput_needed);
+		if (neighbor) {
+			ret = calls->create_thread(name, flags, mode, neighbor);
+			fput_light(neighbor, fput_needed);
 		}
-		module_put(owner);
-	}
+	} else
+		ret = calls->create_thread(name, flags, mode, NULL);
+
+	spufs_calls_put(calls);
 	return ret;
 }
 
@@ -66,37 +91,43 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
 	long ret;
 	struct file *filp;
 	int fput_needed;
-	struct module *owner = spufs_calls.owner;
+	struct spufs_calls *calls;
 
-	ret = -ENOSYS;
-	if (owner && try_module_get(owner)) {
-		ret = -EBADF;
-		filp = fget_light(fd, &fput_needed);
-		if (filp) {
-			ret = spufs_calls.spu_run(filp, unpc, ustatus);
-			fput_light(filp, fput_needed);
-		}
-		module_put(owner);
+	calls = spufs_calls_get();
+	if (!calls)
+		return -ENOSYS;
+
+	ret = -EBADF;
+	filp = fget_light(fd, &fput_needed);
+	if (filp) {
+		ret = calls->spu_run(filp, unpc, ustatus);
+		fput_light(filp, fput_needed);
 	}
+
+	spufs_calls_put(calls);
 	return ret;
 }
 
 int register_spu_syscalls(struct spufs_calls *calls)
 {
-	if (spufs_calls.owner)
-		return -EBUSY;
-
-	spufs_calls.create_thread = calls->create_thread;
-	spufs_calls.spu_run = calls->spu_run;
-	smp_mb();
-	spufs_calls.owner = calls->owner;
-	return 0;
+	int ret = 0;
+
+	mutex_lock(&spufs_calls_mutex);
+	if (!spufs_calls)
+		spufs_calls = calls;
+	else
+		ret = -EBUSY;
+	mutex_unlock(&spufs_calls_mutex);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(register_spu_syscalls);
 
 void unregister_spu_syscalls(struct spufs_calls *calls)
 {
-	BUG_ON(spufs_calls.owner != calls->owner);
-	spufs_calls.owner = NULL;
+	mutex_lock(&spufs_calls_mutex);
+	BUG_ON(spufs_calls->owner != calls->owner);
+	spufs_calls = NULL;
+	mutex_unlock(&spufs_calls_mutex);
 }
 EXPORT_SYMBOL_GPL(unregister_spu_syscalls);
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 2bfdeb8..3dbffeb 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -200,6 +200,7 @@ extern struct tree_descr spufs_dir_contents[];
 extern struct tree_descr spufs_dir_nosched_contents[];
 
 /* system call implementation */
+extern struct spufs_calls spufs_calls;
 long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
 long spufs_create(struct nameidata *nd, unsigned int flags,
 			mode_t mode, struct file *filp);
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 936e0a8..22b138d 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -58,24 +58,6 @@ out:
 	return ret;
 }
 
-#ifndef MODULE
-asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
-{
-	int fput_needed;
-	struct file *filp;
-	long ret;
-
-	ret = -EBADF;
-	filp = fget_light(fd, &fput_needed);
-	if (filp) {
-		ret = do_spu_run(filp, unpc, ustatus);
-		fput_light(filp, fput_needed);
-	}
-
-	return ret;
-}
-#endif
-
 static long do_spu_create(const char __user *pathname, unsigned int flags,
 		mode_t mode, struct file *neighbor)
 {
@@ -99,30 +81,6 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
 	return ret;
 }
 
-#ifndef MODULE
-asmlinkage long sys_spu_create(const char __user *pathname, unsigned int flags,
-				mode_t mode, int neighbor_fd)
-{
-	int fput_needed;
-	struct file *neighbor;
-	long ret;
-
-	if (flags & SPU_CREATE_AFFINITY_SPU) {
-		ret = -EBADF;
-		neighbor = fget_light(neighbor_fd, &fput_needed);
-		if (neighbor) {
-			ret = do_spu_create(pathname, flags, mode, neighbor);
-			fput_light(neighbor, fput_needed);
-		}
-	}
-	else {
-		ret = do_spu_create(pathname, flags, mode, NULL);
-	}
-
-	return ret;
-}
-#endif
-
 struct spufs_calls spufs_calls = {
 	.create_thread = do_spu_create,
 	.spu_run = do_spu_run,
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index 5bde398..383ecfd 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -238,14 +238,14 @@ extern long spu_sys_callback(struct spu_syscall_block *s);
 
 /* syscalls implemented in spufs */
 struct file;
-extern struct spufs_calls {
+struct spufs_calls {
 	asmlinkage long (*create_thread)(const char __user *name,
 					unsigned int flags, mode_t mode,
 					struct file *neighbor);
 	asmlinkage long (*spu_run)(struct file *filp, __u32 __user *unpc,
 						__u32 __user *ustatus);
 	struct module *owner;
-} spufs_calls;
+};
 
 /* coredump calls implemented in spufs */
 struct spu_coredump_calls {
@@ -274,18 +274,8 @@ struct spu_coredump_calls {
 #define SPU_CREATE_FLAG_ALL		0x003f /* mask of all valid flags */
 
 
-#ifdef CONFIG_SPU_FS_MODULE
 int register_spu_syscalls(struct spufs_calls *calls);
 void unregister_spu_syscalls(struct spufs_calls *calls);
-#else
-static inline int register_spu_syscalls(struct spufs_calls *calls)
-{
-	return 0;
-}
-static inline void unregister_spu_syscalls(struct spufs_calls *calls)
-{
-}
-#endif /* MODULE */
 
 int register_arch_coredump_calls(struct spu_coredump_calls *calls);
 void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);

^ permalink raw reply related

* [PATCH 16/25] spufs: Correctly calculate the size of the local-store to dump
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

The routine to dump the local store, __spufs_mem_read(), does not take the
spu_lslr_RW value into account - so we shouldn't check it when we're
calculating the size either.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

---
 arch/powerpc/platforms/cell/spufs/coredump.c |   16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index c65b717..52d6219 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -66,11 +66,6 @@ static int spufs_dump_seek(struct file *file, loff_t off)
 	return 1;
 }
 
-static u64 ctx_ls_size(struct spu_context *ctx)
-{
-	return ctx->csa.priv2.spu_lslr_RW + 1;
-}
-
 static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
 {
 	int i, sz, total = 0;
@@ -85,10 +80,7 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
 
 		total += sizeof(struct elf_note);
 		total += roundup(strlen(fullname) + 1, 4);
-		if (!strcmp(name, "mem"))
-			total += roundup(ctx_ls_size(ctx), 4);
-		else
-			total += roundup(sz, 4);
+		total += roundup(sz, 4);
 	}
 
 	return total;
@@ -164,11 +156,7 @@ static void spufs_arch_write_note(struct spu_context *ctx, int i,
 		return;
 
 	name = spufs_coredump_read[i].name;
-
-	if (!strcmp(name, "mem"))
-		sz = ctx_ls_size(ctx);
-	else
-		sz = spufs_coredump_read[i].size;
+	sz = spufs_coredump_read[i].size;
 
 	sprintf(fullname, "SPU/%d/%s", dfd, name);
 	en.n_namesz = strlen(fullname) + 1;

^ permalink raw reply related

* [PATCH 18/25] spufs: Get rid of spufs_coredump_num_notes, it's not needed if we NULL terminate
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

From: Michael Ellerman <michael@ellerman.id.au>

The spufs_coredump_read array is NULL terminated, and we also store the size.
We only need one or the other, and the other arrays in file.c are NULL
terminated, so do that.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/coredump.c |    4 ++--
 arch/powerpc/platforms/cell/spufs/file.c     |    4 +---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 52d6219..fc988fd 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -72,7 +72,7 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
 	char *name;
 	char fullname[80];
 
-	for (i = 0; spufs_coredump_read[i].name; i++) {
+	for (i = 0; spufs_coredump_read[i].name != NULL; i++) {
 		name = spufs_coredump_read[i].name;
 		sz = spufs_coredump_read[i].size;
 
@@ -194,7 +194,7 @@ static void spufs_arch_write_notes(struct file *file)
 	while ((ctx = coredump_next_context(&fd)) != NULL) {
 		spu_acquire_saved(ctx);
 
-		for (j = 0; j < spufs_coredump_num_notes; j++)
+		for (j = 0; spufs_coredump_read[j].name != NULL; j++)
 			spufs_arch_write_note(ctx, j, file, fd);
 
 		spu_release_saved(ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 85edbec..6095fb1 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2250,7 +2250,5 @@ struct spufs_coredump_reader spufs_coredump_read[] = {
 	{ "proxydma_info", __spufs_proxydma_info_read,
 			   NULL, sizeof(struct spu_proxydma_info)},
 	{ "object-id", NULL, __spufs_object_id_get, 19 },
-	{ },
+	{ NULL },
 };
-int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read) - 1;
-

^ permalink raw reply related

* [PATCH 08/25] Fix restore_decr_wrapped() to match CBE Handbook
From: Jeremy Kerr @ 2007-09-14  6:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>

Based on an original patch from Masato Noguchi
<Masato.Noguchi@jp.sony.com>.

We're currently not restoring the SPE decrementer as specified by the
CBE handbook. This change fixes our implementation to match, and makes
the function read more like the docs.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/switch.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 2506619..de7e5ee 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -1559,15 +1559,15 @@ static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu)
 	 *     "wrapped" flag is set, OR in a '1' to
 	 *     CSA.SPU_Event_Status[Tm].
 	 */
-	if (csa->lscsa->decr_status.slot[0] & SPU_DECR_STATUS_WRAPPED) {
-		csa->spu_chnldata_RW[0] |= 0x20;
-	}
-	if ((csa->lscsa->decr_status.slot[0] & SPU_DECR_STATUS_WRAPPED) &&
-	    (csa->spu_chnlcnt_RW[0] == 0 &&
-	     ((csa->spu_chnldata_RW[2] & 0x20) == 0x0) &&
-	     ((csa->spu_chnldata_RW[0] & 0x20) != 0x1))) {
+	if (!(csa->lscsa->decr_status.slot[0] & SPU_DECR_STATUS_WRAPPED))
+		return;
+
+	if ((csa->spu_chnlcnt_RW[0] == 0) &&
+	    (csa->spu_chnldata_RW[1] & 0x20) &&
+	    !(csa->spu_chnldata_RW[0] & 0x20))
 		csa->spu_chnlcnt_RW[0] = 1;
-	}
+
+	csa->spu_chnldata_RW[0] |= 0x20;
 }
 
 static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu)

^ permalink raw reply related


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