Consistently use a reader/writer flag for lockstat probes in rwlock(9) and
sx(9), rather than using the probe function name to determine whether a given lock is a read lock or a write lock. Update lockstat(1) accordingly.
This commit is contained in:
parent
32cd0147fa
commit
de2c95cc00
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285704
@ -196,17 +196,17 @@ static ls_event_info_t g_event_info[LS_MAX_EVENTS] = {
|
|||||||
"lockstat:::spin-release", NULL,
|
"lockstat:::spin-release", NULL,
|
||||||
"lockstat:::spin-acquire" },
|
"lockstat:::spin-acquire" },
|
||||||
{ 'H', "Lock", "R/W writer hold", "nsec",
|
{ 'H', "Lock", "R/W writer hold", "nsec",
|
||||||
"lockstat::rw_wunlock:rw-release", NULL,
|
"lockstat:::rw-release", "arg1 == 0",
|
||||||
"lockstat::rw_wlock:rw-acquire" },
|
"lockstat:::rw-acquire" },
|
||||||
{ 'H', "Lock", "R/W reader hold", "nsec",
|
{ 'H', "Lock", "R/W reader hold", "nsec",
|
||||||
"lockstat::rw_runlock:rw-release", NULL,
|
"lockstat:::rw-release", "arg1 == 1",
|
||||||
"lockstat::rw_rlock:rw-acquire" },
|
"lockstat:::rw-acquire" },
|
||||||
{ 'H', "Lock", "SX shared hold", "nsec",
|
{ 'H', "Lock", "SX shared hold", "nsec",
|
||||||
"lockstat::sx_sunlock:sx-release", NULL,
|
"lockstat:::sx-release", "arg1 == 0",
|
||||||
"lockstat::sx_slock:sx-acquire" },
|
"lockstat:::sx-acquire" },
|
||||||
{ 'H', "Lock", "SX exclusive hold", "nsec",
|
{ 'H', "Lock", "SX exclusive hold", "nsec",
|
||||||
"lockstat::sx_xunlock:sx-release", NULL,
|
"lockstat:::sx-release", "arg1 == 1",
|
||||||
"lockstat::sx_xlock:sx-acquire" },
|
"lockstat:::sx-acquire" },
|
||||||
{ 'H', "Lock", "Unknown event (type 38)", "units" },
|
{ 'H', "Lock", "Unknown event (type 38)", "units" },
|
||||||
{ 'H', "Lock", "Unknown event (type 39)", "units" },
|
{ 'H', "Lock", "Unknown event (type 39)", "units" },
|
||||||
{ 'H', "Lock", "Unknown event (type 40)", "units" },
|
{ 'H', "Lock", "Unknown event (type 40)", "units" },
|
||||||
|
@ -43,16 +43,16 @@ SDT_PROBE_DEFINE1(lockstat, , , spin__acquire, "struct mtx *");
|
|||||||
SDT_PROBE_DEFINE1(lockstat, , , spin__release, "struct mtx *");
|
SDT_PROBE_DEFINE1(lockstat, , , spin__release, "struct mtx *");
|
||||||
SDT_PROBE_DEFINE2(lockstat, , , spin__spin, "struct mtx *", "uint64_t");
|
SDT_PROBE_DEFINE2(lockstat, , , spin__spin, "struct mtx *", "uint64_t");
|
||||||
|
|
||||||
SDT_PROBE_DEFINE1(lockstat, , , rw__acquire, "struct rwlock *");
|
SDT_PROBE_DEFINE2(lockstat, , , rw__acquire, "struct rwlock *", "int");
|
||||||
SDT_PROBE_DEFINE1(lockstat, , , rw__release, "struct rwlock *");
|
SDT_PROBE_DEFINE2(lockstat, , , rw__release, "struct rwlock *", "int");
|
||||||
SDT_PROBE_DEFINE5(lockstat, , , rw__block, "struct rwlock *", "uint64_t", "int",
|
SDT_PROBE_DEFINE5(lockstat, , , rw__block, "struct rwlock *", "uint64_t", "int",
|
||||||
"int", "int");
|
"int", "int");
|
||||||
SDT_PROBE_DEFINE2(lockstat, , , rw__spin, "struct rwlock *", "uint64_t");
|
SDT_PROBE_DEFINE2(lockstat, , , rw__spin, "struct rwlock *", "uint64_t");
|
||||||
SDT_PROBE_DEFINE1(lockstat, , , rw__upgrade, "struct rwlock *");
|
SDT_PROBE_DEFINE1(lockstat, , , rw__upgrade, "struct rwlock *");
|
||||||
SDT_PROBE_DEFINE1(lockstat, , , rw__downgrade, "struct rwlock *");
|
SDT_PROBE_DEFINE1(lockstat, , , rw__downgrade, "struct rwlock *");
|
||||||
|
|
||||||
SDT_PROBE_DEFINE1(lockstat, , , sx__acquire, "struct sx *");
|
SDT_PROBE_DEFINE2(lockstat, , , sx__acquire, "struct sx *", "int");
|
||||||
SDT_PROBE_DEFINE1(lockstat, , , sx__release, "struct sx *");
|
SDT_PROBE_DEFINE2(lockstat, , , sx__release, "struct sx *", "int");
|
||||||
SDT_PROBE_DEFINE5(lockstat, , , sx__block, "struct sx *", "uint64_t", "int",
|
SDT_PROBE_DEFINE5(lockstat, , , sx__block, "struct sx *", "uint64_t", "int",
|
||||||
"int", "int");
|
"int", "int");
|
||||||
SDT_PROBE_DEFINE2(lockstat, , , sx__spin, "struct sx *", "uint64_t");
|
SDT_PROBE_DEFINE2(lockstat, , , sx__spin, "struct sx *", "uint64_t");
|
||||||
|
@ -301,8 +301,8 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
|
|||||||
WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
|
WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
|
||||||
file, line);
|
file, line);
|
||||||
if (!rw_recursed(rw))
|
if (!rw_recursed(rw))
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire,
|
||||||
rw, 0, 0, file, line);
|
rw, 0, 0, file, line, LOCKSTAT_WRITER);
|
||||||
curthread->td_locks++;
|
curthread->td_locks++;
|
||||||
}
|
}
|
||||||
return (rval);
|
return (rval);
|
||||||
@ -561,8 +561,8 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
|
|||||||
* however. turnstiles don't like owners changing between calls to
|
* however. turnstiles don't like owners changing between calls to
|
||||||
* turnstile_wait() currently.
|
* turnstile_wait() currently.
|
||||||
*/
|
*/
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire, rw, contested,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, contested,
|
||||||
waittime, file, line);
|
waittime, file, line, LOCKSTAT_READER);
|
||||||
LOCK_LOG_LOCK("RLOCK", &rw->lock_object, 0, 0, file, line);
|
LOCK_LOG_LOCK("RLOCK", &rw->lock_object, 0, 0, file, line);
|
||||||
WITNESS_LOCK(&rw->lock_object, 0, file, line);
|
WITNESS_LOCK(&rw->lock_object, 0, file, line);
|
||||||
curthread->td_locks++;
|
curthread->td_locks++;
|
||||||
@ -594,8 +594,8 @@ __rw_try_rlock(volatile uintptr_t *c, const char *file, int line)
|
|||||||
LOCK_LOG_TRY("RLOCK", &rw->lock_object, 0, 1, file,
|
LOCK_LOG_TRY("RLOCK", &rw->lock_object, 0, 1, file,
|
||||||
line);
|
line);
|
||||||
WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line);
|
WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line);
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire,
|
||||||
rw, 0, 0, file, line);
|
rw, 0, 0, file, line, LOCKSTAT_READER);
|
||||||
curthread->td_locks++;
|
curthread->td_locks++;
|
||||||
curthread->td_rw_rlocks++;
|
curthread->td_rw_rlocks++;
|
||||||
return (1);
|
return (1);
|
||||||
@ -713,7 +713,7 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
|
|||||||
turnstile_chain_unlock(&rw->lock_object);
|
turnstile_chain_unlock(&rw->lock_object);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOCKSTAT_PROFILE_RELEASE_LOCK(rw__release, rw);
|
LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw, LOCKSTAT_READER);
|
||||||
curthread->td_locks--;
|
curthread->td_locks--;
|
||||||
curthread->td_rw_rlocks--;
|
curthread->td_rw_rlocks--;
|
||||||
}
|
}
|
||||||
@ -920,8 +920,8 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
|
|||||||
LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
|
LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
|
||||||
(state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
|
(state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
|
||||||
#endif
|
#endif
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire, rw, contested,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, contested,
|
||||||
waittime, file, line);
|
waittime, file, line, LOCKSTAT_WRITER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -288,8 +288,8 @@ sx_try_slock_(struct sx *sx, const char *file, int line)
|
|||||||
if (atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER)) {
|
if (atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER)) {
|
||||||
LOCK_LOG_TRY("SLOCK", &sx->lock_object, 0, 1, file, line);
|
LOCK_LOG_TRY("SLOCK", &sx->lock_object, 0, 1, file, line);
|
||||||
WITNESS_LOCK(&sx->lock_object, LOP_TRYLOCK, file, line);
|
WITNESS_LOCK(&sx->lock_object, LOP_TRYLOCK, file, line);
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire,
|
||||||
sx, 0, 0, file, line);
|
sx, 0, 0, file, line, LOCKSTAT_READER);
|
||||||
curthread->td_locks++;
|
curthread->td_locks++;
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -351,8 +351,8 @@ sx_try_xlock_(struct sx *sx, const char *file, int line)
|
|||||||
WITNESS_LOCK(&sx->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
|
WITNESS_LOCK(&sx->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
|
||||||
file, line);
|
file, line);
|
||||||
if (!sx_recursed(sx))
|
if (!sx_recursed(sx))
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire,
|
||||||
sx, 0, 0, file, line);
|
sx, 0, 0, file, line, LOCKSTAT_WRITER);
|
||||||
curthread->td_locks++;
|
curthread->td_locks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,8 +728,8 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
|
|||||||
(state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
|
(state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
|
||||||
#endif
|
#endif
|
||||||
if (!error)
|
if (!error)
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
|
||||||
contested, waittime, file, line);
|
contested, waittime, file, line, LOCKSTAT_WRITER);
|
||||||
GIANT_RESTORE();
|
GIANT_RESTORE();
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -992,8 +992,8 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
|
|||||||
(state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
|
(state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
|
||||||
#endif
|
#endif
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx, contested,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
|
||||||
waittime, file, line);
|
contested, waittime, file, line, LOCKSTAT_READER);
|
||||||
GIANT_RESTORE();
|
GIANT_RESTORE();
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -90,15 +90,25 @@ SDT_PROBE_DECLARE(lockstat, , , thread__spin);
|
|||||||
LOCKSTAT_RECORD0(probe, lp); \
|
LOCKSTAT_RECORD0(probe, lp); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(probe, lp, c, wt, f, l, a) do { \
|
||||||
|
lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l); \
|
||||||
|
LOCKSTAT_RECORD1(probe, lp, a); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) do { \
|
#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) do { \
|
||||||
lock_profile_release_lock(&(lp)->lock_object); \
|
lock_profile_release_lock(&(lp)->lock_object); \
|
||||||
LOCKSTAT_RECORD0(probe, lp); \
|
LOCKSTAT_RECORD0(probe, lp); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LOCKSTAT_PROFILE_RELEASE_RWLOCK(probe, lp, a) do { \
|
||||||
|
lock_profile_release_lock(&(lp)->lock_object); \
|
||||||
|
LOCKSTAT_RECORD1(probe, lp, a); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
extern int lockstat_enabled;
|
extern int lockstat_enabled;
|
||||||
|
|
||||||
struct lock_object;
|
struct lock_object;
|
||||||
extern uint64_t lockstat_nsecs(struct lock_object *);
|
uint64_t lockstat_nsecs(struct lock_object *);
|
||||||
|
|
||||||
#else /* !KDTRACE_HOOKS */
|
#else /* !KDTRACE_HOOKS */
|
||||||
|
|
||||||
@ -111,9 +121,15 @@ extern uint64_t lockstat_nsecs(struct lock_object *);
|
|||||||
#define LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l) \
|
#define LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l) \
|
||||||
lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l)
|
lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l)
|
||||||
|
|
||||||
|
#define LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(probe, lp, c, wt, f, l, a) \
|
||||||
|
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l)
|
||||||
|
|
||||||
#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) \
|
#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) \
|
||||||
lock_profile_release_lock(&(lp)->lock_object)
|
lock_profile_release_lock(&(lp)->lock_object)
|
||||||
|
|
||||||
|
#define LOCKSTAT_PROFILE_RELEASE_RWLOCK(probe, lp, a) \
|
||||||
|
LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp)
|
||||||
|
|
||||||
#endif /* !KDTRACE_HOOKS */
|
#endif /* !KDTRACE_HOOKS */
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
#endif /* _SYS_LOCKSTAT_H */
|
#endif /* _SYS_LOCKSTAT_H */
|
||||||
|
@ -99,8 +99,8 @@
|
|||||||
if (!_rw_write_lock((rw), _tid)) \
|
if (!_rw_write_lock((rw), _tid)) \
|
||||||
_rw_wlock_hard((rw), _tid, (file), (line)); \
|
_rw_wlock_hard((rw), _tid, (file), (line)); \
|
||||||
else \
|
else \
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire, rw, \
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, \
|
||||||
0, 0, file, line); \
|
0, 0, file, line, LOCKSTAT_WRITER); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Release a write lock. */
|
/* Release a write lock. */
|
||||||
@ -110,7 +110,8 @@
|
|||||||
if ((rw)->rw_recurse) \
|
if ((rw)->rw_recurse) \
|
||||||
(rw)->rw_recurse--; \
|
(rw)->rw_recurse--; \
|
||||||
else { \
|
else { \
|
||||||
LOCKSTAT_PROFILE_RELEASE_LOCK(rw__release, rw); \
|
LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw, \
|
||||||
|
LOCKSTAT_WRITER); \
|
||||||
if (!_rw_write_unlock((rw), _tid)) \
|
if (!_rw_write_unlock((rw), _tid)) \
|
||||||
_rw_wunlock_hard((rw), _tid, (file), (line)); \
|
_rw_wunlock_hard((rw), _tid, (file), (line)); \
|
||||||
} \
|
} \
|
||||||
|
13
sys/sys/sx.h
13
sys/sys/sx.h
@ -153,8 +153,8 @@ __sx_xlock(struct sx *sx, struct thread *td, int opts, const char *file,
|
|||||||
if (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid))
|
if (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid))
|
||||||
error = _sx_xlock_hard(sx, tid, opts, file, line);
|
error = _sx_xlock_hard(sx, tid, opts, file, line);
|
||||||
else
|
else
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
|
||||||
0, 0, file, line);
|
0, 0, file, line, LOCKSTAT_WRITER);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -166,7 +166,8 @@ __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
|
|||||||
uintptr_t tid = (uintptr_t)td;
|
uintptr_t tid = (uintptr_t)td;
|
||||||
|
|
||||||
if (sx->sx_recurse == 0)
|
if (sx->sx_recurse == 0)
|
||||||
LOCKSTAT_PROFILE_RELEASE_LOCK(sx__release, sx);
|
LOCKSTAT_PROFILE_RELEASE_RWLOCK(sx__release, sx,
|
||||||
|
LOCKSTAT_WRITER);
|
||||||
if (!atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED))
|
if (!atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED))
|
||||||
_sx_xunlock_hard(sx, tid, file, line);
|
_sx_xunlock_hard(sx, tid, file, line);
|
||||||
}
|
}
|
||||||
@ -182,8 +183,8 @@ __sx_slock(struct sx *sx, int opts, const char *file, int line)
|
|||||||
!atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER))
|
!atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER))
|
||||||
error = _sx_slock_hard(sx, opts, file, line);
|
error = _sx_slock_hard(sx, opts, file, line);
|
||||||
else
|
else
|
||||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx,
|
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
|
||||||
0, 0, file, line);
|
0, 0, file, line, LOCKSTAT_READER);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -200,7 +201,7 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
|
|||||||
{
|
{
|
||||||
uintptr_t x = sx->sx_lock;
|
uintptr_t x = sx->sx_lock;
|
||||||
|
|
||||||
LOCKSTAT_PROFILE_RELEASE_LOCK(sx__release, sx);
|
LOCKSTAT_PROFILE_RELEASE_RWLOCK(sx__release, sx, LOCKSTAT_READER);
|
||||||
if (x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS) ||
|
if (x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS) ||
|
||||||
!atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER))
|
!atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER))
|
||||||
_sx_sunlock_hard(sx, file, line);
|
_sx_sunlock_hard(sx, file, line);
|
||||||
|
Loading…
Reference in New Issue
Block a user