Change simple lock handling to not depend upon having a local apic

available.  The per-cpu variable ss_tpr has been replaced by ss_eflags.
This reduced the number of interrupts sent to the wrong CPU, due to
the cpu having the global lock being inside a critical region.

Remove some unneeded manipulation of tpr register in mplock.s.

Adjust code in mplock.s to be aware of variables on the stack being
destroyed by MPgetlock if GRAB_LOPRIO is defined.
This commit is contained in:
Tor Egge
1998-05-17 23:08:04 +00:00
parent 333c76c66d
commit 5d183e9691
8 changed files with 55 additions and 51 deletions
+2 -2
View File
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $Id: genassym.c,v 1.55 1998/05/17 18:53:11 tegge Exp $
* $Id: genassym.c,v 1.56 1998/05/17 22:12:07 tegge Exp $
*/
#include "opt_vm86.h"
@@ -218,7 +218,7 @@ main()
printf("#define\tGD_CPU_LOCKID %d\n", &globaldata->cpu_lockid);
printf("#define\tGD_OTHER_CPUS %d\n", &globaldata->other_cpus);
printf("#define\tGD_MY_IDLEPTD %d\n", &globaldata->my_idlePTD);
printf("#define\tGD_SS_TPR %d\n", &globaldata->ss_tpr);
printf("#define\tGD_SS_EFLAGS %d\n", &globaldata->ss_eflags);
printf("#define\tGD_PRV_CMAP1 %d\n", &globaldata->prv_CMAP1);
printf("#define\tGD_PRV_CMAP2 %d\n", &globaldata->prv_CMAP2);
printf("#define\tGD_PRV_CMAP3 %d\n", &globaldata->prv_CMAP3);
+2 -2
View File
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: globaldata.h,v 1.2 1998/04/06 18:59:15 peter Exp $
* $Id: globaldata.h,v 1.3 1998/05/17 18:53:07 tegge Exp $
*/
/*
@@ -53,7 +53,7 @@ struct globaldata {
u_int cpu_lockid;
u_int other_cpus;
pd_entry_t *my_idlePTD;
u_int ss_tpr;
u_int ss_eflags;
pt_entry_t *prv_CMAP1;
pt_entry_t *prv_CMAP2;
pt_entry_t *prv_CMAP3;
+2 -2
View File
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $Id: genassym.c,v 1.55 1998/05/17 18:53:11 tegge Exp $
* $Id: genassym.c,v 1.56 1998/05/17 22:12:07 tegge Exp $
*/
#include "opt_vm86.h"
@@ -218,7 +218,7 @@ main()
printf("#define\tGD_CPU_LOCKID %d\n", &globaldata->cpu_lockid);
printf("#define\tGD_OTHER_CPUS %d\n", &globaldata->other_cpus);
printf("#define\tGD_MY_IDLEPTD %d\n", &globaldata->my_idlePTD);
printf("#define\tGD_SS_TPR %d\n", &globaldata->ss_tpr);
printf("#define\tGD_SS_EFLAGS %d\n", &globaldata->ss_eflags);
printf("#define\tGD_PRV_CMAP1 %d\n", &globaldata->prv_CMAP1);
printf("#define\tGD_PRV_CMAP2 %d\n", &globaldata->prv_CMAP2);
printf("#define\tGD_PRV_CMAP3 %d\n", &globaldata->prv_CMAP3);
+3 -3
View File
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: globals.s,v 1.2 1998/04/06 18:59:14 peter Exp $
* $Id: globals.s,v 1.3 1998/05/17 18:53:19 tegge Exp $
*/
#include "opt_vm86.h"
@@ -86,7 +86,7 @@ globaldata:
* The BSP version of these get setup in locore.s and pmap.c, while
* the AP versions are setup in mp_machdep.c.
*/
.globl _cpuid,_cpu_lockid,_other_cpus,_my_idlePTD,_ss_tpr
.globl _cpuid,_cpu_lockid,_other_cpus,_my_idlePTD,_ss_eflags
.globl _prv_CMAP1,_prv_CMAP2,_prv_CMAP3,_prv_PMAP1
.globl _inside_intr
@@ -94,7 +94,7 @@ globaldata:
.set _cpu_lockid,globaldata + GD_CPU_LOCKID
.set _other_cpus,globaldata + GD_OTHER_CPUS
.set _my_idlePTD,globaldata + GD_MY_IDLEPTD
.set _ss_tpr,globaldata + GD_SS_TPR
.set _ss_eflags,globaldata + GD_SS_EFLAGS
.set _prv_CMAP1,globaldata + GD_PRV_CMAP1
.set _prv_CMAP2,globaldata + GD_PRV_CMAP2
.set _prv_CMAP3,globaldata + GD_PRV_CMAP3
+22 -8
View File
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id: mplock.s,v 1.22 1997/08/29 18:16:17 fsmp Exp $
* $Id: mplock.s,v 1.23 1997/08/30 08:08:10 fsmp Exp $
*
* Functions for locking between CPUs in a SMP system.
*
@@ -77,7 +77,7 @@
/***********************************************************************
* void MPgetlock(unsigned int *lock)
* ----------------------------------
* Destroys %eax, %ecx and %edx.
* Destroys %eax, %ecx, %edx and 12(%esp).
*/
NON_GPROF_ENTRY(MPgetlock)
@@ -213,7 +213,6 @@ NON_GPROF_ENTRY(get_mplock)
pushfl /* save current EFLAGS */
testl $(1<<9), (%esp) /* test EI bit */
jnz 1f /* INTs currently enabled */
movl $TPR_IGNORE_HWI, lapic_tpr /* CHEAP_TPR */
sti /* allow IPI and FAST INTs */
1:
pushl $_mp_lock
@@ -238,10 +237,20 @@ NON_GPROF_ENTRY(boot_get_mplock)
pushl %ecx
pushl %edx
#ifdef GRAB_LOPRIO
pushl $0
pushfl
#endif
pushl $_mp_lock
call _MPgetlock
add $4, %esp
#ifdef GRAB_LOPRIO
popfl
addl $4, %esp
#endif
popl %edx
popl %ecx
popl %eax
@@ -298,7 +307,6 @@ NON_GPROF_ENTRY(get_isrlock)
/* block all HW INTs via Task Priority Register */
pushl lapic_tpr /* save current TPR */
pushfl /* save current EFLAGS */
movl $TPR_IGNORE_HWI, lapic_tpr /* CHEAP_TPR */
sti /* allow IPI and FAST INTs */
pushl $_mp_lock
@@ -344,7 +352,6 @@ NON_GPROF_ENTRY(rel_isrlock)
NON_GPROF_ENTRY(get_fpu_lock)
pushl lapic_tpr
pushfl
movl $TPR_IGNORE_HWI, lapic_tpr /* CHEAP_TPR */
sti
pushl $_mp_lock
call _MPgetlock
@@ -375,7 +382,6 @@ NON_GPROF_ENTRY(rel_fpu_lock)
NON_GPROF_ENTRY(get_align_lock)
pushl lapic_tpr
pushfl
movl $TPR_IGNORE_HWI, lapic_tpr /* CHEAP_TPR */
sti
pushl $_mp_lock
call _MPgetlock
@@ -406,7 +412,6 @@ NON_GPROF_ENTRY(rel_align_lock)
NON_GPROF_ENTRY(get_syscall_lock)
pushl lapic_tpr
pushfl
movl $TPR_IGNORE_HWI, lapic_tpr /* CHEAP_TPR */
sti
pushl $_mp_lock
call _MPgetlock
@@ -437,7 +442,6 @@ NON_GPROF_ENTRY(rel_syscall_lock)
NON_GPROF_ENTRY(get_altsyscall_lock)
pushl lapic_tpr
pushfl
movl $TPR_IGNORE_HWI, lapic_tpr /* CHEAP_TPR */
sti
pushl $_mp_lock
call _MPgetlock
@@ -473,10 +477,20 @@ NON_GPROF_ENTRY(get_mpintrlock)
pushl %ecx
pushl %edx
#ifdef GRAB_LOPRIO
pushl lapic_tpr
pushfl
#endif
pushl $_mpintr_lock
call _MPgetlock
add $4, %esp
#ifdef GRAB_LOPRIO
popfl
popl lapic_tpr
#endif
popl %edx
popl %ecx
popl %eax
+20 -30
View File
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: simplelock.s,v 1.7 1997/12/15 02:18:22 tegge Exp $
* $Id: simplelock.s,v 1.8 1998/01/19 17:33:08 tegge Exp $
*/
/*
@@ -31,6 +31,7 @@
#include <machine/asmacros.h> /* miscellaneous macros */
#include <i386/isa/intr_machdep.h>
#include <machine/psl.h>
#include <machine/smptests.h> /** FAST_HI */
@@ -102,9 +103,6 @@ gotit:
#else /* SL_DEBUG */
ENTRY(s_lock)
cmpl $0, _smp_active
je gotit
movl 4(%esp), %edx /* get the address of the lock */
setlock:
movl _cpu_lockid, %ecx /* add cpu id portion */
@@ -190,16 +188,17 @@ ENTRY(test_and_set)
/*
* These versions of simple_lock block hardware INTS,
* These versions of simple_lock block interrupts,
* making it suitable for regions accessed by both top and bottom levels.
* This is done by saving the current value of the TPR in a per-cpu global,
* then taking the lock. On the way out the lock is released, then the
* original value of the TPR is restored.
* This is done by saving the current value of the cpu flags in a per-cpu
* global, and disabling interrupts when the lock is taken. When the
* lock is released, interrupts might be enabled, depending upon the saved
* cpu flags.
* Because of this, it must ONLY be used for SHORT, deterministic paths!
*
* Note:
* It would appear to be "bad behaviour" to blindly store a value in
* ss_tpr, as this could destroy the previous contents. But since ss_tpr
* ss_eflags, as this could destroy the previous contents. But since ss_eflags
* is a per-cpu variable, and its fatal to attempt to acquire a simplelock
* that you already hold, we get away with it. This needs to be cleaned
* up someday...
@@ -214,40 +213,29 @@ ENTRY(ss_lock)
movl 4(%esp), %eax /* get the address of the lock */
movl $1, %ecx /* value for a held lock */
ssetlock:
pushl lapic_tpr /* save current task priority */
#ifdef FAST_HI
movl $TPR_BLOCK_FHWI, lapic_tpr /* block FAST hw INTs */
#else
movl $TPR_BLOCK_HWI, lapic_tpr /* block hw INTs */
#endif
pushfl
cli
xchgl %ecx, (%eax) /* compete */
testl %ecx, %ecx
jz sgotit /* it was clear, return */
popl lapic_tpr /* previous value while waiting */
popfl /* previous value while waiting */
swait:
cmpl $0, (%eax) /* wait to empty */
jne swait /* still set... */
jmp ssetlock /* empty again, try once more */
sgotit:
popl _ss_tpr /* save the old task priority */
popl _ss_eflags /* save the old eflags */
ret
#else /* SL_DEBUG */
ENTRY(ss_lock)
cmpl $0, _smp_active
je sgotit2
movl 4(%esp), %edx /* get the address of the lock */
ssetlock:
movl _cpu_lockid, %ecx /* add cpu id portion */
incl %ecx /* add lock portion */
pushl lapic_tpr /* save current task priority */
#ifdef FAST_HI
movl $TPR_BLOCK_FHWI, lapic_tpr /* block FAST hw INTs */
#else
movl $TPR_BLOCK_HWI, lapic_tpr /* block hw INTs */
#endif
pushfl
cli
movl $0, %eax
lock
cmpxchgl %ecx, (%edx) /* compete */
@@ -257,13 +245,13 @@ ssetlock:
cmpl _cpu_lockid, %eax /* do we hold it? */
je sbad_slock /* yes, thats not good... */
addl $4, %esp /* clear the stack */
popl lapic_tpr /* previous value while waiting */
popfl
swait:
cmpl $0, (%edx) /* wait to empty */
jne swait /* still set... */
jmp ssetlock /* empty again, try once more */
sgotit:
popl _ss_tpr /* save the old task priority */
popl _ss_eflags /* save the old task priority */
sgotit2:
ret
@@ -285,8 +273,10 @@ sbsl1: .asciz "rsslock: cpu: %d, addr: 0x%08x, lock: 0x%08x"
ENTRY(ss_unlock)
movl 4(%esp), %eax /* get the address of the lock */
movl $0, (%eax) /* clear the simple lock */
movl _ss_tpr, %eax
movl %eax, lapic_tpr /* restore the old task priority */
testl $PSL_I, _ss_eflags
jz ss_unlock2
sti
ss_unlock2:
ret
/*
+2 -2
View File
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: globaldata.h,v 1.2 1998/04/06 18:59:15 peter Exp $
* $Id: globaldata.h,v 1.3 1998/05/17 18:53:07 tegge Exp $
*/
/*
@@ -53,7 +53,7 @@ struct globaldata {
u_int cpu_lockid;
u_int other_cpus;
pd_entry_t *my_idlePTD;
u_int ss_tpr;
u_int ss_eflags;
pt_entry_t *prv_CMAP1;
pt_entry_t *prv_CMAP2;
pt_entry_t *prv_CMAP3;
+2 -2
View File
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: globaldata.h,v 1.2 1998/04/06 18:59:15 peter Exp $
* $Id: globaldata.h,v 1.3 1998/05/17 18:53:07 tegge Exp $
*/
/*
@@ -53,7 +53,7 @@ struct globaldata {
u_int cpu_lockid;
u_int other_cpus;
pd_entry_t *my_idlePTD;
u_int ss_tpr;
u_int ss_eflags;
pt_entry_t *prv_CMAP1;
pt_entry_t *prv_CMAP2;
pt_entry_t *prv_CMAP3;