diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-05-16 13:52:48 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-05-16 13:52:48 +0000 |
commit | 2dec407cd5245c6407ac374404a8f58d9751e246 (patch) | |
tree | a7f75ea1a05001ffecbabbfdc9f923042caf3ddd | |
parent | 1b68ae694a3627fa8c926fea31651ed2fafbd75e (diff) |
Remove incorrect optimization. The current logic for skipping idle CPUs
does not establish strong enough ordering between CPUs. Consequently,
smr_grace_wait() might incorrectly skip a CPU and invoke an SMR
callback too early.
Prompted by haesbaert@
-rw-r--r-- | sys/kern/kern_smr.c | 24 | ||||
-rw-r--r-- | sys/sys/sched.h | 5 |
2 files changed, 4 insertions, 25 deletions
diff --git a/sys/kern/kern_smr.c b/sys/kern/kern_smr.c index eadf828cfd6..50e378c1d2d 100644 --- a/sys/kern/kern_smr.c +++ b/sys/kern/kern_smr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_smr.c,v 1.2 2019/05/14 03:27:43 visa Exp $ */ +/* $OpenBSD: kern_smr.c,v 1.3 2019/05/16 13:52:47 visa Exp $ */ /* * Copyright (c) 2019 Visa Hankala @@ -29,9 +29,6 @@ #include <machine/cpu.h> -#define SMR_ACTIVE 0x01 -#define SMR_ENTERED 0x02 - #define SMR_PAUSE 100 /* pause between rounds in msec */ void smr_create_thread(void *); @@ -149,8 +146,6 @@ smr_grace_wait(void) CPU_INFO_FOREACH(cii, ci) { if (ci == ci_start) continue; - if (smr_cpu_is_idle(ci) && ci->ci_schedstate.spc_insmr == 0) - continue; sched_peg_curproc(ci); } atomic_clearbits_int(&curproc->p_flag, P_CPUPEG); @@ -166,22 +161,11 @@ smr_wakeup(void *arg) void smr_read_enter(void) { - struct cpu_info *ci = curcpu(); - struct schedstate_percpu *spc = &ci->ci_schedstate; - #ifdef DIAGNOSTIC + struct schedstate_percpu *spc = &curcpu()->ci_schedstate; + spc->spc_smrdepth++; #endif - - if (smr_cpu_is_idle(ci) && (spc->spc_insmr & SMR_ENTERED) == 0) { - /* - * Activate in two steps in order not to miss the memory - * barrier with nested interrupts. - */ - spc->spc_insmr = SMR_ACTIVE; - membar_enter(); - spc->spc_insmr = SMR_ACTIVE | SMR_ENTERED; - } } void @@ -230,8 +214,6 @@ smr_idle(void) SMR_ASSERT_NONCRITICAL(); - spc->spc_insmr = 0; - if (spc->spc_ndeferred > 0) smr_dispatch(spc); } diff --git a/sys/sys/sched.h b/sys/sys/sched.h index 30b93b4bd3c..d1ef56b7a9e 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.51 2019/02/26 14:24:21 visa Exp $ */ +/* $OpenBSD: sched.h,v 1.52 2019/05/16 13:52:47 visa Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -119,9 +119,6 @@ struct schedstate_percpu { u_int spc_smrdepth; /* level of smr nesting */ u_char spc_smrexpedite; /* if set, dispatch smr entries * without delay */ - volatile u_char spc_insmr; /* if set, CPU entered smr critical - * section from interrupt context - * that preempted idle state */ }; struct cpustats { |