Commit Graph

14 Commits

Author SHA1 Message Date
Waiman Long ca8db1144f locking/rtmutex: Add a lockdep assert to catch potential nested blocking
JIRA: https://issues.redhat.com/browse/RHEL-28616

commit 45f67f30a22f264bc7a0a61255c2ee1a838e9403
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Fri, 8 Sep 2023 18:22:53 +0200

    locking/rtmutex: Add a lockdep assert to catch potential nested blocking

    There used to be a BUG_ON(current->pi_blocked_on) in the lock acquisition
    functions, but that vanished in one of the rtmutex overhauls.

    Bring it back in form of a lockdep assert to catch code paths which take
    rtmutex based locks with current::pi_blocked_on != NULL.

    Reported-by: Crystal Wood <swood@redhat.com>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: "Peter Zijlstra (Intel)" <peterz@infradead.org>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/20230908162254.999499-7-bigeasy@linutronix.de

Signed-off-by: Waiman Long <longman@redhat.com>
2024-03-27 10:06:01 -04:00
Waiman Long f62c68f20c locking/rtmutex: Use rt_mutex specific scheduler helpers
JIRA: https://issues.redhat.com/browse/RHEL-28616

commit d14f9e930b9073de264c106bf04968286ef9b3a4
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date:   Fri, 8 Sep 2023 18:22:52 +0200

    locking/rtmutex: Use rt_mutex specific scheduler helpers

    Have rt_mutex use the rt_mutex specific scheduler helpers to avoid
    recursion vs rtlock on the PI state.

    [[ peterz: adapted to new names ]]

    Reported-by: Crystal Wood <swood@redhat.com>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/20230908162254.999499-6-bigeasy@linutronix.de

Signed-off-by: Waiman Long <longman@redhat.com>
2024-03-27 10:05:58 -04:00
Waiman Long 0badc86620 Revert "locking/rtmutex: Submit/resume work explicitly before/after blocking"
JIRA: https://issues.redhat.com/browse/RHEL-28616
Upstream Status: RHEL only

Revert linux-rt-devel specific commit a44b38b17bf3 ("locking/rtmutex:
Submit/resume work explicitly before/after blocking") to prepare for
the submission of upstream equivalent.

Signed-off-by: Waiman Long <longman@redhat.com>
2024-03-27 09:56:35 -04:00
Waiman Long 3ad42081d5 Revert "locking/rtmutex: Add a lockdep assert to catch potential nested blocking"
JIRA: https://issues.redhat.com/browse/RHEL-28616
Upstream Status: RHEL only

Revert linux-rt-devel specific commit e2d27efe1923 ("locking/rtmutex:
Add a lockdep assert to catch potential nested blocking") to prepare
for the submission of upstream equivalent.

Signed-off-by: Waiman Long <longman@redhat.com>
2024-03-27 09:56:34 -04:00
Crystal Wood 31f7062808 locking/rtmutex: Add a lockdep assert to catch potential nested blocking
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2218724

Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git

commit e2d27efe19234c94a42e123dc8122c4f13c9a9ab
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Thu Apr 27 13:19:37 2023 +0200

    locking/rtmutex: Add a lockdep assert to catch potential nested blocking

    There used to be a BUG_ON(current->pi_blocked_on) in the lock acquisition
    functions, but that vanished in one of the rtmutex overhauls.

    Bring it back in form of a lockdep assert to catch code paths which take
    rtmutex based locks with current::pi_blocked_on != NULL.

    Reported-by: Crystal Wood <swood@redhat.com>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Link: https://lore.kernel.org/r/20230427111937.2745231-5-bigeasy@linutronix.de

Signed-off-by: Crystal Wood <swood@redhat.com>
2023-07-18 17:22:36 -05:00
Crystal Wood 2ef9c3d906 locking/rtmutex: Submit/resume work explicitly before/after blocking
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2218724

Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git

commit a44b38b17bf31d90509125a8d34c9ac8f0dcc886
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date:   Thu Apr 27 13:19:35 2023 +0200

    locking/rtmutex: Submit/resume work explicitly before/after blocking

    schedule() invokes sched_submit_work() before scheduling and
    sched_resume_work() afterwards to ensure that queued block requests are
    flushed and the (IO)worker machineries can instantiate new workers if
    required. This avoids deadlocks and starvation.

    With rt_mutexes this can lead to a subtle problem:

      When rtmutex blocks current::pi_blocked_on points to the rtmutex it
      blocks on. When one of the functions in sched_submit/resume_work() contends
      on a rtmutex based lock then that would corrupt current::pi_blocked_on.

    Let rtmutex and the RT lock variants which are based on it invoke
    sched_submit/resume_work() explicitly before and after the slowpath so
    it's guaranteed that current::pi_blocked_on cannot be corrupted by blocking
    on two locks.

    This does not apply to the PREEMPT_RT variants of spinlock_t and rwlock_t
    as their scheduling slowpath is separate and cannot invoke the work related
    functions due to potential deadlocks anyway.

    [ tglx: Make it explicit and symmetric. Massage changelog ]

    Fixes: e17ba59b7e8e1 ("locking/rtmutex: Guard regular sleeping locks specific functions")
    Reported-by: Crystal Wood <swood@redhat.com>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Link: https://lore.kernel.org/4b4ab374d3e24e6ea8df5cadc4297619a6d945af.camel@redhat.com
    Link: https://lore.kernel.org/r/20230427111937.2745231-3-bigeasy@linutronix.de

Signed-off-by: Crystal Wood <swood@redhat.com>
2023-07-18 17:22:36 -05:00
Eder Zulian 0bf96af2ea locking/rwbase: Mitigate indefinite writer starvation
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2037670
Upstream Status: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

commit 286deb7ec03d941664ac3ffaff58814b454adf65
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date:   Tue Mar 21 17:11:40 2023 +0100

    locking/rwbase: Mitigate indefinite writer starvation

    On PREEMPT_RT, rw_semaphore and rwlock_t locks are unfair to writers.
    Readers can indefinitely acquire the lock unless the writer fully acquired
    the lock, which might never happen if there is always a reader in the
    critical section owning the lock.

    Mel Gorman reported that since LTP-20220121 the dio_truncate test case
    went from having 1 reader to having 16 readers and that number of readers
    is sufficient to prevent the down_write ever succeeding while readers
    exist. Eventually the test is killed after 30 minutes as a failure.

    Mel proposed a timeout to limit how long a writer can be blocked until
    the reader is forced into the slowpath.

    Thomas argued that there is no added value by providing this timeout.  From
    a PREEMPT_RT point of view, there are no critical rw_semaphore or rwlock_t
    locks left where the reader must be preferred.

    Mitigate indefinite writer starvation by forcing the READER into the
    slowpath once the WRITER attempts to acquire the lock.

    Reported-by: Mel Gorman <mgorman@techsingularity.net>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Acked-by: Mel Gorman <mgorman@techsingularity.net>
    Link: https://lore.kernel.org/877cwbq4cq.ffs@tglx
    Link: https://lore.kernel.org/r/20230321161140.HMcQEhHb@linutronix.de
    Cc: Linus Torvalds <torvalds@linux-foundation.org>

Signed-off-by: Eder Zulian <ezulian@redhat.com>
2023-06-20 14:29:45 +02:00
Joel Savitz 2d216f7bd8 locking: Apply contention tracepoints in the slow path
conflict in kernel/locking/rtmutex.c
	detail: c9s commit c3a495f437 ("rtmutex: Add acquire semantics for rtmutex lock acquisition slow path"), backport of upstream commit 1c0908d8e441, adds a second parameter to fixup_rt_mutex_waiters(), which is not present in upstream commit ee042be16cb4.
	action: keep new call to fixup_rt_mutex_waiters()

commit ee042be16cb455116d0fe99b77c6bc8baf87c8c6
Author: Namhyung Kim <namhyung@kernel.org>
Date:   Tue Mar 22 11:57:09 2022 -0700

    locking: Apply contention tracepoints in the slow path

    Adding the lock contention tracepoints in various lock function slow
    paths.  Note that each arch can define spinlock differently, I only
    added it only to the generic qspinlock for now.

    Signed-off-by: Namhyung Kim <namhyung@kernel.org>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
    Link: https://lkml.kernel.org/r/20220322185709.141236-3-namhyung@kernel.org

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2176147
Signed-off-by: Joel Savitz <jsavitz@redhat.com>
2023-03-07 15:26:28 -05:00
Waiman Long 65d9183f94 rtmutex: Wake up the waiters lockless while dropping the read lock.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2076713

commit 9321f8152d9a764208c3f0dad49e0c55f293b7ab
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Tue, 28 Sep 2021 17:00:06 +0200

    rtmutex: Wake up the waiters lockless while dropping the read lock.

    The rw_semaphore and rwlock_t implementation both wake the waiter while
    holding the rt_mutex_base::wait_lock acquired.
    This can be optimized by waking the waiter lockless outside of the
    locked section to avoid a needless contention on the
    rt_mutex_base::wait_lock lock.

    Extend rt_mutex_wake_q_add() to also accept task and state and use it in
    __rwbase_read_unlock().

    Suggested-by: Davidlohr Bueso <dave@stgolabs.net>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/20210928150006.597310-3-bigeasy@linutronix.de

Signed-off-by: Waiman Long <longman@redhat.com>
2022-05-12 08:32:18 -04:00
Waiman Long 37719d3456 locking/rwbase: Optimize rwbase_read_trylock
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2076713

commit c78416d122243c92992a1d1063f17ddd0bc80e6c
Author: Davidlohr Bueso <dave@stgolabs.net>
Date:   Sun, 19 Sep 2021 22:20:30 -0700

    locking/rwbase: Optimize rwbase_read_trylock

    Instead of a full barrier around the Rmw insn, micro-optimize
    for weakly ordered archs such that we only provide the required
    ACQUIRE semantics when taking the read lock.

    Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Acked-by: Waiman Long <longman@redhat.com>
    Link: https://lkml.kernel.org/r/20210920052031.54220-2-dave@stgolabs.net

Signed-off-by: Waiman Long <longman@redhat.com>
2022-05-12 08:31:49 -04:00
Waiman Long e82b1c9c49 locking/rwbase: Take care of ordering guarantee for fastpath reader
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2007032

commit 81121524f1c798c9481bd7900450b72ee7ac2eef
Author: Boqun Feng <boqun.feng@gmail.com>
Date:   Thu, 9 Sep 2021 12:59:19 +0200

    locking/rwbase: Take care of ordering guarantee for fastpath reader

    Readers of rwbase can lock and unlock without taking any inner lock, if
    that happens, we need the ordering provided by atomic operations to
    satisfy the ordering semantics of lock/unlock. Without that, considering
    the follow case:

            { X = 0 initially }

            CPU 0                   CPU 1
            =====                   =====
                                    rt_write_lock();
                                    X = 1
                                    rt_write_unlock():
                                      atomic_add(READER_BIAS - WRITER_BIAS, ->readers);
                                      // ->readers is READER_BIAS.
            rt_read_lock():
              if ((r = atomic_read(->readers)) < 0) // True
                atomic_try_cmpxchg(->readers, r, r + 1); // succeed.
              <acquire the read lock via fast path>

            r1 = X; // r1 may be 0, because nothing prevent the reordering
                    // of "X=1" and atomic_add() on CPU 1.

    Therefore audit every usage of atomic operations that may happen in a
    fast path, and add necessary barriers.

    Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Link: https://lkml.kernel.org/r/20210909110203.953991276@infradead.org

Signed-off-by: Waiman Long <longman@redhat.com>
2021-09-27 16:19:32 -04:00
Waiman Long 2279be5069 locking/rwbase: Extract __rwbase_write_trylock()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2007032

commit 616be87eac9fa2ab2dca1069712f7236e50f3bf6
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Thu, 9 Sep 2021 12:59:18 +0200

    locking/rwbase: Extract __rwbase_write_trylock()

    The code in rwbase_write_lock() is a little non-obvious vs the
    read+set 'trylock', extract the sequence into a helper function to
    clarify the code.

    This also provides a single site to fix fast-path ordering.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Link: https://lkml.kernel.org/r/YUCq3L+u44NDieEJ@hirez.programming.kicks-ass.net

Signed-off-by: Waiman Long <longman@redhat.com>
2021-09-27 16:19:32 -04:00
Waiman Long 97fe4f6bd0 locking/rwbase: Properly match set_and_save_state() to restore_state()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2007032

commit 7687201e37fabf2b7cf2b828f7ca46bf30e2948f
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Thu, 9 Sep 2021 12:59:17 +0200

    locking/rwbase: Properly match set_and_save_state() to restore_state()

    Noticed while looking at the readers race.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Acked-by: Will Deacon <will@kernel.org>
    Link: https://lkml.kernel.org/r/20210909110203.828203010@infradead.org

Signed-off-by: Waiman Long <longman@redhat.com>
2021-09-27 16:19:31 -04:00
Waiman Long 22c18a10b4 locking/rt: Add base code for RT rw_semaphore and rwlock
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2007032

commit 943f0edb754fac195043c620b44f920e4fb76ec8
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Sun, 15 Aug 2021 23:28:03 +0200

    locking/rt: Add base code for RT rw_semaphore and rwlock

    On PREEMPT_RT, rw_semaphores and rwlocks are substituted with an rtmutex and
    a reader count. The implementation is writer unfair, as it is not feasible
    to do priority inheritance on multiple readers, but experience has shown
    that real-time workloads are not the typical workloads which are sensitive
    to writer starvation.

    The inner workings of rw_semaphores and rwlocks on RT are almost identical
    except for the task state and signal handling. rw_semaphores are not state
    preserving over a contention, they are expected to enter and leave with state
    == TASK_RUNNING. rwlocks have a mechanism to preserve the state of the task
    at entry and restore it after unblocking taking potential non-lock related
    wakeups into account. rw_semaphores can also be subject to signal handling
    interrupting a blocked state, while rwlocks ignore signals.

    To avoid code duplication, provide a shared implementation which takes the
    small difference vs. state and signals into account. The code is included
    into the relevant rw_semaphore/rwlock base code and compiled for each use
    case separately.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Link: https://lore.kernel.org/r/20210815211302.957920571@linutronix.de

Signed-off-by: Waiman Long <longman@redhat.com>
2021-09-27 16:18:47 -04:00