Messages in this thread | | | Subject | Possible race in printk? | Date | Thu, 11 Nov 1999 14:04:51 +0100 (MET) | From | (Rogier Wolff) |
| |
Hi,
/* * 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++); } if (do_clear)
What if at the start the ringbuffer is "full", and an interrupt which prints something comes in while we're blocking interrupts. The interrupt will happen the moment "restore flags" is called.
We'll print "new" info from the buffer, which has just overwritten "old" info. This can be very confusing.
during CLI area: start of buffer end of buffer. ^ ^ 0 1 2 3 4 5 6 7 8 9 j^ <------count------>
after interrupt;
start of buffer end of buffer. ^ ^ a b c 3 4 5 6 7 8 9 j^ <------count------> the copy will copy over abc3456789, instead of 3456789abc.
The naive thing to do would be to move the restore flags to past the forloop, but that, I'm told, leads to nasty Oopsen when the put_user causes some paging.
Does anybody know how I can get printk to print stuff to the console again? I'm trying to track down a "system hang" and my "cat /proc/kmsg" works great, as long as the system doesn't hang....
So far I've been playing with the syslog system call, the "klogd" program iwth the -c argument, and the /proc/sys/kernel/printk file...
Roger.
-- ** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 ** *-- BitWizard writes Linux device drivers for any device you may have! --* "I didn't say it was your fault. I said I was going to blame it on you."
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |