aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/async-thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/async-thread.c')
-rw-r--r--fs/btrfs/async-thread.c146
1 files changed, 71 insertions, 75 deletions
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index 7ec14097fef1..58b7d14b08ee 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -64,6 +64,8 @@ struct btrfs_worker_thread {
64 int idle; 64 int idle;
65}; 65};
66 66
67static int __btrfs_start_workers(struct btrfs_workers *workers);
68
67/* 69/*
68 * btrfs_start_workers uses kthread_run, which can block waiting for memory 70 * btrfs_start_workers uses kthread_run, which can block waiting for memory
69 * for a very long time. It will actually throttle on page writeback, 71 * for a very long time. It will actually throttle on page writeback,
@@ -88,27 +90,10 @@ static void start_new_worker_func(struct btrfs_work *work)
88{ 90{
89 struct worker_start *start; 91 struct worker_start *start;
90 start = container_of(work, struct worker_start, work); 92 start = container_of(work, struct worker_start, work);
91 btrfs_start_workers(start->queue, 1); 93 __btrfs_start_workers(start->queue);
92 kfree(start); 94 kfree(start);
93} 95}
94 96
95static int start_new_worker(struct btrfs_workers *queue)
96{
97 struct worker_start *start;
98 int ret;
99
100 start = kzalloc(sizeof(*start), GFP_NOFS);
101 if (!start)
102 return -ENOMEM;
103
104 start->work.func = start_new_worker_func;
105 start->queue = queue;
106 ret = btrfs_queue_worker(queue->atomic_worker_start, &start->work);
107 if (ret)
108 kfree(start);
109 return ret;
110}
111
112/* 97/*
113 * helper function to move a thread onto the idle list after it 98 * helper function to move a thread onto the idle list after it
114 * has finished some requests. 99 * has finished some requests.
@@ -153,12 +138,20 @@ static void check_busy_worker(struct btrfs_worker_thread *worker)
153static void check_pending_worker_creates(struct btrfs_worker_thread *worker) 138static void check_pending_worker_creates(struct btrfs_worker_thread *worker)
154{ 139{
155 struct btrfs_workers *workers = worker->workers; 140 struct btrfs_workers *workers = worker->workers;
141 struct worker_start *start;
156 unsigned long flags; 142 unsigned long flags;
157 143
158 rmb(); 144 rmb();
159 if (!workers->atomic_start_pending) 145 if (!workers->atomic_start_pending)
160 return; 146 return;
161 147
148 start = kzalloc(sizeof(*start), GFP_NOFS);
149 if (!start)
150 return;
151
152 start->work.func = start_new_worker_func;
153 start->queue = workers;
154
162 spin_lock_irqsave(&workers->lock, flags); 155 spin_lock_irqsave(&workers->lock, flags);
163 if (!workers->atomic_start_pending) 156 if (!workers->atomic_start_pending)
164 goto out; 157 goto out;
@@ -170,18 +163,19 @@ static void check_pending_worker_creates(struct btrfs_worker_thread *worker)
170 163
171 workers->num_workers_starting += 1; 164 workers->num_workers_starting += 1;
172 spin_unlock_irqrestore(&workers->lock, flags); 165 spin_unlock_irqrestore(&workers->lock, flags);
173 start_new_worker(workers); 166 btrfs_queue_worker(workers->atomic_worker_start, &start->work);
174 return; 167 return;
175 168
176out: 169out:
170 kfree(start);
177 spin_unlock_irqrestore(&workers->lock, flags); 171 spin_unlock_irqrestore(&workers->lock, flags);
178} 172}
179 173
180static noinline int run_ordered_completions(struct btrfs_workers *workers, 174static noinline void run_ordered_completions(struct btrfs_workers *workers,
181 struct btrfs_work *work) 175 struct btrfs_work *work)
182{ 176{
183 if (!workers->ordered) 177 if (!workers->ordered)
184 return 0; 178 return;
185 179
186 set_bit(WORK_DONE_BIT, &work->flags); 180 set_bit(WORK_DONE_BIT, &work->flags);
187 181
@@ -212,14 +206,20 @@ static noinline int run_ordered_completions(struct btrfs_workers *workers,
212 206
213 work->ordered_func(work); 207 work->ordered_func(work);
214 208
215 /* now take the lock again and call the freeing code */ 209 /* now take the lock again and drop our item from the list */
216 spin_lock(&workers->order_lock); 210 spin_lock(&workers->order_lock);
217 list_del(&work->order_list); 211 list_del(&work->order_list);
212 spin_unlock(&workers->order_lock);
213
214 /*
215 * we don't want to call the ordered free functions
216 * with the lock held though
217 */
218 work->ordered_free(work); 218 work->ordered_free(work);
219 spin_lock(&workers->order_lock);
219 } 220 }
220 221
221 spin_unlock(&workers->order_lock); 222 spin_unlock(&workers->order_lock);
222 return 0;
223} 223}
224 224
225static void put_worker(struct btrfs_worker_thread *worker) 225static void put_worker(struct btrfs_worker_thread *worker)
@@ -331,7 +331,7 @@ again:
331 run_ordered_completions(worker->workers, work); 331 run_ordered_completions(worker->workers, work);
332 332
333 check_pending_worker_creates(worker); 333 check_pending_worker_creates(worker);
334 334 cond_resched();
335 } 335 }
336 336
337 spin_lock_irq(&worker->lock); 337 spin_lock_irq(&worker->lock);
@@ -340,7 +340,7 @@ again:
340 if (freezing(current)) { 340 if (freezing(current)) {
341 worker->working = 0; 341 worker->working = 0;
342 spin_unlock_irq(&worker->lock); 342 spin_unlock_irq(&worker->lock);
343 refrigerator(); 343 try_to_freeze();
344 } else { 344 } else {
345 spin_unlock_irq(&worker->lock); 345 spin_unlock_irq(&worker->lock);
346 if (!kthread_should_stop()) { 346 if (!kthread_should_stop()) {
@@ -405,7 +405,7 @@ again:
405/* 405/*
406 * this will wait for all the worker threads to shutdown 406 * this will wait for all the worker threads to shutdown
407 */ 407 */
408int btrfs_stop_workers(struct btrfs_workers *workers) 408void btrfs_stop_workers(struct btrfs_workers *workers)
409{ 409{
410 struct list_head *cur; 410 struct list_head *cur;
411 struct btrfs_worker_thread *worker; 411 struct btrfs_worker_thread *worker;
@@ -433,7 +433,6 @@ int btrfs_stop_workers(struct btrfs_workers *workers)
433 put_worker(worker); 433 put_worker(worker);
434 } 434 }
435 spin_unlock_irq(&workers->lock); 435 spin_unlock_irq(&workers->lock);
436 return 0;
437} 436}
438 437
439/* 438/*
@@ -462,56 +461,55 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
462 * starts new worker threads. This does not enforce the max worker 461 * starts new worker threads. This does not enforce the max worker
463 * count in case you need to temporarily go past it. 462 * count in case you need to temporarily go past it.
464 */ 463 */
465static int __btrfs_start_workers(struct btrfs_workers *workers, 464static int __btrfs_start_workers(struct btrfs_workers *workers)
466 int num_workers)
467{ 465{
468 struct btrfs_worker_thread *worker; 466 struct btrfs_worker_thread *worker;
469 int ret = 0; 467 int ret = 0;
470 int i;
471 468
472 for (i = 0; i < num_workers; i++) { 469 worker = kzalloc(sizeof(*worker), GFP_NOFS);
473 worker = kzalloc(sizeof(*worker), GFP_NOFS); 470 if (!worker) {
474 if (!worker) { 471 ret = -ENOMEM;
475 ret = -ENOMEM; 472 goto fail;
476 goto fail; 473 }
477 }
478 474
479 INIT_LIST_HEAD(&worker->pending); 475 INIT_LIST_HEAD(&worker->pending);
480 INIT_LIST_HEAD(&worker->prio_pending); 476 INIT_LIST_HEAD(&worker->prio_pending);
481 INIT_LIST_HEAD(&worker->worker_list); 477 INIT_LIST_HEAD(&worker->worker_list);
482 spin_lock_init(&worker->lock); 478 spin_lock_init(&worker->lock);
483 479
484 atomic_set(&worker->num_pending, 0); 480 atomic_set(&worker->num_pending, 0);
485 atomic_set(&worker->refs, 1); 481 atomic_set(&worker->refs, 1);
486 worker->workers = workers; 482 worker->workers = workers;
487 worker->task = kthread_run(worker_loop, worker, 483 worker->task = kthread_run(worker_loop, worker,
488 "btrfs-%s-%d", workers->name, 484 "btrfs-%s-%d", workers->name,
489 workers->num_workers + i); 485 workers->num_workers + 1);
490 if (IS_ERR(worker->task)) { 486 if (IS_ERR(worker->task)) {
491 ret = PTR_ERR(worker->task); 487 ret = PTR_ERR(worker->task);
492 kfree(worker); 488 kfree(worker);
493 goto fail; 489 goto fail;
494 }
495 spin_lock_irq(&workers->lock);
496 list_add_tail(&worker->worker_list, &workers->idle_list);
497 worker->idle = 1;
498 workers->num_workers++;
499 workers->num_workers_starting--;
500 WARN_ON(workers->num_workers_starting < 0);
501 spin_unlock_irq(&workers->lock);
502 } 490 }
491 spin_lock_irq(&workers->lock);
492 list_add_tail(&worker->worker_list, &workers->idle_list);
493 worker->idle = 1;
494 workers->num_workers++;
495 workers->num_workers_starting--;
496 WARN_ON(workers->num_workers_starting < 0);
497 spin_unlock_irq(&workers->lock);
498
503 return 0; 499 return 0;
504fail: 500fail:
505 btrfs_stop_workers(workers); 501 spin_lock_irq(&workers->lock);
502 workers->num_workers_starting--;
503 spin_unlock_irq(&workers->lock);
506 return ret; 504 return ret;
507} 505}
508 506
509int btrfs_start_workers(struct btrfs_workers *workers, int num_workers) 507int btrfs_start_workers(struct btrfs_workers *workers)
510{ 508{
511 spin_lock_irq(&workers->lock); 509 spin_lock_irq(&workers->lock);
512 workers->num_workers_starting += num_workers; 510 workers->num_workers_starting++;
513 spin_unlock_irq(&workers->lock); 511 spin_unlock_irq(&workers->lock);
514 return __btrfs_start_workers(workers, num_workers); 512 return __btrfs_start_workers(workers);
515} 513}
516 514
517/* 515/*
@@ -568,9 +566,10 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers)
568 struct btrfs_worker_thread *worker; 566 struct btrfs_worker_thread *worker;
569 unsigned long flags; 567 unsigned long flags;
570 struct list_head *fallback; 568 struct list_head *fallback;
569 int ret;
571 570
572again:
573 spin_lock_irqsave(&workers->lock, flags); 571 spin_lock_irqsave(&workers->lock, flags);
572again:
574 worker = next_worker(workers); 573 worker = next_worker(workers);
575 574
576 if (!worker) { 575 if (!worker) {
@@ -584,7 +583,10 @@ again:
584 workers->num_workers_starting++; 583 workers->num_workers_starting++;
585 spin_unlock_irqrestore(&workers->lock, flags); 584 spin_unlock_irqrestore(&workers->lock, flags);
586 /* we're below the limit, start another worker */ 585 /* we're below the limit, start another worker */
587 __btrfs_start_workers(workers, 1); 586 ret = __btrfs_start_workers(workers);
587 spin_lock_irqsave(&workers->lock, flags);
588 if (ret)
589 goto fallback;
588 goto again; 590 goto again;
589 } 591 }
590 } 592 }
@@ -618,14 +620,14 @@ found:
618 * it was taken from. It is intended for use with long running work functions 620 * it was taken from. It is intended for use with long running work functions
619 * that make some progress and want to give the cpu up for others. 621 * that make some progress and want to give the cpu up for others.
620 */ 622 */
621int btrfs_requeue_work(struct btrfs_work *work) 623void btrfs_requeue_work(struct btrfs_work *work)
622{ 624{
623 struct btrfs_worker_thread *worker = work->worker; 625 struct btrfs_worker_thread *worker = work->worker;
624 unsigned long flags; 626 unsigned long flags;
625 int wake = 0; 627 int wake = 0;
626 628
627 if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) 629 if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
628 goto out; 630 return;
629 631
630 spin_lock_irqsave(&worker->lock, flags); 632 spin_lock_irqsave(&worker->lock, flags);
631 if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags)) 633 if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags))
@@ -652,9 +654,6 @@ int btrfs_requeue_work(struct btrfs_work *work)
652 if (wake) 654 if (wake)
653 wake_up_process(worker->task); 655 wake_up_process(worker->task);
654 spin_unlock_irqrestore(&worker->lock, flags); 656 spin_unlock_irqrestore(&worker->lock, flags);
655out:
656
657 return 0;
658} 657}
659 658
660void btrfs_set_work_high_prio(struct btrfs_work *work) 659void btrfs_set_work_high_prio(struct btrfs_work *work)
@@ -665,7 +664,7 @@ void btrfs_set_work_high_prio(struct btrfs_work *work)
665/* 664/*
666 * places a struct btrfs_work into the pending queue of one of the kthreads 665 * places a struct btrfs_work into the pending queue of one of the kthreads
667 */ 666 */
668int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) 667void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
669{ 668{
670 struct btrfs_worker_thread *worker; 669 struct btrfs_worker_thread *worker;
671 unsigned long flags; 670 unsigned long flags;
@@ -673,7 +672,7 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
673 672
674 /* don't requeue something already on a list */ 673 /* don't requeue something already on a list */
675 if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) 674 if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
676 goto out; 675 return;
677 676
678 worker = find_worker(workers); 677 worker = find_worker(workers);
679 if (workers->ordered) { 678 if (workers->ordered) {
@@ -712,7 +711,4 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
712 if (wake) 711 if (wake)
713 wake_up_process(worker->task); 712 wake_up_process(worker->task);
714 spin_unlock_irqrestore(&worker->lock, flags); 713 spin_unlock_irqrestore(&worker->lock, flags);
715
716out:
717 return 0;
718} 714}