locks: fix a long standing bug for primitives with kdtrace but without spinning

In such a case the second argument to lock_delay_arg_init was NULL which was
immediately causing a null pointer deref.

Since the sructure is only used for spin count, provide a dedicate routine
initializing it.

Reported by:	andrew
This commit is contained in:
Mateusz Guzik 2020-07-23 17:26:53 +00:00
parent e605dcc939
commit c795344ff7
4 changed files with 12 additions and 5 deletions

View File

@ -538,7 +538,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v)
#if defined(ADAPTIVE_MUTEXES)
lock_delay_arg_init(&lda, &mtx_delay);
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
lock_delay_arg_init_noadapt(&lda);
#endif
if (__predict_false(v == MTX_UNOWNED))

View File

@ -475,7 +475,7 @@ __rw_rlock_hard(struct rwlock *rw, struct thread *td, uintptr_t v
#if defined(ADAPTIVE_RWLOCKS)
lock_delay_arg_init(&lda, &rw_delay);
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
lock_delay_arg_init_noadapt(&lda);
#endif
#ifdef HWPMC_HOOKS
@ -951,7 +951,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v LOCK_FILE_LINE_ARG_DEF)
#if defined(ADAPTIVE_RWLOCKS)
lock_delay_arg_init(&lda, &rw_delay);
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
lock_delay_arg_init_noadapt(&lda);
#endif
if (__predict_false(v == RW_UNLOCKED))
v = RW_READ_VALUE(rw);

View File

@ -623,7 +623,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, int opts LOCK_FILE_LINE_ARG_DEF)
#if defined(ADAPTIVE_SX)
lock_delay_arg_init(&lda, &sx_delay);
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
lock_delay_arg_init_noadapt(&lda);
#endif
if (__predict_false(x == SX_LOCK_UNLOCKED))
@ -1063,7 +1063,7 @@ _sx_slock_hard(struct sx *sx, int opts, uintptr_t x LOCK_FILE_LINE_ARG_DEF)
#if defined(ADAPTIVE_SX)
lock_delay_arg_init(&lda, &sx_delay);
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
lock_delay_arg_init_noadapt(&lda);
#endif
#ifdef HWPMC_HOOKS

View File

@ -195,6 +195,13 @@ lock_delay_arg_init(struct lock_delay_arg *la, struct lock_delay_config *lc)
la->spin_cnt = 0;
}
static inline void
lock_delay_arg_init_noadapt(struct lock_delay_arg *la)
{
la->delay = 0;
la->spin_cnt = 0;
}
#define lock_delay_spin(n) do { \
u_int _i; \
\