From 45bcf0bd8cbe163c5aec18570b6befd2193f1a57 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 21 Feb 2023 19:02:38 +0000 Subject: [PATCH] locktorture: With nested locks, occasionally skip main lock If we're using nested locking to stress things, occasionally skip taking the main lock, so that we can get some different contention patterns between the writers (to hopefully get two disjoint blocked trees) Cc: Davidlohr Bueso Cc: "Paul E. McKenney" Cc: Josh Triplett Cc: Joel Fernandes Cc: Juri Lelli Cc: Valentin Schneider Cc: Dietmar Eggemann Cc: kernel-team@android.com Co-developed-by: Connor O'Brien Signed-off-by: Connor O'Brien Signed-off-by: John Stultz Signed-off-by: Paul E. McKenney --- kernel/locking/locktorture.c | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c index c7f264aed5b7a..9425aff089365 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c @@ -760,6 +760,7 @@ static int lock_torture_writer(void *arg) int tid = lwsp - cxt.lwsa; DEFINE_TORTURE_RANDOM(rand); u32 lockset_mask; + bool skip_main_lock; VERBOSE_TOROUT_STRING("lock_torture_writer task started"); set_user_nice(current, MAX_NICE); @@ -769,21 +770,37 @@ static int lock_torture_writer(void *arg) schedule_timeout_uninterruptible(1); lockset_mask = torture_random(&rand); + /* + * When using nested_locks, we want to occasionally + * skip the main lock so we can avoid always serializing + * the lock chains on that central lock. By skipping the + * main lock occasionally, we can create different + * contention patterns (allowing for multiple disjoint + * blocked trees) + */ + skip_main_lock = (nested_locks && + !(torture_random(&rand) % 100)); + cxt.cur_ops->task_boost(&rand); if (cxt.cur_ops->nested_lock) cxt.cur_ops->nested_lock(tid, lockset_mask); - cxt.cur_ops->writelock(tid); - if (WARN_ON_ONCE(lock_is_write_held)) - lwsp->n_lock_fail++; - lock_is_write_held = true; - if (WARN_ON_ONCE(atomic_read(&lock_is_read_held))) - lwsp->n_lock_fail++; /* rare, but... */ - lwsp->n_lock_acquired++; + if (!skip_main_lock) { + cxt.cur_ops->writelock(tid); + if (WARN_ON_ONCE(lock_is_write_held)) + lwsp->n_lock_fail++; + lock_is_write_held = true; + if (WARN_ON_ONCE(atomic_read(&lock_is_read_held))) + lwsp->n_lock_fail++; /* rare, but... */ + + lwsp->n_lock_acquired++; + } cxt.cur_ops->write_delay(&rand); - lock_is_write_held = false; - WRITE_ONCE(last_lock_release, jiffies); - cxt.cur_ops->writeunlock(tid); + if (!skip_main_lock) { + lock_is_write_held = false; + WRITE_ONCE(last_lock_release, jiffies); + cxt.cur_ops->writeunlock(tid); + } if (cxt.cur_ops->nested_unlock) cxt.cur_ops->nested_unlock(tid, lockset_mask); -- 2.30.2