diff options
author | Jens Axboe <axboe@kernel.dk> | 2018-12-20 10:49:00 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-12-20 14:17:05 -0500 |
commit | 9f6b7ef6c3ebe35be77b0ae3cf12e4d25ae80420 (patch) | |
tree | dd94ebc8b17053087b9a459beebdd4ed18ad326d /lib/sbitmap.c | |
parent | 3a762de55b4ede47a5369f57d0f92979738be638 (diff) |
sbitmap: add helpers for add/del wait queue handling
After commit 5d2ee7122c73, users of sbitmap that need wait queue
handling must use the provided helpers. But we only added
prepare_to_wait()/finish_wait() style helpers, add the equivalent
add_wait_queue/list_del wrappers as we..
This is needed to ensure kyber plays by the sbitmap waitqueue
rules.
Tested-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'lib/sbitmap.c')
-rw-r--r-- | lib/sbitmap.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/lib/sbitmap.c b/lib/sbitmap.c index 5b3e56d68dab..65c2d06250a6 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c | |||
@@ -671,13 +671,35 @@ void sbitmap_queue_show(struct sbitmap_queue *sbq, struct seq_file *m) | |||
671 | } | 671 | } |
672 | EXPORT_SYMBOL_GPL(sbitmap_queue_show); | 672 | EXPORT_SYMBOL_GPL(sbitmap_queue_show); |
673 | 673 | ||
674 | void sbitmap_add_wait_queue(struct sbitmap_queue *sbq, | ||
675 | struct sbq_wait_state *ws, | ||
676 | struct sbq_wait *sbq_wait) | ||
677 | { | ||
678 | if (!sbq_wait->sbq) { | ||
679 | sbq_wait->sbq = sbq; | ||
680 | atomic_inc(&sbq->ws_active); | ||
681 | } | ||
682 | add_wait_queue(&ws->wait, &sbq_wait->wait); | ||
683 | } | ||
684 | EXPORT_SYMBOL_GPL(sbitmap_add_wait_queue); | ||
685 | |||
686 | void sbitmap_del_wait_queue(struct sbq_wait *sbq_wait) | ||
687 | { | ||
688 | list_del_init(&sbq_wait->wait.entry); | ||
689 | if (sbq_wait->sbq) { | ||
690 | atomic_dec(&sbq_wait->sbq->ws_active); | ||
691 | sbq_wait->sbq = NULL; | ||
692 | } | ||
693 | } | ||
694 | EXPORT_SYMBOL_GPL(sbitmap_del_wait_queue); | ||
695 | |||
674 | void sbitmap_prepare_to_wait(struct sbitmap_queue *sbq, | 696 | void sbitmap_prepare_to_wait(struct sbitmap_queue *sbq, |
675 | struct sbq_wait_state *ws, | 697 | struct sbq_wait_state *ws, |
676 | struct sbq_wait *sbq_wait, int state) | 698 | struct sbq_wait *sbq_wait, int state) |
677 | { | 699 | { |
678 | if (!sbq_wait->accounted) { | 700 | if (!sbq_wait->sbq) { |
679 | atomic_inc(&sbq->ws_active); | 701 | atomic_inc(&sbq->ws_active); |
680 | sbq_wait->accounted = 1; | 702 | sbq_wait->sbq = sbq; |
681 | } | 703 | } |
682 | prepare_to_wait_exclusive(&ws->wait, &sbq_wait->wait, state); | 704 | prepare_to_wait_exclusive(&ws->wait, &sbq_wait->wait, state); |
683 | } | 705 | } |
@@ -687,9 +709,9 @@ void sbitmap_finish_wait(struct sbitmap_queue *sbq, struct sbq_wait_state *ws, | |||
687 | struct sbq_wait *sbq_wait) | 709 | struct sbq_wait *sbq_wait) |
688 | { | 710 | { |
689 | finish_wait(&ws->wait, &sbq_wait->wait); | 711 | finish_wait(&ws->wait, &sbq_wait->wait); |
690 | if (sbq_wait->accounted) { | 712 | if (sbq_wait->sbq) { |
691 | atomic_dec(&sbq->ws_active); | 713 | atomic_dec(&sbq->ws_active); |
692 | sbq_wait->accounted = 0; | 714 | sbq_wait->sbq = NULL; |
693 | } | 715 | } |
694 | } | 716 | } |
695 | EXPORT_SYMBOL_GPL(sbitmap_finish_wait); | 717 | EXPORT_SYMBOL_GPL(sbitmap_finish_wait); |