Module Name: src Committed By: ad Date: Sun Dec 1 14:20:00 UTC 2019
Modified Files: src/sys/kern: subr_xcall.c Log Message: If the system is not up and running yet, just run the function locally. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/kern/subr_xcall.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_xcall.c diff -u src/sys/kern/subr_xcall.c:1.28 src/sys/kern/subr_xcall.c:1.29 --- src/sys/kern/subr_xcall.c:1.28 Mon Nov 11 09:50:11 2019 +++ src/sys/kern/subr_xcall.c Sun Dec 1 14:20:00 2019 @@ -1,7 +1,7 @@ -/* $NetBSD: subr_xcall.c,v 1.28 2019/11/11 09:50:11 maxv Exp $ */ +/* $NetBSD: subr_xcall.c,v 1.29 2019/12/01 14:20:00 ad Exp $ */ /*- - * Copyright (c) 2007-2010 The NetBSD Foundation, Inc. + * Copyright (c) 2007-2010, 2019 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -74,7 +74,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.28 2019/11/11 09:50:11 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.29 2019/12/01 14:20:00 ad Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -84,6 +84,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_xcall.c #include <sys/evcnt.h> #include <sys/kthread.h> #include <sys/cpu.h> +#include <sys/atomic.h> #ifdef _RUMPKERNEL #include "rump_private.h" @@ -259,6 +260,11 @@ xc_broadcast(unsigned int flags, xcfunc_ KASSERT(!cpu_intr_p() && !cpu_softintr_p()); ASSERT_SLEEPABLE(); + if (__predict_false(!mp_online)) { + (*func)(arg1, arg2); + return 0; + } + if ((flags & XC_HIGHPRI) != 0) { int ipl = xc_extract_ipl(flags); return xc_highpri(func, arg1, arg2, NULL, ipl); @@ -300,11 +306,20 @@ uint64_t xc_unicast(unsigned int flags, xcfunc_t func, void *arg1, void *arg2, struct cpu_info *ci) { + int s; KASSERT(ci != NULL); KASSERT(!cpu_intr_p() && !cpu_softintr_p()); ASSERT_SLEEPABLE(); + if (__predict_false(!mp_online)) { + KASSERT(ci == curcpu()); + s = splsoftserial(); + (*func)(arg1, arg2); + splx(s); + return 0; + } + if ((flags & XC_HIGHPRI) != 0) { int ipl = xc_extract_ipl(flags); return xc_highpri(func, arg1, arg2, ci, ipl); @@ -326,6 +341,10 @@ xc_wait(uint64_t where) KASSERT(!cpu_intr_p() && !cpu_softintr_p()); ASSERT_SLEEPABLE(); + if (__predict_false(!mp_online)) { + return; + } + /* Determine whether it is high or low priority cross-call. */ if ((where & XC_PRI_BIT) != 0) { xc = &xc_high_pri; @@ -335,11 +354,15 @@ xc_wait(uint64_t where) } /* Block until awoken. */ - mutex_enter(&xc->xc_lock); - while (xc->xc_donep < where) { - cv_wait(&xc->xc_busy, &xc->xc_lock); + if (xc->xc_donep < where) { + mutex_enter(&xc->xc_lock); + while (xc->xc_donep < where) { + cv_wait(&xc->xc_busy, &xc->xc_lock); + } + mutex_exit(&xc->xc_lock); + } else { + membar_enter(); } - mutex_exit(&xc->xc_lock); } /*