Repeat the spinlock_enter/exit pattern from amd64 on other architectures to

fix an assert violation introduced in r355784.  Without this spinlock_exit()
may see owepreempt and switch before reducing the spinlock count.  amd64
had been optimized to do a single critical enter/exit regardless of the
number of spinlocks which avoided the problem and this optimization had
not been applied elsewhere.

Reported by:	emaste
Suggested by:	rlibby
Discussed with:	jhb, rlibby
Tested by:	manu (arm64)
This commit is contained in:
Jeff Roberson 2019-12-16 20:15:04 +00:00
parent b5f20658ee
commit a94ba188c3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=355819
6 changed files with 22 additions and 17 deletions

View File

@ -389,9 +389,9 @@ spinlock_enter(void)
cspr = disable_interrupts(PSR_I | PSR_F);
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_cspr = cspr;
critical_enter();
} else
td->td_md.md_spinlock_count++;
critical_enter();
}
void
@ -401,11 +401,12 @@ spinlock_exit(void)
register_t cspr;
td = curthread;
critical_exit();
cspr = td->td_md.md_saved_cspr;
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0)
if (td->td_md.md_spinlock_count == 0) {
critical_exit();
restore_interrupts(cspr);
}
}
/*

View File

@ -635,9 +635,9 @@ spinlock_enter(void)
daif = intr_disable();
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_daif = daif;
critical_enter();
} else
td->td_md.md_spinlock_count++;
critical_enter();
}
void
@ -647,11 +647,12 @@ spinlock_exit(void)
register_t daif;
td = curthread;
critical_exit();
daif = td->td_md.md_saved_daif;
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0)
if (td->td_md.md_spinlock_count == 0) {
critical_exit();
intr_restore(daif);
}
}
#ifndef _SYS_SYSPROTO_H_

View File

@ -2679,9 +2679,9 @@ spinlock_enter(void)
flags = intr_disable();
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_flags = flags;
critical_enter();
} else
td->td_md.md_spinlock_count++;
critical_enter();
}
void
@ -2691,11 +2691,12 @@ spinlock_exit(void)
register_t flags;
td = curthread;
critical_exit();
flags = td->td_md.md_saved_flags;
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0)
if (td->td_md.md_spinlock_count == 0) {
critical_exit();
intr_restore(flags);
}
}
#if defined(I586_CPU) && !defined(NO_F00F_HACK)

View File

@ -516,9 +516,9 @@ spinlock_enter(void)
intr = intr_disable();
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_intr = intr;
critical_enter();
} else
td->td_md.md_spinlock_count++;
critical_enter();
}
void
@ -528,11 +528,12 @@ spinlock_exit(void)
register_t intr;
td = curthread;
critical_exit();
intr = td->td_md.md_saved_intr;
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0)
if (td->td_md.md_spinlock_count == 0) {
critical_exit();
intr_restore(intr);
}
}
/*

View File

@ -499,9 +499,9 @@ spinlock_enter(void)
msr = intr_disable();
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_msr = msr;
critical_enter();
} else
td->td_md.md_spinlock_count++;
critical_enter();
}
void
@ -511,10 +511,10 @@ spinlock_exit(void)
register_t msr;
td = curthread;
critical_exit();
msr = td->td_md.md_saved_msr;
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0) {
critical_exit();
intr_restore(msr);
nop_prio_medium();
}

View File

@ -489,9 +489,9 @@ spinlock_enter(void)
reg = intr_disable();
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_sstatus_ie = reg;
critical_enter();
} else
td->td_md.md_spinlock_count++;
critical_enter();
}
void
@ -501,11 +501,12 @@ spinlock_exit(void)
register_t sstatus_ie;
td = curthread;
critical_exit();
sstatus_ie = td->td_md.md_saved_sstatus_ie;
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0)
if (td->td_md.md_spinlock_count == 0) {
critical_exit();
intr_restore(sstatus_ie);
}
}
#ifndef _SYS_SYSPROTO_H_