summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2012-04-01 02:43:28 +0200
committerKay Sievers <kay.sievers@vrfy.org>2012-04-01 02:43:28 +0200
commit6937eff19fe7dd0c708122dbf59825e41453d06b (patch)
tree7508744bf9cb25158f8ba356c2a00b217f8a93dc
parente8e9f05d18aff7cf254743131812b02e3dc5ddb2 (diff)
downloadpatches-6937eff19fe7dd0c708122dbf59825e41453d06b.tar.gz
more wrap-around fixes
-rw-r--r--printk.patch108
1 files changed, 60 insertions, 48 deletions
diff --git a/printk.patch b/printk.patch
index 6e22b7c..2f252bd 100644
--- a/printk.patch
+++ b/printk.patch
@@ -98,8 +98,8 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
drivers/base/core.c | 49 +
drivers/char/mem.c | 40 -
include/linux/printk.h | 13
- kernel/printk.c | 1369 +++++++++++++++++++++++++++++++++----------------
- 4 files changed, 1002 insertions(+), 469 deletions(-)
+ kernel/printk.c | 1381 +++++++++++++++++++++++++++++++++----------------
+ 4 files changed, 1014 insertions(+), 469 deletions(-)
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -303,7 +303,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
* If exclusive_console is non-NULL then only this console is to be printed to.
*/
static struct console *exclusive_console;
-@@ -146,12 +127,525 @@ EXPORT_SYMBOL(console_set_on_cmdline);
+@@ -146,12 +127,536 @@ EXPORT_SYMBOL(console_set_on_cmdline);
static int console_may_schedule;
#ifdef CONFIG_PRINTK
@@ -458,23 +458,34 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
+ return (char *)msg + sizeof(struct log) + msg->text_len;
+}
+
-+/* get record by index */
++/* get record by index; idx must point to valid msg */
+static struct log *log_from_idx(u32 idx)
+{
-+ return (struct log *)&log_buf[idx];
++ struct log *msg = (struct log *)(log_buf + idx);
++
++ /* length == 0 indicates the end of the buffer; wrap */
++ if (!msg->len)
++ return (struct log *)log_buf;
++ return msg;
+}
+
-+/* get next record; log_next_idx indicates the last record */
++/* get next record; idx must point to valid msg */
+static u32 log_next(u32 idx)
+{
-+ u16 len = log_from_idx(idx)->len;
++ struct log *msg = (struct log *)(log_buf + idx);
+
+ /* length == 0 indicates the end of the buffer; wrap */
-+ if (log_from_idx(idx + len)->len == 0)
++ if (!msg->len)
+ return 0;
-+ return idx + len;
++ return idx + msg->len;
+}
+
++#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
++#define LOG_ALIGN 4
++#else
++#define LOG_ALIGN 8
++#endif
++
+/* insert record into the buffer, discard old ones, update heads */
+static void log_store(int facility, int level,
+ const char *dict, u16 dict_len,
@@ -485,37 +496,37 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
+
+ /* number of '\0' padding bytes to next message */
+ size = sizeof(struct log) + text_len + dict_len;
-+ pad_len = (-size) & (8 - 1);
++ pad_len = (-size) & (LOG_ALIGN - 1);
+ size += pad_len;
+
-+ /* drop old messages until we have enough contiuous space */
+ while (log_first_seq < log_next_seq) {
+ u32 free;
+
-+ if (log_next_idx >= log_first_idx)
++ if (log_next_idx > log_first_idx)
+ free = max(log_buf_len - log_next_idx, log_first_idx);
+ else
+ free = log_first_idx - log_next_idx;
+
-+ if (free >= size + sizeof(struct log))
++ if (free > size + sizeof(struct log))
+ break;
+
++ /* drop old messages until we have enough contiuous space */
+ log_first_idx = log_next(log_first_idx);
+ log_first_seq++;
+ }
+
-+ if (log_next_idx + size + sizeof(struct log) > log_buf_len) {
++ if (log_next_idx + size + sizeof(struct log) >= log_buf_len) {
+ /*
-+ * This message + empty last message does not fit at the
-+ * end; wrap. Zero-out the remaining buffer to set len = 0,
-+ * and leave a clean buffer for things like crash dump.
++ * This message + an additional empty header does not fit
++ * at the end of the buffer. Add an empty header with len = 0
++ * to signify a wrap around.
+ */
-+ memset(log_buf + log_next_idx, 0, log_buf_len - log_next_idx);
++ memset(log_buf + log_next_idx, 0, sizeof(struct log));
+ log_next_idx = 0;
+ }
+
+ /* fill message */
-+ msg = log_from_idx(log_next_idx);
++ msg = (struct log *)(log_buf + log_next_idx);
+ memcpy(log_text(msg), text, text_len);
+ msg->text_len = text_len;
+ memcpy(log_dict(msg), dict, dict_len);
@@ -832,7 +843,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
#ifdef CONFIG_KEXEC
/*
-@@ -165,9 +659,9 @@ static int saved_console_loglevel = -1;
+@@ -165,9 +670,9 @@ static int saved_console_loglevel = -1;
void log_buf_kexec_setup(void)
{
VMCOREINFO_SYMBOL(log_buf);
@@ -844,7 +855,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
}
#endif
-@@ -191,7 +685,6 @@ early_param("log_buf_len", log_buf_len_s
+@@ -191,7 +696,6 @@ early_param("log_buf_len", log_buf_len_s
void __init setup_log_buf(int early)
{
unsigned long flags;
@@ -852,7 +863,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
char *new_log_buf;
int free;
-@@ -219,20 +712,8 @@ void __init setup_log_buf(int early)
+@@ -219,20 +723,8 @@ void __init setup_log_buf(int early)
log_buf_len = new_log_buf_len;
log_buf = new_log_buf;
new_log_buf_len = 0;
@@ -875,7 +886,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
pr_info("log_buf_len: %d\n", log_buf_len);
-@@ -332,11 +813,165 @@ static int check_syslog_permissions(int
+@@ -332,11 +824,165 @@ static int check_syslog_permissions(int
return 0;
}
@@ -1044,7 +1055,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
int error;
error = check_syslog_permissions(type, from_file);
-@@ -364,28 +999,14 @@ int do_syslog(int type, char __user *buf
+@@ -364,28 +1010,14 @@ int do_syslog(int type, char __user *buf
goto out;
}
error = wait_event_interruptible(log_wait,
@@ -1076,7 +1087,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/* FALL THRU */
/* Read last kernel messages */
case SYSLOG_ACTION_READ_ALL:
-@@ -399,52 +1020,11 @@ int do_syslog(int type, char __user *buf
+@@ -399,52 +1031,11 @@ int do_syslog(int type, char __user *buf
error = -EFAULT;
goto out;
}
@@ -1131,7 +1142,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/* Disable logging to console */
case SYSLOG_ACTION_CONSOLE_OFF:
if (saved_console_loglevel == -1)
-@@ -472,7 +1052,33 @@ int do_syslog(int type, char __user *buf
+@@ -472,7 +1063,33 @@ int do_syslog(int type, char __user *buf
break;
/* Number of chars in the log buffer */
case SYSLOG_ACTION_SIZE_UNREAD:
@@ -1144,7 +1155,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
+ }
+ if (from_file) {
+ /*
-+ * Optimize for poll(/"proc/kmsg") which simply checks
++ * Short-cut for poll(/"proc/kmsg") which simply checks
+ * for pending data, not the size; return the count of
+ * records, not the length.
+ */
@@ -1166,7 +1177,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
break;
/* Size of the log buffer */
case SYSLOG_ACTION_SIZE_BUFFER:
-@@ -501,29 +1107,11 @@ void kdb_syslog_data(char *syslog_data[4
+@@ -501,29 +1118,11 @@ void kdb_syslog_data(char *syslog_data[4
{
syslog_data[0] = log_buf;
syslog_data[1] = log_buf + log_buf_len;
@@ -1198,7 +1209,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
static bool __read_mostly ignore_loglevel;
static int __init ignore_loglevel_setup(char *str)
-@@ -540,142 +1128,33 @@ MODULE_PARM_DESC(ignore_loglevel, "ignor
+@@ -540,142 +1139,33 @@ MODULE_PARM_DESC(ignore_loglevel, "ignor
"print all kernel messages to the console.");
/*
@@ -1360,7 +1371,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
}
/*
-@@ -700,16 +1179,6 @@ static void zap_locks(void)
+@@ -700,16 +1190,6 @@ static void zap_locks(void)
sema_init(&console_sem, 1);
}
@@ -1377,7 +1388,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/* Check if we have any console registered that can be called early in boot. */
static int have_callable_console(void)
{
-@@ -722,51 +1191,6 @@ static int have_callable_console(void)
+@@ -722,51 +1202,6 @@ static int have_callable_console(void)
return 0;
}
@@ -1429,7 +1440,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/*
* Can we actually use the console at this time on this cpu?
*
-@@ -810,17 +1234,12 @@ static int console_trylock_for_printk(un
+@@ -810,17 +1245,12 @@ static int console_trylock_for_printk(un
retval = 0;
}
}
@@ -1448,7 +1459,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
int printk_delay_msec __read_mostly;
-@@ -836,15 +1255,22 @@ static inline void printk_delay(void)
+@@ -836,15 +1266,22 @@ static inline void printk_delay(void)
}
}
@@ -1478,7 +1489,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
boot_delay_msec();
printk_delay();
-@@ -856,7 +1282,7 @@ asmlinkage int vprintk(const char *fmt,
+@@ -856,7 +1293,7 @@ asmlinkage int vprintk(const char *fmt,
/*
* Ouch, printk recursed into itself!
*/
@@ -1487,7 +1498,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/*
* If a crash is occurring during printk() on this CPU,
* then try to get the crash message out but make sure
-@@ -873,97 +1299,92 @@ asmlinkage int vprintk(const char *fmt,
+@@ -873,97 +1310,92 @@ asmlinkage int vprintk(const char *fmt,
lockdep_off();
raw_spin_lock(&logbuf_lock);
@@ -1656,7 +1667,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
*/
if (console_trylock_for_printk(this_cpu))
console_unlock();
-@@ -974,12 +1395,73 @@ out_restore_irqs:
+@@ -974,12 +1406,73 @@ out_restore_irqs:
return printed_len;
}
@@ -1732,7 +1743,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
{
}
-@@ -1217,7 +1699,7 @@ int is_console_locked(void)
+@@ -1217,7 +1710,7 @@ int is_console_locked(void)
}
/*
@@ -1741,7 +1752,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
*/
#define PRINTK_BUF_SIZE 512
-@@ -1253,6 +1735,10 @@ void wake_up_klogd(void)
+@@ -1253,6 +1746,10 @@ void wake_up_klogd(void)
this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
}
@@ -1752,7 +1763,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/**
* console_unlock - unlock the console system
*
-@@ -1263,15 +1749,16 @@ void wake_up_klogd(void)
+@@ -1263,15 +1760,16 @@ void wake_up_klogd(void)
* by printk(). If this is the case, console_unlock(); emits
* the output prior to releasing the lock.
*
@@ -1772,7 +1783,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
if (console_suspended) {
up(&console_sem);
-@@ -1281,17 +1768,40 @@ void console_unlock(void)
+@@ -1281,17 +1779,41 @@ void console_unlock(void)
console_may_schedule = 0;
again:
@@ -1795,14 +1806,15 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
+ seen_seq = log_next_seq;
+ }
+
-+ if (console_seq == log_next_seq)
-+ break;
-+
+ if (console_seq < log_first_seq) {
+ /* messages are gone, move to first one */
+ console_seq = log_first_seq;
+ console_idx = log_first_idx;
+ }
++
++ if (console_seq == log_next_seq)
++ break;
++
+ msg = log_from_idx(console_idx);
+ level = msg->level;
+ len = msg->text_len;
@@ -1821,7 +1833,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
start_critical_timings();
local_irq_restore(flags);
}
-@@ -1312,8 +1822,7 @@ again:
+@@ -1312,8 +1834,7 @@ again:
* flush, no worries.
*/
raw_spin_lock(&logbuf_lock);
@@ -1831,7 +1843,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
if (retry && console_trylock())
-@@ -1549,7 +2058,8 @@ void register_console(struct console *ne
+@@ -1549,7 +2070,8 @@ void register_console(struct console *ne
* for us.
*/
raw_spin_lock_irqsave(&logbuf_lock, flags);
@@ -1841,7 +1853,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
/*
* We're about to replay the log buffer. Only do this to the
-@@ -1758,6 +2268,9 @@ int kmsg_dump_unregister(struct kmsg_dum
+@@ -1758,6 +2280,9 @@ int kmsg_dump_unregister(struct kmsg_dum
}
EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
@@ -1851,7 +1863,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
/**
* kmsg_dump - dump kernel log to kernel message dumpers.
* @reason: the reason (oops, panic etc) for dumping
-@@ -1767,8 +2280,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
+@@ -1767,8 +2292,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
*/
void kmsg_dump(enum kmsg_dump_reason reason)
{
@@ -1861,7 +1873,7 @@ Signed-off-by: Kay Sievers <kay@vrfy.org>
struct kmsg_dumper *dumper;
const char *s1, *s2;
unsigned long l1, l2;
-@@ -1780,24 +2292,27 @@ void kmsg_dump(enum kmsg_dump_reason rea
+@@ -1780,24 +2304,27 @@ void kmsg_dump(enum kmsg_dump_reason rea
/* Theoretically, the log could move on after we do this, but
there's not a lot we can do about that. The new messages
will overwrite the start of what we dump. */