Commit f6ea2d57 authored by Kent Overstreet's avatar Kent Overstreet

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0bfb9f42
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/preempt.h> #include <linux/preempt.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/clock.h>
#include <linux/sched/rt.h> #include <linux/sched/rt.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -466,6 +467,17 @@ static int __six_lock_type_slowpath(struct six_lock *lock, enum six_lock_type ty ...@@ -466,6 +467,17 @@ static int __six_lock_type_slowpath(struct six_lock *lock, enum six_lock_type ty
raw_spin_lock(&lock->wait_lock); raw_spin_lock(&lock->wait_lock);
if (!(lock->state.waiters & (1 << type))) if (!(lock->state.waiters & (1 << type)))
set_bit(waitlist_bitnr(type), (unsigned long *) &lock->state.v); 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); list_add_tail(&wait->list, &lock->wait_list);
raw_spin_unlock(&lock->wait_lock); raw_spin_unlock(&lock->wait_lock);
...@@ -503,6 +515,8 @@ static int __six_lock_type_waiter(struct six_lock *lock, enum six_lock_type type ...@@ -503,6 +515,8 @@ static int __six_lock_type_waiter(struct six_lock *lock, enum six_lock_type type
{ {
int ret; int ret;
wait->start_time = 0;
if (type != SIX_LOCK_write) if (type != SIX_LOCK_write)
six_acquire(&lock->dep_map, 0); six_acquire(&lock->dep_map, 0);
......
...@@ -126,6 +126,7 @@ struct six_lock_waiter { ...@@ -126,6 +126,7 @@ struct six_lock_waiter {
struct list_head list; struct list_head list;
struct task_struct *task; struct task_struct *task;
enum six_lock_type lock_want; enum six_lock_type lock_want;
u64 start_time;
}; };
typedef int (*six_lock_should_sleep_fn)(struct six_lock *lock, void *); typedef int (*six_lock_should_sleep_fn)(struct six_lock *lock, void *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment