diff options
| author | Christoph Hellwig <hch@lst.de> | 2015-05-07 03:38:13 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@fb.com> | 2015-05-19 11:12:59 -0400 |
| commit | 4ecd4fef3a074c8bb43c391a57742c422469ebbd (patch) | |
| tree | 76916ca92a584daf7dd398eff0997e7e82bfa4f9 | |
| parent | 5b3f341f098d60da2970758db6a05bd851eb6b39 (diff) | |
block: use an atomic_t for mq_freeze_depth
lockdep gets unhappy about the not disabling irqs when using the queue_lock
around it. Instead of trying to fix that up just switch to an atomic_t
and get rid of the lock.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
| -rw-r--r-- | block/blk-mq.c | 24 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 2 |
2 files changed, 11 insertions, 15 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 31df47443699..c382a34fe5ac 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -89,7 +89,8 @@ static int blk_mq_queue_enter(struct request_queue *q, gfp_t gfp) | |||
| 89 | return -EBUSY; | 89 | return -EBUSY; |
| 90 | 90 | ||
| 91 | ret = wait_event_interruptible(q->mq_freeze_wq, | 91 | ret = wait_event_interruptible(q->mq_freeze_wq, |
| 92 | !q->mq_freeze_depth || blk_queue_dying(q)); | 92 | !atomic_read(&q->mq_freeze_depth) || |
| 93 | blk_queue_dying(q)); | ||
| 93 | if (blk_queue_dying(q)) | 94 | if (blk_queue_dying(q)) |
| 94 | return -ENODEV; | 95 | return -ENODEV; |
| 95 | if (ret) | 96 | if (ret) |
| @@ -112,13 +113,10 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref) | |||
| 112 | 113 | ||
| 113 | void blk_mq_freeze_queue_start(struct request_queue *q) | 114 | void blk_mq_freeze_queue_start(struct request_queue *q) |
| 114 | { | 115 | { |
| 115 | bool freeze; | 116 | int freeze_depth; |
| 116 | 117 | ||
| 117 | spin_lock_irq(q->queue_lock); | 118 | freeze_depth = atomic_inc_return(&q->mq_freeze_depth); |
| 118 | freeze = !q->mq_freeze_depth++; | 119 | if (freeze_depth == 1) { |
| 119 | spin_unlock_irq(q->queue_lock); | ||
| 120 | |||
| 121 | if (freeze) { | ||
| 122 | percpu_ref_kill(&q->mq_usage_counter); | 120 | percpu_ref_kill(&q->mq_usage_counter); |
| 123 | blk_mq_run_hw_queues(q, false); | 121 | blk_mq_run_hw_queues(q, false); |
| 124 | } | 122 | } |
| @@ -143,13 +141,11 @@ EXPORT_SYMBOL_GPL(blk_mq_freeze_queue); | |||
| 143 | 141 | ||
| 144 | void blk_mq_unfreeze_queue(struct request_queue *q) | 142 | void blk_mq_unfreeze_queue(struct request_queue *q) |
| 145 | { | 143 | { |
| 146 | bool wake; | 144 | int freeze_depth; |
| 147 | 145 | ||
| 148 | spin_lock_irq(q->queue_lock); | 146 | freeze_depth = atomic_dec_return(&q->mq_freeze_depth); |
| 149 | wake = !--q->mq_freeze_depth; | 147 | WARN_ON_ONCE(freeze_depth < 0); |
| 150 | WARN_ON_ONCE(q->mq_freeze_depth < 0); | 148 | if (!freeze_depth) { |
| 151 | spin_unlock_irq(q->queue_lock); | ||
| 152 | if (wake) { | ||
| 153 | percpu_ref_reinit(&q->mq_usage_counter); | 149 | percpu_ref_reinit(&q->mq_usage_counter); |
| 154 | wake_up_all(&q->mq_freeze_wq); | 150 | wake_up_all(&q->mq_freeze_wq); |
| 155 | } | 151 | } |
| @@ -2081,7 +2077,7 @@ void blk_mq_free_queue(struct request_queue *q) | |||
| 2081 | /* Basically redo blk_mq_init_queue with queue frozen */ | 2077 | /* Basically redo blk_mq_init_queue with queue frozen */ |
| 2082 | static void blk_mq_queue_reinit(struct request_queue *q) | 2078 | static void blk_mq_queue_reinit(struct request_queue *q) |
| 2083 | { | 2079 | { |
| 2084 | WARN_ON_ONCE(!q->mq_freeze_depth); | 2080 | WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth)); |
| 2085 | 2081 | ||
| 2086 | blk_mq_sysfs_unregister(q); | 2082 | blk_mq_sysfs_unregister(q); |
| 2087 | 2083 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2da818a48097..bc917956a6d0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -444,7 +444,7 @@ struct request_queue { | |||
| 444 | struct mutex sysfs_lock; | 444 | struct mutex sysfs_lock; |
| 445 | 445 | ||
| 446 | int bypass_depth; | 446 | int bypass_depth; |
| 447 | int mq_freeze_depth; | 447 | atomic_t mq_freeze_depth; |
| 448 | 448 | ||
| 449 | #if defined(CONFIG_BLK_DEV_BSG) | 449 | #if defined(CONFIG_BLK_DEV_BSG) |
| 450 | bsg_job_fn *bsg_job_fn; | 450 | bsg_job_fn *bsg_job_fn; |
