summaryrefslogtreecommitdiffstats
path: root/kernel/printk
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-25 14:27:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-15 00:02:49 -0500
commit5aa068ea4082b39eafc356c27c9ecd155b0895f6 (patch)
tree7904b431eed74578a43a09c9984090b08350065a /kernel/printk
parent196202be3cfc75762b0075e2d69f55cef949c610 (diff)
printk: remove games with previous record flags
The record logging code looks at the previous record flags in various ways, and they are all wrong. You can't use the previous record flags to determine anything about the next record, because they may simply not be related. In particular, the reason the previous record was a continuation record may well be exactly _because_ the new record was printed by a different process, which is why the previous record was flushed. So all those games are simply wrong, and make the code hard to understand (because the code fundamentally cdoes not make sense). So remove it. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/printk')
-rw-r--r--kernel/printk/printk.c109
1 files changed, 24 insertions, 85 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index a3ce35e0fa1e..50b2703d6d6a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -356,7 +356,6 @@ DECLARE_WAIT_QUEUE_HEAD(log_wait);
356/* the next printk record to read by syslog(READ) or /proc/kmsg */ 356/* the next printk record to read by syslog(READ) or /proc/kmsg */
357static u64 syslog_seq; 357static u64 syslog_seq;
358static u32 syslog_idx; 358static u32 syslog_idx;
359static enum log_flags syslog_prev;
360static size_t syslog_partial; 359static size_t syslog_partial;
361 360
362/* index and sequence number of the first record stored in the buffer */ 361/* index and sequence number of the first record stored in the buffer */
@@ -370,7 +369,6 @@ static u32 log_next_idx;
370/* the next printk record to write to the console */ 369/* the next printk record to write to the console */
371static u64 console_seq; 370static u64 console_seq;
372static u32 console_idx; 371static u32 console_idx;
373static enum log_flags console_prev;
374 372
375/* the next printk record to read after the last 'clear' command */ 373/* the next printk record to read after the last 'clear' command */
376static u64 clear_seq; 374static u64 clear_seq;
@@ -639,27 +637,15 @@ static void append_char(char **pp, char *e, char c)
639} 637}
640 638
641static ssize_t msg_print_ext_header(char *buf, size_t size, 639static ssize_t msg_print_ext_header(char *buf, size_t size,
642 struct printk_log *msg, u64 seq, 640 struct printk_log *msg, u64 seq)
643 enum log_flags prev_flags)
644{ 641{
645 u64 ts_usec = msg->ts_nsec; 642 u64 ts_usec = msg->ts_nsec;
646 char cont = '-';
647 643
648 do_div(ts_usec, 1000); 644 do_div(ts_usec, 1000);
649 645
650 /*
651 * If we couldn't merge continuation line fragments during the print,
652 * export the stored flags to allow an optional external merge of the
653 * records. Merging the records isn't always neccessarily correct, like
654 * when we hit a race during printing. In most cases though, it produces
655 * better readable output. 'c' in the record flags mark the first
656 * fragment of a line, '+' the following.
657 */
658 if (msg->flags & LOG_CONT)
659 cont = (prev_flags & LOG_CONT) ? '+' : 'c';
660
661 return scnprintf(buf, size, "%u,%llu,%llu,%c;", 646 return scnprintf(buf, size, "%u,%llu,%llu,%c;",
662 (msg->facility << 3) | msg->level, seq, ts_usec, cont); 647 (msg->facility << 3) | msg->level, seq, ts_usec,
648 msg->flags & LOG_CONT ? 'c' : '-');
663} 649}
664 650
665static ssize_t msg_print_ext_body(char *buf, size_t size, 651static ssize_t msg_print_ext_body(char *buf, size_t size,
@@ -714,7 +700,6 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
714struct devkmsg_user { 700struct devkmsg_user {
715 u64 seq; 701 u64 seq;
716 u32 idx; 702 u32 idx;
717 enum log_flags prev;
718 struct ratelimit_state rs; 703 struct ratelimit_state rs;
719 struct mutex lock; 704 struct mutex lock;
720 char buf[CONSOLE_EXT_LOG_MAX]; 705 char buf[CONSOLE_EXT_LOG_MAX];
@@ -824,12 +809,11 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
824 809
825 msg = log_from_idx(user->idx); 810 msg = log_from_idx(user->idx);
826 len = msg_print_ext_header(user->buf, sizeof(user->buf), 811 len = msg_print_ext_header(user->buf, sizeof(user->buf),
827 msg, user->seq, user->prev); 812 msg, user->seq);
828 len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len, 813 len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
829 log_dict(msg), msg->dict_len, 814 log_dict(msg), msg->dict_len,
830 log_text(msg), msg->text_len); 815 log_text(msg), msg->text_len);
831 816
832 user->prev = msg->flags;
833 user->idx = log_next(user->idx); 817 user->idx = log_next(user->idx);
834 user->seq++; 818 user->seq++;
835 raw_spin_unlock_irq(&logbuf_lock); 819 raw_spin_unlock_irq(&logbuf_lock);
@@ -1210,26 +1194,12 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
1210 return len; 1194 return len;
1211} 1195}
1212 1196
1213static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, 1197static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *buf, size_t size)
1214 bool syslog, char *buf, size_t size)
1215{ 1198{
1216 const char *text = log_text(msg); 1199 const char *text = log_text(msg);
1217 size_t text_size = msg->text_len; 1200 size_t text_size = msg->text_len;
1218 bool prefix = true;
1219 bool newline = true;
1220 size_t len = 0; 1201 size_t len = 0;
1221 1202
1222 if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
1223 prefix = false;
1224
1225 if (msg->flags & LOG_CONT) {
1226 if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
1227 prefix = false;
1228
1229 if (!(msg->flags & LOG_NEWLINE))
1230 newline = false;
1231 }
1232
1233 do { 1203 do {
1234 const char *next = memchr(text, '\n', text_size); 1204 const char *next = memchr(text, '\n', text_size);
1235 size_t text_len; 1205 size_t text_len;
@@ -1247,22 +1217,17 @@ static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
1247 text_len + 1 >= size - len) 1217 text_len + 1 >= size - len)
1248 break; 1218 break;
1249 1219
1250 if (prefix) 1220 len += print_prefix(msg, syslog, buf + len);
1251 len += print_prefix(msg, syslog, buf + len);
1252 memcpy(buf + len, text, text_len); 1221 memcpy(buf + len, text, text_len);
1253 len += text_len; 1222 len += text_len;
1254 if (next || newline) 1223 buf[len++] = '\n';
1255 buf[len++] = '\n';
1256 } else { 1224 } else {
1257 /* SYSLOG_ACTION_* buffer size only calculation */ 1225 /* SYSLOG_ACTION_* buffer size only calculation */
1258 if (prefix) 1226 len += print_prefix(msg, syslog, NULL);
1259 len += print_prefix(msg, syslog, NULL);
1260 len += text_len; 1227 len += text_len;
1261 if (next || newline) 1228 len++;
1262 len++;
1263 } 1229 }
1264 1230
1265 prefix = true;
1266 text = next; 1231 text = next;
1267 } while (text); 1232 } while (text);
1268 1233
@@ -1288,7 +1253,6 @@ static int syslog_print(char __user *buf, int size)
1288 /* messages are gone, move to first one */ 1253 /* messages are gone, move to first one */
1289 syslog_seq = log_first_seq; 1254 syslog_seq = log_first_seq;
1290 syslog_idx = log_first_idx; 1255 syslog_idx = log_first_idx;
1291 syslog_prev = 0;
1292 syslog_partial = 0; 1256 syslog_partial = 0;
1293 } 1257 }
1294 if (syslog_seq == log_next_seq) { 1258 if (syslog_seq == log_next_seq) {
@@ -1298,13 +1262,11 @@ static int syslog_print(char __user *buf, int size)
1298 1262
1299 skip = syslog_partial; 1263 skip = syslog_partial;
1300 msg = log_from_idx(syslog_idx); 1264 msg = log_from_idx(syslog_idx);
1301 n = msg_print_text(msg, syslog_prev, true, text, 1265 n = msg_print_text(msg, true, text, LOG_LINE_MAX + PREFIX_MAX);
1302 LOG_LINE_MAX + PREFIX_MAX);
1303 if (n - syslog_partial <= size) { 1266 if (n - syslog_partial <= size) {
1304 /* message fits into buffer, move forward */ 1267 /* message fits into buffer, move forward */
1305 syslog_idx = log_next(syslog_idx); 1268 syslog_idx = log_next(syslog_idx);
1306 syslog_seq++; 1269 syslog_seq++;
1307 syslog_prev = msg->flags;
1308 n -= syslog_partial; 1270 n -= syslog_partial;
1309 syslog_partial = 0; 1271 syslog_partial = 0;
1310 } else if (!len){ 1272 } else if (!len){
@@ -1347,7 +1309,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1347 u64 next_seq; 1309 u64 next_seq;
1348 u64 seq; 1310 u64 seq;
1349 u32 idx; 1311 u32 idx;
1350 enum log_flags prev;
1351 1312
1352 /* 1313 /*
1353 * Find first record that fits, including all following records, 1314 * Find first record that fits, including all following records,
@@ -1355,12 +1316,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1355 */ 1316 */
1356 seq = clear_seq; 1317 seq = clear_seq;
1357 idx = clear_idx; 1318 idx = clear_idx;
1358 prev = 0;
1359 while (seq < log_next_seq) { 1319 while (seq < log_next_seq) {
1360 struct printk_log *msg = log_from_idx(idx); 1320 struct printk_log *msg = log_from_idx(idx);
1361 1321
1362 len += msg_print_text(msg, prev, true, NULL, 0); 1322 len += msg_print_text(msg, true, NULL, 0);
1363 prev = msg->flags;
1364 idx = log_next(idx); 1323 idx = log_next(idx);
1365 seq++; 1324 seq++;
1366 } 1325 }
@@ -1368,12 +1327,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1368 /* move first record forward until length fits into the buffer */ 1327 /* move first record forward until length fits into the buffer */
1369 seq = clear_seq; 1328 seq = clear_seq;
1370 idx = clear_idx; 1329 idx = clear_idx;
1371 prev = 0;
1372 while (len > size && seq < log_next_seq) { 1330 while (len > size && seq < log_next_seq) {
1373 struct printk_log *msg = log_from_idx(idx); 1331 struct printk_log *msg = log_from_idx(idx);
1374 1332
1375 len -= msg_print_text(msg, prev, true, NULL, 0); 1333 len -= msg_print_text(msg, true, NULL, 0);
1376 prev = msg->flags;
1377 idx = log_next(idx); 1334 idx = log_next(idx);
1378 seq++; 1335 seq++;
1379 } 1336 }
@@ -1386,7 +1343,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1386 struct printk_log *msg = log_from_idx(idx); 1343 struct printk_log *msg = log_from_idx(idx);
1387 int textlen; 1344 int textlen;
1388 1345
1389 textlen = msg_print_text(msg, prev, true, text, 1346 textlen = msg_print_text(msg, true, text,
1390 LOG_LINE_MAX + PREFIX_MAX); 1347 LOG_LINE_MAX + PREFIX_MAX);
1391 if (textlen < 0) { 1348 if (textlen < 0) {
1392 len = textlen; 1349 len = textlen;
@@ -1394,7 +1351,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1394 } 1351 }
1395 idx = log_next(idx); 1352 idx = log_next(idx);
1396 seq++; 1353 seq++;
1397 prev = msg->flags;
1398 1354
1399 raw_spin_unlock_irq(&logbuf_lock); 1355 raw_spin_unlock_irq(&logbuf_lock);
1400 if (copy_to_user(buf + len, text, textlen)) 1356 if (copy_to_user(buf + len, text, textlen))
@@ -1407,7 +1363,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1407 /* messages are gone, move to next one */ 1363 /* messages are gone, move to next one */
1408 seq = log_first_seq; 1364 seq = log_first_seq;
1409 idx = log_first_idx; 1365 idx = log_first_idx;
1410 prev = 0;
1411 } 1366 }
1412 } 1367 }
1413 } 1368 }
@@ -1508,7 +1463,6 @@ int do_syslog(int type, char __user *buf, int len, int source)
1508 /* messages are gone, move to first one */ 1463 /* messages are gone, move to first one */
1509 syslog_seq = log_first_seq; 1464 syslog_seq = log_first_seq;
1510 syslog_idx = log_first_idx; 1465 syslog_idx = log_first_idx;
1511 syslog_prev = 0;
1512 syslog_partial = 0; 1466 syslog_partial = 0;
1513 } 1467 }
1514 if (source == SYSLOG_FROM_PROC) { 1468 if (source == SYSLOG_FROM_PROC) {
@@ -1521,16 +1475,14 @@ int do_syslog(int type, char __user *buf, int len, int source)
1521 } else { 1475 } else {
1522 u64 seq = syslog_seq; 1476 u64 seq = syslog_seq;
1523 u32 idx = syslog_idx; 1477 u32 idx = syslog_idx;
1524 enum log_flags prev = syslog_prev;
1525 1478
1526 error = 0; 1479 error = 0;
1527 while (seq < log_next_seq) { 1480 while (seq < log_next_seq) {
1528 struct printk_log *msg = log_from_idx(idx); 1481 struct printk_log *msg = log_from_idx(idx);
1529 1482
1530 error += msg_print_text(msg, prev, true, NULL, 0); 1483 error += msg_print_text(msg, true, NULL, 0);
1531 idx = log_next(idx); 1484 idx = log_next(idx);
1532 seq++; 1485 seq++;
1533 prev = msg->flags;
1534 } 1486 }
1535 error -= syslog_partial; 1487 error -= syslog_partial;
1536 } 1488 }
@@ -1712,7 +1664,7 @@ static size_t cont_print_text(char *text, size_t size)
1712 size_t textlen = 0; 1664 size_t textlen = 0;
1713 size_t len; 1665 size_t len;
1714 1666
1715 if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) { 1667 if (cont.cons == 0) {
1716 textlen += print_time(cont.ts_nsec, text); 1668 textlen += print_time(cont.ts_nsec, text);
1717 size -= textlen; 1669 size -= textlen;
1718 } 1670 }
@@ -1981,11 +1933,9 @@ static u64 syslog_seq;
1981static u32 syslog_idx; 1933static u32 syslog_idx;
1982static u64 console_seq; 1934static u64 console_seq;
1983static u32 console_idx; 1935static u32 console_idx;
1984static enum log_flags syslog_prev;
1985static u64 log_first_seq; 1936static u64 log_first_seq;
1986static u32 log_first_idx; 1937static u32 log_first_idx;
1987static u64 log_next_seq; 1938static u64 log_next_seq;
1988static enum log_flags console_prev;
1989static struct cont { 1939static struct cont {
1990 size_t len; 1940 size_t len;
1991 size_t cons; 1941 size_t cons;
@@ -1997,15 +1947,15 @@ static char *log_dict(const struct printk_log *msg) { return NULL; }
1997static struct printk_log *log_from_idx(u32 idx) { return NULL; } 1947static struct printk_log *log_from_idx(u32 idx) { return NULL; }
1998static u32 log_next(u32 idx) { return 0; } 1948static u32 log_next(u32 idx) { return 0; }
1999static ssize_t msg_print_ext_header(char *buf, size_t size, 1949static ssize_t msg_print_ext_header(char *buf, size_t size,
2000 struct printk_log *msg, u64 seq, 1950 struct printk_log *msg,
2001 enum log_flags prev_flags) { return 0; } 1951 u64 seq) { return 0; }
2002static ssize_t msg_print_ext_body(char *buf, size_t size, 1952static ssize_t msg_print_ext_body(char *buf, size_t size,
2003 char *dict, size_t dict_len, 1953 char *dict, size_t dict_len,
2004 char *text, size_t text_len) { return 0; } 1954 char *text, size_t text_len) { return 0; }
2005static void call_console_drivers(int level, 1955static void call_console_drivers(int level,
2006 const char *ext_text, size_t ext_len, 1956 const char *ext_text, size_t ext_len,
2007 const char *text, size_t len) {} 1957 const char *text, size_t len) {}
2008static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, 1958static size_t msg_print_text(const struct printk_log *msg,
2009 bool syslog, char *buf, size_t size) { return 0; } 1959 bool syslog, char *buf, size_t size) { return 0; }
2010static size_t cont_print_text(char *text, size_t size) { return 0; } 1960static size_t cont_print_text(char *text, size_t size) { return 0; }
2011static bool suppress_message_printing(int level) { return false; } 1961static bool suppress_message_printing(int level) { return false; }
@@ -2382,7 +2332,6 @@ again:
2382 /* messages are gone, move to first one */ 2332 /* messages are gone, move to first one */
2383 console_seq = log_first_seq; 2333 console_seq = log_first_seq;
2384 console_idx = log_first_idx; 2334 console_idx = log_first_idx;
2385 console_prev = 0;
2386 } else { 2335 } else {
2387 len = 0; 2336 len = 0;
2388 } 2337 }
@@ -2407,16 +2356,14 @@ skip:
2407 * will properly dump everything later. 2356 * will properly dump everything later.
2408 */ 2357 */
2409 msg->flags &= ~LOG_NOCONS; 2358 msg->flags &= ~LOG_NOCONS;
2410 console_prev = msg->flags;
2411 goto skip; 2359 goto skip;
2412 } 2360 }
2413 2361
2414 len += msg_print_text(msg, console_prev, false, 2362 len += msg_print_text(msg, false, text + len, sizeof(text) - len);
2415 text + len, sizeof(text) - len);
2416 if (nr_ext_console_drivers) { 2363 if (nr_ext_console_drivers) {
2417 ext_len = msg_print_ext_header(ext_text, 2364 ext_len = msg_print_ext_header(ext_text,
2418 sizeof(ext_text), 2365 sizeof(ext_text),
2419 msg, console_seq, console_prev); 2366 msg, console_seq);
2420 ext_len += msg_print_ext_body(ext_text + ext_len, 2367 ext_len += msg_print_ext_body(ext_text + ext_len,
2421 sizeof(ext_text) - ext_len, 2368 sizeof(ext_text) - ext_len,
2422 log_dict(msg), msg->dict_len, 2369 log_dict(msg), msg->dict_len,
@@ -2424,7 +2371,6 @@ skip:
2424 } 2371 }
2425 console_idx = log_next(console_idx); 2372 console_idx = log_next(console_idx);
2426 console_seq++; 2373 console_seq++;
2427 console_prev = msg->flags;
2428 raw_spin_unlock(&logbuf_lock); 2374 raw_spin_unlock(&logbuf_lock);
2429 2375
2430 stop_critical_timings(); /* don't trace print latency */ 2376 stop_critical_timings(); /* don't trace print latency */
@@ -2719,7 +2665,6 @@ void register_console(struct console *newcon)
2719 raw_spin_lock_irqsave(&logbuf_lock, flags); 2665 raw_spin_lock_irqsave(&logbuf_lock, flags);
2720 console_seq = syslog_seq; 2666 console_seq = syslog_seq;
2721 console_idx = syslog_idx; 2667 console_idx = syslog_idx;
2722 console_prev = syslog_prev;
2723 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2668 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2724 /* 2669 /*
2725 * We're about to replay the log buffer. Only do this to the 2670 * We're about to replay the log buffer. Only do this to the
@@ -3075,7 +3020,7 @@ bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
3075 goto out; 3020 goto out;
3076 3021
3077 msg = log_from_idx(dumper->cur_idx); 3022 msg = log_from_idx(dumper->cur_idx);
3078 l = msg_print_text(msg, 0, syslog, line, size); 3023 l = msg_print_text(msg, syslog, line, size);
3079 3024
3080 dumper->cur_idx = log_next(dumper->cur_idx); 3025 dumper->cur_idx = log_next(dumper->cur_idx);
3081 dumper->cur_seq++; 3026 dumper->cur_seq++;
@@ -3144,7 +3089,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
3144 u32 idx; 3089 u32 idx;
3145 u64 next_seq; 3090 u64 next_seq;
3146 u32 next_idx; 3091 u32 next_idx;
3147 enum log_flags prev;
3148 size_t l = 0; 3092 size_t l = 0;
3149 bool ret = false; 3093 bool ret = false;
3150 3094
@@ -3167,27 +3111,23 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
3167 /* calculate length of entire buffer */ 3111 /* calculate length of entire buffer */
3168 seq = dumper->cur_seq; 3112 seq = dumper->cur_seq;
3169 idx = dumper->cur_idx; 3113 idx = dumper->cur_idx;
3170 prev = 0;
3171 while (seq < dumper->next_seq) { 3114 while (seq < dumper->next_seq) {
3172 struct printk_log *msg = log_from_idx(idx); 3115 struct printk_log *msg = log_from_idx(idx);
3173 3116
3174 l += msg_print_text(msg, prev, true, NULL, 0); 3117 l += msg_print_text(msg, true, NULL, 0);
3175 idx = log_next(idx); 3118 idx = log_next(idx);
3176 seq++; 3119 seq++;
3177 prev = msg->flags;
3178 } 3120 }
3179 3121
3180 /* move first record forward until length fits into the buffer */ 3122 /* move first record forward until length fits into the buffer */
3181 seq = dumper->cur_seq; 3123 seq = dumper->cur_seq;
3182 idx = dumper->cur_idx; 3124 idx = dumper->cur_idx;
3183 prev = 0;
3184 while (l > size && seq < dumper->next_seq) { 3125 while (l > size && seq < dumper->next_seq) {
3185 struct printk_log *msg = log_from_idx(idx); 3126 struct printk_log *msg = log_from_idx(idx);
3186 3127
3187 l -= msg_print_text(msg, prev, true, NULL, 0); 3128 l -= msg_print_text(msg, true, NULL, 0);
3188 idx = log_next(idx); 3129 idx = log_next(idx);
3189 seq++; 3130 seq++;
3190 prev = msg->flags;
3191 } 3131 }
3192 3132
3193 /* last message in next interation */ 3133 /* last message in next interation */
@@ -3198,10 +3138,9 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
3198 while (seq < dumper->next_seq) { 3138 while (seq < dumper->next_seq) {
3199 struct printk_log *msg = log_from_idx(idx); 3139 struct printk_log *msg = log_from_idx(idx);
3200 3140
3201 l += msg_print_text(msg, prev, syslog, buf + l, size - l); 3141 l += msg_print_text(msg, syslog, buf + l, size - l);
3202 idx = log_next(idx); 3142 idx = log_next(idx);
3203 seq++; 3143 seq++;
3204 prev = msg->flags;
3205 } 3144 }
3206 3145
3207 dumper->next_seq = next_seq; 3146 dumper->next_seq = next_seq;