aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c727
1 files changed, 554 insertions, 173 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 32462d2b364a..ac4bc9e79465 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -193,12 +193,21 @@ static int console_may_schedule;
193 * separated by ',', and find the message after the ';' character. 193 * separated by ',', and find the message after the ';' character.
194 */ 194 */
195 195
196enum log_flags {
197 LOG_NOCONS = 1, /* already flushed, do not print to console */
198 LOG_NEWLINE = 2, /* text ended with a newline */
199 LOG_PREFIX = 4, /* text started with a prefix */
200 LOG_CONT = 8, /* text is a fragment of a continuation line */
201};
202
196struct log { 203struct log {
197 u64 ts_nsec; /* timestamp in nanoseconds */ 204 u64 ts_nsec; /* timestamp in nanoseconds */
198 u16 len; /* length of entire record */ 205 u16 len; /* length of entire record */
199 u16 text_len; /* length of text buffer */ 206 u16 text_len; /* length of text buffer */
200 u16 dict_len; /* length of dictionary buffer */ 207 u16 dict_len; /* length of dictionary buffer */
201 u16 level; /* syslog level + facility */ 208 u8 facility; /* syslog facility */
209 u8 flags:5; /* internal record flags */
210 u8 level:3; /* syslog level */
202}; 211};
203 212
204/* 213/*
@@ -210,6 +219,8 @@ static DEFINE_RAW_SPINLOCK(logbuf_lock);
210/* the next printk record to read by syslog(READ) or /proc/kmsg */ 219/* the next printk record to read by syslog(READ) or /proc/kmsg */
211static u64 syslog_seq; 220static u64 syslog_seq;
212static u32 syslog_idx; 221static u32 syslog_idx;
222static enum log_flags syslog_prev;
223static size_t syslog_partial;
213 224
214/* index and sequence number of the first record stored in the buffer */ 225/* index and sequence number of the first record stored in the buffer */
215static u64 log_first_seq; 226static u64 log_first_seq;
@@ -227,10 +238,10 @@ static u32 clear_idx;
227#define LOG_LINE_MAX 1024 238#define LOG_LINE_MAX 1024
228 239
229/* record buffer */ 240/* record buffer */
230#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 241#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
231#define LOG_ALIGN 4 242#define LOG_ALIGN 4
232#else 243#else
233#define LOG_ALIGN 8 244#define LOG_ALIGN __alignof__(struct log)
234#endif 245#endif
235#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) 246#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
236static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); 247static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
@@ -286,6 +297,7 @@ static u32 log_next(u32 idx)
286 297
287/* insert record into the buffer, discard old ones, update heads */ 298/* insert record into the buffer, discard old ones, update heads */
288static void log_store(int facility, int level, 299static void log_store(int facility, int level,
300 enum log_flags flags, u64 ts_nsec,
289 const char *dict, u16 dict_len, 301 const char *dict, u16 dict_len,
290 const char *text, u16 text_len) 302 const char *text, u16 text_len)
291{ 303{
@@ -329,8 +341,13 @@ static void log_store(int facility, int level,
329 msg->text_len = text_len; 341 msg->text_len = text_len;
330 memcpy(log_dict(msg), dict, dict_len); 342 memcpy(log_dict(msg), dict, dict_len);
331 msg->dict_len = dict_len; 343 msg->dict_len = dict_len;
332 msg->level = (facility << 3) | (level & 7); 344 msg->facility = facility;
333 msg->ts_nsec = local_clock(); 345 msg->level = level & 7;
346 msg->flags = flags & 0x1f;
347 if (ts_nsec > 0)
348 msg->ts_nsec = ts_nsec;
349 else
350 msg->ts_nsec = local_clock();
334 memset(log_dict(msg) + dict_len, 0, pad_len); 351 memset(log_dict(msg) + dict_len, 0, pad_len);
335 msg->len = sizeof(struct log) + text_len + dict_len + pad_len; 352 msg->len = sizeof(struct log) + text_len + dict_len + pad_len;
336 353
@@ -414,21 +431,23 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
414 if (!user) 431 if (!user)
415 return -EBADF; 432 return -EBADF;
416 433
417 mutex_lock(&user->lock); 434 ret = mutex_lock_interruptible(&user->lock);
418 raw_spin_lock(&logbuf_lock); 435 if (ret)
436 return ret;
437 raw_spin_lock_irq(&logbuf_lock);
419 while (user->seq == log_next_seq) { 438 while (user->seq == log_next_seq) {
420 if (file->f_flags & O_NONBLOCK) { 439 if (file->f_flags & O_NONBLOCK) {
421 ret = -EAGAIN; 440 ret = -EAGAIN;
422 raw_spin_unlock(&logbuf_lock); 441 raw_spin_unlock_irq(&logbuf_lock);
423 goto out; 442 goto out;
424 } 443 }
425 444
426 raw_spin_unlock(&logbuf_lock); 445 raw_spin_unlock_irq(&logbuf_lock);
427 ret = wait_event_interruptible(log_wait, 446 ret = wait_event_interruptible(log_wait,
428 user->seq != log_next_seq); 447 user->seq != log_next_seq);
429 if (ret) 448 if (ret)
430 goto out; 449 goto out;
431 raw_spin_lock(&logbuf_lock); 450 raw_spin_lock_irq(&logbuf_lock);
432 } 451 }
433 452
434 if (user->seq < log_first_seq) { 453 if (user->seq < log_first_seq) {
@@ -436,7 +455,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
436 user->idx = log_first_idx; 455 user->idx = log_first_idx;
437 user->seq = log_first_seq; 456 user->seq = log_first_seq;
438 ret = -EPIPE; 457 ret = -EPIPE;
439 raw_spin_unlock(&logbuf_lock); 458 raw_spin_unlock_irq(&logbuf_lock);
440 goto out; 459 goto out;
441 } 460 }
442 461
@@ -444,13 +463,13 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
444 ts_usec = msg->ts_nsec; 463 ts_usec = msg->ts_nsec;
445 do_div(ts_usec, 1000); 464 do_div(ts_usec, 1000);
446 len = sprintf(user->buf, "%u,%llu,%llu;", 465 len = sprintf(user->buf, "%u,%llu,%llu;",
447 msg->level, user->seq, ts_usec); 466 (msg->facility << 3) | msg->level, user->seq, ts_usec);
448 467
449 /* escape non-printable characters */ 468 /* escape non-printable characters */
450 for (i = 0; i < msg->text_len; i++) { 469 for (i = 0; i < msg->text_len; i++) {
451 unsigned char c = log_text(msg)[i]; 470 unsigned char c = log_text(msg)[i];
452 471
453 if (c < ' ' || c >= 128) 472 if (c < ' ' || c >= 127 || c == '\\')
454 len += sprintf(user->buf + len, "\\x%02x", c); 473 len += sprintf(user->buf + len, "\\x%02x", c);
455 else 474 else
456 user->buf[len++] = c; 475 user->buf[len++] = c;
@@ -474,7 +493,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
474 continue; 493 continue;
475 } 494 }
476 495
477 if (c < ' ' || c >= 128) { 496 if (c < ' ' || c >= 127 || c == '\\') {
478 len += sprintf(user->buf + len, "\\x%02x", c); 497 len += sprintf(user->buf + len, "\\x%02x", c);
479 continue; 498 continue;
480 } 499 }
@@ -486,7 +505,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
486 505
487 user->idx = log_next(user->idx); 506 user->idx = log_next(user->idx);
488 user->seq++; 507 user->seq++;
489 raw_spin_unlock(&logbuf_lock); 508 raw_spin_unlock_irq(&logbuf_lock);
490 509
491 if (len > count) { 510 if (len > count) {
492 ret = -EINVAL; 511 ret = -EINVAL;
@@ -513,7 +532,7 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
513 if (offset) 532 if (offset)
514 return -ESPIPE; 533 return -ESPIPE;
515 534
516 raw_spin_lock(&logbuf_lock); 535 raw_spin_lock_irq(&logbuf_lock);
517 switch (whence) { 536 switch (whence) {
518 case SEEK_SET: 537 case SEEK_SET:
519 /* the first record */ 538 /* the first record */
@@ -537,7 +556,7 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
537 default: 556 default:
538 ret = -EINVAL; 557 ret = -EINVAL;
539 } 558 }
540 raw_spin_unlock(&logbuf_lock); 559 raw_spin_unlock_irq(&logbuf_lock);
541 return ret; 560 return ret;
542} 561}
543 562
@@ -551,14 +570,14 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait)
551 570
552 poll_wait(file, &log_wait, wait); 571 poll_wait(file, &log_wait, wait);
553 572
554 raw_spin_lock(&logbuf_lock); 573 raw_spin_lock_irq(&logbuf_lock);
555 if (user->seq < log_next_seq) { 574 if (user->seq < log_next_seq) {
556 /* return error when data has vanished underneath us */ 575 /* return error when data has vanished underneath us */
557 if (user->seq < log_first_seq) 576 if (user->seq < log_first_seq)
558 ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI; 577 ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI;
559 ret = POLLIN|POLLRDNORM; 578 ret = POLLIN|POLLRDNORM;
560 } 579 }
561 raw_spin_unlock(&logbuf_lock); 580 raw_spin_unlock_irq(&logbuf_lock);
562 581
563 return ret; 582 return ret;
564} 583}
@@ -582,10 +601,10 @@ static int devkmsg_open(struct inode *inode, struct file *file)
582 601
583 mutex_init(&user->lock); 602 mutex_init(&user->lock);
584 603
585 raw_spin_lock(&logbuf_lock); 604 raw_spin_lock_irq(&logbuf_lock);
586 user->idx = log_first_idx; 605 user->idx = log_first_idx;
587 user->seq = log_first_seq; 606 user->seq = log_first_seq;
588 raw_spin_unlock(&logbuf_lock); 607 raw_spin_unlock_irq(&logbuf_lock);
589 608
590 file->private_data = user; 609 file->private_data = user;
591 return 0; 610 return 0;
@@ -785,44 +804,64 @@ static bool printk_time;
785#endif 804#endif
786module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); 805module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
787 806
807static size_t print_time(u64 ts, char *buf)
808{
809 unsigned long rem_nsec;
810
811 if (!printk_time)
812 return 0;
813
814 if (!buf)
815 return 15;
816
817 rem_nsec = do_div(ts, 1000000000);
818 return sprintf(buf, "[%5lu.%06lu] ",
819 (unsigned long)ts, rem_nsec / 1000);
820}
821
788static size_t print_prefix(const struct log *msg, bool syslog, char *buf) 822static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
789{ 823{
790 size_t len = 0; 824 size_t len = 0;
825 unsigned int prefix = (msg->facility << 3) | msg->level;
791 826
792 if (syslog) { 827 if (syslog) {
793 if (buf) { 828 if (buf) {
794 len += sprintf(buf, "<%u>", msg->level); 829 len += sprintf(buf, "<%u>", prefix);
795 } else { 830 } else {
796 len += 3; 831 len += 3;
797 if (msg->level > 9) 832 if (prefix > 999)
798 len++; 833 len += 3;
799 if (msg->level > 99) 834 else if (prefix > 99)
835 len += 2;
836 else if (prefix > 9)
800 len++; 837 len++;
801 } 838 }
802 } 839 }
803 840
804 if (printk_time) { 841 len += print_time(msg->ts_nsec, buf ? buf + len : NULL);
805 if (buf) {
806 unsigned long long ts = msg->ts_nsec;
807 unsigned long rem_nsec = do_div(ts, 1000000000);
808
809 len += sprintf(buf + len, "[%5lu.%06lu] ",
810 (unsigned long) ts, rem_nsec / 1000);
811 } else {
812 len += 15;
813 }
814 }
815
816 return len; 842 return len;
817} 843}
818 844
819static size_t msg_print_text(const struct log *msg, bool syslog, 845static size_t msg_print_text(const struct log *msg, enum log_flags prev,
820 char *buf, size_t size) 846 bool syslog, char *buf, size_t size)
821{ 847{
822 const char *text = log_text(msg); 848 const char *text = log_text(msg);
823 size_t text_size = msg->text_len; 849 size_t text_size = msg->text_len;
850 bool prefix = true;
851 bool newline = true;
824 size_t len = 0; 852 size_t len = 0;
825 853
854 if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
855 prefix = false;
856
857 if (msg->flags & LOG_CONT) {
858 if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
859 prefix = false;
860
861 if (!(msg->flags & LOG_NEWLINE))
862 newline = false;
863 }
864
826 do { 865 do {
827 const char *next = memchr(text, '\n', text_size); 866 const char *next = memchr(text, '\n', text_size);
828 size_t text_len; 867 size_t text_len;
@@ -840,16 +879,22 @@ static size_t msg_print_text(const struct log *msg, bool syslog,
840 text_len + 1>= size - len) 879 text_len + 1>= size - len)
841 break; 880 break;
842 881
843 len += print_prefix(msg, syslog, buf + len); 882 if (prefix)
883 len += print_prefix(msg, syslog, buf + len);
844 memcpy(buf + len, text, text_len); 884 memcpy(buf + len, text, text_len);
845 len += text_len; 885 len += text_len;
846 buf[len++] = '\n'; 886 if (next || newline)
887 buf[len++] = '\n';
847 } else { 888 } else {
848 /* SYSLOG_ACTION_* buffer size only calculation */ 889 /* SYSLOG_ACTION_* buffer size only calculation */
849 len += print_prefix(msg, syslog, NULL); 890 if (prefix)
850 len += text_len + 1; 891 len += print_prefix(msg, syslog, NULL);
892 len += text_len;
893 if (next || newline)
894 len++;
851 } 895 }
852 896
897 prefix = true;
853 text = next; 898 text = next;
854 } while (text); 899 } while (text);
855 900
@@ -860,26 +905,60 @@ static int syslog_print(char __user *buf, int size)
860{ 905{
861 char *text; 906 char *text;
862 struct log *msg; 907 struct log *msg;
863 int len; 908 int len = 0;
864 909
865 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); 910 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
866 if (!text) 911 if (!text)
867 return -ENOMEM; 912 return -ENOMEM;
868 913
869 raw_spin_lock_irq(&logbuf_lock); 914 while (size > 0) {
870 if (syslog_seq < log_first_seq) { 915 size_t n;
871 /* messages are gone, move to first one */ 916 size_t skip;
872 syslog_seq = log_first_seq;
873 syslog_idx = log_first_idx;
874 }
875 msg = log_from_idx(syslog_idx);
876 len = msg_print_text(msg, true, text, LOG_LINE_MAX);
877 syslog_idx = log_next(syslog_idx);
878 syslog_seq++;
879 raw_spin_unlock_irq(&logbuf_lock);
880 917
881 if (len > 0 && copy_to_user(buf, text, len)) 918 raw_spin_lock_irq(&logbuf_lock);
882 len = -EFAULT; 919 if (syslog_seq < log_first_seq) {
920 /* messages are gone, move to first one */
921 syslog_seq = log_first_seq;
922 syslog_idx = log_first_idx;
923 syslog_prev = 0;
924 syslog_partial = 0;
925 }
926 if (syslog_seq == log_next_seq) {
927 raw_spin_unlock_irq(&logbuf_lock);
928 break;
929 }
930
931 skip = syslog_partial;
932 msg = log_from_idx(syslog_idx);
933 n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX);
934 if (n - syslog_partial <= size) {
935 /* message fits into buffer, move forward */
936 syslog_idx = log_next(syslog_idx);
937 syslog_seq++;
938 syslog_prev = msg->flags;
939 n -= syslog_partial;
940 syslog_partial = 0;
941 } else if (!len){
942 /* partial read(), remember position */
943 n = size;
944 syslog_partial += n;
945 } else
946 n = 0;
947 raw_spin_unlock_irq(&logbuf_lock);
948
949 if (!n)
950 break;
951
952 if (copy_to_user(buf, text + skip, n)) {
953 if (!len)
954 len = -EFAULT;
955 break;
956 }
957
958 len += n;
959 size -= n;
960 buf += n;
961 }
883 962
884 kfree(text); 963 kfree(text);
885 return len; 964 return len;
@@ -899,6 +978,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
899 u64 next_seq; 978 u64 next_seq;
900 u64 seq; 979 u64 seq;
901 u32 idx; 980 u32 idx;
981 enum log_flags prev;
902 982
903 if (clear_seq < log_first_seq) { 983 if (clear_seq < log_first_seq) {
904 /* messages are gone, move to first available one */ 984 /* messages are gone, move to first available one */
@@ -909,41 +989,47 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
909 /* 989 /*
910 * Find first record that fits, including all following records, 990 * Find first record that fits, including all following records,
911 * into the user-provided buffer for this dump. 991 * into the user-provided buffer for this dump.
912 */ 992 */
913 seq = clear_seq; 993 seq = clear_seq;
914 idx = clear_idx; 994 idx = clear_idx;
995 prev = 0;
915 while (seq < log_next_seq) { 996 while (seq < log_next_seq) {
916 struct log *msg = log_from_idx(idx); 997 struct log *msg = log_from_idx(idx);
917 998
918 len += msg_print_text(msg, true, NULL, 0); 999 len += msg_print_text(msg, prev, true, NULL, 0);
919 idx = log_next(idx); 1000 idx = log_next(idx);
920 seq++; 1001 seq++;
921 } 1002 }
1003
1004 /* move first record forward until length fits into the buffer */
922 seq = clear_seq; 1005 seq = clear_seq;
923 idx = clear_idx; 1006 idx = clear_idx;
1007 prev = 0;
924 while (len > size && seq < log_next_seq) { 1008 while (len > size && seq < log_next_seq) {
925 struct log *msg = log_from_idx(idx); 1009 struct log *msg = log_from_idx(idx);
926 1010
927 len -= msg_print_text(msg, true, NULL, 0); 1011 len -= msg_print_text(msg, prev, true, NULL, 0);
928 idx = log_next(idx); 1012 idx = log_next(idx);
929 seq++; 1013 seq++;
930 } 1014 }
931 1015
932 /* last message in this dump */ 1016 /* last message fitting into this dump */
933 next_seq = log_next_seq; 1017 next_seq = log_next_seq;
934 1018
935 len = 0; 1019 len = 0;
1020 prev = 0;
936 while (len >= 0 && seq < next_seq) { 1021 while (len >= 0 && seq < next_seq) {
937 struct log *msg = log_from_idx(idx); 1022 struct log *msg = log_from_idx(idx);
938 int textlen; 1023 int textlen;
939 1024
940 textlen = msg_print_text(msg, true, text, LOG_LINE_MAX); 1025 textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX);
941 if (textlen < 0) { 1026 if (textlen < 0) {
942 len = textlen; 1027 len = textlen;
943 break; 1028 break;
944 } 1029 }
945 idx = log_next(idx); 1030 idx = log_next(idx);
946 seq++; 1031 seq++;
1032 prev = msg->flags;
947 1033
948 raw_spin_unlock_irq(&logbuf_lock); 1034 raw_spin_unlock_irq(&logbuf_lock);
949 if (copy_to_user(buf + len, text, textlen)) 1035 if (copy_to_user(buf + len, text, textlen))
@@ -956,6 +1042,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
956 /* messages are gone, move to next one */ 1042 /* messages are gone, move to next one */
957 seq = log_first_seq; 1043 seq = log_first_seq;
958 idx = log_first_idx; 1044 idx = log_first_idx;
1045 prev = 0;
959 } 1046 }
960 } 1047 }
961 } 1048 }
@@ -1027,6 +1114,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1027 /* Clear ring buffer */ 1114 /* Clear ring buffer */
1028 case SYSLOG_ACTION_CLEAR: 1115 case SYSLOG_ACTION_CLEAR:
1029 syslog_print_all(NULL, 0, true); 1116 syslog_print_all(NULL, 0, true);
1117 break;
1030 /* Disable logging to console */ 1118 /* Disable logging to console */
1031 case SYSLOG_ACTION_CONSOLE_OFF: 1119 case SYSLOG_ACTION_CONSOLE_OFF:
1032 if (saved_console_loglevel == -1) 1120 if (saved_console_loglevel == -1)
@@ -1059,6 +1147,8 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1059 /* messages are gone, move to first one */ 1147 /* messages are gone, move to first one */
1060 syslog_seq = log_first_seq; 1148 syslog_seq = log_first_seq;
1061 syslog_idx = log_first_idx; 1149 syslog_idx = log_first_idx;
1150 syslog_prev = 0;
1151 syslog_partial = 0;
1062 } 1152 }
1063 if (from_file) { 1153 if (from_file) {
1064 /* 1154 /*
@@ -1068,19 +1158,20 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1068 */ 1158 */
1069 error = log_next_idx - syslog_idx; 1159 error = log_next_idx - syslog_idx;
1070 } else { 1160 } else {
1071 u64 seq; 1161 u64 seq = syslog_seq;
1072 u32 idx; 1162 u32 idx = syslog_idx;
1163 enum log_flags prev = syslog_prev;
1073 1164
1074 error = 0; 1165 error = 0;
1075 seq = syslog_seq;
1076 idx = syslog_idx;
1077 while (seq < log_next_seq) { 1166 while (seq < log_next_seq) {
1078 struct log *msg = log_from_idx(idx); 1167 struct log *msg = log_from_idx(idx);
1079 1168
1080 error += msg_print_text(msg, true, NULL, 0); 1169 error += msg_print_text(msg, prev, true, NULL, 0);
1081 idx = log_next(idx); 1170 idx = log_next(idx);
1082 seq++; 1171 seq++;
1172 prev = msg->flags;
1083 } 1173 }
1174 error -= syslog_partial;
1084 } 1175 }
1085 raw_spin_unlock_irq(&logbuf_lock); 1176 raw_spin_unlock_irq(&logbuf_lock);
1086 break; 1177 break;
@@ -1101,21 +1192,6 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
1101 return do_syslog(type, buf, len, SYSLOG_FROM_CALL); 1192 return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
1102} 1193}
1103 1194
1104#ifdef CONFIG_KGDB_KDB
1105/* kdb dmesg command needs access to the syslog buffer. do_syslog()
1106 * uses locks so it cannot be used during debugging. Just tell kdb
1107 * where the start and end of the physical and logical logs are. This
1108 * is equivalent to do_syslog(3).
1109 */
1110void kdb_syslog_data(char *syslog_data[4])
1111{
1112 syslog_data[0] = log_buf;
1113 syslog_data[1] = log_buf + log_buf_len;
1114 syslog_data[2] = log_buf + log_first_idx;
1115 syslog_data[3] = log_buf + log_next_idx;
1116}
1117#endif /* CONFIG_KGDB_KDB */
1118
1119static bool __read_mostly ignore_loglevel; 1195static bool __read_mostly ignore_loglevel;
1120 1196
1121static int __init ignore_loglevel_setup(char *str) 1197static int __init ignore_loglevel_setup(char *str)
@@ -1259,22 +1335,98 @@ static inline void printk_delay(void)
1259 } 1335 }
1260} 1336}
1261 1337
1338/*
1339 * Continuation lines are buffered, and not committed to the record buffer
1340 * until the line is complete, or a race forces it. The line fragments
1341 * though, are printed immediately to the consoles to ensure everything has
1342 * reached the console in case of a kernel crash.
1343 */
1344static struct cont {
1345 char buf[LOG_LINE_MAX];
1346 size_t len; /* length == 0 means unused buffer */
1347 size_t cons; /* bytes written to console */
1348 struct task_struct *owner; /* task of first print*/
1349 u64 ts_nsec; /* time of first print */
1350 u8 level; /* log level of first message */
1351 u8 facility; /* log level of first message */
1352 bool flushed:1; /* buffer sealed and committed */
1353} cont;
1354
1355static void cont_flush(void)
1356{
1357 if (cont.flushed)
1358 return;
1359 if (cont.len == 0)
1360 return;
1361
1362 log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec,
1363 NULL, 0, cont.buf, cont.len);
1364
1365 cont.flushed = true;
1366}
1367
1368static bool cont_add(int facility, int level, const char *text, size_t len)
1369{
1370 if (cont.len && cont.flushed)
1371 return false;
1372
1373 if (cont.len + len > sizeof(cont.buf)) {
1374 cont_flush();
1375 return false;
1376 }
1377
1378 if (!cont.len) {
1379 cont.facility = facility;
1380 cont.level = level;
1381 cont.owner = current;
1382 cont.ts_nsec = local_clock();
1383 cont.cons = 0;
1384 cont.flushed = false;
1385 }
1386
1387 memcpy(cont.buf + cont.len, text, len);
1388 cont.len += len;
1389 return true;
1390}
1391
1392static size_t cont_print_text(char *text, size_t size)
1393{
1394 size_t textlen = 0;
1395 size_t len;
1396
1397 if (cont.cons == 0) {
1398 textlen += print_time(cont.ts_nsec, text);
1399 size -= textlen;
1400 }
1401
1402 len = cont.len - cont.cons;
1403 if (len > 0) {
1404 if (len+1 > size)
1405 len = size-1;
1406 memcpy(text + textlen, cont.buf + cont.cons, len);
1407 textlen += len;
1408 cont.cons = cont.len;
1409 }
1410
1411 if (cont.flushed) {
1412 text[textlen++] = '\n';
1413 /* got everything, release buffer */
1414 cont.len = 0;
1415 }
1416 return textlen;
1417}
1418
1262asmlinkage int vprintk_emit(int facility, int level, 1419asmlinkage int vprintk_emit(int facility, int level,
1263 const char *dict, size_t dictlen, 1420 const char *dict, size_t dictlen,
1264 const char *fmt, va_list args) 1421 const char *fmt, va_list args)
1265{ 1422{
1266 static int recursion_bug; 1423 static int recursion_bug;
1267 static char cont_buf[LOG_LINE_MAX];
1268 static size_t cont_len;
1269 static int cont_level;
1270 static struct task_struct *cont_task;
1271 static char textbuf[LOG_LINE_MAX]; 1424 static char textbuf[LOG_LINE_MAX];
1272 char *text = textbuf; 1425 char *text = textbuf;
1273 size_t text_len; 1426 size_t text_len;
1427 enum log_flags lflags = 0;
1274 unsigned long flags; 1428 unsigned long flags;
1275 int this_cpu; 1429 int this_cpu;
1276 bool newline = false;
1277 bool prefix = false;
1278 int printed_len = 0; 1430 int printed_len = 0;
1279 1431
1280 boot_delay_msec(); 1432 boot_delay_msec();
@@ -1313,7 +1465,8 @@ asmlinkage int vprintk_emit(int facility, int level,
1313 recursion_bug = 0; 1465 recursion_bug = 0;
1314 printed_len += strlen(recursion_msg); 1466 printed_len += strlen(recursion_msg);
1315 /* emit KERN_CRIT message */ 1467 /* emit KERN_CRIT message */
1316 log_store(0, 2, NULL, 0, recursion_msg, printed_len); 1468 log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0,
1469 NULL, 0, recursion_msg, printed_len);
1317 } 1470 }
1318 1471
1319 /* 1472 /*
@@ -1325,7 +1478,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1325 /* mark and strip a trailing newline */ 1478 /* mark and strip a trailing newline */
1326 if (text_len && text[text_len-1] == '\n') { 1479 if (text_len && text[text_len-1] == '\n') {
1327 text_len--; 1480 text_len--;
1328 newline = true; 1481 lflags |= LOG_NEWLINE;
1329 } 1482 }
1330 1483
1331 /* strip syslog prefix and extract log level or control flags */ 1484 /* strip syslog prefix and extract log level or control flags */
@@ -1335,7 +1488,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1335 if (level == -1) 1488 if (level == -1)
1336 level = text[1] - '0'; 1489 level = text[1] - '0';
1337 case 'd': /* KERN_DEFAULT */ 1490 case 'd': /* KERN_DEFAULT */
1338 prefix = true; 1491 lflags |= LOG_PREFIX;
1339 case 'c': /* KERN_CONT */ 1492 case 'c': /* KERN_CONT */
1340 text += 3; 1493 text += 3;
1341 text_len -= 3; 1494 text_len -= 3;
@@ -1345,61 +1498,41 @@ asmlinkage int vprintk_emit(int facility, int level,
1345 if (level == -1) 1498 if (level == -1)
1346 level = default_message_loglevel; 1499 level = default_message_loglevel;
1347 1500
1348 if (dict) { 1501 if (dict)
1349 prefix = true; 1502 lflags |= LOG_PREFIX|LOG_NEWLINE;
1350 newline = true;
1351 }
1352
1353 if (!newline) {
1354 if (cont_len && (prefix || cont_task != current)) {
1355 /*
1356 * Flush earlier buffer, which is either from a
1357 * different thread, or when we got a new prefix.
1358 */
1359 log_store(facility, cont_level, NULL, 0, cont_buf, cont_len);
1360 cont_len = 0;
1361 }
1362 1503
1363 if (!cont_len) { 1504 if (!(lflags & LOG_NEWLINE)) {
1364 cont_level = level; 1505 /*
1365 cont_task = current; 1506 * Flush the conflicting buffer. An earlier newline was missing,
1366 } 1507 * or another task also prints continuation lines.
1508 */
1509 if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
1510 cont_flush();
1367 1511
1368 /* buffer or append to earlier buffer from the same thread */ 1512 /* buffer line if possible, otherwise store it right away */
1369 if (cont_len + text_len > sizeof(cont_buf)) 1513 if (!cont_add(facility, level, text, text_len))
1370 text_len = sizeof(cont_buf) - cont_len; 1514 log_store(facility, level, lflags | LOG_CONT, 0,
1371 memcpy(cont_buf + cont_len, text, text_len); 1515 dict, dictlen, text, text_len);
1372 cont_len += text_len;
1373 } else { 1516 } else {
1374 if (cont_len && cont_task == current) { 1517 bool stored = false;
1375 if (prefix) {
1376 /*
1377 * New prefix from the same thread; flush. We
1378 * either got no earlier newline, or we race
1379 * with an interrupt.
1380 */
1381 log_store(facility, cont_level,
1382 NULL, 0, cont_buf, cont_len);
1383 cont_len = 0;
1384 }
1385 1518
1386 /* append to the earlier buffer and flush */ 1519 /*
1387 if (cont_len + text_len > sizeof(cont_buf)) 1520 * If an earlier newline was missing and it was the same task,
1388 text_len = sizeof(cont_buf) - cont_len; 1521 * either merge it with the current buffer and flush, or if
1389 memcpy(cont_buf + cont_len, text, text_len); 1522 * there was a race with interrupts (prefix == true) then just
1390 cont_len += text_len; 1523 * flush it out and store this line separately.
1391 log_store(facility, cont_level, 1524 */
1392 NULL, 0, cont_buf, cont_len); 1525 if (cont.len && cont.owner == current) {
1393 cont_len = 0; 1526 if (!(lflags & LOG_PREFIX))
1394 cont_task = NULL; 1527 stored = cont_add(facility, level, text, text_len);
1395 printed_len = cont_len; 1528 cont_flush();
1396 } else {
1397 /* ordinary single and terminated line */
1398 log_store(facility, level,
1399 dict, dictlen, text, text_len);
1400 printed_len = text_len;
1401 } 1529 }
1530
1531 if (!stored)
1532 log_store(facility, level, lflags, 0,
1533 dict, dictlen, text, text_len);
1402 } 1534 }
1535 printed_len += text_len;
1403 1536
1404 /* 1537 /*
1405 * Try to acquire and then immediately release the console semaphore. 1538 * Try to acquire and then immediately release the console semaphore.
@@ -1486,11 +1619,18 @@ EXPORT_SYMBOL(printk);
1486#else 1619#else
1487 1620
1488#define LOG_LINE_MAX 0 1621#define LOG_LINE_MAX 0
1622static struct cont {
1623 size_t len;
1624 size_t cons;
1625 u8 level;
1626 bool flushed:1;
1627} cont;
1489static struct log *log_from_idx(u32 idx) { return NULL; } 1628static struct log *log_from_idx(u32 idx) { return NULL; }
1490static u32 log_next(u32 idx) { return 0; } 1629static u32 log_next(u32 idx) { return 0; }
1491static void call_console_drivers(int level, const char *text, size_t len) {} 1630static void call_console_drivers(int level, const char *text, size_t len) {}
1492static size_t msg_print_text(const struct log *msg, bool syslog, 1631static size_t msg_print_text(const struct log *msg, enum log_flags prev,
1493 char *buf, size_t size) { return 0; } 1632 bool syslog, char *buf, size_t size) { return 0; }
1633static size_t cont_print_text(char *text, size_t size) { return 0; }
1494 1634
1495#endif /* CONFIG_PRINTK */ 1635#endif /* CONFIG_PRINTK */
1496 1636
@@ -1765,6 +1905,7 @@ void wake_up_klogd(void)
1765/* the next printk record to write to the console */ 1905/* the next printk record to write to the console */
1766static u64 console_seq; 1906static u64 console_seq;
1767static u32 console_idx; 1907static u32 console_idx;
1908static enum log_flags console_prev;
1768 1909
1769/** 1910/**
1770 * console_unlock - unlock the console system 1911 * console_unlock - unlock the console system
@@ -1782,6 +1923,7 @@ static u32 console_idx;
1782 */ 1923 */
1783void console_unlock(void) 1924void console_unlock(void)
1784{ 1925{
1926 static char text[LOG_LINE_MAX];
1785 static u64 seen_seq; 1927 static u64 seen_seq;
1786 unsigned long flags; 1928 unsigned long flags;
1787 bool wake_klogd = false; 1929 bool wake_klogd = false;
@@ -1794,10 +1936,23 @@ void console_unlock(void)
1794 1936
1795 console_may_schedule = 0; 1937 console_may_schedule = 0;
1796 1938
1939 /* flush buffered message fragment immediately to console */
1940 raw_spin_lock_irqsave(&logbuf_lock, flags);
1941 if (cont.len && (cont.cons < cont.len || cont.flushed)) {
1942 size_t len;
1943
1944 len = cont_print_text(text, sizeof(text));
1945 raw_spin_unlock(&logbuf_lock);
1946 stop_critical_timings();
1947 call_console_drivers(cont.level, text, len);
1948 start_critical_timings();
1949 local_irq_restore(flags);
1950 } else
1951 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
1952
1797again: 1953again:
1798 for (;;) { 1954 for (;;) {
1799 struct log *msg; 1955 struct log *msg;
1800 static char text[LOG_LINE_MAX];
1801 size_t len; 1956 size_t len;
1802 int level; 1957 int level;
1803 1958
@@ -1811,18 +1966,35 @@ again:
1811 /* messages are gone, move to first one */ 1966 /* messages are gone, move to first one */
1812 console_seq = log_first_seq; 1967 console_seq = log_first_seq;
1813 console_idx = log_first_idx; 1968 console_idx = log_first_idx;
1969 console_prev = 0;
1814 } 1970 }
1815 1971skip:
1816 if (console_seq == log_next_seq) 1972 if (console_seq == log_next_seq)
1817 break; 1973 break;
1818 1974
1819 msg = log_from_idx(console_idx); 1975 msg = log_from_idx(console_idx);
1820 level = msg->level & 7; 1976 if (msg->flags & LOG_NOCONS) {
1821 1977 /*
1822 len = msg_print_text(msg, false, text, sizeof(text)); 1978 * Skip record we have buffered and already printed
1979 * directly to the console when we received it.
1980 */
1981 console_idx = log_next(console_idx);
1982 console_seq++;
1983 /*
1984 * We will get here again when we register a new
1985 * CON_PRINTBUFFER console. Clear the flag so we
1986 * will properly dump everything later.
1987 */
1988 msg->flags &= ~LOG_NOCONS;
1989 goto skip;
1990 }
1823 1991
1992 level = msg->level;
1993 len = msg_print_text(msg, console_prev, false,
1994 text, sizeof(text));
1824 console_idx = log_next(console_idx); 1995 console_idx = log_next(console_idx);
1825 console_seq++; 1996 console_seq++;
1997 console_prev = msg->flags;
1826 raw_spin_unlock(&logbuf_lock); 1998 raw_spin_unlock(&logbuf_lock);
1827 1999
1828 stop_critical_timings(); /* don't trace print latency */ 2000 stop_critical_timings(); /* don't trace print latency */
@@ -2085,6 +2257,7 @@ void register_console(struct console *newcon)
2085 raw_spin_lock_irqsave(&logbuf_lock, flags); 2257 raw_spin_lock_irqsave(&logbuf_lock, flags);
2086 console_seq = syslog_seq; 2258 console_seq = syslog_seq;
2087 console_idx = syslog_idx; 2259 console_idx = syslog_idx;
2260 console_prev = syslog_prev;
2088 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2261 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2089 /* 2262 /*
2090 * We're about to replay the log buffer. Only do this to the 2263 * We're about to replay the log buffer. Only do this to the
@@ -2300,48 +2473,256 @@ module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR);
2300 * kmsg_dump - dump kernel log to kernel message dumpers. 2473 * kmsg_dump - dump kernel log to kernel message dumpers.
2301 * @reason: the reason (oops, panic etc) for dumping 2474 * @reason: the reason (oops, panic etc) for dumping
2302 * 2475 *
2303 * Iterate through each of the dump devices and call the oops/panic 2476 * Call each of the registered dumper's dump() callback, which can
2304 * callbacks with the log buffer. 2477 * retrieve the kmsg records with kmsg_dump_get_line() or
2478 * kmsg_dump_get_buffer().
2305 */ 2479 */
2306void kmsg_dump(enum kmsg_dump_reason reason) 2480void kmsg_dump(enum kmsg_dump_reason reason)
2307{ 2481{
2308 u64 idx;
2309 struct kmsg_dumper *dumper; 2482 struct kmsg_dumper *dumper;
2310 const char *s1, *s2;
2311 unsigned long l1, l2;
2312 unsigned long flags; 2483 unsigned long flags;
2313 2484
2314 if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump) 2485 if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
2315 return; 2486 return;
2316 2487
2317 /* Theoretically, the log could move on after we do this, but 2488 rcu_read_lock();
2318 there's not a lot we can do about that. The new messages 2489 list_for_each_entry_rcu(dumper, &dump_list, list) {
2319 will overwrite the start of what we dump. */ 2490 if (dumper->max_reason && reason > dumper->max_reason)
2491 continue;
2492
2493 /* initialize iterator with data about the stored records */
2494 dumper->active = true;
2495
2496 raw_spin_lock_irqsave(&logbuf_lock, flags);
2497 dumper->cur_seq = clear_seq;
2498 dumper->cur_idx = clear_idx;
2499 dumper->next_seq = log_next_seq;
2500 dumper->next_idx = log_next_idx;
2501 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2502
2503 /* invoke dumper which will iterate over records */
2504 dumper->dump(dumper, reason);
2505
2506 /* reset iterator */
2507 dumper->active = false;
2508 }
2509 rcu_read_unlock();
2510}
2511
2512/**
2513 * kmsg_dump_get_line_nolock - retrieve one kmsg log line (unlocked version)
2514 * @dumper: registered kmsg dumper
2515 * @syslog: include the "<4>" prefixes
2516 * @line: buffer to copy the line to
2517 * @size: maximum size of the buffer
2518 * @len: length of line placed into buffer
2519 *
2520 * Start at the beginning of the kmsg buffer, with the oldest kmsg
2521 * record, and copy one record into the provided buffer.
2522 *
2523 * Consecutive calls will return the next available record moving
2524 * towards the end of the buffer with the youngest messages.
2525 *
2526 * A return value of FALSE indicates that there are no more records to
2527 * read.
2528 *
2529 * The function is similar to kmsg_dump_get_line(), but grabs no locks.
2530 */
2531bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
2532 char *line, size_t size, size_t *len)
2533{
2534 struct log *msg;
2535 size_t l = 0;
2536 bool ret = false;
2537
2538 if (!dumper->active)
2539 goto out;
2540
2541 if (dumper->cur_seq < log_first_seq) {
2542 /* messages are gone, move to first available one */
2543 dumper->cur_seq = log_first_seq;
2544 dumper->cur_idx = log_first_idx;
2545 }
2546
2547 /* last entry */
2548 if (dumper->cur_seq >= log_next_seq)
2549 goto out;
2550
2551 msg = log_from_idx(dumper->cur_idx);
2552 l = msg_print_text(msg, 0, syslog, line, size);
2553
2554 dumper->cur_idx = log_next(dumper->cur_idx);
2555 dumper->cur_seq++;
2556 ret = true;
2557out:
2558 if (len)
2559 *len = l;
2560 return ret;
2561}
2562
2563/**
2564 * kmsg_dump_get_line - retrieve one kmsg log line
2565 * @dumper: registered kmsg dumper
2566 * @syslog: include the "<4>" prefixes
2567 * @line: buffer to copy the line to
2568 * @size: maximum size of the buffer
2569 * @len: length of line placed into buffer
2570 *
2571 * Start at the beginning of the kmsg buffer, with the oldest kmsg
2572 * record, and copy one record into the provided buffer.
2573 *
2574 * Consecutive calls will return the next available record moving
2575 * towards the end of the buffer with the youngest messages.
2576 *
2577 * A return value of FALSE indicates that there are no more records to
2578 * read.
2579 */
2580bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
2581 char *line, size_t size, size_t *len)
2582{
2583 unsigned long flags;
2584 bool ret;
2585
2586 raw_spin_lock_irqsave(&logbuf_lock, flags);
2587 ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len);
2588 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2589
2590 return ret;
2591}
2592EXPORT_SYMBOL_GPL(kmsg_dump_get_line);
2593
2594/**
2595 * kmsg_dump_get_buffer - copy kmsg log lines
2596 * @dumper: registered kmsg dumper
2597 * @syslog: include the "<4>" prefixes
2598 * @buf: buffer to copy the line to
2599 * @size: maximum size of the buffer
2600 * @len: length of line placed into buffer
2601 *
2602 * Start at the end of the kmsg buffer and fill the provided buffer
2603 * with as many of the the *youngest* kmsg records that fit into it.
2604 * If the buffer is large enough, all available kmsg records will be
2605 * copied with a single call.
2606 *
2607 * Consecutive calls will fill the buffer with the next block of
2608 * available older records, not including the earlier retrieved ones.
2609 *
2610 * A return value of FALSE indicates that there are no more records to
2611 * read.
2612 */
2613bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
2614 char *buf, size_t size, size_t *len)
2615{
2616 unsigned long flags;
2617 u64 seq;
2618 u32 idx;
2619 u64 next_seq;
2620 u32 next_idx;
2621 enum log_flags prev;
2622 size_t l = 0;
2623 bool ret = false;
2624
2625 if (!dumper->active)
2626 goto out;
2320 2627
2321 raw_spin_lock_irqsave(&logbuf_lock, flags); 2628 raw_spin_lock_irqsave(&logbuf_lock, flags);
2322 if (syslog_seq < log_first_seq) 2629 if (dumper->cur_seq < log_first_seq) {
2323 idx = syslog_idx; 2630 /* messages are gone, move to first available one */
2324 else 2631 dumper->cur_seq = log_first_seq;
2325 idx = log_first_idx; 2632 dumper->cur_idx = log_first_idx;
2633 }
2634
2635 /* last entry */
2636 if (dumper->cur_seq >= dumper->next_seq) {
2637 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2638 goto out;
2639 }
2326 2640
2327 if (idx > log_next_idx) { 2641 /* calculate length of entire buffer */
2328 s1 = log_buf; 2642 seq = dumper->cur_seq;
2329 l1 = log_next_idx; 2643 idx = dumper->cur_idx;
2644 prev = 0;
2645 while (seq < dumper->next_seq) {
2646 struct log *msg = log_from_idx(idx);
2647
2648 l += msg_print_text(msg, prev, true, NULL, 0);
2649 idx = log_next(idx);
2650 seq++;
2651 prev = msg->flags;
2652 }
2330 2653
2331 s2 = log_buf + idx; 2654 /* move first record forward until length fits into the buffer */
2332 l2 = log_buf_len - idx; 2655 seq = dumper->cur_seq;
2333 } else { 2656 idx = dumper->cur_idx;
2334 s1 = ""; 2657 prev = 0;
2335 l1 = 0; 2658 while (l > size && seq < dumper->next_seq) {
2659 struct log *msg = log_from_idx(idx);
2660
2661 l -= msg_print_text(msg, prev, true, NULL, 0);
2662 idx = log_next(idx);
2663 seq++;
2664 prev = msg->flags;
2665 }
2666
2667 /* last message in next interation */
2668 next_seq = seq;
2669 next_idx = idx;
2670
2671 l = 0;
2672 prev = 0;
2673 while (seq < dumper->next_seq) {
2674 struct log *msg = log_from_idx(idx);
2336 2675
2337 s2 = log_buf + idx; 2676 l += msg_print_text(msg, prev, syslog, buf + l, size - l);
2338 l2 = log_next_idx - idx; 2677 idx = log_next(idx);
2678 seq++;
2679 prev = msg->flags;
2339 } 2680 }
2681
2682 dumper->next_seq = next_seq;
2683 dumper->next_idx = next_idx;
2684 ret = true;
2340 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2685 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2686out:
2687 if (len)
2688 *len = l;
2689 return ret;
2690}
2691EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
2341 2692
2342 rcu_read_lock(); 2693/**
2343 list_for_each_entry_rcu(dumper, &dump_list, list) 2694 * kmsg_dump_rewind_nolock - reset the interator (unlocked version)
2344 dumper->dump(dumper, reason, s1, l1, s2, l2); 2695 * @dumper: registered kmsg dumper
2345 rcu_read_unlock(); 2696 *
2697 * Reset the dumper's iterator so that kmsg_dump_get_line() and
2698 * kmsg_dump_get_buffer() can be called again and used multiple
2699 * times within the same dumper.dump() callback.
2700 *
2701 * The function is similar to kmsg_dump_rewind(), but grabs no locks.
2702 */
2703void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
2704{
2705 dumper->cur_seq = clear_seq;
2706 dumper->cur_idx = clear_idx;
2707 dumper->next_seq = log_next_seq;
2708 dumper->next_idx = log_next_idx;
2709}
2710
2711/**
2712 * kmsg_dump_rewind - reset the interator
2713 * @dumper: registered kmsg dumper
2714 *
2715 * Reset the dumper's iterator so that kmsg_dump_get_line() and
2716 * kmsg_dump_get_buffer() can be called again and used multiple
2717 * times within the same dumper.dump() callback.
2718 */
2719void kmsg_dump_rewind(struct kmsg_dumper *dumper)
2720{
2721 unsigned long flags;
2722
2723 raw_spin_lock_irqsave(&logbuf_lock, flags);
2724 kmsg_dump_rewind_nolock(dumper);
2725 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2346} 2726}
2727EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
2347#endif 2728#endif