Skip to content

Commit f5f022e

Browse files
jognesspmladek
authored andcommitted
printk: reimplement log_cont using record extension
Use the record extending feature of the ringbuffer to implement continuous messages. This preserves the existing continuous message behavior. 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/20200914123354.832-7-john.ogness@linutronix.de
1 parent 4cfc725 commit f5f022e

1 file changed

Lines changed: 20 additions & 78 deletions

File tree

kernel/printk/printk.c

Lines changed: 20 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,10 @@ static int log_store(u32 caller_id, int facility, int level,
535535
r.info->caller_id = caller_id;
536536

537537
/* insert message */
538-
prb_commit(&e);
538+
if ((flags & LOG_CONT) || !(flags & LOG_NEWLINE))
539+
prb_commit(&e);
540+
else
541+
prb_final_commit(&e);
539542

540543
return (text_len + trunc_msg_len);
541544
}
@@ -1084,7 +1087,7 @@ static unsigned int __init add_to_rb(struct printk_ringbuffer *rb,
10841087
dest_r.info->ts_nsec = r->info->ts_nsec;
10851088
dest_r.info->caller_id = r->info->caller_id;
10861089

1087-
prb_commit(&e);
1090+
prb_final_commit(&e);
10881091

10891092
return prb_record_text_space(&e);
10901093
}
@@ -1884,87 +1887,26 @@ static inline u32 printk_caller_id(void)
18841887
0x80000000 + raw_smp_processor_id();
18851888
}
18861889

1887-
/*
1888-
* Continuation lines are buffered, and not committed to the record buffer
1889-
* until the line is complete, or a race forces it. The line fragments
1890-
* though, are printed immediately to the consoles to ensure everything has
1891-
* reached the console in case of a kernel crash.
1892-
*/
1893-
static struct cont {
1894-
char buf[LOG_LINE_MAX];
1895-
size_t len; /* length == 0 means unused buffer */
1896-
u32 caller_id; /* printk_caller_id() of first print */
1897-
u64 ts_nsec; /* time of first print */
1898-
u8 level; /* log level of first message */
1899-
u8 facility; /* log facility of first message */
1900-
enum log_flags flags; /* prefix, newline flags */
1901-
} cont;
1902-
1903-
static void cont_flush(void)
1904-
{
1905-
if (cont.len == 0)
1906-
return;
1907-
1908-
log_store(cont.caller_id, cont.facility, cont.level, cont.flags,
1909-
cont.ts_nsec, NULL, 0, cont.buf, cont.len);
1910-
cont.len = 0;
1911-
}
1912-
1913-
static bool cont_add(u32 caller_id, int facility, int level,
1914-
enum log_flags flags, const char *text, size_t len)
1915-
{
1916-
/* If the line gets too long, split it up in separate records. */
1917-
if (cont.len + len > sizeof(cont.buf)) {
1918-
cont_flush();
1919-
return false;
1920-
}
1921-
1922-
if (!cont.len) {
1923-
cont.facility = facility;
1924-
cont.level = level;
1925-
cont.caller_id = caller_id;
1926-
cont.ts_nsec = local_clock();
1927-
cont.flags = flags;
1928-
}
1929-
1930-
memcpy(cont.buf + cont.len, text, len);
1931-
cont.len += len;
1932-
1933-
// The original flags come from the first line,
1934-
// but later continuations can add a newline.
1935-
if (flags & LOG_NEWLINE) {
1936-
cont.flags |= LOG_NEWLINE;
1937-
cont_flush();
1938-
}
1939-
1940-
return true;
1941-
}
1942-
19431890
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)
19441891
{
19451892
const u32 caller_id = printk_caller_id();
19461893

1947-
/*
1948-
* If an earlier line was buffered, and we're a continuation
1949-
* write from the same context, try to add it to the buffer.
1950-
*/
1951-
if (cont.len) {
1952-
if (cont.caller_id == caller_id && (lflags & LOG_CONT)) {
1953-
if (cont_add(caller_id, facility, level, lflags, text, text_len))
1954-
return text_len;
1955-
}
1956-
/* Otherwise, make sure it's flushed */
1957-
cont_flush();
1958-
}
1959-
1960-
/* Skip empty continuation lines that couldn't be added - they just flush */
1961-
if (!text_len && (lflags & LOG_CONT))
1962-
return 0;
1963-
1964-
/* If it doesn't end in a newline, try to buffer the current line */
1965-
if (!(lflags & LOG_NEWLINE)) {
1966-
if (cont_add(caller_id, facility, level, lflags, text, text_len))
1894+
if (lflags & LOG_CONT) {
1895+
struct prb_reserved_entry e;
1896+
struct printk_record r;
1897+
1898+
prb_rec_init_wr(&r, text_len, 0);
1899+
if (prb_reserve_in_last(&e, prb, &r, caller_id)) {
1900+
memcpy(&r.text_buf[r.info->text_len], text, text_len);
1901+
r.info->text_len += text_len;
1902+
if (lflags & LOG_NEWLINE) {
1903+
r.info->flags |= LOG_NEWLINE;
1904+
prb_final_commit(&e);
1905+
} else {
1906+
prb_commit(&e);
1907+
}
19671908
return text_len;
1909+
}
19681910
}
19691911

19701912
/* Store it in the record log */

0 commit comments

Comments
 (0)