summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-05-14 21:43:58 +0200
committerKay Sievers <kay@vrfy.org>2012-05-14 21:43:58 +0200
commitd639a17ab4d435a2cebf3bbcabb7e4150efd1661 (patch)
tree26ed8bedbc3a8b23654c244cf61fe11b06586f5e
parent8c556ad44e089fe75e1dac058a3fd5219663b40f (diff)
downloadpatches-d639a17ab4d435a2cebf3bbcabb7e4150efd1661.tar.gz
all merged in Greg's tree
-rw-r--r--kmsg-sep-cont.patch217
-rw-r--r--series1
2 files changed, 0 insertions, 218 deletions
diff --git a/kmsg-sep-cont.patch b/kmsg-sep-cont.patch
deleted file mode 100644
index 146fa94..0000000
--- a/kmsg-sep-cont.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From: Kay Sievers <kay@vrfy.org>
-Subject: printk() - isolate KERN_CONT users from ordinary complete lines
-
-Arrange the contination printk() buffering to be fully separated from the
-ordinary full line users.
-
-Limit the exposure to races and wrong printk() line merges to users of
-continuation only. Ordinary users racing against continuation users will
-no longer affect each other.
-
-Multiple continuation users from differnt threads, racing against each
-other will not wrongly be merged into a single line, but printed as
-separate lines.
-
-Test output of a kernel module which starts two separate threads which
-race against each other, one of them printing a single full terminated
-line:
- printk("(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)\n");
-
-The other one printing the line, every character separate in a
-continuation loop:
- printk("(C");
- for (i = 0; i < 58; i++)
- printk(KERN_CONT "C");
- printk(KERN_CONT "C)\n");
-
-Behavior of single and non-thread-aware printk() buffer:
- # modprobe printk-race
- printk test init
- (CC(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- C(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- CC(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- C(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- CC(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- C(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- C(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- CC(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- C(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- C(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC)
- (CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC)
-
-New behavior with separate and thread-aware continuation buffer:
- # modprobe printk-race
- printk test init
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC)
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
- (CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC)
- (CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC)
-
-Signed-off-by: Kay Sievers <kay@vrfy.org>
----
-
- kernel/printk.c | 113 ++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 65 insertions(+), 48 deletions(-)
-
---- a/kernel/printk.c
-+++ b/kernel/printk.c
-@@ -1264,13 +1264,13 @@ asmlinkage int vprintk_emit(int facility
- const char *fmt, va_list args)
- {
- static int recursion_bug;
-- static char buf[LOG_LINE_MAX];
-- static size_t buflen;
-- static int buflevel;
-+ static char cont_buf[LOG_LINE_MAX];
-+ static size_t cont_len;
-+ static int cont_level;
-+ static struct task_struct *cont_task;
- static char textbuf[LOG_LINE_MAX];
-- static struct task_struct *cont;
- char *text = textbuf;
-- size_t textlen;
-+ size_t text_len;
- unsigned long flags;
- int this_cpu;
- bool newline = false;
-@@ -1320,15 +1320,15 @@ asmlinkage int vprintk_emit(int facility
- * The printf needs to come first; we need the syslog
- * prefix which might be passed-in as a parameter.
- */
-- textlen = vscnprintf(text, sizeof(textbuf), fmt, args);
-+ text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
-
- /* mark and strip a trailing newline */
-- if (textlen && text[textlen-1] == '\n') {
-- textlen--;
-+ if (text_len && text[text_len-1] == '\n') {
-+ text_len--;
- newline = true;
- }
-
-- /* strip syslog prefix and extract log level or flags */
-+ /* strip syslog prefix and extract log level or control flags */
- if (text[0] == '<' && text[1] && text[2] == '>') {
- switch (text[1]) {
- case '0' ... '7':
-@@ -1338,49 +1338,67 @@ asmlinkage int vprintk_emit(int facility
- prefix = true;
- case 'c': /* KERN_CONT */
- text += 3;
-- textlen -= 3;
-+ text_len -= 3;
- }
- }
-
-- if (buflen && (prefix || dict || cont != current)) {
-- /* flush existing buffer */
-- log_store(facility, buflevel, NULL, 0, buf, buflen);
-- printed_len += buflen;
-- buflen = 0;
-- }
--
-- if (buflen == 0) {
-- /* remember level for first message in the buffer */
-- if (level == -1)
-- buflevel = default_message_loglevel;
-- else
-- buflevel = level;
-- }
--
-- if (buflen || !newline) {
-- /* append to existing buffer, or buffer until next message */
-- if (buflen + textlen > sizeof(buf))
-- textlen = sizeof(buf) - buflen;
-- memcpy(buf + buflen, text, textlen);
-- buflen += textlen;
-- }
--
-- if (newline) {
-- /* end of line; flush buffer */
-- if (buflen) {
-- log_store(facility, buflevel,
-- dict, dictlen, buf, buflen);
-- printed_len += buflen;
-- buflen = 0;
-- } else {
-- log_store(facility, buflevel,
-- dict, dictlen, text, textlen);
-- printed_len += textlen;
-+ if (level == -1)
-+ level = default_message_loglevel;
-+
-+ if (dict) {
-+ prefix = true;
-+ newline = true;
-+ }
-+
-+ if (!newline) {
-+ if (cont_len && (prefix || cont_task != current)) {
-+ /*
-+ * Flush earlier buffer, which is either from a
-+ * different thread, or when we got a new prefix.
-+ */
-+ log_store(facility, cont_level, NULL, 0, cont_buf, cont_len);
-+ cont_len = 0;
- }
-- cont = NULL;
-+
-+ if (!cont_len) {
-+ cont_level = level;
-+ cont_task = current;
-+ }
-+
-+ /* buffer or append to earlier buffer from the same thread */
-+ if (cont_len + text_len > sizeof(cont_buf))
-+ text_len = sizeof(cont_buf) - cont_len;
-+ memcpy(cont_buf + cont_len, text, text_len);
-+ cont_len += text_len;
- } else {
-- /* remember thread which filled the buffer */
-- cont = current;
-+ if (cont_len && cont_task == current) {
-+ if (prefix) {
-+ /*
-+ * New prefix from the same thread; flush. We
-+ * either got no earlier newline, or we race
-+ * with an interrupt.
-+ */
-+ log_store(facility, cont_level,
-+ NULL, 0, cont_buf, cont_len);
-+ cont_len = 0;
-+ }
-+
-+ /* append to the earlier buffer and flush */
-+ if (cont_len + text_len > sizeof(cont_buf))
-+ text_len = sizeof(cont_buf) - cont_len;
-+ memcpy(cont_buf + cont_len, text, text_len);
-+ cont_len += text_len;
-+ log_store(facility, cont_level,
-+ NULL, 0, cont_buf, cont_len);
-+ cont_len = 0;
-+ cont_task = NULL;
-+ printed_len = cont_len;
-+ } else {
-+ /* ordinary single and terminated line */
-+ log_store(facility, level,
-+ dict, dictlen, text, text_len);
-+ printed_len = text_len;
-+ }
- }
-
- /*
-@@ -1470,7 +1488,6 @@ EXPORT_SYMBOL(printk);
- #define LOG_LINE_MAX 0
- static struct log *log_from_idx(u32 idx) { return NULL; }
- static u32 log_next(u32 idx) { return 0; }
--static char *log_text(const struct log *msg) { return NULL; }
- static void call_console_drivers(int level, const char *text, size_t len) {}
- static size_t msg_print_text(const struct log *msg, bool syslog,
- char *buf, size_t size) { return 0; }
diff --git a/series b/series
index 6b57b5f..24de0b3 100644
--- a/series
+++ b/series
@@ -1,3 +1,2 @@
-kmsg-sep-cont.patch
printk-race.patch