linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code
@ 2007-09-12  7:43 Michael Ellerman
  2007-09-12  7:43 ` [PATCH 02/15] Remove ctx_info and ctx_info_list Michael Ellerman
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

Extract the logic for searching through the file descriptors for spu contexts
into a separate routine, coredump_next_context(), so we can use it elsewhere
in future. In the process we flatten the for loop, and move the NOSCHED test
into coredump_next_context().

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |   58 +++++++++++++++++---------
 1 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 5e31799..99f8e0b 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -109,16 +109,11 @@ static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
 	return total;
 }
 
-static int spufs_add_one_context(struct file *file, int dfd)
+static int spufs_add_one_context(struct spu_context *ctx, int dfd)
 {
-	struct spu_context *ctx;
 	struct spufs_ctx_info *ctx_info;
 	int size;
 
-	ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
-	if (ctx->flags & SPU_CREATE_NOSCHED)
-		return 0;
-
 	ctx_info = kzalloc(sizeof(*ctx_info), GFP_KERNEL);
 	if (unlikely(!ctx_info))
 		return -ENOMEM;
@@ -142,22 +137,45 @@ static int spufs_add_one_context(struct file *file, int dfd)
  * internal functionality to dump them without needing to actually
  * open the files.
  */
-static int spufs_arch_notes_size(void)
+static struct spu_context *coredump_next_context(int *fd)
 {
 	struct fdtable *fdt = files_fdtable(current->files);
-	int size = 0, fd;
-
-	for (fd = 0; fd < fdt->max_fds; fd++) {
-		if (FD_ISSET(fd, fdt->open_fds)) {
-			struct file *file = fcheck(fd);
-
-			if (file && file->f_op == &spufs_context_fops) {
-				int rval = spufs_add_one_context(file, fd);
-				if (rval < 0)
-					break;
-				size += rval;
-			}
-		}
+	struct file *file;
+	struct spu_context *ctx = NULL;
+
+	for (; *fd < fdt->max_fds; (*fd)++) {
+		if (!FD_ISSET(*fd, fdt->open_fds))
+			continue;
+
+		file = fcheck(*fd);
+
+		if (!file || file->f_op != &spufs_context_fops)
+			continue;
+
+		ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
+		if (ctx->flags & SPU_CREATE_NOSCHED)
+			continue;
+
+		/* start searching the next fd next time we're called */
+		(*fd)++;
+		break;
+	}
+
+	return ctx;
+}
+
+static int spufs_arch_notes_size(void)
+{
+	struct spu_context *ctx;
+	int size = 0, rc, fd;
+
+	fd = 0;
+	while ((ctx = coredump_next_context(&fd)) != NULL) {
+		rc = spufs_add_one_context(ctx, fd);
+		if (rc < 0)
+			break;
+
+		size += rc;
 	}
 
 	return size;
-- 
1.5.1.3.g7a33b

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

* [PATCH 02/15] Remove ctx_info and ctx_info_list
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 03/15] Call spu_acquire_saved() before calculating the SPU note sizes Michael Ellerman
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |   79 ++++++-------------------
 1 files 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);
 	}
 }
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 03/15] Call spu_acquire_saved() before calculating the SPU note sizes
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
  2007-09-12  7:43 ` [PATCH 02/15] Remove ctx_info and ctx_info_list Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 04/15] Use computed sizes/#defines rather than literals in SPU coredump code Michael Ellerman
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

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;
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 04/15] Use computed sizes/#defines rather than literals in SPU coredump code
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
  2007-09-12  7:43 ` [PATCH 02/15] Remove ctx_info and ctx_info_list Michael Ellerman
  2007-09-12  7:43 ` [PATCH 03/15] Call spu_acquire_saved() before calculating the SPU note sizes Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 05/15] Write some SPU coredump values as ASCII Michael Ellerman
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 arch/powerpc/platforms/cell/spufs/file.c |   21 +++++++++++----------
 1 files 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 },
 	{ },
 };
-- 
1.5.1.3.g7a33b

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

* [PATCH 05/15] Write some SPU coredump values as ASCII
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (2 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 04/15] Use computed sizes/#defines rather than literals in SPU coredump code Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 06/15] Correctly calculate the size of the local-store to dump Michael Ellerman
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

Unfortunately GDB expects some of the SPU coredump values to be identical
in format to what is found in spufs. This means we need to dump some of
the values as ASCII strings, not the actual values.

Because we don't know what the values will be, we always print the values
with the format "0x%.16lx", that way we know the result will be 19 bytes.

do_coredump_read() doesn't take a __user buffer, so remove the annotation,
and because we know that it's safe to just snprintf() directly to it.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |    8 +++++---
 arch/powerpc/platforms/cell/spufs/file.c     |   14 +++++++-------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 21283f6..c65b717 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -31,7 +31,7 @@
 
 #include "spufs.h"
 
-static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *buffer,
+static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
 				size_t size, loff_t *off)
 {
 	u64 data;
@@ -41,8 +41,10 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *b
 		return spufs_coredump_read[num].read(ctx, buffer, size, off);
 
 	data = spufs_coredump_read[num].get(ctx);
-	ret = copy_to_user(buffer, &data, 8);
-	return ret ? -EFAULT : 8;
+	ret = snprintf(buffer, size, "0x%.16lx", data);
+	if (ret >= size)
+		return size;
+	return ++ret; /* count trailing NULL */
 }
 
 /*
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 18ddde8..85edbec 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2233,16 +2233,16 @@ 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, 11 },
-	{ "decr", NULL, __spufs_decr_get, 11 },
-	{ "decr_status", NULL, __spufs_decr_status_get, 11 },
+	{ "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, 2 },
+	{ "signal1_type", NULL, __spufs_signal1_type_get, 19 },
 	{ "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 },
+	{ "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)},
-- 
1.5.1.3.g7a33b

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

* [PATCH 06/15] Correctly calculate the size of the local-store to dump
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (3 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 05/15] Write some SPU coredump values as ASCII Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12 11:31   ` Arnd Bergmann
  2007-09-12  7:43 ` [PATCH 07/15] Don't return -ENOSYS as extra notes size if spufs is not loaded Michael Ellerman
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |   16 ++--------------
 1 files 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;
-- 
1.5.1.3.g7a33b

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

* [PATCH 07/15] Don't return -ENOSYS as extra notes size if spufs is not loaded
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (4 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 06/15] Correctly calculate the size of the local-store to dump Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12 11:04   ` Arnd Bergmann
  2007-09-12  7:43 ` [PATCH 08/15] Use spufs_coredump_num_notes everywhere, and don't NULL terminate Michael Ellerman
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

Because the SPU coredump code might be built as part of a module (spufs),
we have a stub which is called by the coredump code, this routine then calls
into spufs if it's loaded.

Unfortunately the stub returns -ENOSYS if spufs is not loaded, which is
interpreted by the coredump code as an extra note size of -38 bytes. This
leads to a corrupt core dump.

If spufs is not loaded there will be no SPU ELF notes to write, and so the
extra notes size will be == 0.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spu_coredump.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spu_coredump.c b/arch/powerpc/platforms/cell/spu_coredump.c
index 4fd37ff..656a8c5 100644
--- a/arch/powerpc/platforms/cell/spu_coredump.c
+++ b/arch/powerpc/platforms/cell/spu_coredump.c
@@ -31,15 +31,19 @@ static DEFINE_MUTEX(spu_coredump_mutex);
 
 int arch_notes_size(void)
 {
-	long ret;
+	int ret;
 
-	ret = -ENOSYS;
 	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;
 }
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 08/15] Use spufs_coredump_num_notes everywhere, and don't NULL terminate
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (5 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 07/15] Don't return -ENOSYS as extra notes size if spufs is not loaded Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  8:55   ` Arnd Bergmann
  2007-09-12  7:43 ` [PATCH 09/15] Internal __spufs_get_foo() routines should take a spu_context * Michael Ellerman
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

The spufs_coredump_read array is NULL terminated, and we also store the size.
We only need one or the other, and storing the size should save a teensy bit
of memory vs NULL terminating, so do that.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |    2 +-
 arch/powerpc/platforms/cell/spufs/file.c     |    3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 52d6219..8348d21 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; i < spufs_coredump_num_notes; i++) {
 		name = spufs_coredump_read[i].name;
 		sz = spufs_coredump_read[i].size;
 
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 85edbec..220c7fe 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2250,7 +2250,6 @@ 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 },
-	{ },
 };
-int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read) - 1;
 
+int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read);
-- 
1.5.1.3.g7a33b

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

* [PATCH 09/15] Internal __spufs_get_foo() routines should take a spu_context *
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (6 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 08/15] Use spufs_coredump_num_notes everywhere, and don't NULL terminate Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  8:53   ` Arnd Bergmann
  2007-09-12  7:43 ` [PATCH 10/15] Add contents of npc file to SPU coredumps Michael Ellerman
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 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 220c7fe..d19220f 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[];
-- 
1.5.1.3.g7a33b

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

* [PATCH 10/15] Add contents of npc file to SPU coredumps
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (7 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 09/15] Internal __spufs_get_foo() routines should take a spu_context * Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  8:52   ` Arnd Bergmann
  2007-09-12  7:43 ` [PATCH 11/15] Combine spufs_coredump_calls with spufs_calls Michael Ellerman
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spufs/file.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index d19220f..52f020a 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1606,12 +1606,17 @@ static void spufs_npc_set(void *data, u64 val)
 	spu_release(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 = ctx->ops->npc_read(ctx);
+	ret = __spufs_npc_get(ctx);
 	spu_release(ctx);
 	return ret;
 }
@@ -2242,6 +2247,7 @@ 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 },
+	{ "npc", NULL, __spufs_npc_get, 19 },
 };
 
 int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read);
-- 
1.5.1.3.g7a33b

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

* [PATCH 11/15] Combine spufs_coredump_calls with spufs_calls
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (8 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 10/15] Add contents of npc file to SPU coredumps Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  8:51   ` Arnd Bergmann
  2007-09-12  7:43 ` [PATCH 12/15] Cleanup ELF coredump extra notes logic Michael Ellerman
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 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 8348d21..7395350 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 a0f2d28..10c40cd 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);
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 12/15] Cleanup ELF coredump extra notes logic
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (9 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 11/15] Combine spufs_coredump_calls with spufs_calls Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 13/15] Handle errors in SPU coredump code, and support coredump to a pipe Michael Ellerman
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

To start with, arch_notes_size() etc. is a little too ambiguous a name for
my liking, so change the function names to be more explicit.

Calling through macros is ugly, especially with hidden parameters, so don't
do that, call the routines directly.

Use ARCH_HAVE_EXTRA_ELF_NOTES as the only flag, and based on it decide
whether we want the extern declarations or the empty versions.

Since we have empty routines, actually use them in the coredump code to
save a few #ifdefs.

We want to change the handling of foffset so that the write routine updates
foffset as it goes, instead of using file->f_pos (so that writing to a pipe
works). So pass foffset to the write routine, and for now just set it to
file->f_pos at the end of writing.

It should also be possible for the write routine to fail, so change it to
return int and treat a non-zero return as failure.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spu_syscalls.c |   12 +++++++++---
 fs/binfmt_elf.c                            |   14 +++-----------
 include/asm-powerpc/elf.h                  |    9 ++-------
 include/linux/elf.h                        |   14 ++++++++------
 4 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index cf00251..d9b2fd2 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -21,6 +21,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/file.h>
+#include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/mutex.h>
@@ -109,7 +110,7 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
 	return ret;
 }
 
-int arch_notes_size(void)
+int elf_coredump_extra_notes_size(void)
 {
 	struct spufs_calls *calls;
 	int ret;
@@ -125,17 +126,22 @@ int arch_notes_size(void)
 	return ret;
 }
 
-void arch_write_notes(struct file *file)
+int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset)
 {
 	struct spufs_calls *calls;
 
 	calls = spufs_calls_get();
 	if (!calls)
-		return;
+		return 0;
 
 	calls->coredump_extra_notes_write(file);
 
 	spufs_calls_put(calls);
+
+	/* Fudge foffset for now */
+	*foffset = file->f_pos;
+
+	return 0;
 }
 
 int register_spu_syscalls(struct spufs_calls *calls)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 4482a06..b1013f3 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1514,9 +1514,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
 	int thread_status_size = 0;
 	elf_addr_t *auxv;
 	unsigned long mm_flags;
-#ifdef ELF_CORE_WRITE_EXTRA_NOTES
-	int extra_notes_size;
-#endif
 
 	/*
 	 * We no longer stop all VM operations.
@@ -1645,10 +1642,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
 		
 		sz += thread_status_size;
 
-#ifdef ELF_CORE_WRITE_EXTRA_NOTES
-		extra_notes_size = ELF_CORE_EXTRA_NOTES_SIZE;
-		sz += extra_notes_size;
-#endif
+		sz += elf_coredump_extra_notes_size();
 
 		fill_elf_note_phdr(&phdr, sz, offset);
 		offset += sz;
@@ -1698,10 +1692,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
 		if (!writenote(notes + i, file, &foffset))
 			goto end_coredump;
 
-#ifdef ELF_CORE_WRITE_EXTRA_NOTES
-	ELF_CORE_WRITE_EXTRA_NOTES;
-	foffset += extra_notes_size;
-#endif
+	if (elf_coredump_extra_notes_write(file, &foffset))
+		goto end_coredump;
 
 	/* write out the thread status notes section */
 	list_for_each(t, &thread_list) {
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index de50799..e42820d 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -413,13 +413,8 @@ do {									\
 /* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
 #define NT_SPU		1
 
-extern int arch_notes_size(void);
-extern void arch_write_notes(struct file *file);
-
-#define ELF_CORE_EXTRA_NOTES_SIZE arch_notes_size()
-#define ELF_CORE_WRITE_EXTRA_NOTES arch_write_notes(file)
-
 #define ARCH_HAVE_EXTRA_ELF_NOTES
-#endif /* CONFIG_PPC_CELL */
+
+#endif /* CONFIG_SPU_BASE */
 
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 8b17ffe..d2da84a 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -389,12 +389,14 @@ extern Elf64_Dyn _DYNAMIC [];
 
 #endif
 
+/* Optional callbacks to write extra ELF notes. */
 #ifndef ARCH_HAVE_EXTRA_ELF_NOTES
-static inline int arch_notes_size(void) { return 0; }
-static inline void arch_write_notes(struct file *file) { }
-
-#define ELF_CORE_EXTRA_NOTES_SIZE arch_notes_size()
-#define ELF_CORE_WRITE_EXTRA_NOTES arch_write_notes(file)
-#endif /* ARCH_HAVE_EXTRA_ELF_NOTES */
+static inline int elf_coredump_extra_notes_size(void) { return 0; }
+static inline int elf_coredump_extra_notes_write(struct file *file,
+			loff_t *foffset) { return 0; }
+#else
+extern int elf_coredump_extra_notes_size(void);
+extern int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset);
+#endif
 
 #endif /* _LINUX_ELF_H */
-- 
1.5.1.3.g7a33b

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

* [PATCH 13/15] Handle errors in SPU coredump code, and support coredump to a pipe
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (10 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 12/15] Cleanup ELF coredump extra notes logic Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 14/15] Respect RLIMIT_CORE in spu coredump code Michael Ellerman
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 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 7395350..c3b5cd5 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; j < spufs_coredump_num_notes; j++)
-			spufs_arch_write_note(ctx, j, file, fd);
+		for (j = 0; j < spufs_coredump_num_notes; 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 10c40cd..eed63dd 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;
 };
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 14/15] Respect RLIMIT_CORE in spu coredump code
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (11 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 13/15] Handle errors in SPU coredump code, and support coredump to a pipe Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:43 ` [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE() Michael Ellerman
  2007-09-12  8:17 ` [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Jeremy Kerr
  14 siblings, 0 replies; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

Currently the spu coredump code doesn't respect the ulimit, it should.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/spufs/coredump.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index c3b5cd5..b8ab2c6 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -53,8 +53,12 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
  */
 static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
 {
+	unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
 	ssize_t written;
 
+	if (*foffset + nr > limit)
+		return -EIO;
+
 	written = file->f_op->write(file, addr, nr, &file->f_pos);
 	*foffset += written;
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE()
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (12 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 14/15] Respect RLIMIT_CORE in spu coredump code Michael Ellerman
@ 2007-09-12  7:43 ` Michael Ellerman
  2007-09-12  7:49   ` Michael Ellerman
  2007-09-12  8:17 ` [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Jeremy Kerr
  14 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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>
---
 arch/powerpc/platforms/cell/spufs/file.c |  216 +++++++++++-------------------
 1 files changed, 76 insertions(+), 140 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 52f020a..46ec8eb 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,24 +2166,24 @@ 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 },
 };
 
 int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read);
-- 
1.5.1.3.g7a33b

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

* Re: [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE()
  2007-09-12  7:43 ` [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE() Michael Ellerman
@ 2007-09-12  7:49   ` Michael Ellerman
  2007-09-12  8:47     ` Arnd Bergmann
  0 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-12  7:49 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

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

On Wed, 2007-09-12 at 17:43 +1000, Michael Ellerman wrote:
> 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>
> ---
>  arch/powerpc/platforms/cell/spufs/file.c |  216 +++++++++++-------------------
>  1 files changed, 76 insertions(+), 140 deletions(-)


jk said:
> "Good god man!"

Yeah, I'm a bit lukewarm on this one. But the diffstat is nice, 50% code
reduction ain't 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: 189 bytes --]

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

* Re: [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code
  2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
                   ` (13 preceding siblings ...)
  2007-09-12  7:43 ` [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE() Michael Ellerman
@ 2007-09-12  8:17 ` Jeremy Kerr
  2007-09-12  8:35   ` Andrew Morton
  14 siblings, 1 reply; 27+ messages in thread
From: Jeremy Kerr @ 2007-09-12  8:17 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Andrew Morton, linux-kernel

Hi Michael,

This series looks good to me, thanks for the fixes. I'll do some testing 
tomorrow but it looks like it'll be fine as-is.

Andrew - almost all of these are for spufs, the notable exception being:

 [PATCH 12/15] Cleanup ELF coredump extra notes logic

which touches the generic elf/coredump path.

Are you ok for me to merge this to my spufs tree, and upstream via 
paulus?

Cheers,


Jeremy

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

* Re: [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code
  2007-09-12  8:17 ` [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Jeremy Kerr
@ 2007-09-12  8:35   ` Andrew Morton
  0 siblings, 0 replies; 27+ messages in thread
From: Andrew Morton @ 2007-09-12  8:35 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linuxppc-dev, linux-kernel

On Wed, 12 Sep 2007 18:17:42 +1000 Jeremy Kerr <jk@ozlabs.org> wrote:

> This series looks good to me, thanks for the fixes. I'll do some testing 
> tomorrow but it looks like it'll be fine as-is.
> 
> Andrew - almost all of these are for spufs, the notable exception being:
> 
>  [PATCH 12/15] Cleanup ELF coredump extra notes logic
> 
> which touches the generic elf/coredump path.
> 
> Are you ok for me to merge this to my spufs tree, and upstream via 
> paulus?

Sure.  I'd only get in the way with spufs stuff.

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

* Re: [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE()
  2007-09-12  7:49   ` Michael Ellerman
@ 2007-09-12  8:47     ` Arnd Bergmann
  2007-09-13  2:05       ` Michael Ellerman
  0 siblings, 1 reply; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12  8:47 UTC (permalink / raw)
  To: linuxppc-dev, michael; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> On Wed, 2007-09-12 at 17:43 +1000, Michael Ellerman wrote:
> > 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.

> 
> jk said:
> > "Good god man!"
> 
> Yeah, I'm a bit lukewarm on this one. But the diffstat is nice, 50% code
> reduction ain't bad :)

Have you looked at the change in object code size? I would expect the
object code to actually become bigger. I also think that it hurts
readability rather than help it.

Maybe a better solution is to change the core dump code to not
require the mutex to be held in the first place. By the time
we get to call the get functions, it should already be in
saved state and no longer be able to get scheduled, so we might
not actually need all the extra tricks with avoiding the
mutex to be taken again.

	Arnd <><

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

* Re: [PATCH 11/15] Combine spufs_coredump_calls with spufs_calls
  2007-09-12  7:43 ` [PATCH 11/15] Combine spufs_coredump_calls with spufs_calls Michael Ellerman
@ 2007-09-12  8:51   ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12  8:51 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> 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.

Nice cleanup!

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

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

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

* Re: [PATCH 10/15] Add contents of npc file to SPU coredumps
  2007-09-12  7:43 ` [PATCH 10/15] Add contents of npc file to SPU coredumps Michael Ellerman
@ 2007-09-12  8:52   ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12  8:52 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

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

* Re: [PATCH 09/15] Internal __spufs_get_foo() routines should take a spu_context *
  2007-09-12  7:43 ` [PATCH 09/15] Internal __spufs_get_foo() routines should take a spu_context * Michael Ellerman
@ 2007-09-12  8:53   ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12  8:53 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> 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>

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

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

* Re: [PATCH 08/15] Use spufs_coredump_num_notes everywhere, and don't NULL terminate
  2007-09-12  7:43 ` [PATCH 08/15] Use spufs_coredump_num_notes everywhere, and don't NULL terminate Michael Ellerman
@ 2007-09-12  8:55   ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12  8:55 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> The spufs_coredump_read array is NULL terminated, and we also store the size.
> We only need one or the other, and storing the size should save a teensy bit
> of memory vs NULL terminating, so do that.

Given that we have another array in there with almost the same contents
and that is NULL terminated, I'd vote for doing it the other way and also
use NULL-termination instead of the count here.

	Arnd <><

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

* Re: [PATCH 07/15] Don't return -ENOSYS as extra notes size if spufs is not loaded
  2007-09-12  7:43 ` [PATCH 07/15] Don't return -ENOSYS as extra notes size if spufs is not loaded Michael Ellerman
@ 2007-09-12 11:04   ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12 11:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> Because the SPU coredump code might be built as part of a module (spufs),
> we have a stub which is called by the coredump code, this routine then calls
> into spufs if it's loaded.
> 
> Unfortunately the stub returns -ENOSYS if spufs is not loaded, which is
> interpreted by the coredump code as an extra note size of -38 bytes. This
> leads to a corrupt core dump.
> 
> If spufs is not loaded there will be no SPU ELF notes to write, and so the
> extra notes size will be == 0.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

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

* Re: [PATCH 06/15] Correctly calculate the size of the local-store to dump
  2007-09-12  7:43 ` [PATCH 06/15] Correctly calculate the size of the local-store to dump Michael Ellerman
@ 2007-09-12 11:31   ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-12 11:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr, linux-kernel

On Wednesday 12 September 2007, Michael Ellerman wrote:
> 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>

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

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

* Re: [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE()
  2007-09-12  8:47     ` Arnd Bergmann
@ 2007-09-13  2:05       ` Michael Ellerman
  2007-09-13 12:17         ` Arnd Bergmann
  0 siblings, 1 reply; 27+ messages in thread
From: Michael Ellerman @ 2007-09-13  2:05 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, Jeremy Kerr, linux-kernel

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

On Wed, 2007-09-12 at 10:47 +0200, Arnd Bergmann wrote:
> On Wednesday 12 September 2007, Michael Ellerman wrote:
> > On Wed, 2007-09-12 at 17:43 +1000, Michael Ellerman wrote:
> > > 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.
> 
> > 
> > jk said:
> > > "Good god man!"
> > 
> > Yeah, I'm a bit lukewarm on this one. But the diffstat is nice, 50% code
> > reduction ain't bad :)
> 
> Have you looked at the change in object code size? I would expect the
> object code to actually become bigger. I also think that it hurts
> readability rather than help it.

Yeah I did, it's smaller actually:

   text    data     bss     dec     hex filename
  44898   17804     120   62822    f566 spufs-before.o
  44886   17804     120   62810    f55a spufs-after.o

> Maybe a better solution is to change the core dump code to not
> require the mutex to be held in the first place. By the time
> we get to call the get functions, it should already be in
> saved state and no longer be able to get scheduled, so we might
> not actually need all the extra tricks with avoiding the
> mutex to be taken again.

Well that'd be nice, but I don't see anywhere that that happens. AFAICT
the acquire we do in the first coredump callback is the first the SPU
contexts know about their PPE process dying. And spufs is still live, so
I think we definitely need to grab the mutex, or we might race with
userspace accessing spufs files.

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: 189 bytes --]

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

* Re: [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE()
  2007-09-13  2:05       ` Michael Ellerman
@ 2007-09-13 12:17         ` Arnd Bergmann
  0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2007-09-13 12:17 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev, Jeremy Kerr, linux-kernel

On Thursday 13 September 2007, Michael Ellerman wrote:
> Well that'd be nice, but I don't see anywhere that that happens. AFAICT
> the acquire we do in the first coredump callback is the first the SPU
> contexts know about their PPE process dying. And spufs is still live, so
> I think we definitely need to grab the mutex, or we might race with
> userspace accessing spufs files.

Right, I was only thinking about the dumping process itself, but there
may be other processes that still have files open for that context.

	Arnd <><

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

end of thread, other threads:[~2007-09-13 12:17 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-12  7:43 [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Michael Ellerman
2007-09-12  7:43 ` [PATCH 02/15] Remove ctx_info and ctx_info_list Michael Ellerman
2007-09-12  7:43 ` [PATCH 03/15] Call spu_acquire_saved() before calculating the SPU note sizes Michael Ellerman
2007-09-12  7:43 ` [PATCH 04/15] Use computed sizes/#defines rather than literals in SPU coredump code Michael Ellerman
2007-09-12  7:43 ` [PATCH 05/15] Write some SPU coredump values as ASCII Michael Ellerman
2007-09-12  7:43 ` [PATCH 06/15] Correctly calculate the size of the local-store to dump Michael Ellerman
2007-09-12 11:31   ` Arnd Bergmann
2007-09-12  7:43 ` [PATCH 07/15] Don't return -ENOSYS as extra notes size if spufs is not loaded Michael Ellerman
2007-09-12 11:04   ` Arnd Bergmann
2007-09-12  7:43 ` [PATCH 08/15] Use spufs_coredump_num_notes everywhere, and don't NULL terminate Michael Ellerman
2007-09-12  8:55   ` Arnd Bergmann
2007-09-12  7:43 ` [PATCH 09/15] Internal __spufs_get_foo() routines should take a spu_context * Michael Ellerman
2007-09-12  8:53   ` Arnd Bergmann
2007-09-12  7:43 ` [PATCH 10/15] Add contents of npc file to SPU coredumps Michael Ellerman
2007-09-12  8:52   ` Arnd Bergmann
2007-09-12  7:43 ` [PATCH 11/15] Combine spufs_coredump_calls with spufs_calls Michael Ellerman
2007-09-12  8:51   ` Arnd Bergmann
2007-09-12  7:43 ` [PATCH 12/15] Cleanup ELF coredump extra notes logic Michael Ellerman
2007-09-12  7:43 ` [PATCH 13/15] Handle errors in SPU coredump code, and support coredump to a pipe Michael Ellerman
2007-09-12  7:43 ` [PATCH 14/15] Respect RLIMIT_CORE in spu coredump code Michael Ellerman
2007-09-12  7:43 ` [PATCH 15/15] Add DEFINE_SPUFS_ATTRIBUTE() Michael Ellerman
2007-09-12  7:49   ` Michael Ellerman
2007-09-12  8:47     ` Arnd Bergmann
2007-09-13  2:05       ` Michael Ellerman
2007-09-13 12:17         ` Arnd Bergmann
2007-09-12  8:17 ` [PATCH 01/15] Extract the file descriptor search logic in SPU coredump code Jeremy Kerr
2007-09-12  8:35   ` Andrew Morton

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