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

Reply via email to