diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-09-24 01:33:13 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2022-10-03 23:54:50 -0400 |
commit | 054de1a405017bc1bb4ae4246a0e1e2ff5f5259c (patch) | |
tree | a544317aa4b5fe23cf974405c1672ff2c2307dd9 | |
parent | 8cd358f239097fec2a021d4a7f71c44ef77aa8f3 (diff) |
six locks: Add start_time to six_lock_waiter
This is needed by the cycle detector in bcachefs - we need a way to
iterater over waitlist entries while dropping and retaking the waitlist
lock.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | include/linux/six.h | 1 | ||||
-rw-r--r-- | kernel/locking/six.c | 17 |
2 files changed, 17 insertions, 1 deletions
diff --git a/include/linux/six.h b/include/linux/six.h index f336ae049df8..fe4b6292d773 100644 --- a/include/linux/six.h +++ b/include/linux/six.h @@ -119,6 +119,7 @@ struct six_lock_waiter { struct task_struct *task; enum six_lock_type lock_want; bool lock_acquired; + u64 start_time; }; typedef int (*six_lock_should_sleep_fn)(struct six_lock *lock, void *); diff --git a/kernel/locking/six.c b/kernel/locking/six.c index 91cbca5a1ae9..18bc060241a2 100644 --- a/kernel/locking/six.c +++ b/kernel/locking/six.c @@ -6,6 +6,7 @@ #include <linux/preempt.h> #include <linux/rcupdate.h> #include <linux/sched.h> +#include <linux/sched/clock.h> #include <linux/sched/rt.h> #include <linux/six.h> #include <linux/slab.h> @@ -421,8 +422,20 @@ static int __six_lock_type_slowpath(struct six_lock *lock, enum six_lock_type ty * unlock: */ ret = __do_six_trylock_type(lock, type, current, false); - if (ret <= 0) + if (ret <= 0) { + wait->start_time = local_clock(); + + if (!list_empty(&lock->wait_list)) { + struct six_lock_waiter *last = + list_last_entry(&lock->wait_list, + struct six_lock_waiter, list); + + if (time_before_eq64(wait->start_time, last->start_time)) + wait->start_time = last->start_time + 1; + } + list_add_tail(&wait->list, &lock->wait_list); + } raw_spin_unlock(&lock->wait_lock); if (unlikely(ret > 0)) { @@ -477,6 +490,8 @@ static int __six_lock_type_waiter(struct six_lock *lock, enum six_lock_type type { int ret; + wait->start_time = 0; + if (type != SIX_LOCK_write) six_acquire(&lock->dep_map, 0); |