[PATCH v2 03/14] printk: reclaim cont buffer immediately for fully printed messages

From: Jan H. SchÃnherr
Date: Thu Dec 06 2012 - 12:08:43 EST


We only need to keep the contents of the cont buffer, when there is a
partly printed message in it. In both other cases, not yet printed as
well as fully printed messages, we can reclaim the buffer immediately.

Currently, we do not reclaim the cont buffer when it contains a fully
printed message. This commit restructures the logic to achieve that.
(Note, that LOG_NOCONS must still be set for partly _and_ fully printed
messages, making it a bit more complicated than just changing the
if-condition.)

Signed-off-by: Jan H. SchÃnherr <schnhrr@xxxxxxxxxxxxxxx>
---
v2:
- fixed a bug, where the buffer was considered fully printed although
a final newline was still pending
---
kernel/printk.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/kernel/printk.c b/kernel/printk.c
index 0927068..13af61c 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1400,24 +1400,27 @@ static void cont_flush(enum log_flags flags)
return;

cont.flags |= flags;
- if (cont.cons) {
- /*
- * If a fragment of this line was directly flushed to the
- * console; wait for the console to pick up the rest of the
- * line. LOG_NOCONS suppresses a duplicated output.
- */
- log_store(cont.facility, cont.level, cont.flags | LOG_NOCONS,
- cont.ts_nsec, NULL, 0, cont.buf, cont.len);
- cont.flushed = true;
- } else {
- /*
- * If no fragment of this line ever reached the console,
- * just submit it to the store and free the buffer.
- */
- log_store(cont.facility, cont.level, cont.flags, cont.ts_nsec,
- NULL, 0, cont.buf, cont.len);
+
+ /*
+ * If a fragment of this line was directly flushed to the console, the
+ * whole line is/was directly printed. Use LOG_NOCONS to suppress a
+ * duplicated output later -- see console_unlock().
+ */
+ if (cont.cons)
+ cont.flags |= LOG_NOCONS;
+
+ log_store(cont.facility, cont.level, cont.flags, cont.ts_nsec, NULL, 0,
+ cont.buf, cont.len);
+
+ /*
+ * If no fragment of this line ever reached the console or everything
+ * has been printed, free the buffer. Otherwise keep it available.
+ */
+ if (!cont.cons || (cont.cons == cont.len &&
+ !(cont.flags & LOG_NEWLINE)))
cont.len = 0;
- }
+ else
+ cont.flushed = true;
}

static bool cont_add(int facility, int level, enum log_flags flags,
--
1.8.0.1.20.g7c65b2e.dirty

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/