Currently the LO_NOPROFILE flag (which is masked on upper level code by

per-primitive macros like MTX_NOPROFILE, SX_NOPROFILE or RW_NOPROFILE) is
not really honoured. In particular lock_profile_obtain_lock_failure() and
lock_profile_obtain_lock_success() are naked respect this flag.
The bug leads to locks marked with no-profiling to be profiled as well.
In the case of the clock_lock, used by the timer i8254 this leads to
unpredictable behaviour both on amd64 and ia32 (double faults panic,
sudden reboots, etc.). The amd64 clock_lock is also not marked as
not profilable as it should be.
Fix these bugs adding proper checks in the lock profiling code and at
clock_lock initialization time.

i8254 bug pointed out by: kris
Tested by: matteo, Giuseppe Cocomazzi <sbudella at libero dot it>
Approved by: jeff (mentor)
Approved by: re
This commit is contained in:
Attilio Rao 2007-09-14 01:12:39 +00:00
parent f15444982b
commit 4486adc51f
3 changed files with 7 additions and 5 deletions

View File

@ -565,7 +565,7 @@ void
i8254_init(void)
{
mtx_init(&clock_lock, "clk", NULL, MTX_SPIN);
mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
set_timer_freq(timer_freq, hz);
}

View File

@ -274,7 +274,7 @@ void _lock_profile_release_lock(struct lock_object *lo)
{
struct lock_profile_object *l = &lo->lo_profile_obj;
if (l->lpo_acqtime && !(lo->lo_flags & LO_NOPROFILE)) {
if (l->lpo_acqtime) {
const char *unknown = "(unknown)";
u_int64_t acqtime, now, waittime;
struct lock_prof *mpp;

View File

@ -119,7 +119,8 @@ static inline void lock_profile_obtain_lock_failed(struct lock_object *lo, int *
{
struct lock_profile_object *l = &lo->lo_profile_obj;
if (lock_prof_enable && *contested == 0) {
if (!(lo->lo_flags & LO_NOPROFILE) && lock_prof_enable &&
*contested == 0) {
*waittime = nanoseconds();
atomic_add_int(&l->lpo_contest_holding, 1);
*contested = 1;
@ -130,7 +131,8 @@ static inline void lock_profile_obtain_lock_success(struct lock_object *lo, int
{
/* don't reset the timer when/if recursing */
if (lock_prof_enable && lo->lo_profile_obj.lpo_acqtime == 0) {
if (!(lo->lo_flags & LO_NOPROFILE) && lock_prof_enable &&
lo->lo_profile_obj.lpo_acqtime == 0) {
#ifdef LOCK_PROFILING_FAST
if (contested == 0)
return;
@ -142,7 +144,7 @@ static inline void lock_profile_release_lock(struct lock_object *lo)
{
struct lock_profile_object *l = &lo->lo_profile_obj;
if (l->lpo_acqtime)
if (!(lo->lo_flags & LO_NOPROFILE) && l->lpo_acqtime)
_lock_profile_release_lock(lo);
}