Re: [PATCH 1/4] jbd2/journal_commit_transaction: relocate state lock to incorporate all users

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[Re: [PATCH 1/4] jbd2/journal_commit_transaction: relocate state lock to incorporate all users] On 11/06/2013 (Tue 13:53) Theodore Ts'o wrote:

> On Tue, Jun 11, 2013 at 01:38:24PM -0400, Paul Gortmaker wrote:
> >  
> > +#if defined(CONFIG_JBD_DEBUG) || defined(CONFIG_JBD2_DEBUG)
> > +static inline void __jbd_debug(int level, const char *file, const char *func,
> > +			       unsigned int line, const char *fmt, ...)
> > +{
> > +	struct va_format vaf;
> > +	va_list args;
> > +
> > +	if (level > JOURNAL_ENABLE_DEBUG)
> > +		return;
> > +	va_start(args, fmt);
> > +	vaf.fmt = fmt;
> > +	vaf.va = &args;
> > +	printk(KERN_DEBUG "%s: (%s, %u): %pV\n", file, func, line, &vaf);
> > +	va_end(args);
> > +}
> > +#endif
> 
> What's the difference in the overall size of jbd.ko and jbd2.ko using
> an inline __jbd_debug compared with one where the __jbd_debug is
> defined as a function in fs/jbd2/journal.c (or fs/jbd/journal.c; that
> will be the problem trying to solve this problem for jbd and jbd2 at
> the same time)?
> 
> If gcc was competent at optimizing inline functions with varargs, this
> might be fine.  But I'm a bit concerned whether this might cause a lot
> of bloat if CONFIG_JBD2_DEBUG is enabled.  It would be nice if the
> impact was small enough that people were willing to enable so it's
> available when we want to do debuggin.

There is a small delta for inline vs non-inline, but it isn't anywhere
near as big as the off-vs-on delta (with gcc-4.7.3):

JBD[2]_DEBUG off:
     text	   data	    bss	    dec	    hex	filename
    48072	    113	    128	  48313	   bcb9	fs/jbd2/built-in.o
    36862	     50	     32	  36944	   9050	fs/jbd/built-in.o

JBD[2]_DEBUG on, __jbd[2]_debug as two independent real void functions:
     text	   data	    bss	    dec	    hex	filename
    55261	    115	    132	  55508	   d8d4	fs/jbd2/built-in.o
    43752	     51	     52	  43855	   ab4f	fs/jbd/built-in.o

JBD[2]_DEBUG on, __jbd_debug as a shared inline function in jbd_common.h:
     text	   data	    bss	    dec	    hex	filename
    55862	    115	    132	  56109	   db2d	fs/jbd2/built-in.o
    44353	     51	     52	  44456	   ada8	fs/jbd/built-in.o

So it looks like you can choose whichever solution you like
better.  I don't have a real preference either way.  The
non-inline version looks like what I've included below.

Paul.
--

>From d22a2bbe9108934ba3d1374f61f6e3a01aaa36e6 Mon Sep 17 00:00:00 2001
From: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>
Date: Tue, 11 Jun 2013 11:46:10 -0400
Subject: [PATCH] jbd/jbd2: make jbd_debug that won't split printk statements

Since the jbd_debug() is implemented with two separate printk()
calls, it can lead to corrupted and misleading debug output like
the following (see lines marked with "*"):

[  290.339362] (fs/jbd2/journal.c, 203): kjournald2: kjournald2 wakes
[  290.339365] (fs/jbd2/journal.c, 155): kjournald2: commit_sequence=42103, commit_request=42104
[  290.339369] (fs/jbd2/journal.c, 158): kjournald2: OK, requests differ
[* 290.339376] (fs/jbd2/journal.c, 648): jbd2_log_wait_commit:
[* 290.339379] (fs/jbd2/commit.c, 370): jbd2_journal_commit_transaction: JBD2: want 42104, j_commit_sequence=42103
[* 290.339382] JBD2: starting commit of transaction 42104
[  290.339410] (fs/jbd2/revoke.c, 566): jbd2_journal_write_revoke_records: Wrote 0 revoke records
[  290.376555] (fs/jbd2/commit.c, 1088): jbd2_journal_commit_transaction: JBD2: commit 42104 complete, head 42079

i.e. the debug output from log_wait_commit and journal_commit_transaction
have become interleaved.  The output should have been:

(fs/jbd2/journal.c, 648): jbd2_log_wait_commit: JBD2: want 42104, j_commit_sequence=42103
(fs/jbd2/commit.c, 370): jbd2_journal_commit_transaction: JBD2: starting commit of transaction 42104

It is expected that this is not easy to replicate -- I was only able
to cause it on preempt-rt kernels, and even then only under heavy
I/O load.  Ted suggested we make use of va_args to reduce it to a single
printk() call to fix it.

This was originally seen on ext4, but since ext3 should suffer the
same problem, I've taken the next step to implement the same kind of
fix there as well.

Signed-off-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>

diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 6510d63..5e046a6 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -90,6 +90,23 @@ static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
 static const char *journal_dev_name(journal_t *journal, char *buffer);
 
+#ifdef CONFIG_JBD_DEBUG
+void __jbd_debug(int level, const char *file, const char *func,
+		 unsigned int line, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	if (level > journal_enable_debug)
+		return;
+	va_start(args, fmt);
+	vaf.fmt = fmt;
+	vaf.va = &args;
+	printk(KERN_DEBUG "%s: (%s, %u): %pV\n", file, func, line, &vaf);
+	va_end(args);
+}
+#endif
+
 /*
  * Helper function used to manage commit timeouts
  */
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 9545757..6aa196e 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -103,6 +103,23 @@ EXPORT_SYMBOL(jbd2_inode_cache);
 static void __journal_abort_soft (journal_t *journal, int errno);
 static int jbd2_journal_create_slab(size_t slab_size);
 
+#ifdef CONFIG_JBD2_DEBUG
+void __jbd2_debug(int level, const char *file, const char *func,
+		  unsigned int line, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	if (level > jbd2_journal_enable_debug)
+		return;
+	va_start(args, fmt);
+	vaf.fmt = fmt;
+	vaf.va = &args;
+	printk(KERN_DEBUG "%s: (%s, %u): %pV\n", file, func, line, &vaf);
+	va_end(args);
+}
+#endif
+
 /* Checksumming functions */
 int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb)
 {
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 6e5524f..bc12abc 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -56,17 +56,13 @@
  */
 #define JBD_EXPENSIVE_CHECKING
 extern u8 journal_enable_debug;
+void __jbd_debug(int level, const char *file, const char *func,
+		 unsigned int line, const char *fmt, ...);
 
-#define jbd_debug(n, f, a...)						\
-	do {								\
-		if ((n) <= journal_enable_debug) {			\
-			printk (KERN_DEBUG "(%s, %d): %s: ",		\
-				__FILE__, __LINE__, __func__);	\
-			printk (f, ## a);				\
-		}							\
-	} while (0)
+#define jbd_debug(n, fmt, a...) \
+	__jbd_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a)
 #else
-#define jbd_debug(f, a...)	/**/
+#define jbd_debug(n, fmt, a...)    /**/
 #endif
 
 static inline void *jbd_alloc(size_t size, gfp_t flags)
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 9986ab8..8d95314 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -56,17 +56,13 @@
  */
 #define JBD2_EXPENSIVE_CHECKING
 extern ushort jbd2_journal_enable_debug;
+void __jbd2_debug(int level, const char *file, const char *func,
+		  unsigned int line, const char *fmt, ...);
 
-#define jbd_debug(n, f, a...)						\
-	do {								\
-		if ((n) <= jbd2_journal_enable_debug) {			\
-			printk (KERN_DEBUG "(%s, %d): %s: ",		\
-				__FILE__, __LINE__, __func__);	\
-			printk (f, ## a);				\
-		}							\
-	} while (0)
+#define jbd_debug(n, fmt, a...) \
+	__jbd2_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a)
 #else
-#define jbd_debug(f, a...)	/**/
+#define jbd_debug(n, fmt, a...)    /**/
 #endif
 
 extern void *jbd2_alloc(size_t size, gfp_t flags);
-- 
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux