On Thu, Jan 07, 2021 at 07:08:05AM +0000, Miod Vallat wrote:
> > The per-CPU struct is mapped using a 64K locked TLB entry. That TLB
> > entry is installed by sun4u_bootstrap_cpu(), which gets called *after*
> > initsmgbuf() is called. So this issue was introduced when locking was
> > added to msgbuf_putchar().
> >
> > Now the real question is why this doesn't crash even on a cold boot?
> > I suspect that is because on a cold boot the buffer is clean and the
> > msgbuf_putchar() call in initmsgbuf() is skipped.
> >
> > It may be possible to do some reordering in pmap_bootstrap(), but
> > frankly I think the locking added to msgbuf_putchar() was a mistake.
> > Or maybe the locking code should be bypassed when cold.
>
> Indeed. Wrappinge the mutex operations in msgbuf_putchar with if (!cold)
> makes the kernel boot again.
Here is a diff for that.
Index: kern/subr_log.c
===================================================================
RCS file: src/sys/kern/subr_log.c,v
retrieving revision 1.70
diff -u -p -r1.70 subr_log.c
--- kern/subr_log.c 25 Dec 2020 12:59:52 -0000 1.70
+++ kern/subr_log.c 7 Jan 2021 09:25:16 -0000
@@ -157,11 +157,17 @@ initconsbuf(void)
void
msgbuf_putchar(struct msgbuf *mbp, const char c)
{
+ int dolock;
+
if (mbp->msg_magic != MSG_MAGIC)
/* Nothing we can do */
return;
- mtx_enter(&log_mtx);
+ /* Mutex cannot be used during early boot on some architectures. */
+ dolock = (cold == 0);
+
+ if (dolock)
+ mtx_enter(&log_mtx);
mbp->msg_bufc[mbp->msg_bufx++] = c;
if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs)
mbp->msg_bufx = 0;
@@ -171,7 +177,8 @@ msgbuf_putchar(struct msgbuf *mbp, const
mbp->msg_bufr = 0;
mbp->msg_bufd++;
}
- mtx_leave(&log_mtx);
+ if (dolock)
+ mtx_leave(&log_mtx);
}
size_t