*** printk.c~ Fri Jun 30 16:24:38 2000 --- printk.c Sat Jul 1 11:18:41 2000 *************** *** 19,32 **** #include #include #include #include #define LOG_BUF_LEN (16384) #define LOG_BUF_MASK (LOG_BUF_LEN-1) - static char buf[1024]; - /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ --- 19,31 ---- #include #include #include + #include #include #define LOG_BUF_LEN (16384) #define LOG_BUF_MASK (LOG_BUF_LEN-1) /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ *************** *** 253,271 **** asmlinkage int printk(const char *fmt, ...) { va_list args; int i; char *msg, *p, *buf_end; int line_feed; static signed char msg_level = -1; long flags; va_start(args, fmt); i = vsprintf(buf + 3, fmt, args); /* hopefully i < sizeof(buf)-4 */ buf_end = buf + 3 + i; va_end(args); ! spin_lock_irqsave(&console_lock, flags); for (p = buf + 3; p < buf_end; p++) { msg = p; if (msg_level < 0) { --- 252,292 ---- asmlinkage int printk(const char *fmt, ...) { + static spinlock_t printk_buf_lock = SPIN_LOCK_UNLOCKED; + static struct task_struct *printk_buf_holder = 0; + static char printk_buf[1024]; + va_list args; int i; char *msg, *p, *buf_end; int line_feed; static signed char msg_level = -1; long flags; + char *buf = printk_buf; + + if (!spin_trylock(&printk_buf_lock)) { + /* Couldn't get spinlock... do we already have it? */ + if (printk_buf_holder == current) { + /* Yup, don't clobber printk_buf, use a temporary one + * instead... this is a very uncommon case... + */ + buf = (char*)kmalloc(1024, GFP_KERNEL); + } else { + /* Nope, wait for someone to release it... */ + spin_lock(&printk_buf_lock); + } + } + + /* We are now the proud holders of the printk_buf_lock! :) */ + printk_buf_holder = current; va_start(args, fmt); i = vsprintf(buf + 3, fmt, args); /* hopefully i < sizeof(buf)-4 */ buf_end = buf + 3 + i; va_end(args); ! spin_lock_irqsave(&console_lock, flags); + for (p = buf + 3; p < buf_end; p++) { msg = p; if (msg_level < 0) { *************** *** 308,315 **** --- 329,346 ---- if (line_feed) msg_level = -1; } + spin_unlock_irqrestore(&console_lock, flags); wake_up_interruptible(&log_wait); + + if (buf != printk_buf) { + /* We recursed into printk... release our temporary buffer.. */ + kfree(buf); + } else { + /* This is the normal case... just release the spinlock... */ + spin_unlock(&printk_buf_lock); + } + return i; }