|
@@ -1583,46 +1583,25 @@ static inline void printk_delay(void)
|
|
|
static struct cont {
|
|
|
char buf[LOG_LINE_MAX];
|
|
|
size_t len; /* length == 0 means unused buffer */
|
|
|
- size_t cons; /* bytes written to console */
|
|
|
struct task_struct *owner; /* task of first print*/
|
|
|
u64 ts_nsec; /* time of first print */
|
|
|
u8 level; /* log level of first message */
|
|
|
u8 facility; /* log facility of first message */
|
|
|
enum log_flags flags; /* prefix, newline flags */
|
|
|
- bool flushed:1; /* buffer sealed and committed */
|
|
|
} cont;
|
|
|
|
|
|
static void cont_flush(void)
|
|
|
{
|
|
|
- if (cont.flushed)
|
|
|
- return;
|
|
|
if (cont.len == 0)
|
|
|
return;
|
|
|
- if (cont.cons) {
|
|
|
- /*
|
|
|
- * If a fragment of this line was directly flushed to the
|
|
|
- * console; wait for the console to pick up the rest of the
|
|
|
- * line. LOG_NOCONS suppresses a duplicated output.
|
|
|
- */
|
|
|
- log_store(cont.facility, cont.level, cont.flags | LOG_NOCONS,
|
|
|
- cont.ts_nsec, NULL, 0, cont.buf, cont.len);
|
|
|
- cont.flushed = true;
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * If no fragment of this line ever reached the console,
|
|
|
- * just submit it to the store and free the buffer.
|
|
|
- */
|
|
|
- log_store(cont.facility, cont.level, cont.flags, 0,
|
|
|
- NULL, 0, cont.buf, cont.len);
|
|
|
- cont.len = 0;
|
|
|
- }
|
|
|
+
|
|
|
+ log_store(cont.facility, cont.level, cont.flags, cont.ts_nsec,
|
|
|
+ NULL, 0, cont.buf, cont.len);
|
|
|
+ cont.len = 0;
|
|
|
}
|
|
|
|
|
|
static bool cont_add(int facility, int level, enum log_flags flags, const char *text, size_t len)
|
|
|
{
|
|
|
- if (cont.len && cont.flushed)
|
|
|
- return false;
|
|
|
-
|
|
|
/*
|
|
|
* If ext consoles are present, flush and skip in-kernel
|
|
|
* continuation. See nr_ext_console_drivers definition. Also, if
|
|
@@ -1639,8 +1618,6 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char *
|
|
|
cont.owner = current;
|
|
|
cont.ts_nsec = local_clock();
|
|
|
cont.flags = flags;
|
|
|
- cont.cons = 0;
|
|
|
- cont.flushed = false;
|
|
|
}
|
|
|
|
|
|
memcpy(cont.buf + cont.len, text, len);
|
|
@@ -1659,34 +1636,6 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char *
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static size_t cont_print_text(char *text, size_t size)
|
|
|
-{
|
|
|
- size_t textlen = 0;
|
|
|
- size_t len;
|
|
|
-
|
|
|
- if (cont.cons == 0) {
|
|
|
- textlen += print_time(cont.ts_nsec, text);
|
|
|
- size -= textlen;
|
|
|
- }
|
|
|
-
|
|
|
- len = cont.len - cont.cons;
|
|
|
- if (len > 0) {
|
|
|
- if (len+1 > size)
|
|
|
- len = size-1;
|
|
|
- memcpy(text + textlen, cont.buf + cont.cons, len);
|
|
|
- textlen += len;
|
|
|
- cont.cons = cont.len;
|
|
|
- }
|
|
|
-
|
|
|
- if (cont.flushed) {
|
|
|
- if (cont.flags & LOG_NEWLINE)
|
|
|
- text[textlen++] = '\n';
|
|
|
- /* got everything, release buffer */
|
|
|
- cont.len = 0;
|
|
|
- }
|
|
|
- return textlen;
|
|
|
-}
|
|
|
-
|
|
|
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)
|
|
|
{
|
|
|
/*
|
|
@@ -1957,7 +1906,6 @@ static void call_console_drivers(int level,
|
|
|
const char *text, size_t len) {}
|
|
|
static size_t msg_print_text(const struct printk_log *msg,
|
|
|
bool syslog, char *buf, size_t size) { return 0; }
|
|
|
-static size_t cont_print_text(char *text, size_t size) { return 0; }
|
|
|
static bool suppress_message_printing(int level) { return false; }
|
|
|
|
|
|
/* Still needs to be defined for users */
|
|
@@ -2221,42 +2169,6 @@ static inline int can_use_console(void)
|
|
|
return cpu_online(raw_smp_processor_id()) || have_callable_console();
|
|
|
}
|
|
|
|
|
|
-static void console_cont_flush(char *text, size_t size)
|
|
|
-{
|
|
|
- unsigned long flags;
|
|
|
- size_t len;
|
|
|
-
|
|
|
- raw_spin_lock_irqsave(&logbuf_lock, flags);
|
|
|
-
|
|
|
- if (!cont.len)
|
|
|
- goto out;
|
|
|
-
|
|
|
- if (suppress_message_printing(cont.level)) {
|
|
|
- cont.cons = cont.len;
|
|
|
- if (cont.flushed)
|
|
|
- cont.len = 0;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * We still queue earlier records, likely because the console was
|
|
|
- * busy. The earlier ones need to be printed before this one, we
|
|
|
- * did not flush any fragment so far, so just let it queue up.
|
|
|
- */
|
|
|
- if (console_seq < log_next_seq && !cont.cons)
|
|
|
- goto out;
|
|
|
-
|
|
|
- len = cont_print_text(text, size);
|
|
|
- raw_spin_unlock(&logbuf_lock);
|
|
|
- stop_critical_timings();
|
|
|
- call_console_drivers(cont.level, NULL, 0, text, len);
|
|
|
- start_critical_timings();
|
|
|
- local_irq_restore(flags);
|
|
|
- return;
|
|
|
-out:
|
|
|
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* console_unlock - unlock the console system
|
|
|
*
|
|
@@ -2310,9 +2222,6 @@ again:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* flush buffered message fragment immediately to console */
|
|
|
- console_cont_flush(text, sizeof(text));
|
|
|
-
|
|
|
for (;;) {
|
|
|
struct printk_log *msg;
|
|
|
size_t ext_len = 0;
|
|
@@ -2341,8 +2250,7 @@ skip:
|
|
|
|
|
|
msg = log_from_idx(console_idx);
|
|
|
level = msg->level;
|
|
|
- if ((msg->flags & LOG_NOCONS) ||
|
|
|
- suppress_message_printing(level)) {
|
|
|
+ if (suppress_message_printing(level)) {
|
|
|
/*
|
|
|
* Skip record we have buffered and already printed
|
|
|
* directly to the console when we received it, and
|
|
@@ -2350,12 +2258,6 @@ skip:
|
|
|
*/
|
|
|
console_idx = log_next(console_idx);
|
|
|
console_seq++;
|
|
|
- /*
|
|
|
- * We will get here again when we register a new
|
|
|
- * CON_PRINTBUFFER console. Clear the flag so we
|
|
|
- * will properly dump everything later.
|
|
|
- */
|
|
|
- msg->flags &= ~LOG_NOCONS;
|
|
|
goto skip;
|
|
|
}
|
|
|
|