summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-09-24 01:33:13 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-03-13 11:34:36 -0400
commit58b4b006bed601b049934f847c83943558d184f2 (patch)
treedf3a86b3cb4c21991a6dbc033f5bac7325d7ecb1
parente2fb73f0fc1f80dc422d81657f3e8549aac446b1 (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.h1
-rw-r--r--kernel/locking/six.c14
2 files changed, 15 insertions, 0 deletions
diff --git a/include/linux/six.h b/include/linux/six.h
index 59ced467ee86..37e6fb22d71d 100644
--- a/include/linux/six.h
+++ b/include/linux/six.h
@@ -121,6 +121,7 @@ struct six_lock_waiter {
struct list_head list;
struct task_struct *task;
enum six_lock_type lock_want;
+ 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 4aebc064066c..c0c4809dbdde 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>
@@ -465,6 +466,17 @@ static int __six_lock_type_slowpath(struct six_lock *lock, enum six_lock_type ty
raw_spin_lock(&lock->wait_lock);
if (!(lock->state.waiters & (1 << type)))
set_bit(waitlist_bitnr(type), (unsigned long *) &lock->state.v);
+ 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);
@@ -502,6 +514,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);