diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-06-03 16:21:35 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2020-06-03 19:56:33 -0400 |
commit | 1952c0790c74e4e81d7066a19aabc5c55a13f10f (patch) | |
tree | 501fa5db6a5f1fd3b2412a2660e995c74ebf0bba /linux | |
parent | 90d54b388666b258c97be6a4e632824d136356c4 (diff) |
Update bcachefs sources to c9b4a210f9 fixup! bcachefs: Fixes for going RO
Diffstat (limited to 'linux')
-rw-r--r-- | linux/six.c | 12 | ||||
-rw-r--r-- | linux/workqueue.c | 54 |
2 files changed, 47 insertions, 19 deletions
diff --git a/linux/six.c b/linux/six.c index c7781235..3d863a9b 100644 --- a/linux/six.c +++ b/linux/six.c @@ -108,7 +108,8 @@ static bool __six_trylock_type(struct six_lock *lock, enum six_lock_type type) if (!do_six_trylock_type(lock, type)) return false; - six_acquire(&lock->dep_map, 1); + if (type != SIX_LOCK_write) + six_acquire(&lock->dep_map, 1); return true; } @@ -130,7 +131,8 @@ static bool __six_relock_type(struct six_lock *lock, enum six_lock_type type, old.v + l[type].lock_val)) != old.v); six_set_owner(lock, type, old); - six_acquire(&lock->dep_map, 1); + if (type != SIX_LOCK_write) + six_acquire(&lock->dep_map, 1); return true; } @@ -323,7 +325,8 @@ static void __six_lock_type_slowpath(struct six_lock *lock, enum six_lock_type t __always_inline static void __six_lock_type(struct six_lock *lock, enum six_lock_type type) { - six_acquire(&lock->dep_map, 0); + if (type != SIX_LOCK_write) + six_acquire(&lock->dep_map, 0); if (!do_six_trylock_type(lock, type)) __six_lock_type_slowpath(lock, type); @@ -382,7 +385,8 @@ static void __six_unlock_type(struct six_lock *lock, enum six_lock_type type) EBUG_ON(type == SIX_LOCK_write && !(lock->state.v & __SIX_LOCK_HELD_intent)); - six_release(&lock->dep_map); + if (type != SIX_LOCK_write) + six_release(&lock->dep_map); if (type == SIX_LOCK_intent) { EBUG_ON(lock->owner != current); diff --git a/linux/workqueue.c b/linux/workqueue.c index 550cfd3b..0d5af3fb 100644 --- a/linux/workqueue.c +++ b/linux/workqueue.c @@ -5,6 +5,7 @@ #include <linux/workqueue.h> static pthread_mutex_t wq_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t work_finished = PTHREAD_COND_INITIALIZER; static LIST_HEAD(wq_list); struct workqueue_struct { @@ -13,8 +14,6 @@ struct workqueue_struct { struct work_struct *current_work; struct list_head pending_work; - pthread_cond_t work_finished; - struct task_struct *worker; char name[24]; }; @@ -23,6 +22,11 @@ enum { WORK_PENDING_BIT, }; +static bool work_pending(struct work_struct *work) +{ + return test_bit(WORK_PENDING_BIT, work_data_bits(work)); +} + static void clear_work_pending(struct work_struct *work) { clear_bit(WORK_PENDING_BIT, work_data_bits(work)); @@ -36,7 +40,7 @@ static bool set_work_pending(struct work_struct *work) static void __queue_work(struct workqueue_struct *wq, struct work_struct *work) { - BUG_ON(!test_bit(WORK_PENDING_BIT, work_data_bits(work))); + BUG_ON(!work_pending(work)); BUG_ON(!list_empty(&work->entry)); list_add_tail(&work->entry, &wq->pending_work); @@ -130,17 +134,39 @@ retry: goto retry; } -static bool __flush_work(struct work_struct *work) +static bool work_running(struct work_struct *work) { struct workqueue_struct *wq; - bool ret = false; -retry: + list_for_each_entry(wq, &wq_list, list) - if (wq->current_work == work) { - pthread_cond_wait(&wq->work_finished, &wq_lock); - ret = true; - goto retry; - } + if (wq->current_work == work) + return true; + + return false; +} + +bool flush_work(struct work_struct *work) +{ + bool ret = false; + + pthread_mutex_lock(&wq_lock); + while (work_pending(work) || work_running(work)) { + pthread_cond_wait(&work_finished, &wq_lock); + ret = true; + } + pthread_mutex_unlock(&wq_lock); + + return ret; +} + +static bool __flush_work(struct work_struct *work) +{ + bool ret = false; + + while (work_running(work)) { + pthread_cond_wait(&work_finished, &wq_lock); + ret = true; + } return ret; } @@ -228,7 +254,7 @@ static int worker_thread(void *arg) continue; } - BUG_ON(!test_bit(WORK_PENDING_BIT, work_data_bits(work))); + BUG_ON(!work_pending(work)); list_del_init(&work->entry); clear_work_pending(work); @@ -236,7 +262,7 @@ static int worker_thread(void *arg) work->func(work); pthread_mutex_lock(&wq_lock); - pthread_cond_broadcast(&wq->work_finished); + pthread_cond_broadcast(&work_finished); } pthread_mutex_unlock(&wq_lock); @@ -269,8 +295,6 @@ struct workqueue_struct *alloc_workqueue(const char *fmt, INIT_LIST_HEAD(&wq->list); INIT_LIST_HEAD(&wq->pending_work); - pthread_cond_init(&wq->work_finished, NULL); - va_start(args, max_active); vsnprintf(wq->name, sizeof(wq->name), fmt, args); va_end(args); |