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:
parent
f15444982b
commit
4486adc51f
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user