Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

printk: move dictionary keys to dev_printk_info

Dictionaries are only used for SUBSYSTEM and DEVICE properties. The
current implementation stores the property names each time they are
used. This requires more space than otherwise necessary. Also,
because the dictionary entries are currently considered optional,
it cannot be relied upon that they are always available, even if the
writer wanted to store them. These issues will increase should new
dictionary properties be introduced.

Rather than storing the subsystem and device properties in the
dict ring, introduce a struct dev_printk_info with separate fields
to store only the property values. Embed this struct within the
struct printk_info to provide guaranteed availability.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/87mu1jl6ne.fsf@jogness.linutronix.de

authored by

John Ogness and committed by
Petr Mladek
74caba7f cfe2790b

+172 -168
+36 -43
Documentation/admin-guide/kdump/gdbmacros.txt
··· 172 172 173 173 define dump_record 174 174 set var $desc = $arg0 175 - if ($argc > 1) 176 - set var $prev_flags = $arg1 175 + set var $info = $arg1 176 + if ($argc > 2) 177 + set var $prev_flags = $arg2 177 178 else 178 179 set var $prev_flags = 0 179 180 end 180 181 181 - set var $info = &$desc->info 182 182 set var $prefix = 1 183 183 set var $newline = 1 184 184 ··· 237 237 238 238 # handle dictionary data 239 239 240 - set var $begin = $desc->dict_blk_lpos.begin % (1U << prb->dict_data_ring.size_bits) 241 - set var $next = $desc->dict_blk_lpos.next % (1U << prb->dict_data_ring.size_bits) 242 - 243 - # handle data-less record 244 - if ($begin & 1) 245 - set var $dict_len = 0 246 - set var $dict = "" 247 - else 248 - # handle wrapping data block 249 - if ($begin > $next) 250 - set var $begin = 0 251 - end 252 - 253 - # skip over descriptor id 254 - set var $begin = $begin + sizeof(long) 255 - 256 - # handle truncated message 257 - if ($next - $begin < $info->dict_len) 258 - set var $dict_len = $next - $begin 259 - else 260 - set var $dict_len = $info->dict_len 261 - end 262 - 263 - set var $dict = &prb->dict_data_ring.data[$begin] 264 - end 265 - 266 - if ($dict_len > 0) 240 + set var $dict = &$info->dev_info.subsystem[0] 241 + set var $dict_len = sizeof($info->dev_info.subsystem) 242 + if ($dict[0] != '\0') 243 + printf " SUBSYSTEM=" 267 244 set var $idx = 0 268 - set var $line = 1 269 245 while ($idx < $dict_len) 270 - if ($line) 271 - printf " " 272 - set var $line = 0 273 - end 274 246 set var $c = $dict[$idx] 275 247 if ($c == '\0') 276 - printf "\n" 277 - set var $line = 1 248 + loop_break 249 + else 250 + if ($c < ' ' || $c >= 127 || $c == '\\') 251 + printf "\\x%02x", $c 252 + else 253 + printf "%c", $c 254 + end 255 + end 256 + set var $idx = $idx + 1 257 + end 258 + printf "\n" 259 + end 260 + 261 + set var $dict = &$info->dev_info.device[0] 262 + set var $dict_len = sizeof($info->dev_info.device) 263 + if ($dict[0] != '\0') 264 + printf " DEVICE=" 265 + set var $idx = 0 266 + while ($idx < $dict_len) 267 + set var $c = $dict[$idx] 268 + if ($c == '\0') 269 + loop_break 278 270 else 279 271 if ($c < ' ' || $c >= 127 || $c == '\\') 280 272 printf "\\x%02x", $c ··· 280 288 end 281 289 end 282 290 document dump_record 283 - Dump a single record. The first parameter is the descriptor 284 - sequence number, the second is optional and specifies the 285 - previous record's flags, used for properly formatting 286 - continued lines. 291 + Dump a single record. The first parameter is the descriptor, 292 + the second parameter is the info, the third parameter is 293 + optional and specifies the previous record's flags, used for 294 + properly formatting continued lines. 287 295 end 288 296 289 297 define dmesg ··· 303 311 304 312 while (1) 305 313 set var $desc = &prb->desc_ring.descs[$id % $desc_count] 314 + set var $info = &prb->desc_ring.infos[$id % $desc_count] 306 315 307 316 # skip non-committed record 308 317 set var $state = 3 & ($desc->state_var.counter >> $desc_flags_shift) 309 318 if ($state == $desc_committed || $state == $desc_finalized) 310 - dump_record $desc $prev_flags 311 - set var $prev_flags = $desc->info.flags 319 + dump_record $desc $info $prev_flags 320 + set var $prev_flags = $info->flags 312 321 end 313 322 314 323 set var $id = ($id + 1) & $id_mask
+16 -30
drivers/base/core.c
··· 3815 3815 */ 3816 3816 3817 3817 #ifdef CONFIG_PRINTK 3818 - static int 3819 - create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 3818 + static void 3819 + set_dev_info(const struct device *dev, struct dev_printk_info *dev_info) 3820 3820 { 3821 3821 const char *subsys; 3822 - size_t pos = 0; 3822 + 3823 + memset(dev_info, 0, sizeof(*dev_info)); 3823 3824 3824 3825 if (dev->class) 3825 3826 subsys = dev->class->name; 3826 3827 else if (dev->bus) 3827 3828 subsys = dev->bus->name; 3828 3829 else 3829 - return 0; 3830 + return; 3830 3831 3831 - pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 3832 - if (pos >= hdrlen) 3833 - goto overflow; 3832 + strscpy(dev_info->subsystem, subsys, sizeof(dev_info->subsystem)); 3834 3833 3835 3834 /* 3836 3835 * Add device identifier DEVICE=: ··· 3845 3846 c = 'b'; 3846 3847 else 3847 3848 c = 'c'; 3848 - pos++; 3849 - pos += snprintf(hdr + pos, hdrlen - pos, 3850 - "DEVICE=%c%u:%u", 3851 - c, MAJOR(dev->devt), MINOR(dev->devt)); 3849 + 3850 + snprintf(dev_info->device, sizeof(dev_info->device), 3851 + "%c%u:%u", c, MAJOR(dev->devt), MINOR(dev->devt)); 3852 3852 } else if (strcmp(subsys, "net") == 0) { 3853 3853 struct net_device *net = to_net_dev(dev); 3854 3854 3855 - pos++; 3856 - pos += snprintf(hdr + pos, hdrlen - pos, 3857 - "DEVICE=n%u", net->ifindex); 3855 + snprintf(dev_info->device, sizeof(dev_info->device), 3856 + "n%u", net->ifindex); 3858 3857 } else { 3859 - pos++; 3860 - pos += snprintf(hdr + pos, hdrlen - pos, 3861 - "DEVICE=+%s:%s", subsys, dev_name(dev)); 3858 + snprintf(dev_info->device, sizeof(dev_info->device), 3859 + "+%s:%s", subsys, dev_name(dev)); 3862 3860 } 3863 - 3864 - if (pos >= hdrlen) 3865 - goto overflow; 3866 - 3867 - return pos; 3868 - 3869 - overflow: 3870 - dev_WARN(dev, "device/subsystem name too long"); 3871 - return 0; 3872 3861 } 3873 3862 3874 3863 int dev_vprintk_emit(int level, const struct device *dev, 3875 3864 const char *fmt, va_list args) 3876 3865 { 3877 - char hdr[128]; 3878 - size_t hdrlen; 3866 + struct dev_printk_info dev_info; 3879 3867 3880 - hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 3868 + set_dev_info(dev, &dev_info); 3881 3869 3882 - return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 3870 + return vprintk_emit(0, level, &dev_info, fmt, args); 3883 3871 } 3884 3872 EXPORT_SYMBOL(dev_vprintk_emit); 3885 3873
+8
include/linux/dev_printk.h
··· 21 21 22 22 struct device; 23 23 24 + #define PRINTK_INFO_SUBSYSTEM_LEN 16 25 + #define PRINTK_INFO_DEVICE_LEN 48 26 + 27 + struct dev_printk_info { 28 + char subsystem[PRINTK_INFO_SUBSYSTEM_LEN]; 29 + char device[PRINTK_INFO_DEVICE_LEN]; 30 + }; 31 + 24 32 #ifdef CONFIG_PRINTK 25 33 26 34 __printf(3, 0) __cold
+4 -2
include/linux/printk.h
··· 158 158 static inline void printk_nmi_direct_exit(void) { } 159 159 #endif /* PRINTK_NMI */ 160 160 161 + struct dev_printk_info; 162 + 161 163 #ifdef CONFIG_PRINTK 162 - asmlinkage __printf(5, 0) 164 + asmlinkage __printf(4, 0) 163 165 int vprintk_emit(int facility, int level, 164 - const char *dict, size_t dictlen, 166 + const struct dev_printk_info *dev_info, 165 167 const char *fmt, va_list args); 166 168 167 169 asmlinkage __printf(1, 0)
+2 -2
kernel/printk/internal.h
··· 14 14 15 15 extern raw_spinlock_t logbuf_lock; 16 16 17 - __printf(5, 0) 17 + __printf(4, 0) 18 18 int vprintk_store(int facility, int level, 19 - const char *dict, size_t dictlen, 19 + const struct dev_printk_info *dev_info, 20 20 const char *fmt, va_list args); 21 21 22 22 __printf(1, 0) int vprintk_default(const char *fmt, va_list args);
+91 -85
kernel/printk/printk.c
··· 296 296 297 297 /* 298 298 * The printk log buffer consists of a sequenced collection of records, each 299 - * containing variable length message and dictionary text. Every record 300 - * also contains its own meta-data (@info). 299 + * containing variable length message text. Every record also contains its 300 + * own meta-data (@info). 301 301 * 302 302 * Every record meta-data carries the timestamp in microseconds, as well as 303 303 * the standard userspace syslog level and syslog facility. The usual kernel ··· 310 310 * terminated. 311 311 * 312 312 * Optionally, a record can carry a dictionary of properties (key/value 313 - * pairs), to provide userspace with a machine-readable message context. The 314 - * length of the dictionary is available in @dict_len. The dictionary is not 315 - * terminated. 313 + * pairs), to provide userspace with a machine-readable message context. 316 314 * 317 315 * Examples for well-defined, commonly used property names are: 318 316 * DEVICE=b12:8 device identifier ··· 320 322 * +sound:card0 subsystem:devname 321 323 * SUBSYSTEM=pci driver-core subsystem name 322 324 * 323 - * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value 324 - * follows directly after a '=' character. Every property is terminated by 325 - * a '\0' character. The last property is not terminated. 325 + * Valid characters in property names are [a-zA-Z0-9.-_]. Property names 326 + * and values are terminated by a '\0' character. 326 327 * 327 328 * Example of record values: 328 - * record.text_buf = "it's a line" (unterminated) 329 - * record.dict_buf = "DEVICE=b8:2\0DRIVER=bug" (unterminated) 330 - * record.info.seq = 56 331 - * record.info.ts_nsec = 36863 332 - * record.info.text_len = 11 333 - * record.info.dict_len = 22 334 - * record.info.facility = 0 (LOG_KERN) 335 - * record.info.flags = 0 336 - * record.info.level = 3 (LOG_ERR) 337 - * record.info.caller_id = 299 (task 299) 329 + * record.text_buf = "it's a line" (unterminated) 330 + * record.info.seq = 56 331 + * record.info.ts_nsec = 36863 332 + * record.info.text_len = 11 333 + * record.info.facility = 0 (LOG_KERN) 334 + * record.info.flags = 0 335 + * record.info.level = 3 (LOG_ERR) 336 + * record.info.caller_id = 299 (task 299) 337 + * record.info.dev_info.subsystem = "pci" (terminated) 338 + * record.info.dev_info.device = "+pci:0000:00:01.0" (terminated) 338 339 * 339 340 * The 'struct printk_info' buffer must never be directly exported to 340 341 * userspace, it is a kernel-private implementation detail that might ··· 495 498 /* insert record into the buffer, discard old ones, update heads */ 496 499 static int log_store(u32 caller_id, int facility, int level, 497 500 enum log_flags flags, u64 ts_nsec, 498 - const char *dict, u16 dict_len, 501 + const struct dev_printk_info *dev_info, 499 502 const char *text, u16 text_len) 500 503 { 501 504 struct prb_reserved_entry e; 502 505 struct printk_record r; 503 506 u16 trunc_msg_len = 0; 504 507 505 - prb_rec_init_wr(&r, text_len, dict_len); 508 + prb_rec_init_wr(&r, text_len, 0); 506 509 507 510 if (!prb_reserve(&e, prb, &r)) { 508 511 /* truncate the message if it is too long for empty buffer */ 509 512 truncate_msg(&text_len, &trunc_msg_len); 510 - prb_rec_init_wr(&r, text_len + trunc_msg_len, dict_len); 513 + prb_rec_init_wr(&r, text_len + trunc_msg_len, 0); 511 514 /* survive when the log buffer is too small for trunc_msg */ 512 515 if (!prb_reserve(&e, prb, &r)) 513 516 return 0; ··· 518 521 if (trunc_msg_len) 519 522 memcpy(&r.text_buf[text_len], trunc_msg, trunc_msg_len); 520 523 r.info->text_len = text_len + trunc_msg_len; 521 - if (r.dict_buf) { 522 - memcpy(&r.dict_buf[0], dict, dict_len); 523 - r.info->dict_len = dict_len; 524 - } 525 524 r.info->facility = facility; 526 525 r.info->level = level & 7; 527 526 r.info->flags = flags & 0x1f; ··· 526 533 else 527 534 r.info->ts_nsec = local_clock(); 528 535 r.info->caller_id = caller_id; 536 + if (dev_info) 537 + memcpy(&r.info->dev_info, dev_info, sizeof(r.info->dev_info)); 529 538 530 539 /* insert message */ 531 540 if ((flags & LOG_CONT) || !(flags & LOG_NEWLINE)) ··· 608 613 ts_usec, info->flags & LOG_CONT ? 'c' : '-', caller); 609 614 } 610 615 611 - static ssize_t msg_print_ext_body(char *buf, size_t size, 612 - char *dict, size_t dict_len, 613 - char *text, size_t text_len) 616 + static ssize_t msg_add_ext_text(char *buf, size_t size, 617 + const char *text, size_t text_len, 618 + unsigned char endc) 614 619 { 615 620 char *p = buf, *e = buf + size; 616 621 size_t i; ··· 624 629 else 625 630 append_char(&p, e, c); 626 631 } 627 - append_char(&p, e, '\n'); 628 - 629 - if (dict_len) { 630 - bool line = true; 631 - 632 - for (i = 0; i < dict_len; i++) { 633 - unsigned char c = dict[i]; 634 - 635 - if (line) { 636 - append_char(&p, e, ' '); 637 - line = false; 638 - } 639 - 640 - if (c == '\0') { 641 - append_char(&p, e, '\n'); 642 - line = true; 643 - continue; 644 - } 645 - 646 - if (c < ' ' || c >= 127 || c == '\\') { 647 - p += scnprintf(p, e - p, "\\x%02x", c); 648 - continue; 649 - } 650 - 651 - append_char(&p, e, c); 652 - } 653 - append_char(&p, e, '\n'); 654 - } 632 + append_char(&p, e, endc); 655 633 656 634 return p - buf; 635 + } 636 + 637 + static ssize_t msg_add_dict_text(char *buf, size_t size, 638 + const char *key, const char *val) 639 + { 640 + size_t val_len = strlen(val); 641 + ssize_t len; 642 + 643 + if (!val_len) 644 + return 0; 645 + 646 + len = msg_add_ext_text(buf, size, "", 0, ' '); /* dict prefix */ 647 + len += msg_add_ext_text(buf + len, size - len, key, strlen(key), '='); 648 + len += msg_add_ext_text(buf + len, size - len, val, val_len, '\n'); 649 + 650 + return len; 651 + } 652 + 653 + static ssize_t msg_print_ext_body(char *buf, size_t size, 654 + char *text, size_t text_len, 655 + struct dev_printk_info *dev_info) 656 + { 657 + ssize_t len; 658 + 659 + len = msg_add_ext_text(buf, size, text, text_len, '\n'); 660 + 661 + if (!dev_info) 662 + goto out; 663 + 664 + len += msg_add_dict_text(buf + len, size - len, "SUBSYSTEM", 665 + dev_info->subsystem); 666 + len += msg_add_dict_text(buf + len, size - len, "DEVICE", 667 + dev_info->device); 668 + out: 669 + return len; 657 670 } 658 671 659 672 /* /dev/kmsg - userspace message inject/listen interface */ ··· 673 670 674 671 struct printk_info info; 675 672 char text_buf[CONSOLE_EXT_LOG_MAX]; 676 - char dict_buf[CONSOLE_EXT_LOG_MAX]; 677 673 struct printk_record record; 678 674 }; 679 675 ··· 683 681 int r; 684 682 685 683 va_start(args, fmt); 686 - r = vprintk_emit(facility, level, NULL, 0, fmt, args); 684 + r = vprintk_emit(facility, level, NULL, fmt, args); 687 685 va_end(args); 688 686 689 687 return r; ··· 793 791 794 792 len = info_print_ext_header(user->buf, sizeof(user->buf), r->info); 795 793 len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len, 796 - &r->dict_buf[0], r->info->dict_len, 797 - &r->text_buf[0], r->info->text_len); 794 + &r->text_buf[0], r->info->text_len, 795 + &r->info->dev_info); 798 796 799 797 user->seq = r->info->seq + 1; 800 798 logbuf_unlock_irq(); ··· 899 897 900 898 prb_rec_init_rd(&user->record, &user->info, 901 899 &user->text_buf[0], sizeof(user->text_buf), 902 - &user->dict_buf[0], sizeof(user->dict_buf)); 900 + NULL, 0); 903 901 904 902 logbuf_lock_irq(); 905 903 user->seq = prb_first_valid_seq(prb); ··· 943 941 */ 944 942 void log_buf_vmcoreinfo_setup(void) 945 943 { 944 + struct dev_printk_info *dev_info = NULL; 945 + 946 946 VMCOREINFO_SYMBOL(prb); 947 947 VMCOREINFO_SYMBOL(printk_rb_static); 948 948 VMCOREINFO_SYMBOL(clear_seq); ··· 982 978 VMCOREINFO_OFFSET(printk_info, text_len); 983 979 VMCOREINFO_OFFSET(printk_info, dict_len); 984 980 VMCOREINFO_OFFSET(printk_info, caller_id); 981 + VMCOREINFO_OFFSET(printk_info, dev_info); 982 + 983 + VMCOREINFO_STRUCT_SIZE(dev_printk_info); 984 + VMCOREINFO_OFFSET(dev_printk_info, subsystem); 985 + VMCOREINFO_LENGTH(printk_info_subsystem, sizeof(dev_info->subsystem)); 986 + VMCOREINFO_OFFSET(dev_printk_info, device); 987 + VMCOREINFO_LENGTH(printk_info_device, sizeof(dev_info->device)); 985 988 986 989 VMCOREINFO_STRUCT_SIZE(prb_data_ring); 987 990 VMCOREINFO_OFFSET(prb_data_ring, size_bits); ··· 1081 1070 struct prb_reserved_entry e; 1082 1071 struct printk_record dest_r; 1083 1072 1084 - prb_rec_init_wr(&dest_r, r->info->text_len, r->info->dict_len); 1073 + prb_rec_init_wr(&dest_r, r->info->text_len, 0); 1085 1074 1086 1075 if (!prb_reserve(&e, rb, &dest_r)) 1087 1076 return 0; 1088 1077 1089 1078 memcpy(&dest_r.text_buf[0], &r->text_buf[0], r->info->text_len); 1090 1079 dest_r.info->text_len = r->info->text_len; 1091 - if (dest_r.dict_buf) { 1092 - memcpy(&dest_r.dict_buf[0], &r->dict_buf[0], r->info->dict_len); 1093 - dest_r.info->dict_len = r->info->dict_len; 1094 - } 1095 1080 dest_r.info->facility = r->info->facility; 1096 1081 dest_r.info->level = r->info->level; 1097 1082 dest_r.info->flags = r->info->flags; 1098 1083 dest_r.info->ts_nsec = r->info->ts_nsec; 1099 1084 dest_r.info->caller_id = r->info->caller_id; 1085 + memcpy(&dest_r.info->dev_info, &r->info->dev_info, sizeof(dest_r.info->dev_info)); 1100 1086 1101 1087 prb_final_commit(&e); 1102 1088 ··· 1101 1093 } 1102 1094 1103 1095 static char setup_text_buf[CONSOLE_EXT_LOG_MAX] __initdata; 1104 - static char setup_dict_buf[CONSOLE_EXT_LOG_MAX] __initdata; 1105 1096 1106 1097 void __init setup_log_buf(int early) 1107 1098 { ··· 1172 1165 1173 1166 prb_rec_init_rd(&r, &info, 1174 1167 &setup_text_buf[0], sizeof(setup_text_buf), 1175 - &setup_dict_buf[0], sizeof(setup_dict_buf)); 1168 + NULL, 0); 1176 1169 1177 1170 prb_init(&printk_rb_dynamic, 1178 1171 new_log_buf, ilog2(new_log_buf_len), ··· 1910 1903 0x80000000 + raw_smp_processor_id(); 1911 1904 } 1912 1905 1913 - static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len) 1906 + static size_t log_output(int facility, int level, enum log_flags lflags, 1907 + const struct dev_printk_info *dev_info, 1908 + char *text, size_t text_len) 1914 1909 { 1915 1910 const u32 caller_id = printk_caller_id(); 1916 1911 ··· 1936 1927 1937 1928 /* Store it in the record log */ 1938 1929 return log_store(caller_id, facility, level, lflags, 0, 1939 - dict, dictlen, text, text_len); 1930 + dev_info, text, text_len); 1940 1931 } 1941 1932 1942 1933 /* Must be called under logbuf_lock. */ 1943 1934 int vprintk_store(int facility, int level, 1944 - const char *dict, size_t dictlen, 1935 + const struct dev_printk_info *dev_info, 1945 1936 const char *fmt, va_list args) 1946 1937 { 1947 1938 static char textbuf[LOG_LINE_MAX]; ··· 1983 1974 if (level == LOGLEVEL_DEFAULT) 1984 1975 level = default_message_loglevel; 1985 1976 1986 - if (dict) 1977 + if (dev_info) 1987 1978 lflags |= LOG_NEWLINE; 1988 1979 1989 - return log_output(facility, level, lflags, 1990 - dict, dictlen, text, text_len); 1980 + return log_output(facility, level, lflags, dev_info, text, text_len); 1991 1981 } 1992 1982 1993 1983 asmlinkage int vprintk_emit(int facility, int level, 1994 - const char *dict, size_t dictlen, 1984 + const struct dev_printk_info *dev_info, 1995 1985 const char *fmt, va_list args) 1996 1986 { 1997 1987 int printed_len; ··· 2011 2003 2012 2004 /* This stops the holder of console_sem just where we want him */ 2013 2005 logbuf_lock_irqsave(flags); 2014 - printed_len = vprintk_store(facility, level, dict, dictlen, fmt, args); 2006 + printed_len = vprintk_store(facility, level, dev_info, fmt, args); 2015 2007 logbuf_unlock_irqrestore(flags); 2016 2008 2017 2009 /* If called from the scheduler, we can not call up(). */ ··· 2045 2037 2046 2038 int vprintk_default(const char *fmt, va_list args) 2047 2039 { 2048 - return vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); 2040 + return vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, fmt, args); 2049 2041 } 2050 2042 EXPORT_SYMBOL_GPL(vprintk_default); 2051 2043 ··· 2108 2100 return 0; 2109 2101 } 2110 2102 static ssize_t msg_print_ext_body(char *buf, size_t size, 2111 - char *dict, size_t dict_len, 2112 - char *text, size_t text_len) { return 0; } 2103 + char *text, size_t text_len, 2104 + struct dev_printk_info *dev_info) { return 0; } 2113 2105 static void console_lock_spinning_enable(void) { } 2114 2106 static int console_lock_spinning_disable_and_check(void) { return 0; } 2115 2107 static void call_console_drivers(const char *ext_text, size_t ext_len, ··· 2398 2390 { 2399 2391 static char ext_text[CONSOLE_EXT_LOG_MAX]; 2400 2392 static char text[LOG_LINE_MAX + PREFIX_MAX]; 2401 - static char dict[LOG_LINE_MAX]; 2402 2393 unsigned long flags; 2403 2394 bool do_cond_resched, retry; 2404 2395 struct printk_info info; ··· 2408 2401 return; 2409 2402 } 2410 2403 2411 - prb_rec_init_rd(&r, &info, text, sizeof(text), dict, sizeof(dict)); 2404 + prb_rec_init_rd(&r, &info, text, sizeof(text), NULL, 0); 2412 2405 2413 2406 /* 2414 2407 * Console drivers are called with interrupts disabled, so ··· 2480 2473 r.info); 2481 2474 ext_len += msg_print_ext_body(ext_text + ext_len, 2482 2475 sizeof(ext_text) - ext_len, 2483 - &r.dict_buf[0], 2484 - r.info->dict_len, 2485 2476 &r.text_buf[0], 2486 - r.info->text_len); 2477 + r.info->text_len, 2478 + &r.info->dev_info); 2487 2479 } 2488 2480 len = record_print_text(&r, 2489 2481 console_msg_format & MSG_FORMAT_SYSLOG, ··· 3061 3055 { 3062 3056 int r; 3063 3057 3064 - r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args); 3058 + r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); 3065 3059 defer_console_output(); 3066 3060 3067 3061 return r;
+3
kernel/printk/printk_ringbuffer.h
··· 4 4 #define _KERNEL_PRINTK_RINGBUFFER_H 5 5 6 6 #include <linux/atomic.h> 7 + #include <linux/dev_printk.h> 7 8 8 9 /* 9 10 * Meta information about each stored message. ··· 22 21 u8 flags:5; /* internal record flags */ 23 22 u8 level:3; /* syslog level */ 24 23 u32 caller_id; /* thread id or processor id */ 24 + 25 + struct dev_printk_info dev_info; 25 26 }; 26 27 27 28 /*
+1 -1
kernel/printk/printk_safe.c
··· 375 375 raw_spin_trylock(&logbuf_lock)) { 376 376 int len; 377 377 378 - len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); 378 + len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args); 379 379 raw_spin_unlock(&logbuf_lock); 380 380 defer_console_output(); 381 381 return len;
+11 -5
scripts/gdb/linux/dmesg.py
··· 52 52 addr = utils.read_ulong(desc_ring, off) 53 53 descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes() 54 54 55 + # read in info array 56 + info_sz = printk_info_type.get_type().sizeof 57 + off = prb_desc_ring_type.get_type()['infos'].bitpos // 8 58 + addr = utils.read_ulong(desc_ring, off) 59 + infos = utils.read_memoryview(inf, addr, info_sz * desc_ring_count).tobytes() 60 + 55 61 # read in text data ring structure 56 62 off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8 57 63 addr = prb_addr + off ··· 79 73 begin_off = off + (prb_data_blk_lpos_type.get_type()['begin'].bitpos // 8) 80 74 next_off = off + (prb_data_blk_lpos_type.get_type()['next'].bitpos // 8) 81 75 82 - off = prb_desc_type.get_type()['info'].bitpos // 8 83 - ts_off = off + printk_info_type.get_type()['ts_nsec'].bitpos // 8 84 - len_off = off + printk_info_type.get_type()['text_len'].bitpos // 8 76 + ts_off = printk_info_type.get_type()['ts_nsec'].bitpos // 8 77 + len_off = printk_info_type.get_type()['text_len'].bitpos // 8 85 78 86 79 # definitions from kernel/printk/printk_ringbuffer.h 87 80 desc_committed = 1 ··· 100 95 while True: 101 96 ind = did % desc_ring_count 102 97 desc_off = desc_sz * ind 98 + info_off = info_sz * ind 103 99 104 100 # skip non-committed record 105 101 state = 3 & (utils.read_u64(descs, desc_off + sv_off + ··· 125 119 # skip over descriptor id 126 120 text_start = begin + utils.get_long_type().sizeof 127 121 128 - text_len = utils.read_u16(descs, desc_off + len_off) 122 + text_len = utils.read_u16(infos, info_off + len_off) 129 123 130 124 # handle truncated message 131 125 if end - text_start < text_len: ··· 134 128 text = text_data[text_start:text_start + text_len].decode( 135 129 encoding='utf8', errors='replace') 136 130 137 - time_stamp = utils.read_u64(descs, desc_off + ts_off) 131 + time_stamp = utils.read_u64(infos, info_off + ts_off) 138 132 139 133 for line in text.splitlines(): 140 134 msg = u"[{time:12.6f}] {line}\n".format(