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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user