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);
}
/*