NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/60776
The following reply was made to PR kern/60776; it has been noted by GNATS.
From: =?UTF-8?Q?Lo=C3=AFc_Gregoire?= <loicgre%gmail.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: kern/60776
Date: Wed, 23 Sep 2026 22:25:58 -0400
Hi,
I submitted the original bug report.
I think I have figured out roughly where the bug is:
/*
* Lend our priority to the 'owner' LWP.
*
* Update lenders info for turnstile_unlendpri.
*/
ts = l->l_ts;
KASSERT(ts->ts_inheritor == owner || ts->ts_inheritor == NULL);
if (ts->ts_inheritor == NULL) {
ts->ts_inheritor = owner;
ts->ts_eprio = prio;
SLIST_INSERT_HEAD(&owner->l_pi_lenders, ts, ts_pichain);
lwp_lendpri(owner, prio);
} else if (prio > ts->ts_eprio) {
ts->ts_eprio = prio;
lwp_lendpri(owner, prio);
}
lwp_lendpri doesn't check whether or not the priority is raised, so
what happens here is that a waiter with a lower priority than the
owner donates its priority to the owner incorrectly.
Intuitively this whole block should be wrapped in
if (prio > lwp_eprio(owner))
As a minimal fix.
However I think this introduces another kind of bug (which was also
present before) where a lower-priority thread is not inserted in
pi_lenders, which means the following situation could occur:
A inherits prio 100 from X
B of priority 50 waits on another lock held by A on turnstile Y
Since A is already of priority > 50, B doesn't get added to lenders.
A releases the lock backed by X, priority is returned
A's priority now could be under 50 even though it still holds Y!
So the real fix would be doing something like this:
ts = l->l_ts;
KASSERT(ts->ts_inheritor == owner || ts->ts_inheritor == NULL);
if (ts->ts_inheritor == NULL) {
ts->ts_inheritor = owner;
ts->ts_eprio = prio;
SLIST_INSERT_HEAD(&owner->l_pi_lenders, ts, ts_pichain);
} else if (prio > ts->ts_eprio) {
ts->ts_eprio = prio;
}
if (prio > owner->l_inheritedprio)
lwp_lendpri(owner, prio);
Instead.
As a bonus I think prio should be set to the eprio of the new owner on each hop.
Home |
Main Index |
Thread Index |
Old Index