This prevents the merging of printk() continuation lines of different threads, in the case they race against each other. It should properly isolate "atomic" single-line printk() users from continuation users, to make sure the single-line users will never be merged with the racy continuation ones.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -1230,12 +1230,13 @@ asmlinkage int vprintk_emit(int facility, int level, · 1229 unmodified lines | ||
| 1230 | 1230 | static size_t buflen; |
| 1231 | 1231 | static int buflevel; |
| 1232 | 1232 | static char textbuf[LOG_LINE_MAX]; |
| 1233 | + static struct task_struct *cont; | |
| 1233 | 1234 | char *text = textbuf; |
| 1234 | 1235 | size_t textlen; |
| 1235 | 1236 | unsigned long flags; |
| 1236 | 1237 | int this_cpu; |
| 1237 | 1238 | bool newline = false; |
| 1238 | − bool cont = false; | |
| 1239 | + bool prefix = false; | |
| 1239 | 1240 | int printed_len = 0; |
| 1240 | 1241 | |
| 1241 | 1242 | boot_delay_msec(); |
| @@ -1295,20 +1296,16 @@ asmlinkage int vprintk_emit(int facility, int level, · 53 unmodified lines | ||
| 1295 | 1296 | case '0' ... '7': |
| 1296 | 1297 | if (level == -1) |
| 1297 | 1298 | level = text[1] - '0'; |
| 1298 | − text += 3; | |
| 1299 | − textlen -= 3; | |
| 1300 | − break; | |
| 1301 | − case 'c': /* KERN_CONT */ | |
| 1302 | − cont = true; | |
| 1303 | 1299 | case 'd': /* KERN_DEFAULT */ |
| 1300 | + prefix = true; | |
| 1301 | + case 'c': /* KERN_CONT */ | |
| 1304 | 1302 | text += 3; |
| 1305 | 1303 | textlen -= 3; |
| 1306 | − break; | |
| 1307 | 1304 | } |
| 1308 | 1305 | } |
| 1309 | 1306 | |
| 1310 | − if (buflen && (!cont || dict)) { | |
| 1311 | − /* no continuation; flush existing buffer */ | |
| 1307 | + if (buflen && (prefix || dict || cont != current)) { | |
| 1308 | + /* flush existing buffer */ | |
| 1312 | 1309 | log_store(facility, buflevel, NULL, 0, buf, buflen); |
| 1313 | 1310 | printed_len += buflen; |
| 1314 | 1311 | buflen = 0; |
| @@ -1342,6 +1339,10 @@ asmlinkage int vprintk_emit(int facility, int level, · 27 unmodified lines | ||
| 1342 | 1339 | dict, dictlen, text, textlen); |
| 1343 | 1340 | printed_len += textlen; |
| 1344 | 1341 | } |
| 1342 | + cont = NULL; | |
| 1343 | + } else { | |
| 1344 | + /* remember thread which filled the buffer */ | |
| 1345 | + cont = current; | |
| 1345 | 1346 | } |
| 1346 | 1347 | |
| 1347 | 1348 | /* |