public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
To: linux-kernel@vger.kernel.org
Cc: Eiichi Tsukata <eiichi.tsukata.xh@hitachi.com>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Kay Sievers <kay@vrfy.org>, Tejun Heo <tj@kernel.org>,
	yrl.pp-manager.tt@hitachi.com,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Joe Perches <joe@perches.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Subject: [PATCH 1/2] printk: Add dictionary information in structure cont
Date: Fri, 20 Dec 2013 18:41:37 +0900	[thread overview]
Message-ID: <20131220094137.24233.46216.stgit@yunodevel> (raw)
In-Reply-To: <20131220094134.24233.2969.stgit@yunodevel>

Add dictionary information in structure cont.
Dictionary information is added when a driver uses structured printk, and the
information is shown in /dev/kmsg. Current kernel directly stores the
information to log_buf. This patch stores the dict information in structure cont
first, then the information in cont is stored to log_buf.

Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
Cc: Kay Sievers <kay@vrfy.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Joe Perches <joe@perches.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: linux-kernel@vger.kernel.org
---
 kernel/printk/printk.c |   70 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 47 insertions(+), 23 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index be7c86b..c3662e6 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1391,8 +1391,10 @@ static inline void printk_delay(void)
  * reached the console in case of a kernel crash.
  */
 static struct cont {
-	char buf[LOG_LINE_MAX];
-	size_t len;			/* length == 0 means unused buffer */
+	char text[LOG_LINE_MAX];
+	size_t text_len;		/* length == 0 means unused buffer */
+	char dict[LOG_LINE_MAX];	/* stores dict */
+	size_t dict_len;		/* 0 means dict is unstored */
 	size_t cons;			/* bytes written to console */
 	struct task_struct *owner;	/* task of first print*/
 	u64 ts_nsec;			/* time of first print */
@@ -1406,7 +1408,7 @@ static void cont_flush(enum log_flags flags)
 {
 	if (cont.flushed)
 		return;
-	if (cont.len == 0)
+	if (cont.text_len == 0)
 		return;
 
 	if (cont.cons) {
@@ -1416,7 +1418,7 @@ static void cont_flush(enum log_flags flags)
 		 * line. LOG_NOCONS suppresses a duplicated output.
 		 */
 		log_store(cont.facility, cont.level, flags | LOG_NOCONS,
-			  cont.ts_nsec, NULL, 0, cont.buf, cont.len);
+			  cont.ts_nsec, NULL, 0, cont.text, cont.text_len);
 		cont.flags = flags;
 		cont.flushed = true;
 	} else {
@@ -1425,23 +1427,32 @@ static void cont_flush(enum log_flags flags)
 		 * just submit it to the store and free the buffer.
 		 */
 		log_store(cont.facility, cont.level, flags, 0,
-			  NULL, 0, cont.buf, cont.len);
-		cont.len = 0;
+			  NULL, 0, cont.text, cont.text_len);
+		cont.text_len = 0;
 	}
 }
 
-static bool cont_add(int facility, int level, const char *text, size_t len)
+static void cont_dict_add(const char *dict, size_t dict_len)
 {
-	if (cont.len && cont.flushed)
+	if (cont.dict_len + dict_len > sizeof(cont.dict))
+		return;
+
+	memcpy(cont.dict + cont.dict_len, dict, dict_len);
+	cont.dict_len += dict_len;
+}
+
+static bool cont_add(int facility, int level, const char *text, size_t text_len)
+{
+	if (cont.text_len && cont.flushed)
 		return false;
 
-	if (cont.len + len > sizeof(cont.buf)) {
+	if (cont.text_len + text_len > sizeof(cont.text)) {
 		/* the line gets too long, split it up in separate records */
 		cont_flush(LOG_CONT);
 		return false;
 	}
 
-	if (!cont.len) {
+	if (!cont.text_len) {
 		cont.facility = facility;
 		cont.level = level;
 		cont.owner = current;
@@ -1451,10 +1462,10 @@ static bool cont_add(int facility, int level, const char *text, size_t len)
 		cont.flushed = false;
 	}
 
-	memcpy(cont.buf + cont.len, text, len);
-	cont.len += len;
+	memcpy(cont.text + cont.text_len, text, text_len);
+	cont.text_len += text_len;
 
-	if (cont.len > (sizeof(cont.buf) * 80) / 100)
+	if (cont.text_len > (sizeof(cont.text) * 80) / 100)
 		cont_flush(LOG_CONT);
 
 	return true;
@@ -1470,20 +1481,20 @@ static size_t cont_print_text(char *text, size_t size)
 		size -= textlen;
 	}
 
-	len = cont.len - cont.cons;
+	len = cont.text_len - cont.cons;
 	if (len > 0) {
 		if (len+1 > size)
 			len = size-1;
-		memcpy(text + textlen, cont.buf + cont.cons, len);
+		memcpy(text + textlen, cont.text + cont.cons, len);
 		textlen += len;
-		cont.cons = cont.len;
+		cont.cons = cont.text_len;
 	}
 
 	if (cont.flushed) {
 		if (cont.flags & LOG_NEWLINE)
 			text[textlen++] = '\n';
 		/* got everything, release buffer */
-		cont.len = 0;
+		cont.text_len = 0;
 	}
 	return textlen;
 }
@@ -1576,21 +1587,29 @@ asmlinkage int vprintk_emit(int facility, int level,
 	if (level == -1)
 		level = default_message_loglevel;
 
-	if (dict)
+	if (dict) {
 		lflags |= LOG_PREFIX|LOG_NEWLINE;
 
+		/* Another task is trying to output a message */
+		if (cont.text_len && cont.owner != current)
+			cont_flush(LOG_NEWLINE);
+
+		cont_dict_add(dict, dictlen);
+	}
+
 	if (!(lflags & LOG_NEWLINE)) {
 		/*
 		 * Flush the conflicting buffer. An earlier newline was missing,
 		 * or another task also prints continuation lines.
 		 */
-		if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+		if (cont.text_len &&
+		    (lflags & LOG_PREFIX || cont.owner != current))
 			cont_flush(LOG_NEWLINE);
 
 		/* buffer line if possible, otherwise store it right away */
 		if (!cont_add(facility, level, text, text_len))
 			log_store(facility, level, lflags | LOG_CONT, 0,
-				  dict, dictlen, text, text_len);
+				  NULL, 0, text, text_len);
 	} else {
 		bool stored = false;
 
@@ -1600,7 +1619,7 @@ asmlinkage int vprintk_emit(int facility, int level,
 		 * there was a race with interrupts (prefix == true) then just
 		 * flush it out and store this line separately.
 		 */
-		if (cont.len && cont.owner == current) {
+		if (cont.text_len && cont.owner == current) {
 			if (!(lflags & LOG_PREFIX))
 				stored = cont_add(facility, level, text, text_len);
 			cont_flush(LOG_NEWLINE);
@@ -1608,7 +1627,12 @@ asmlinkage int vprintk_emit(int facility, int level,
 
 		if (!stored)
 			log_store(facility, level, lflags, 0,
-				  dict, dictlen, text, text_len);
+				  cont.dict, cont.dict_len, text, text_len);
+		/*
+		 * Structured printk always starts a new line now, so clear
+		 * current dictionary information for next structured printk.
+		 */
+		cont.dict_len = 0;
 	}
 	printed_len += text_len;
 
@@ -1974,7 +1998,7 @@ static void console_cont_flush(char *text, size_t size)
 
 	raw_spin_lock_irqsave(&logbuf_lock, flags);
 
-	if (!cont.len)
+	if (!cont.text_len)
 		goto out;
 
 	/*


  reply	other threads:[~2013-12-20  9:41 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-20  9:41 [PATCH 0/2] [BUGFIX] printk: Fix message continuation breakage involved with structured printk Yoshihiro YUNOMAE
2013-12-20  9:41 ` Yoshihiro YUNOMAE [this message]
2013-12-20 11:32   ` [PATCH 1/2] printk: Add dictionary information in structure cont Kay Sievers
2013-12-20  9:41 ` [PATCH 2/2] printk: Delete LOG_NEWLINE flag for structured printk Yoshihiro YUNOMAE
2013-12-20 11:36   ` Kay Sievers
2013-12-20 11:29 ` [PATCH 0/2] [BUGFIX] printk: Fix message continuation breakage involved with " Kay Sievers
2013-12-24  2:50   ` Yoshihiro YUNOMAE
2013-12-24  3:00     ` Kay Sievers
2013-12-24  4:54       ` Yoshihiro YUNOMAE

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=20131220094137.24233.46216.stgit@yunodevel \
    --to=yoshihiro.yunomae.ez@hitachi.com \
    --cc=akpm@linux-foundation.org \
    --cc=eiichi.tsukata.xh@hitachi.com \
    --cc=fweisbec@gmail.com \
    --cc=hidehiro.kawai.ez@hitachi.com \
    --cc=joe@perches.com \
    --cc=kay@vrfy.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=tj@kernel.org \
    --cc=yrl.pp-manager.tt@hitachi.com \
    /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