Skip to content

Commit

Permalink
Consistently use a reader/writer flag for lockstat probes in rwlock(9…
Browse files Browse the repository at this point in the history
…) 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.
  • Loading branch information
markjdb committed Jul 19, 2015
1 parent fb4cb70 commit 2092d6e
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 39 deletions.
16 changes: 8 additions & 8 deletions cddl/contrib/opensolaris/cmd/lockstat/lockstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,17 @@ static ls_event_info_t g_event_info[LS_MAX_EVENTS] = {
"lockstat:::spin-release", NULL,
"lockstat:::spin-acquire" },
{ 'H', "Lock", "R/W writer hold", "nsec",
"lockstat::rw_wunlock:rw-release", NULL,
"lockstat::rw_wlock:rw-acquire" },
"lockstat:::rw-release", "arg1 == 0",
"lockstat:::rw-acquire" },
{ 'H', "Lock", "R/W reader hold", "nsec",
"lockstat::rw_runlock:rw-release", NULL,
"lockstat::rw_rlock:rw-acquire" },
"lockstat:::rw-release", "arg1 == 1",
"lockstat:::rw-acquire" },
{ 'H', "Lock", "SX shared hold", "nsec",
"lockstat::sx_sunlock:sx-release", NULL,
"lockstat::sx_slock:sx-acquire" },
"lockstat:::sx-release", "arg1 == 0",
"lockstat:::sx-acquire" },
{ 'H', "Lock", "SX exclusive hold", "nsec",
"lockstat::sx_xunlock:sx-release", NULL,
"lockstat::sx_xlock:sx-acquire" },
"lockstat:::sx-release", "arg1 == 1",
"lockstat:::sx-acquire" },
{ 'H', "Lock", "Unknown event (type 38)", "units" },
{ 'H', "Lock", "Unknown event (type 39)", "units" },
{ 'H', "Lock", "Unknown event (type 40)", "units" },
Expand Down
8 changes: 4 additions & 4 deletions sys/kern/kern_lockstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ SDT_PROBE_DEFINE1(lockstat, , , spin__acquire, "struct mtx *");
SDT_PROBE_DEFINE1(lockstat, , , spin__release, "struct mtx *");
SDT_PROBE_DEFINE2(lockstat, , , spin__spin, "struct mtx *", "uint64_t");

SDT_PROBE_DEFINE1(lockstat, , , rw__acquire, "struct rwlock *");
SDT_PROBE_DEFINE1(lockstat, , , rw__release, "struct rwlock *");
SDT_PROBE_DEFINE2(lockstat, , , rw__acquire, "struct rwlock *", "int");
SDT_PROBE_DEFINE2(lockstat, , , rw__release, "struct rwlock *", "int");
SDT_PROBE_DEFINE5(lockstat, , , rw__block, "struct rwlock *", "uint64_t", "int",
"int", "int");
SDT_PROBE_DEFINE2(lockstat, , , rw__spin, "struct rwlock *", "uint64_t");
SDT_PROBE_DEFINE1(lockstat, , , rw__upgrade, "struct rwlock *");
SDT_PROBE_DEFINE1(lockstat, , , rw__downgrade, "struct rwlock *");

SDT_PROBE_DEFINE1(lockstat, , , sx__acquire, "struct sx *");
SDT_PROBE_DEFINE1(lockstat, , , sx__release, "struct sx *");
SDT_PROBE_DEFINE2(lockstat, , , sx__acquire, "struct sx *", "int");
SDT_PROBE_DEFINE2(lockstat, , , sx__release, "struct sx *", "int");
SDT_PROBE_DEFINE5(lockstat, , , sx__block, "struct sx *", "uint64_t", "int",
"int", "int");
SDT_PROBE_DEFINE2(lockstat, , , sx__spin, "struct sx *", "uint64_t");
Expand Down
18 changes: 9 additions & 9 deletions sys/kern/kern_rwlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
file, line);
if (!rw_recursed(rw))
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire,
rw, 0, 0, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire,
rw, 0, 0, file, line, LOCKSTAT_WRITER);
curthread->td_locks++;
}
return (rval);
Expand Down Expand Up @@ -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
* turnstile_wait() currently.
*/
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire, rw, contested,
waittime, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, contested,
waittime, file, line, LOCKSTAT_READER);
LOCK_LOG_LOCK("RLOCK", &rw->lock_object, 0, 0, file, line);
WITNESS_LOCK(&rw->lock_object, 0, file, line);
curthread->td_locks++;
Expand Down Expand Up @@ -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,
line);
WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line);
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire,
rw, 0, 0, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire,
rw, 0, 0, file, line, LOCKSTAT_READER);
curthread->td_locks++;
curthread->td_rw_rlocks++;
return (1);
Expand Down Expand Up @@ -713,7 +713,7 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
turnstile_chain_unlock(&rw->lock_object);
break;
}
LOCKSTAT_PROFILE_RELEASE_LOCK(rw__release, rw);
LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw, LOCKSTAT_READER);
curthread->td_locks--;
curthread->td_rw_rlocks--;
}
Expand Down Expand Up @@ -920,8 +920,8 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
(state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
#endif
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire, rw, contested,
waittime, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, contested,
waittime, file, line, LOCKSTAT_WRITER);
}

/*
Expand Down
16 changes: 8 additions & 8 deletions sys/kern/kern_sx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
LOCK_LOG_TRY("SLOCK", &sx->lock_object, 0, 1, file, line);
WITNESS_LOCK(&sx->lock_object, LOP_TRYLOCK, file, line);
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire,
sx, 0, 0, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire,
sx, 0, 0, file, line, LOCKSTAT_READER);
curthread->td_locks++;
return (1);
}
Expand Down Expand Up @@ -351,8 +351,8 @@ sx_try_xlock_(struct sx *sx, const char *file, int line)
WITNESS_LOCK(&sx->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
file, line);
if (!sx_recursed(sx))
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire,
sx, 0, 0, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire,
sx, 0, 0, file, line, LOCKSTAT_WRITER);
curthread->td_locks++;
}

Expand Down Expand Up @@ -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));
#endif
if (!error)
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx,
contested, waittime, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
contested, waittime, file, line, LOCKSTAT_WRITER);
GIANT_RESTORE();
return (error);
}
Expand Down Expand Up @@ -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));
#endif
if (error == 0)
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx, contested,
waittime, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
contested, waittime, file, line, LOCKSTAT_READER);
GIANT_RESTORE();
return (error);
}
Expand Down
18 changes: 17 additions & 1 deletion sys/sys/lockstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,25 @@ SDT_PROBE_DECLARE(lockstat, , , thread__spin);
LOCKSTAT_RECORD0(probe, lp); \
} 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 { \
lock_profile_release_lock(&(lp)->lock_object); \
LOCKSTAT_RECORD0(probe, lp); \
} 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;

struct lock_object;
extern uint64_t lockstat_nsecs(struct lock_object *);
uint64_t lockstat_nsecs(struct lock_object *);

#else /* !KDTRACE_HOOKS */

Expand All @@ -111,9 +121,15 @@ extern uint64_t lockstat_nsecs(struct lock_object *);
#define LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, 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) \
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 /* _KERNEL */
#endif /* _SYS_LOCKSTAT_H */
7 changes: 4 additions & 3 deletions sys/sys/rwlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@
if (!_rw_write_lock((rw), _tid)) \
_rw_wlock_hard((rw), _tid, (file), (line)); \
else \
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(rw__acquire, rw, \
0, 0, file, line); \
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, \
0, 0, file, line, LOCKSTAT_WRITER); \
} while (0)

/* Release a write lock. */
Expand All @@ -110,7 +110,8 @@
if ((rw)->rw_recurse) \
(rw)->rw_recurse--; \
else { \
LOCKSTAT_PROFILE_RELEASE_LOCK(rw__release, rw); \
LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw, \
LOCKSTAT_WRITER); \
if (!_rw_write_unlock((rw), _tid)) \
_rw_wunlock_hard((rw), _tid, (file), (line)); \
} \
Expand Down
13 changes: 7 additions & 6 deletions sys/sys/sx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
error = _sx_xlock_hard(sx, tid, opts, file, line);
else
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx,
0, 0, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
0, 0, file, line, LOCKSTAT_WRITER);

return (error);
}
Expand All @@ -166,7 +166,8 @@ __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
uintptr_t tid = (uintptr_t)td;

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))
_sx_xunlock_hard(sx, tid, file, line);
}
Expand All @@ -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))
error = _sx_slock_hard(sx, opts, file, line);
else
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx,
0, 0, file, line);
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
0, 0, file, line, LOCKSTAT_READER);

return (error);
}
Expand All @@ -200,7 +201,7 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
{
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) ||
!atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER))
_sx_sunlock_hard(sx, file, line);
Expand Down

0 comments on commit 2092d6e

Please sign in to comment.