public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files)
       [not found]     ` <1339404517.6001.1767.camel@edumazet-glaptop>
@ 2012-06-11 10:21       ` Steven Whitehouse
  2012-06-11 11:12         ` Eric Dumazet
                           ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Steven Whitehouse @ 2012-06-11 10:21 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: cluster-devel, linux-kernel, Al Viro

Hi,

On Mon, 2012-06-11 at 10:48 +0200, Eric Dumazet wrote:
> On Mon, 2012-06-11 at 09:29 +0100, Steven Whitehouse wrote:
> > > 
> > That is on top of the almost 8x from increasing the buffer size with a
> > patch that Al Viro had suggested as a response to our earlier
> > discussion:
> 
> Ah OK, I understand ;)
> 
> > 
> > http://git.kernel.org/?p=linux/kernel/git/steve/gfs2-3.0-nmw.git;a=commitdiff;h=df5d2f5560a9c33129391a136ed9f0ac26abe69b
> 
> 
> Hmm, this patch seems overkill if PAGE_SIZE=65536 ?
> 
> #define GFS2_SEQ_GOODSIZE   \
> 	min(PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER, 65536)
> 
> 
Thats true, but are there any arches with a 64k page size? In any case
I'll follow up with another patch for that rather than try to combine it
with this one...

Here is a patch to add seq_vprintf and make use of it. It does speed
things up a bit, but not hugely (from approx 1.3 to approx 1.2 seconds
for my test). I can split this up into two bit if required, but lets see
what Al thinks is the best way to apply this. I'm happy to keep it in
the GFS2 tree if there are no objections - that should reduce conflicts
and complications, I hope.

Copying in lkml again, since this has ventured back into generic code
once more.

This patch adds an seq_vprintf function and then uses this in the GFS2
code in order to remove the need for a temporary buffer in the
glock/glstats file iteration state.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 10ae164..4d5d63d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -51,7 +51,6 @@ struct gfs2_glock_iter {
 	struct gfs2_sbd *sdp;		/* incore superblock           */
 	struct gfs2_glock *gl;		/* current glock struct        */
 	loff_t last_pos;		/* last position               */
-	char string[512];		/* scratch space               */
 };
 
 typedef void (*glock_examiner) (struct gfs2_glock * gl);
@@ -951,9 +950,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
 	va_start(args, fmt);
 
 	if (seq) {
-		struct gfs2_glock_iter *gi = seq->private;
-		vsprintf(gi->string, fmt, args);
-		seq_puts(seq, gi->string);
+		seq_vprintf(seq, fmt, args);
 	} else {
 		vaf.fmt = fmt;
 		vaf.va = &args;
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 0cbd049..14cf9de 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -385,15 +385,12 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc)
 }
 EXPORT_SYMBOL(seq_escape);
 
-int seq_printf(struct seq_file *m, const char *f, ...)
+int seq_vprintf(struct seq_file *m, const char *f, va_list args)
 {
-	va_list args;
 	int len;
 
 	if (m->count < m->size) {
-		va_start(args, f);
 		len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
-		va_end(args);
 		if (m->count + len < m->size) {
 			m->count += len;
 			return 0;
@@ -402,6 +399,19 @@ int seq_printf(struct seq_file *m, const char *f, ...)
 	seq_set_overflow(m);
 	return -1;
 }
+EXPORT_SYMBOL(seq_vprintf);
+
+int seq_printf(struct seq_file *m, const char *f, ...)
+{
+	int ret;
+	va_list args;
+
+	va_start(args, f);
+	ret = seq_vprintf(m, f, args);
+	va_end(args);
+
+	return ret;
+}
 EXPORT_SYMBOL(seq_printf);
 
 /**
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index fc61854..83c44ee 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -86,6 +86,7 @@ int seq_puts(struct seq_file *m, const char *s);
 int seq_write(struct seq_file *seq, const void *data, size_t len);
 
 __printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
+__printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);
 
 int seq_path(struct seq_file *, const struct path *, const char *);
 int seq_dentry(struct seq_file *, struct dentry *, const char *);



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

* Re: [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files)
  2012-06-11 10:21       ` [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files) Steven Whitehouse
@ 2012-06-11 11:12         ` Eric Dumazet
  2012-06-11 13:32           ` Steven Whitehouse
  2012-06-11 12:56         ` [Cluster-devel] " Steven Whitehouse
  2012-06-11 12:56         ` Steven Whitehouse
  2 siblings, 1 reply; 5+ messages in thread
From: Eric Dumazet @ 2012-06-11 11:12 UTC (permalink / raw)
  To: Steven Whitehouse; +Cc: cluster-devel, linux-kernel, Al Viro

On Mon, 2012-06-11 at 11:21 +0100, Steven Whitehouse wrote:

> Thats true, but are there any arches with a 64k page size? In any case
> I'll follow up with another patch for that rather than try to combine it
> with this one...

Some arches have page size from 16K to 1MB in size

sh, frv, hexagon, tile, ia64, mips, microblaze, sparc64, ppc64...




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

* Re: [Cluster-devel] [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files)
  2012-06-11 10:21       ` [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files) Steven Whitehouse
  2012-06-11 11:12         ` Eric Dumazet
@ 2012-06-11 12:56         ` Steven Whitehouse
  2012-06-11 12:56         ` Steven Whitehouse
  2 siblings, 0 replies; 5+ messages in thread
From: Steven Whitehouse @ 2012-06-11 12:56 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: cluster-devel, linux-kernel, Al Viro

Hi,

I've split that original patch into two, and I'll carry both bits in the
GFS2 -nmw tree for now. Here are the (hopefully) final versions of the
two patches. I'll follow up with a buffer sizing patch too a bit later,

Steve.

-------------------------------------------------------------------------------
>From a4808147dcf1ecf2f76212a78fd9692b3c112f47 Mon Sep 17 00:00:00 2001
From: Steven Whitehouse <swhiteho@redhat.com>
Date: Mon, 11 Jun 2012 13:16:35 +0100
Subject: [PATCH 1/2] seq_file: Add seq_vprintf function and export it

The existing seq_printf function is rewritten in terms of the new
seq_vprintf which is also exported to modules. This allows GFS2
(and potentially other seq_file users) to have a vprintf based
interface and to avoid an extra copy into a temporary buffer in
some cases.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
---
 fs/seq_file.c            |   18 ++++++++++++++----
 include/linux/seq_file.h |    1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 0cbd049..14cf9de 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -385,15 +385,12 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc)
 }
 EXPORT_SYMBOL(seq_escape);
 
-int seq_printf(struct seq_file *m, const char *f, ...)
+int seq_vprintf(struct seq_file *m, const char *f, va_list args)
 {
-	va_list args;
 	int len;
 
 	if (m->count < m->size) {
-		va_start(args, f);
 		len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
-		va_end(args);
 		if (m->count + len < m->size) {
 			m->count += len;
 			return 0;
@@ -402,6 +399,19 @@ int seq_printf(struct seq_file *m, const char *f, ...)
 	seq_set_overflow(m);
 	return -1;
 }
+EXPORT_SYMBOL(seq_vprintf);
+
+int seq_printf(struct seq_file *m, const char *f, ...)
+{
+	int ret;
+	va_list args;
+
+	va_start(args, f);
+	ret = seq_vprintf(m, f, args);
+	va_end(args);
+
+	return ret;
+}
 EXPORT_SYMBOL(seq_printf);
 
 /**
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index fc61854..83c44ee 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -86,6 +86,7 @@ int seq_puts(struct seq_file *m, const char *s);
 int seq_write(struct seq_file *seq, const void *data, size_t len);
 
 __printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
+__printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);
 
 int seq_path(struct seq_file *, const struct path *, const char *);
 int seq_dentry(struct seq_file *, struct dentry *, const char *);
-- 
1.7.4




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

* Re: [Cluster-devel] [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files)
  2012-06-11 10:21       ` [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files) Steven Whitehouse
  2012-06-11 11:12         ` Eric Dumazet
  2012-06-11 12:56         ` [Cluster-devel] " Steven Whitehouse
@ 2012-06-11 12:56         ` Steven Whitehouse
  2 siblings, 0 replies; 5+ messages in thread
From: Steven Whitehouse @ 2012-06-11 12:56 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: cluster-devel, linux-kernel, Al Viro

>From 1bb49303b7a82eb9bce0595087523343683abdf0 Mon Sep 17 00:00:00 2001
From: Steven Whitehouse <swhiteho@redhat.com>
Date: Mon, 11 Jun 2012 13:26:50 +0100
Subject: [PATCH 2/2] GFS2: Use seq_vprintf for glocks debugfs file

Make use of the newly added seq_vprintf() function.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
---
 fs/gfs2/glock.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 10ae164..4d5d63d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -51,7 +51,6 @@ struct gfs2_glock_iter {
 	struct gfs2_sbd *sdp;		/* incore superblock           */
 	struct gfs2_glock *gl;		/* current glock struct        */
 	loff_t last_pos;		/* last position               */
-	char string[512];		/* scratch space               */
 };
 
 typedef void (*glock_examiner) (struct gfs2_glock * gl);
@@ -951,9 +950,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
 	va_start(args, fmt);
 
 	if (seq) {
-		struct gfs2_glock_iter *gi = seq->private;
-		vsprintf(gi->string, fmt, args);
-		seq_puts(seq, gi->string);
+		seq_vprintf(seq, fmt, args);
 	} else {
 		vaf.fmt = fmt;
 		vaf.va = &args;
-- 
1.7.4




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

* Re: [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files)
  2012-06-11 11:12         ` Eric Dumazet
@ 2012-06-11 13:32           ` Steven Whitehouse
  0 siblings, 0 replies; 5+ messages in thread
From: Steven Whitehouse @ 2012-06-11 13:32 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: cluster-devel, linux-kernel, Al Viro

Hi,

On Mon, 2012-06-11 at 13:12 +0200, Eric Dumazet wrote:
> On Mon, 2012-06-11 at 11:21 +0100, Steven Whitehouse wrote:
> 
> > Thats true, but are there any arches with a 64k page size? In any case
> > I'll follow up with another patch for that rather than try to combine it
> > with this one...
> 
> Some arches have page size from 16K to 1MB in size
> 
> sh, frv, hexagon, tile, ia64, mips, microblaze, sparc64, ppc64...
> 
> 
> 
I can't imagine running GFS2 on many of those, sparc64 and/or ppc64
maybe, but rather unlikely on the others. Nevertheless, here is a patch
to ensure that we don't land up allocating too much memory. No
performance impact on x86_64 since the buffer size hasn't changed in
that case.

Hopefully this should be the last bit for this set of patches. Many
thanks for taking the time to look at this - things should be much
improved from my initial idea and I think that our QE and support teams
will be happy with the result,

Steve.


>From 0fe2f1e929ecabf834f4af2ffd300fe70700f4b3 Mon Sep 17 00:00:00 2001
From: Steven Whitehouse <swhiteho@redhat.com>
Date: Mon, 11 Jun 2012 13:49:47 +0100
Subject: [PATCH] GFS2: Size seq_file buffer more carefully

This places a limit on the buffer size for archs with larger
PAGE_SIZE.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 4d5d63d..1ed81f4 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1977,6 +1977,8 @@ static const struct seq_operations gfs2_sbstats_seq_ops = {
 	.show  = gfs2_sbstats_seq_show,
 };
 
+#define GFS2_SEQ_GOODSIZE min(PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER, 65536UL)
+
 static int gfs2_glocks_open(struct inode *inode, struct file *file)
 {
 	int ret = seq_open_private(file, &gfs2_glock_seq_ops,
@@ -1985,9 +1987,9 @@ static int gfs2_glocks_open(struct inode *inode, struct file *file)
 		struct seq_file *seq = file->private_data;
 		struct gfs2_glock_iter *gi = seq->private;
 		gi->sdp = inode->i_private;
-		seq->buf = kmalloc(8*PAGE_SIZE, GFP_KERNEL | __GFP_NOWARN);
+		seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN);
 		if (seq->buf)
-			seq->size = 8*PAGE_SIZE;
+			seq->size = GFS2_SEQ_GOODSIZE;
 	}
 	return ret;
 }
@@ -2000,9 +2002,9 @@ static int gfs2_glstats_open(struct inode *inode, struct file *file)
 		struct seq_file *seq = file->private_data;
 		struct gfs2_glock_iter *gi = seq->private;
 		gi->sdp = inode->i_private;
-		seq->buf = kmalloc(8*PAGE_SIZE, GFP_KERNEL | __GFP_NOWARN);
+		seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN);
 		if (seq->buf)
-			seq->size = 8*PAGE_SIZE;
+			seq->size = GFS2_SEQ_GOODSIZE;
 	}
 	return ret;
 }
-- 
1.7.4





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

end of thread, other threads:[~2012-06-11 13:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1339152726.2752.3.camel@menhir>
     [not found] ` <1339230731.6001.159.camel@edumazet-glaptop>
     [not found]   ` <1339403377.2734.7.camel@menhir>
     [not found]     ` <1339404517.6001.1767.camel@edumazet-glaptop>
2012-06-11 10:21       ` [PATCH] Add seq_vprintf and use in gfs2 (was Re: GFS2: Cache last hash bucket for glock seq_files) Steven Whitehouse
2012-06-11 11:12         ` Eric Dumazet
2012-06-11 13:32           ` Steven Whitehouse
2012-06-11 12:56         ` [Cluster-devel] " Steven Whitehouse
2012-06-11 12:56         ` Steven Whitehouse

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