diff --git a/arch/x86/tools/mcreboot-smp-x86.sh.in b/arch/x86/tools/mcreboot-smp-x86.sh.in index 8645f123..68790f95 100644 --- a/arch/x86/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86/tools/mcreboot-smp-x86.sh.in @@ -126,6 +126,16 @@ if [ "${irqbalance_used}" == "yes" ]; then if ! systemctl stop irqbalance.service 2>/dev/null ; then echo "error: stopping irqbalance" >&2; exit 1; fi; fi +# Start mcklogd. Note that McKernel blocks when kmsg buffer is full +# with '-k 1' until mcklogd unblocks it so starting mcklogd must preceeds +# booting McKernel +if [ ${LOGMODE} -ne 0 ] +then +# Stop mcklogd which has survived McKernel shutdown because mcstop+release.sh is not used + pkill mcklogd + SBINDIR=${SBINDIR} ${SBINDIR}/mcklogd -i ${INTERVAL} -f ${facility} +fi + # Load IHK if not loaded if [ "`lsmod | grep ihk`" == "" ]; then if ! insmod ${KMODDIR}/ihk.ko; then echo "error: loading ihk" >&2; exit 1; fi; @@ -249,12 +259,6 @@ if [ "$enable_mcoverlay" == "yes" ]; then fi done fi -if [ ${LOGMODE} -ne 0 ] -then -# mcklogd survives when McKernel isn't shut down by mcstop+release.sh - pkill mcklogd - SBINDIR=${SBINDIR} ${SBINDIR}/mcklogd -i ${INTERVAL} -f ${facility} -fi # Start irqbalance with CPUs and IRQ for McKernel banned if [ "${irqbalance_used}" == "yes" ]; then diff --git a/kernel/debug.c b/kernel/debug.c index 1061b6fc..7df6d2e3 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -37,6 +37,8 @@ static void kprintf_wait(int len, unsigned long *flags_head, int *slide) { if (head < tail) head += buf_len; if (tail + len > buf_len) adj = buf_len - tail; if (head > tail && head <= tail + len + adj) { + /* When proceeding tail (producer pointer) by len would + cross head (consumer pointer) in ring-buffer */ if (mode != 1) { *slide = 1; break; @@ -70,6 +72,9 @@ void kputs(char *buf) memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len); kmsg_buf.tail += len; + /* When proceeding tail (producer pointer) by len would + cross head (consumer pointer) in ring-buffer, give up + [head, tail] because the range is overwritten */ if (slide == 1) { kmsg_buf.head = kmsg_buf.tail + 1; if (kmsg_buf.head >= kmsg_buf.len) kmsg_buf.head = 0; @@ -170,6 +175,17 @@ int kprintf(const char *format, ...) return len; } +/* mode: + 0: mcklogd is not running. + When kmsg buffer is full, writer doesn't block + and overwrites the buffer. + 1: mcklogd periodically retrieves kmsg. + When kmsg buffer is full, writer blocks until + someone retrieves kmsg. + 2: mcklogd periodically retrieves kmsg. + When kmsg buffer is full, writer doesn't block + and overwrites the buffer. +*/ void kmsg_init(int mode) { ihk_mc_spinlock_init(&kmsg_lock);