@@ -1126,7 +1126,7 @@ void __init setup_log_buf(int early)
11261126 new_descs , ilog2 (new_descs_count ),
11271127 new_infos );
11281128
1129- logbuf_lock_irqsave (flags );
1129+ printk_safe_enter_irqsave (flags );
11301130
11311131 log_buf_len = new_log_buf_len ;
11321132 log_buf = new_log_buf ;
@@ -1143,7 +1143,7 @@ void __init setup_log_buf(int early)
11431143 */
11441144 prb = & printk_rb_dynamic ;
11451145
1146- logbuf_unlock_irqrestore (flags );
1146+ printk_safe_exit_irqrestore (flags );
11471147
11481148 if (seq != prb_next_seq (& printk_rb_static )) {
11491149 pr_err ("dropped %llu messages\n" ,
@@ -1861,18 +1861,90 @@ static inline u32 printk_caller_id(void)
18611861 0x80000000 + raw_smp_processor_id ();
18621862}
18631863
1864- /* Must be called under logbuf_lock. */
1864+ /**
1865+ * parse_prefix - Parse level and control flags.
1866+ *
1867+ * @text: The terminated text message.
1868+ * @level: A pointer to the current level value, will be updated.
1869+ * @lflags: A pointer to the current log flags, will be updated.
1870+ *
1871+ * @level may be NULL if the caller is not interested in the parsed value.
1872+ * Otherwise the variable pointed to by @level must be set to
1873+ * LOGLEVEL_DEFAULT in order to be updated with the parsed value.
1874+ *
1875+ * @lflags may be NULL if the caller is not interested in the parsed value.
1876+ * Otherwise the variable pointed to by @lflags will be OR'd with the parsed
1877+ * value.
1878+ *
1879+ * Return: The length of the parsed level and control flags.
1880+ */
1881+ static u16 parse_prefix (char * text , int * level , enum log_flags * lflags )
1882+ {
1883+ u16 prefix_len = 0 ;
1884+ int kern_level ;
1885+
1886+ while (* text ) {
1887+ kern_level = printk_get_level (text );
1888+ if (!kern_level )
1889+ break ;
1890+
1891+ switch (kern_level ) {
1892+ case '0' ... '7' :
1893+ if (level && * level == LOGLEVEL_DEFAULT )
1894+ * level = kern_level - '0' ;
1895+ break ;
1896+ case 'c' : /* KERN_CONT */
1897+ if (lflags )
1898+ * lflags |= LOG_CONT ;
1899+ }
1900+
1901+ prefix_len += 2 ;
1902+ text += 2 ;
1903+ }
1904+
1905+ return prefix_len ;
1906+ }
1907+
1908+ static u16 printk_sprint (char * text , u16 size , int facility , enum log_flags * lflags ,
1909+ const char * fmt , va_list args )
1910+ {
1911+ u16 text_len ;
1912+
1913+ text_len = vscnprintf (text , size , fmt , args );
1914+
1915+ /* Mark and strip a trailing newline. */
1916+ if (text_len && text [text_len - 1 ] == '\n' ) {
1917+ text_len -- ;
1918+ * lflags |= LOG_NEWLINE ;
1919+ }
1920+
1921+ /* Strip log level and control flags. */
1922+ if (facility == 0 ) {
1923+ u16 prefix_len ;
1924+
1925+ prefix_len = parse_prefix (text , NULL , NULL );
1926+ if (prefix_len ) {
1927+ text_len -= prefix_len ;
1928+ memmove (text , text + prefix_len , text_len );
1929+ }
1930+ }
1931+
1932+ return text_len ;
1933+ }
1934+
1935+ __printf (4 , 0 )
18651936int vprintk_store (int facility , int level ,
18661937 const struct dev_printk_info * dev_info ,
18671938 const char * fmt , va_list args )
18681939{
18691940 const u32 caller_id = printk_caller_id ();
1870- static char textbuf [LOG_LINE_MAX ];
18711941 struct prb_reserved_entry e ;
18721942 enum log_flags lflags = 0 ;
18731943 struct printk_record r ;
18741944 u16 trunc_msg_len = 0 ;
1875- char * text = textbuf ;
1945+ char prefix_buf [8 ];
1946+ u16 reserve_size ;
1947+ va_list args2 ;
18761948 u16 text_len ;
18771949 u64 ts_nsec ;
18781950
@@ -1885,35 +1957,21 @@ int vprintk_store(int facility, int level,
18851957 ts_nsec = local_clock ();
18861958
18871959 /*
1888- * The printf needs to come first; we need the syslog
1889- * prefix which might be passed-in as a parameter.
1960+ * The sprintf needs to come first since the syslog prefix might be
1961+ * passed in as a parameter. An extra byte must be reserved so that
1962+ * later the vscnprintf() into the reserved buffer has room for the
1963+ * terminating '\0', which is not counted by vsnprintf().
18901964 */
1891- text_len = vscnprintf (text , sizeof (textbuf ), fmt , args );
1892-
1893- /* mark and strip a trailing newline */
1894- if (text_len && text [text_len - 1 ] == '\n' ) {
1895- text_len -- ;
1896- lflags |= LOG_NEWLINE ;
1897- }
1898-
1899- /* strip kernel syslog prefix and extract log level or control flags */
1900- if (facility == 0 ) {
1901- int kern_level ;
1965+ va_copy (args2 , args );
1966+ reserve_size = vsnprintf (& prefix_buf [0 ], sizeof (prefix_buf ), fmt , args2 ) + 1 ;
1967+ va_end (args2 );
19021968
1903- while ((kern_level = printk_get_level (text )) != 0 ) {
1904- switch (kern_level ) {
1905- case '0' ... '7' :
1906- if (level == LOGLEVEL_DEFAULT )
1907- level = kern_level - '0' ;
1908- break ;
1909- case 'c' : /* KERN_CONT */
1910- lflags |= LOG_CONT ;
1911- }
1969+ if (reserve_size > LOG_LINE_MAX )
1970+ reserve_size = LOG_LINE_MAX ;
19121971
1913- text_len -= 2 ;
1914- text += 2 ;
1915- }
1916- }
1972+ /* Extract log level or control flags. */
1973+ if (facility == 0 )
1974+ parse_prefix (& prefix_buf [0 ], & level , & lflags );
19171975
19181976 if (level == LOGLEVEL_DEFAULT )
19191977 level = default_message_loglevel ;
@@ -1922,9 +1980,10 @@ int vprintk_store(int facility, int level,
19221980 lflags |= LOG_NEWLINE ;
19231981
19241982 if (lflags & LOG_CONT ) {
1925- prb_rec_init_wr (& r , text_len );
1983+ prb_rec_init_wr (& r , reserve_size );
19261984 if (prb_reserve_in_last (& e , prb , & r , caller_id , LOG_LINE_MAX )) {
1927- memcpy (& r .text_buf [r .info -> text_len ], text , text_len );
1985+ text_len = printk_sprint (& r .text_buf [r .info -> text_len ], reserve_size ,
1986+ facility , & lflags , fmt , args );
19281987 r .info -> text_len += text_len ;
19291988
19301989 if (lflags & LOG_NEWLINE ) {
@@ -1943,18 +2002,18 @@ int vprintk_store(int facility, int level,
19432002 * prb_reserve_in_last() and prb_reserve() purposely invalidate the
19442003 * structure when they fail.
19452004 */
1946- prb_rec_init_wr (& r , text_len );
2005+ prb_rec_init_wr (& r , reserve_size );
19472006 if (!prb_reserve (& e , prb , & r )) {
19482007 /* truncate the message if it is too long for empty buffer */
1949- truncate_msg (& text_len , & trunc_msg_len );
2008+ truncate_msg (& reserve_size , & trunc_msg_len );
19502009
1951- prb_rec_init_wr (& r , text_len + trunc_msg_len );
2010+ prb_rec_init_wr (& r , reserve_size + trunc_msg_len );
19522011 if (!prb_reserve (& e , prb , & r ))
19532012 return 0 ;
19542013 }
19552014
19562015 /* fill message */
1957- memcpy (& r .text_buf [0 ], text , text_len );
2016+ text_len = printk_sprint (& r .text_buf [0 ], reserve_size , facility , & lflags , fmt , args );
19582017 if (trunc_msg_len )
19592018 memcpy (& r .text_buf [text_len ], trunc_msg , trunc_msg_len );
19602019 r .info -> text_len = text_len + trunc_msg_len ;
@@ -1995,10 +2054,9 @@ asmlinkage int vprintk_emit(int facility, int level,
19952054 boot_delay_msec (level );
19962055 printk_delay ();
19972056
1998- /* This stops the holder of console_sem just where we want him */
1999- logbuf_lock_irqsave (flags );
2057+ printk_safe_enter_irqsave (flags );
20002058 printed_len = vprintk_store (facility , level , dev_info , fmt , args );
2001- logbuf_unlock_irqrestore (flags );
2059+ printk_safe_exit_irqrestore (flags );
20022060
20032061 /* If called from the scheduler, we can not call up(). */
20042062 if (!in_sched ) {
0 commit comments