summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2020-02-25 16:55:34 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2020-02-25 16:55:34 +0000
commit810425e7f3da2acdc26e14b9ea708db37466b3f6 (patch)
tree62038fed4e0f9c7e9e86690eeb2b814f3b5468f5
parent10401e27f0a138679431d2c5eeb71daf12f4983a (diff)
Start the SMR thread when all CPUs are ready for scheduling. This
prevents the appearance of a "smr: dispatch took N seconds" message during boot when there is an early smr_call(). Such a call can happen with mfii(4). The initial dispatch cannot make progress until smr_grace_wait() can visit all CPUs. This fix is essentially a hack. It makes use of the fact that there is no hard guarantee on how quickly the callback of smr_call() gets invoked. It is assumed that the SMR call backlog does not grow large during boot. An alternative fix is to make smr_grace_wait() skip secondary CPUs until they have been started. However, this could break if the spinup logic of secondary CPUs was changed. Delayed SMR dispatch reported and fix tested by Hrvoje Popovski Discussed with and OK kettenis@, claudio@
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/kern_smr.c8
-rw-r--r--sys/sys/smr.h3
3 files changed, 9 insertions, 7 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 93e88828d2f..2be1d41b8ab 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.295 2020/01/01 07:06:35 jsg Exp $ */
+/* $OpenBSD: init_main.c,v 1.296 2020/02/25 16:55:33 visa Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -551,6 +551,9 @@ main(void *framep)
cpu_boot_secondary_processors();
#endif
+ /* Now that all CPUs partake in scheduling, start SMR thread. */
+ smr_startup_thread();
+
config_process_deferred_mountroot();
/*
diff --git a/sys/kern/kern_smr.c b/sys/kern/kern_smr.c
index 51165b0c3c8..a5605ed0f64 100644
--- a/sys/kern/kern_smr.c
+++ b/sys/kern/kern_smr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_smr.c,v 1.6 2019/12/30 23:56:26 jsg Exp $ */
+/* $OpenBSD: kern_smr.c,v 1.7 2020/02/25 16:55:33 visa Exp $ */
/*
* Copyright (c) 2019 Visa Hankala
@@ -31,7 +31,6 @@
#define SMR_PAUSE 100 /* pause between rounds in msec */
-void smr_create_thread(void *);
void smr_dispatch(struct schedstate_percpu *);
void smr_grace_wait(void);
void smr_thread(void *);
@@ -66,13 +65,12 @@ smr_startup(void)
{
SIMPLEQ_INIT(&smr_deferred);
WITNESS_INIT(&smr_lock_obj, &smr_lock_type);
- kthread_create_deferred(smr_create_thread, NULL);
+ timeout_set(&smr_wakeup_tmo, smr_wakeup, NULL);
}
void
-smr_create_thread(void *arg)
+smr_startup_thread(void)
{
- timeout_set(&smr_wakeup_tmo, smr_wakeup, NULL);
if (kthread_create(smr_thread, NULL, NULL, "smr") != 0)
panic("could not create smr thread");
}
diff --git a/sys/sys/smr.h b/sys/sys/smr.h
index bb220358277..b1ee5e968b1 100644
--- a/sys/sys/smr.h
+++ b/sys/sys/smr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smr.h,v 1.2 2019/03/09 06:15:48 visa Exp $ */
+/* $OpenBSD: smr.h,v 1.3 2020/02/25 16:55:33 visa Exp $ */
/*
* Copyright (c) 2019 Visa Hankala
@@ -34,6 +34,7 @@ SIMPLEQ_HEAD(smr_entry_list, smr_entry);
#include <sys/atomic.h>
void smr_startup(void);
+void smr_startup_thread(void);
void smr_idle(void);
void smr_read_enter(void);
void smr_read_leave(void);