Start mcklogd before McKernel to avoid deadlock
McKernel blocks forever waiting for mcklogd to retrieve kmsg when kmsg bufer is full with boot log and mcklogd isn't running.
This commit is contained 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;
|
if ! systemctl stop irqbalance.service 2>/dev/null ; then echo "error: stopping irqbalance" >&2; exit 1; fi;
|
||||||
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
|
# Load IHK if not loaded
|
||||||
if [ "`lsmod | grep ihk`" == "" ]; then
|
if [ "`lsmod | grep ihk`" == "" ]; then
|
||||||
if ! insmod ${KMODDIR}/ihk.ko; then echo "error: loading ihk" >&2; exit 1; fi;
|
if ! insmod ${KMODDIR}/ihk.ko; then echo "error: loading ihk" >&2; exit 1; fi;
|
||||||
@ -249,12 +259,6 @@ if [ "$enable_mcoverlay" == "yes" ]; then
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
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
|
# Start irqbalance with CPUs and IRQ for McKernel banned
|
||||||
if [ "${irqbalance_used}" == "yes" ]; then
|
if [ "${irqbalance_used}" == "yes" ]; then
|
||||||
|
|||||||
@ -37,6 +37,8 @@ static void kprintf_wait(int len, unsigned long *flags_head, int *slide) {
|
|||||||
if (head < tail) head += buf_len;
|
if (head < tail) head += buf_len;
|
||||||
if (tail + len > buf_len) adj = buf_len - tail;
|
if (tail + len > buf_len) adj = buf_len - tail;
|
||||||
if (head > tail && head <= tail + len + adj) {
|
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) {
|
if (mode != 1) {
|
||||||
*slide = 1;
|
*slide = 1;
|
||||||
break;
|
break;
|
||||||
@ -70,6 +72,9 @@ void kputs(char *buf)
|
|||||||
|
|
||||||
memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len);
|
memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len);
|
||||||
kmsg_buf.tail += 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) {
|
if (slide == 1) {
|
||||||
kmsg_buf.head = kmsg_buf.tail + 1;
|
kmsg_buf.head = kmsg_buf.tail + 1;
|
||||||
if (kmsg_buf.head >= kmsg_buf.len) kmsg_buf.head = 0;
|
if (kmsg_buf.head >= kmsg_buf.len) kmsg_buf.head = 0;
|
||||||
@ -170,6 +175,17 @@ int kprintf(const char *format, ...)
|
|||||||
return len;
|
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)
|
void kmsg_init(int mode)
|
||||||
{
|
{
|
||||||
ihk_mc_spinlock_init(&kmsg_lock);
|
ihk_mc_spinlock_init(&kmsg_lock);
|
||||||
|
|||||||
Reference in New Issue
Block a user