Skip to content

Commit 5860f5c

Browse files
kkdwvdAlexei Starovoitov
authored andcommitted
rqspinlock: Perform AA checks immediately
Currently, while we enter the check_timeout call immediately due to the way the ts.spin is initialized, we still invoke the AA and ABBA checks in the second invocation, and only initialize the timestamp in the first one. Since each iteration is at least done with a 1ms delay, this can add delays in detection of AA deadlocks, up to a ms. Rework check_timeout() to avoid this. First, call check_deadlock_AA() while initializing the timestamps for the wait period. This also means that we only do it once per waiting period, instead of every invocation. Finally, drop check_deadlock() and call check_deadlock_ABBA() directly. To save on unnecessary ktime_get_mono_fast_ns() in case of AA deadlock, sample the time only if it returns 0. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20251128232802.1031906-3-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent beb7021 commit 5860f5c

1 file changed

Lines changed: 7 additions & 18 deletions

File tree

kernel/bpf/rqspinlock.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -196,32 +196,21 @@ static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask)
196196
return 0;
197197
}
198198

199-
static noinline int check_deadlock(rqspinlock_t *lock, u32 mask)
200-
{
201-
int ret;
202-
203-
ret = check_deadlock_AA(lock);
204-
if (ret)
205-
return ret;
206-
ret = check_deadlock_ABBA(lock, mask);
207-
if (ret)
208-
return ret;
209-
210-
return 0;
211-
}
212-
213199
static noinline int check_timeout(rqspinlock_t *lock, u32 mask,
214200
struct rqspinlock_timeout *ts)
215201
{
216-
u64 time = ktime_get_mono_fast_ns();
217202
u64 prev = ts->cur;
203+
u64 time;
218204

219205
if (!ts->timeout_end) {
220-
ts->cur = time;
221-
ts->timeout_end = time + ts->duration;
206+
if (check_deadlock_AA(lock))
207+
return -EDEADLK;
208+
ts->cur = ktime_get_mono_fast_ns();
209+
ts->timeout_end = ts->cur + ts->duration;
222210
return 0;
223211
}
224212

213+
time = ktime_get_mono_fast_ns();
225214
if (time > ts->timeout_end)
226215
return -ETIMEDOUT;
227216

@@ -231,7 +220,7 @@ static noinline int check_timeout(rqspinlock_t *lock, u32 mask,
231220
*/
232221
if (prev + NSEC_PER_MSEC < time) {
233222
ts->cur = time;
234-
return check_deadlock(lock, mask);
223+
return check_deadlock_ABBA(lock, mask);
235224
}
236225

237226
return 0;

0 commit comments

Comments
 (0)