Merge tag 'driver-core-3.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver Core fixes from Greg Kroah-Hartman:
"Here is a number of printk() fixes, specifically a few reported by the
crazy blog program that ships in SUSE releases (that's "boot log" and
not "web log", it predates the general "blog" terminology by many
years), and the restoration of the continuation line functionality
reported by Stephen and others. Yes, the changes seem a bit big this
late in the cycle, but I've been beating on them for a while now, and
Stephen has even optimized it a bit, so all looks good to me.

The other change in here is a Documentation update for the stable
kernel rules describing how some distro patches should be backported,
to hopefully drive a bit more response from the distros to the stable
kernel releases.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"

* tag 'driver-core-3.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
printk: Optimize if statement logic where newline exists
printk: flush continuation lines immediately to console
syslog: fill buffer with more than a single message for SYSLOG_ACTION_READ
Revert "printk: return -EINVAL if the message len is bigger than the buf size"
printk: fix regression in SYSLOG_ACTION_CLEAR
stable: Allow merging of backports for serious user-visible performance issues

Changed files
+220 -85
Documentation
kernel
+6
Documentation/stable_kernel_rules.txt
··· 12 12 marked CONFIG_BROKEN), an oops, a hang, data corruption, a real 13 13 security issue, or some "oh, that's not good" issue. In short, something 14 14 critical. 15 + - Serious issues as reported by a user of a distribution kernel may also 16 + be considered if they fix a notable performance or interactivity issue. 17 + As these fixes are not as obvious and have a higher risk of a subtle 18 + regression they should only be submitted by a distribution kernel 19 + maintainer and include an addendum linking to a bugzilla entry if it 20 + exists and additional information on the user-visible impact. 15 21 - New device IDs and quirks are also accepted. 16 22 - No "theoretical race condition" issues, unless an explanation of how the 17 23 race can be exploited is also provided.
+214 -85
kernel/printk.c
··· 193 193 * separated by ',', and find the message after the ';' character. 194 194 */ 195 195 196 + enum log_flags { 197 + LOG_DEFAULT = 0, 198 + LOG_NOCONS = 1, /* already flushed, do not print to console */ 199 + }; 200 + 196 201 struct log { 197 202 u64 ts_nsec; /* timestamp in nanoseconds */ 198 203 u16 len; /* length of entire record */ 199 204 u16 text_len; /* length of text buffer */ 200 205 u16 dict_len; /* length of dictionary buffer */ 201 - u16 level; /* syslog level + facility */ 206 + u8 facility; /* syslog facility */ 207 + u8 flags:5; /* internal record flags */ 208 + u8 level:3; /* syslog level */ 202 209 }; 203 210 204 211 /* ··· 293 286 294 287 /* insert record into the buffer, discard old ones, update heads */ 295 288 static void log_store(int facility, int level, 289 + enum log_flags flags, u64 ts_nsec, 296 290 const char *dict, u16 dict_len, 297 291 const char *text, u16 text_len) 298 292 { ··· 337 329 msg->text_len = text_len; 338 330 memcpy(log_dict(msg), dict, dict_len); 339 331 msg->dict_len = dict_len; 340 - msg->level = (facility << 3) | (level & 7); 341 - msg->ts_nsec = local_clock(); 332 + msg->facility = facility; 333 + msg->level = level & 7; 334 + msg->flags = flags & 0x1f; 335 + if (ts_nsec > 0) 336 + msg->ts_nsec = ts_nsec; 337 + else 338 + msg->ts_nsec = local_clock(); 342 339 memset(log_dict(msg) + dict_len, 0, pad_len); 343 340 msg->len = sizeof(struct log) + text_len + dict_len + pad_len; 344 341 ··· 459 446 ts_usec = msg->ts_nsec; 460 447 do_div(ts_usec, 1000); 461 448 len = sprintf(user->buf, "%u,%llu,%llu;", 462 - msg->level, user->seq, ts_usec); 449 + (msg->facility << 3) | msg->level, user->seq, ts_usec); 463 450 464 451 /* escape non-printable characters */ 465 452 for (i = 0; i < msg->text_len; i++) { ··· 800 787 #endif 801 788 module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); 802 789 790 + static size_t print_time(u64 ts, char *buf) 791 + { 792 + unsigned long rem_nsec; 793 + 794 + if (!printk_time) 795 + return 0; 796 + 797 + if (!buf) 798 + return 15; 799 + 800 + rem_nsec = do_div(ts, 1000000000); 801 + return sprintf(buf, "[%5lu.%06lu] ", 802 + (unsigned long)ts, rem_nsec / 1000); 803 + } 804 + 803 805 static size_t print_prefix(const struct log *msg, bool syslog, char *buf) 804 806 { 805 807 size_t len = 0; ··· 831 803 } 832 804 } 833 805 834 - if (printk_time) { 835 - if (buf) { 836 - unsigned long long ts = msg->ts_nsec; 837 - unsigned long rem_nsec = do_div(ts, 1000000000); 838 - 839 - len += sprintf(buf + len, "[%5lu.%06lu] ", 840 - (unsigned long) ts, rem_nsec / 1000); 841 - } else { 842 - len += 15; 843 - } 844 - } 845 - 806 + len += print_time(msg->ts_nsec, buf ? buf + len : NULL); 846 807 return len; 847 808 } 848 809 ··· 879 862 { 880 863 char *text; 881 864 struct log *msg; 882 - int len; 865 + int len = 0; 883 866 884 867 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); 885 868 if (!text) 886 869 return -ENOMEM; 887 870 888 - raw_spin_lock_irq(&logbuf_lock); 889 - if (syslog_seq < log_first_seq) { 890 - /* messages are gone, move to first one */ 891 - syslog_seq = log_first_seq; 892 - syslog_idx = log_first_idx; 893 - } 894 - msg = log_from_idx(syslog_idx); 895 - len = msg_print_text(msg, true, text, LOG_LINE_MAX); 896 - syslog_idx = log_next(syslog_idx); 897 - syslog_seq++; 898 - raw_spin_unlock_irq(&logbuf_lock); 871 + while (size > 0) { 872 + size_t n; 899 873 900 - if (len > size) 901 - len = -EINVAL; 902 - else if (len > 0 && copy_to_user(buf, text, len)) 903 - len = -EFAULT; 874 + raw_spin_lock_irq(&logbuf_lock); 875 + if (syslog_seq < log_first_seq) { 876 + /* messages are gone, move to first one */ 877 + syslog_seq = log_first_seq; 878 + syslog_idx = log_first_idx; 879 + } 880 + if (syslog_seq == log_next_seq) { 881 + raw_spin_unlock_irq(&logbuf_lock); 882 + break; 883 + } 884 + msg = log_from_idx(syslog_idx); 885 + n = msg_print_text(msg, true, text, LOG_LINE_MAX); 886 + if (n <= size) { 887 + syslog_idx = log_next(syslog_idx); 888 + syslog_seq++; 889 + } else 890 + n = 0; 891 + raw_spin_unlock_irq(&logbuf_lock); 892 + 893 + if (!n) 894 + break; 895 + 896 + len += n; 897 + size -= n; 898 + buf += n; 899 + n = copy_to_user(buf - n, text, n); 900 + 901 + if (n) { 902 + len -= n; 903 + if (!len) 904 + len = -EFAULT; 905 + break; 906 + } 907 + } 904 908 905 909 kfree(text); 906 910 return len; ··· 1078 1040 /* Clear ring buffer */ 1079 1041 case SYSLOG_ACTION_CLEAR: 1080 1042 syslog_print_all(NULL, 0, true); 1043 + break; 1081 1044 /* Disable logging to console */ 1082 1045 case SYSLOG_ACTION_CONSOLE_OFF: 1083 1046 if (saved_console_loglevel == -1) ··· 1311 1272 } 1312 1273 } 1313 1274 1275 + /* 1276 + * Continuation lines are buffered, and not committed to the record buffer 1277 + * until the line is complete, or a race forces it. The line fragments 1278 + * though, are printed immediately to the consoles to ensure everything has 1279 + * reached the console in case of a kernel crash. 1280 + */ 1281 + static struct cont { 1282 + char buf[LOG_LINE_MAX]; 1283 + size_t len; /* length == 0 means unused buffer */ 1284 + size_t cons; /* bytes written to console */ 1285 + struct task_struct *owner; /* task of first print*/ 1286 + u64 ts_nsec; /* time of first print */ 1287 + u8 level; /* log level of first message */ 1288 + u8 facility; /* log level of first message */ 1289 + bool flushed:1; /* buffer sealed and committed */ 1290 + } cont; 1291 + 1292 + static void cont_flush(void) 1293 + { 1294 + if (cont.flushed) 1295 + return; 1296 + if (cont.len == 0) 1297 + return; 1298 + 1299 + log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec, 1300 + NULL, 0, cont.buf, cont.len); 1301 + 1302 + cont.flushed = true; 1303 + } 1304 + 1305 + static bool cont_add(int facility, int level, const char *text, size_t len) 1306 + { 1307 + if (cont.len && cont.flushed) 1308 + return false; 1309 + 1310 + if (cont.len + len > sizeof(cont.buf)) { 1311 + cont_flush(); 1312 + return false; 1313 + } 1314 + 1315 + if (!cont.len) { 1316 + cont.facility = facility; 1317 + cont.level = level; 1318 + cont.owner = current; 1319 + cont.ts_nsec = local_clock(); 1320 + cont.cons = 0; 1321 + cont.flushed = false; 1322 + } 1323 + 1324 + memcpy(cont.buf + cont.len, text, len); 1325 + cont.len += len; 1326 + return true; 1327 + } 1328 + 1329 + static size_t cont_print_text(char *text, size_t size) 1330 + { 1331 + size_t textlen = 0; 1332 + size_t len; 1333 + 1334 + if (cont.cons == 0) { 1335 + textlen += print_time(cont.ts_nsec, text); 1336 + size -= textlen; 1337 + } 1338 + 1339 + len = cont.len - cont.cons; 1340 + if (len > 0) { 1341 + if (len+1 > size) 1342 + len = size-1; 1343 + memcpy(text + textlen, cont.buf + cont.cons, len); 1344 + textlen += len; 1345 + cont.cons = cont.len; 1346 + } 1347 + 1348 + if (cont.flushed) { 1349 + text[textlen++] = '\n'; 1350 + /* got everything, release buffer */ 1351 + cont.len = 0; 1352 + } 1353 + return textlen; 1354 + } 1355 + 1314 1356 asmlinkage int vprintk_emit(int facility, int level, 1315 1357 const char *dict, size_t dictlen, 1316 1358 const char *fmt, va_list args) 1317 1359 { 1318 1360 static int recursion_bug; 1319 - static char cont_buf[LOG_LINE_MAX]; 1320 - static size_t cont_len; 1321 - static int cont_level; 1322 - static struct task_struct *cont_task; 1323 1361 static char textbuf[LOG_LINE_MAX]; 1324 1362 char *text = textbuf; 1325 1363 size_t text_len; ··· 1442 1326 recursion_bug = 0; 1443 1327 printed_len += strlen(recursion_msg); 1444 1328 /* emit KERN_CRIT message */ 1445 - log_store(0, 2, NULL, 0, recursion_msg, printed_len); 1329 + log_store(0, 2, LOG_DEFAULT, 0, 1330 + NULL, 0, recursion_msg, printed_len); 1446 1331 } 1447 1332 1448 1333 /* ··· 1481 1364 } 1482 1365 1483 1366 if (!newline) { 1484 - if (cont_len && (prefix || cont_task != current)) { 1485 - /* 1486 - * Flush earlier buffer, which is either from a 1487 - * different thread, or when we got a new prefix. 1488 - */ 1489 - log_store(facility, cont_level, NULL, 0, cont_buf, cont_len); 1490 - cont_len = 0; 1491 - } 1367 + /* 1368 + * Flush the conflicting buffer. An earlier newline was missing, 1369 + * or another task also prints continuation lines. 1370 + */ 1371 + if (cont.len && (prefix || cont.owner != current)) 1372 + cont_flush(); 1492 1373 1493 - if (!cont_len) { 1494 - cont_level = level; 1495 - cont_task = current; 1496 - } 1497 - 1498 - /* buffer or append to earlier buffer from the same thread */ 1499 - if (cont_len + text_len > sizeof(cont_buf)) 1500 - text_len = sizeof(cont_buf) - cont_len; 1501 - memcpy(cont_buf + cont_len, text, text_len); 1502 - cont_len += text_len; 1503 - } else { 1504 - if (cont_len && cont_task == current) { 1505 - if (prefix) { 1506 - /* 1507 - * New prefix from the same thread; flush. We 1508 - * either got no earlier newline, or we race 1509 - * with an interrupt. 1510 - */ 1511 - log_store(facility, cont_level, 1512 - NULL, 0, cont_buf, cont_len); 1513 - cont_len = 0; 1514 - } 1515 - 1516 - /* append to the earlier buffer and flush */ 1517 - if (cont_len + text_len > sizeof(cont_buf)) 1518 - text_len = sizeof(cont_buf) - cont_len; 1519 - memcpy(cont_buf + cont_len, text, text_len); 1520 - cont_len += text_len; 1521 - log_store(facility, cont_level, 1522 - NULL, 0, cont_buf, cont_len); 1523 - cont_len = 0; 1524 - cont_task = NULL; 1525 - printed_len = cont_len; 1526 - } else { 1527 - /* ordinary single and terminated line */ 1528 - log_store(facility, level, 1374 + /* buffer line if possible, otherwise store it right away */ 1375 + if (!cont_add(facility, level, text, text_len)) 1376 + log_store(facility, level, LOG_DEFAULT, 0, 1529 1377 dict, dictlen, text, text_len); 1530 - printed_len = text_len; 1378 + } else { 1379 + bool stored = false; 1380 + 1381 + /* 1382 + * If an earlier newline was missing and it was the same task, 1383 + * either merge it with the current buffer and flush, or if 1384 + * there was a race with interrupts (prefix == true) then just 1385 + * flush it out and store this line separately. 1386 + */ 1387 + if (cont.len && cont.owner == current) { 1388 + if (!prefix) 1389 + stored = cont_add(facility, level, text, text_len); 1390 + cont_flush(); 1531 1391 } 1392 + 1393 + if (!stored) 1394 + log_store(facility, level, LOG_DEFAULT, 0, 1395 + dict, dictlen, text, text_len); 1532 1396 } 1397 + printed_len += text_len; 1533 1398 1534 1399 /* 1535 1400 * Try to acquire and then immediately release the console semaphore. ··· 1598 1499 #else 1599 1500 1600 1501 #define LOG_LINE_MAX 0 1502 + static struct cont { 1503 + size_t len; 1504 + size_t cons; 1505 + u8 level; 1506 + bool flushed:1; 1507 + } cont; 1601 1508 static struct log *log_from_idx(u32 idx) { return NULL; } 1602 1509 static u32 log_next(u32 idx) { return 0; } 1603 1510 static void call_console_drivers(int level, const char *text, size_t len) {} 1604 1511 static size_t msg_print_text(const struct log *msg, bool syslog, 1605 1512 char *buf, size_t size) { return 0; } 1513 + static size_t cont_print_text(char *text, size_t size) { return 0; } 1606 1514 1607 1515 #endif /* CONFIG_PRINTK */ 1608 1516 ··· 1901 1795 */ 1902 1796 void console_unlock(void) 1903 1797 { 1798 + static char text[LOG_LINE_MAX]; 1904 1799 static u64 seen_seq; 1905 1800 unsigned long flags; 1906 1801 bool wake_klogd = false; ··· 1914 1807 1915 1808 console_may_schedule = 0; 1916 1809 1810 + /* flush buffered message fragment immediately to console */ 1811 + raw_spin_lock_irqsave(&logbuf_lock, flags); 1812 + if (cont.len && (cont.cons < cont.len || cont.flushed)) { 1813 + size_t len; 1814 + 1815 + len = cont_print_text(text, sizeof(text)); 1816 + raw_spin_unlock(&logbuf_lock); 1817 + stop_critical_timings(); 1818 + call_console_drivers(cont.level, text, len); 1819 + start_critical_timings(); 1820 + local_irq_restore(flags); 1821 + } else 1822 + raw_spin_unlock_irqrestore(&logbuf_lock, flags); 1823 + 1917 1824 again: 1918 1825 for (;;) { 1919 1826 struct log *msg; 1920 - static char text[LOG_LINE_MAX]; 1921 1827 size_t len; 1922 1828 int level; 1923 1829 ··· 1945 1825 console_seq = log_first_seq; 1946 1826 console_idx = log_first_idx; 1947 1827 } 1948 - 1828 + skip: 1949 1829 if (console_seq == log_next_seq) 1950 1830 break; 1951 1831 1952 1832 msg = log_from_idx(console_idx); 1953 - level = msg->level & 7; 1833 + if (msg->flags & LOG_NOCONS) { 1834 + /* 1835 + * Skip record we have buffered and already printed 1836 + * directly to the console when we received it. 1837 + */ 1838 + console_idx = log_next(console_idx); 1839 + console_seq++; 1840 + goto skip; 1841 + } 1954 1842 1843 + level = msg->level; 1955 1844 len = msg_print_text(msg, false, text, sizeof(text)); 1956 1845 1957 1846 console_idx = log_next(console_idx);