diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-08-25 10:49:52 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:40 -0400 |
commit | ebc6f76a667f5fc599a5f76515f6881dfb82af2f (patch) | |
tree | 24bb2c72eda0ee8bca9ea831eefda0a2a6ed01e9 /fs/bcachefs/six.h | |
parent | 098ef98d5bff461c66c3798fbebca7b1c06fdf79 (diff) | |
download | linux-ebc6f76a667f5fc599a5f76515f6881dfb82af2f.tar.gz linux-ebc6f76a667f5fc599a5f76515f6881dfb82af2f.tar.bz2 linux-ebc6f76a667f5fc599a5f76515f6881dfb82af2f.zip |
six locks: Simplify wait lists
This switches to a single list of waiters, instead of separate lists for
read and intent, and switches write locks to also use the wait lists
instead of being handled differently.
Also, removal from the wait list is now done by the process waiting on
the lock, not the process doing the wakeup. This is needed for the new
deadlock cycle detector - we need tasks to stay on the waitlist until
they've successfully acquired the lock.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/six.h')
-rw-r--r-- | fs/bcachefs/six.h | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/bcachefs/six.h b/fs/bcachefs/six.h index 6c9ac82d146d..0e55845195d9 100644 --- a/fs/bcachefs/six.h +++ b/fs/bcachefs/six.h @@ -116,12 +116,18 @@ struct six_lock { unsigned __percpu *readers; raw_spinlock_t wait_lock; - struct list_head wait_list[2]; + struct list_head wait_list; #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif }; +struct six_lock_waiter { + struct list_head list; + struct task_struct *task; + enum six_lock_type lock_want; +}; + typedef int (*six_lock_should_sleep_fn)(struct six_lock *lock, void *); static __always_inline void __six_lock_init(struct six_lock *lock, @@ -130,8 +136,7 @@ static __always_inline void __six_lock_init(struct six_lock *lock, { atomic64_set(&lock->state.counter, 0); raw_spin_lock_init(&lock->wait_lock); - INIT_LIST_HEAD(&lock->wait_list[SIX_LOCK_read]); - INIT_LIST_HEAD(&lock->wait_list[SIX_LOCK_intent]); + INIT_LIST_HEAD(&lock->wait_list); #ifdef CONFIG_DEBUG_LOCK_ALLOC debug_check_no_locks_freed((void *) lock, sizeof(*lock)); lockdep_init_map(&lock->dep_map, name, key, 0); |