diff options
-rw-r--r-- | kernel/printk/internal.h | 11 | ||||
-rw-r--r-- | kernel/printk/nmi.c | 5 | ||||
-rw-r--r-- | kernel/printk/printk.c | 10 |
3 files changed, 25 insertions, 1 deletions
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 2de99faedfc1..341bedccc065 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h | |||
@@ -34,6 +34,12 @@ static inline __printf(1, 0) int vprintk_func(const char *fmt, va_list args) | |||
34 | return this_cpu_read(printk_func)(fmt, args); | 34 | return this_cpu_read(printk_func)(fmt, args); |
35 | } | 35 | } |
36 | 36 | ||
37 | extern atomic_t nmi_message_lost; | ||
38 | static inline int get_nmi_message_lost(void) | ||
39 | { | ||
40 | return atomic_xchg(&nmi_message_lost, 0); | ||
41 | } | ||
42 | |||
37 | #else /* CONFIG_PRINTK_NMI */ | 43 | #else /* CONFIG_PRINTK_NMI */ |
38 | 44 | ||
39 | static inline __printf(1, 0) int vprintk_func(const char *fmt, va_list args) | 45 | static inline __printf(1, 0) int vprintk_func(const char *fmt, va_list args) |
@@ -41,4 +47,9 @@ static inline __printf(1, 0) int vprintk_func(const char *fmt, va_list args) | |||
41 | return vprintk_default(fmt, args); | 47 | return vprintk_default(fmt, args); |
42 | } | 48 | } |
43 | 49 | ||
50 | static inline int get_nmi_message_lost(void) | ||
51 | { | ||
52 | return 0; | ||
53 | } | ||
54 | |||
44 | #endif /* CONFIG_PRINTK_NMI */ | 55 | #endif /* CONFIG_PRINTK_NMI */ |
diff --git a/kernel/printk/nmi.c b/kernel/printk/nmi.c index 303cf0d15e57..572f94922230 100644 --- a/kernel/printk/nmi.c +++ b/kernel/printk/nmi.c | |||
@@ -39,6 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default; | 40 | DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default; |
41 | static int printk_nmi_irq_ready; | 41 | static int printk_nmi_irq_ready; |
42 | atomic_t nmi_message_lost; | ||
42 | 43 | ||
43 | #define NMI_LOG_BUF_LEN (4096 - sizeof(atomic_t) - sizeof(struct irq_work)) | 44 | #define NMI_LOG_BUF_LEN (4096 - sizeof(atomic_t) - sizeof(struct irq_work)) |
44 | 45 | ||
@@ -64,8 +65,10 @@ static int vprintk_nmi(const char *fmt, va_list args) | |||
64 | again: | 65 | again: |
65 | len = atomic_read(&s->len); | 66 | len = atomic_read(&s->len); |
66 | 67 | ||
67 | if (len >= sizeof(s->buffer)) | 68 | if (len >= sizeof(s->buffer)) { |
69 | atomic_inc(&nmi_message_lost); | ||
68 | return 0; | 70 | return 0; |
71 | } | ||
69 | 72 | ||
70 | /* | 73 | /* |
71 | * Make sure that all old data have been read before the buffer was | 74 | * Make sure that all old data have been read before the buffer was |
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 71eba0607034..e38579d730f4 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -1617,6 +1617,7 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
1617 | unsigned long flags; | 1617 | unsigned long flags; |
1618 | int this_cpu; | 1618 | int this_cpu; |
1619 | int printed_len = 0; | 1619 | int printed_len = 0; |
1620 | int nmi_message_lost; | ||
1620 | bool in_sched = false; | 1621 | bool in_sched = false; |
1621 | /* cpu currently holding logbuf_lock in this function */ | 1622 | /* cpu currently holding logbuf_lock in this function */ |
1622 | static unsigned int logbuf_cpu = UINT_MAX; | 1623 | static unsigned int logbuf_cpu = UINT_MAX; |
@@ -1667,6 +1668,15 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
1667 | strlen(recursion_msg)); | 1668 | strlen(recursion_msg)); |
1668 | } | 1669 | } |
1669 | 1670 | ||
1671 | nmi_message_lost = get_nmi_message_lost(); | ||
1672 | if (unlikely(nmi_message_lost)) { | ||
1673 | text_len = scnprintf(textbuf, sizeof(textbuf), | ||
1674 | "BAD LUCK: lost %d message(s) from NMI context!", | ||
1675 | nmi_message_lost); | ||
1676 | printed_len += log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0, | ||
1677 | NULL, 0, textbuf, text_len); | ||
1678 | } | ||
1679 | |||
1670 | /* | 1680 | /* |
1671 | * The printf needs to come first; we need the syslog | 1681 | * The printf needs to come first; we need the syslog |
1672 | * prefix which might be passed-in as a parameter. | 1682 | * prefix which might be passed-in as a parameter. |