From: Paul Gortmaker <paul.gortmaker@windriver.com>
To: "Theodore Ts'o" <tytso@mit.edu>
Cc: <linux-ext4@vger.kernel.org>, <linux-rt-users@vger.kernel.org>
Subject: Re: [PATCH 1/4] jbd2/journal_commit_transaction: relocate state lock to incorporate all users
Date: Tue, 11 Jun 2013 13:38:24 -0400 [thread overview]
Message-ID: <20130611173824.GA29033@windriver.com> (raw)
In-Reply-To: <20130611021230.GA23966@thunk.org>
[Re: [PATCH 1/4] jbd2/journal_commit_transaction: relocate state lock to incorporate all users] On 10/06/2013 (Mon 22:12) Theodore Ts'o wrote:
> On Mon, Jun 10, 2013 at 03:32:00PM -0400, Paul Gortmaker wrote:
> > The state lock is taken after we are doing an assert on the state
> > value, not before. It is also taken after the jbd_debug() call.
> > Noting that 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 "*"):
>
> This is only a cosmetic fix, but instead of trying to fix it by moving
> a lock --- which would only fix this issue, but there are probably
> others cases where this might be an issue, I'd suggest fixing it with
> something like this:
>
> /* in fs/jbd2/journal.c */
> void __jbd2_debug(int level, const char *func, unsigned int line, const char *fmt, ...)
> {
> struct va_format vaf;
> va_list args;
>
> if (level < jbd2_journal_enable_debug)
> return;
I've changed "level <" for "level >" here....
> va_start(args, fmt);
> vaf.fmt = fmt;
> vaf.va = &args
...and added a ";" here.
> printk(KERN_DEBUG, "jbd2: (%s, %u): %pV\n", func, line, &vaf);
I'm so glad to see that I am not the only one who accidentally keeps
putting a comma after the KERN_<N> values. :)
I'd thought about using pr_debug() but decided not to, since it is a
no-op without us actually defining DEBUG somewhere, and if we don't,
then people would wonder where their debug output went, I think.
> va_end(args);
> }
>
> /* in jbd2.h */
>
> #define jbd_debug(n, fmt, a...) __jbd2_debug((n), __func__, __LINE__, (fmt), ##a)
>
> Could you give this approach a try?
Since both ext3 and ext4 will suffer the same problem, I've made
a combined solution. It has passed a basic sanity test here, so
maybe if you have a spare moment, you could have a look to determine
if you are OK with the implementation, while I continue fixing up
the others and doing more testing?
Thanks,
Paul.
--
>From fbedf3102700b034395404dfdc7ac2dcae145af8 Mon Sep 17 00:00:00 2001
From: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Tue, 11 Jun 2013 11:46:10 -0400
Subject: [PATCH] jbd/jbd2: make common 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 make the jbd_debug a shared
implementation, so to fix ext3 and reduce duplication at the same time.
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 6e5524f..ea88e8e 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -56,17 +56,9 @@
*/
#define JBD_EXPENSIVE_CHECKING
extern u8 journal_enable_debug;
-
-#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 JOURNAL_ENABLE_DEBUG journal_enable_debug
#else
-#define jbd_debug(f, a...) /**/
+#define JOURNAL_ENABLE_DEBUG INT_MAX
#endif
static inline void *jbd_alloc(size_t size, gfp_t flags)
@@ -245,6 +237,13 @@ typedef struct journal_superblock_s
#include <linux/sched.h>
#include <linux/jbd_common.h>
+#ifdef CONFIG_JBD_DEBUG
+#define jbd_debug(n, fmt, a...) \
+ __jbd_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a)
+#else
+#define jbd_debug(n, fmt, a...) /**/
+#endif
+
#define J_ASSERT(assert) BUG_ON(!(assert))
#define J_ASSERT_BH(bh, expr) J_ASSERT(expr)
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 9986ab8..c39a9ca 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -56,17 +56,9 @@
*/
#define JBD2_EXPENSIVE_CHECKING
extern ushort jbd2_journal_enable_debug;
-
-#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 JOURNAL_ENABLE_DEBUG jbd2_journal_enable_debug
#else
-#define jbd_debug(f, a...) /**/
+#define JOURNAL_ENABLE_DEBUG INT_MAX
#endif
extern void *jbd2_alloc(size_t size, gfp_t flags);
@@ -303,6 +295,13 @@ typedef struct journal_superblock_s
#include <linux/sched.h>
#include <linux/jbd_common.h>
+#ifdef CONFIG_JBD2_DEBUG
+#define jbd_debug(n, fmt, a...) \
+ __jbd_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a)
+#else
+#define jbd_debug(n, fmt, a...) /**/
+#endif
+
#define J_ASSERT(assert) BUG_ON(!(assert))
#define J_ASSERT_BH(bh, expr) J_ASSERT(expr)
diff --git a/include/linux/jbd_common.h b/include/linux/jbd_common.h
index 949b5dd..c8e2fba 100644
--- a/include/linux/jbd_common.h
+++ b/include/linux/jbd_common.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_JBD_STATE_H
#define _LINUX_JBD_STATE_H
+#include <linux/printk.h>
#include <linux/bit_spinlock.h>
enum jbd_state_bits {
@@ -29,6 +30,23 @@ TAS_BUFFER_FNS(RevokeValid, revokevalid)
BUFFER_FNS(Freed, freed)
BUFFER_FNS(Verified, verified)
+#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
+
static inline struct buffer_head *jh2bh(struct journal_head *jh)
{
return jh->b_bh;
--
1.8.1.2
next prev parent reply other threads:[~2013-06-11 17:38 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-10 19:31 [RFC PATCH 0/4] ext4/jbd2: several possible mainline fixes Paul Gortmaker
2013-06-10 19:32 ` [PATCH 1/4] jbd2/journal_commit_transaction: relocate state lock to incorporate all users Paul Gortmaker
2013-06-11 2:12 ` Theodore Ts'o
2013-06-11 2:45 ` Paul Gortmaker
2013-06-11 2:52 ` Theodore Ts'o
2013-06-11 17:38 ` Paul Gortmaker [this message]
2013-06-11 17:53 ` Theodore Ts'o
2013-06-11 18:48 ` Paul Gortmaker
2013-06-11 21:54 ` Paul Gortmaker
2013-06-10 19:32 ` [PATCH 2/4] jbd2/log_wait_for_space: drop checkpoint mutex when waiting Paul Gortmaker
2013-06-11 2:33 ` Theodore Ts'o
2013-06-11 3:20 ` Paul Gortmaker
2013-06-11 13:03 ` Theodore Ts'o
2013-06-11 13:20 ` Paul Gortmaker
2013-06-10 19:32 ` [PATCH 3/4] jbd2: fix duplicate debug label for phase 2 Paul Gortmaker
2013-06-10 19:32 ` [PATCH 4/4] jbd/jbd2: relocate bit_spinlock header to jbd_common Paul Gortmaker
2013-06-10 23:38 ` [RFC PATCH 0/4] ext4/jbd2: several possible mainline fixes Theodore Ts'o
2013-06-11 3:09 ` Paul Gortmaker
2013-06-11 22:44 ` [PATCH v2 0/6] misc jbd2 fixes and cleanups Paul Gortmaker
2013-06-11 22:44 ` [PATCH 1/6] jbd2/journal_commit_transaction: relocate assert after state lock Paul Gortmaker
2013-06-13 2:42 ` Theodore Ts'o
2013-06-11 22:44 ` [PATCH 2/6] jbd2/log_wait_for_space: drop checkpoint mutex when waiting Paul Gortmaker
2013-06-13 2:55 ` Theodore Ts'o
2013-06-11 22:44 ` [PATCH 3/6] jbd2: fix duplicate debug label for phase 2 Paul Gortmaker
2013-06-13 2:57 ` Theodore Ts'o
2013-06-11 22:44 ` [PATCH 4/6] jbd/jbd2: relocate bit_spinlock header to jbd_common Paul Gortmaker
2013-06-13 3:02 ` Theodore Ts'o
2013-06-11 22:44 ` [PATCH 5/6] jbd2: make jbd_debug that won't split printk statements Paul Gortmaker
2013-06-11 22:44 ` [PATCH 6/6] jbd2: remove debug dependency on debug_fs; update help text Paul Gortmaker
2013-06-13 3:08 ` Theodore Ts'o
2013-06-13 13:51 ` Paul Gortmaker
2013-06-13 14:14 ` Theodore Ts'o
2013-06-13 14:47 ` Paul Gortmaker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130611173824.GA29033@windriver.com \
--to=paul.gortmaker@windriver.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-rt-users@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).