Messages in this thread Patch in this message | | | Subject | Re: [PATCH 0/2] printk vs rq->lock and xtime lock | From | Peter Zijlstra <> | Date | Fri, 08 Aug 2008 19:10:54 +0200 |
| |
On Fri, 2008-08-08 at 09:41 -0700, Linus Torvalds wrote: > > On Fri, 8 Aug 2008, Peter Zijlstra wrote: > > > > Something along the lines of the below patch? > > Could we not literally just make this a RCU event? Unconditionally too?
Sure, but the RCU callback period is at least 3 jiffies and much longer when busy - I'm not sure how long before we force a grace period, we do that to avoid DoS, right Paul?
So this version would have a much higher risk of overflowing the console buffer and making klogd miss bits. Then again, I really don't care about klogd at _all_, I've been running with the wakeup patched out for ages.
Gah, the below doesn't boot - because I guess we start using rcu before its properly set up.. should I poke at it more?
--- diff --git a/kernel/printk.c b/kernel/printk.c index b51b156..3d80e30 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -32,6 +32,7 @@ #include <linux/security.h> #include <linux/bootmem.h> #include <linux/syscalls.h> +#include <linux/rcupdate.h> #include <asm/uaccess.h> @@ -982,10 +983,38 @@ int is_console_locked(void) return console_locked; } -void wake_up_klogd(void) +void __wake_up_klogd(struct rcu_head *head); + +static struct { + struct rcu_head head; + spinlock_t lock; + int pending; +} klogd_wakeup_state = { + .lock = __SPIN_LOCK_UNLOCKED(klogd_wakeup_state.lock), +}; + +void __wake_up_klogd(struct rcu_head *head) { + unsigned long flags; + + spin_lock_irqsave(&klogd_wakeup_state.lock, flags); + BUG_ON(!klogd_wakeup_state.pending); if (!oops_in_progress && waitqueue_active(&log_wait)) wake_up_interruptible(&log_wait); + klogd_wakeup_state.pending = 0; + spin_unlock_irqrestore(&klogd_wakeup_state.lock, flags); +} + +void wake_up_klogd(void) +{ + unsigned long flags; + + spin_lock_irqsave(&klogd_wakeup_state.lock, flags); + if (!klogd_wakeup_state.pending) { + call_rcu(&klogd_wakeup_state.head, __wake_up_klogd); + klogd_wakeup_state.pending = 1; + } + spin_unlock_irqrestore(&klogd_wakeup_state.lock, flags); } /**
| |