Re: Wierd kernel crash (Motherboard bug?) after check_bugs

Pavel Machek (pavel@elf.ucw.cz)
Mon, 26 Jan 1998 23:34:49 +0100


Hi!

> One interesting thing about the crash was that with an untouched kernel,
> it appeared to happen immediately after the "checking 'htl'
> instruction..." printout, leading me to look at that check first.
> However, after all my for() loop delays were added, the thread lasted
> through the tests and the kernel banner printing (ie. only one line
> further on the screen, but a number of lines in the code), up till the
> idle() loop (cpu_idle()). I have two hypotheses: 1 - the crash is caused
> by another thread which waits for the start_kernel thread to go idle
> before doing whatever causes the crash, 2 - the crash is caused by the
> start_kernel thread, but only comes into affect when the thread goes idle.
> I really don't have any further ideas.

I do not really think that there is >1 kernel thread at that time. Try
removing hlt occurences in kernel with nothing.

Try running 2.1.80.

Well, when delays after printk are topic (yes, I think that they are
usefull for debugging), please try to merge this into suitably
mainstream kernel:

It adds slow-printk command line switch, which is good if your machine
reboots before you can read message. It also 'cleans up' code in
printk.c so it is callable from outside of printk.c

diff -ur -x .dep* -x .hdep* -x *.[oas] -x *~ -x #* -x *CVS* -x *.orig -x *.rej -x *.old -x .menu* -x asm -x local.h -x System.map -x autoconf.h -x compile.h -x version.h -x .version -x defkeymap.c -x uni_hash.tbl -x zImage -x vmlinu?* -x TAGS -x bootsect -x *RCS* -x conmakehash -x map -x build -x build -x configure -x *target* -x Makefile* clean/init/main.c linux/init/main.c
--- clean/init/main.c Sat Jan 24 17:00:01 1998
+++ linux/init/main.c Sat Jan 24 16:52:07 1998
@@ -416,6 +421,12 @@
{ NULL, 0 }
};

+__initfunc(static void printk_setup(char *line, int *num))
+{
+extern int slow_printk;
+slow_printk = 1;
+}
+
__initfunc(static void root_dev_setup(char *line, int *num))
{
int base = 0;
@@ -478,6 +489,7 @@
{ "swap=", swap_setup },
{ "buff=", buff_setup },
{ "panic=", panic_setup },
+ { "slow-printk", printk_setup },
{ "console=", console_setup },
#ifdef CONFIG_VT
{ "no-scroll", no_scroll },
diff -ur -x .dep* -x .hdep* -x *.[oas] -x *~ -x #* -x *CVS* -x *.orig -x *.rej -x *.old -x .menu* -x asm -x local.h -x System.map -x autoconf.h -x compile.h -x version.h -x .version -x defkeymap.c -x uni_hash.tbl -x zImage -x vmlinu?* -x TAGS -x bootsect -x *RCS* -x conmakehash -x map -x build -x build -x configure -x *target* -x Makefile* clean/kernel/printk.c linux/kernel/printk.c
--- clean/kernel/printk.c Sat Jan 24 17:00:01 1998
+++ linux/kernel/printk.c Sat Jan 24 16:53:07 1998
@@ -26,6 +26,7 @@
#include <linux/smp_lock.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/delay.h>

#include <asm/uaccess.h>

@@ -93,6 +94,34 @@
*s = 0;
}

+int
+get_syslog_data( char *buf, int from, int len )
+{
+ int i, j, count;
+ unsigned long flags;
+ char c;
+
+/*
+ * The logged_chars, log_start, and log_size values may
+ * change from an interrupt, so we disable interrupts.
+ */
+ __save_flags(flags);
+ __cli();
+ count = len + from;
+ if (count > LOG_BUF_LEN)
+ count = LOG_BUF_LEN;
+ if (count > logged_chars)
+ count = logged_chars;
+ j = log_start + log_size - count;
+ __restore_flags(flags);
+ for (i = 0; i < count; i++)
+ if (from) from--;
+ else {
+ c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
+ __put_user(c, buf++);
+ }
+ return i;
+}

/*
* Commands to sys_syslog:
@@ -109,9 +138,9 @@
*/
asmlinkage int sys_syslog(int type, char * buf, int len)
{
- unsigned long i, j, count, flags;
- int do_clear = 0;
+ unsigned long i;
char c;
+ int do_clear = 0;
int error = -EPERM;

lock_kernel();
@@ -170,26 +199,10 @@
error = verify_area(VERIFY_WRITE,buf,len);
if (error)
goto out;
- /*
- * The logged_chars, log_start, and log_size values may
- * change from an interrupt, so we disable interrupts.
- */
- __save_flags(flags);
- __cli();
- count = len;
- if (count > LOG_BUF_LEN)
- count = LOG_BUF_LEN;
- if (count > logged_chars)
- count = logged_chars;
- j = log_start + log_size - count;
- __restore_flags(flags);
- for (i = 0; i < count; i++) {
- c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
- __put_user(c, buf++);
- }
+
+ error = get_syslog_data(buf,0,len);
if (do_clear)
logged_chars = 0;
- error = i;
break;
case 5: /* Clear ring buffer */
logged_chars = 0;
@@ -218,6 +231,7 @@
return error;
}

+int slow_printk;
spinlock_t console_lock;

asmlinkage int printk(const char *fmt, ...)
@@ -277,6 +291,8 @@
if (line_feed)
msg_level = -1;
}
+ if (slow_printk)
+ udelay( 1000000 );
spin_unlock_irqrestore(&console_lock, flags);
wake_up_interruptible(&log_wait);
return i;

-- 
I'm really pavel@atrey.karlin.mff.cuni.cz. 	   Pavel
Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).