aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-mq-sched.c14
-rw-r--r--block/blk-mq.c17
-rw-r--r--block/blk-mq.h5
-rw-r--r--drivers/scsi/scsi_lib.c11
-rw-r--r--include/linux/blk-mq.h2
5 files changed, 12 insertions, 37 deletions
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 7775f6b12fa9..13a27d4d1671 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -94,23 +94,18 @@ static void blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx)
94 94
95 do { 95 do {
96 struct request *rq; 96 struct request *rq;
97 blk_status_t ret;
98 97
99 if (e->type->ops.mq.has_work && 98 if (e->type->ops.mq.has_work &&
100 !e->type->ops.mq.has_work(hctx)) 99 !e->type->ops.mq.has_work(hctx))
101 break; 100 break;
102 101
103 ret = blk_mq_get_dispatch_budget(hctx); 102 if (!blk_mq_get_dispatch_budget(hctx))
104 if (ret == BLK_STS_RESOURCE)
105 break; 103 break;
106 104
107 rq = e->type->ops.mq.dispatch_request(hctx); 105 rq = e->type->ops.mq.dispatch_request(hctx);
108 if (!rq) { 106 if (!rq) {
109 blk_mq_put_dispatch_budget(hctx); 107 blk_mq_put_dispatch_budget(hctx);
110 break; 108 break;
111 } else if (ret != BLK_STS_OK) {
112 blk_mq_end_request(rq, ret);
113 continue;
114 } 109 }
115 110
116 /* 111 /*
@@ -146,22 +141,17 @@ static void blk_mq_do_dispatch_ctx(struct blk_mq_hw_ctx *hctx)
146 141
147 do { 142 do {
148 struct request *rq; 143 struct request *rq;
149 blk_status_t ret;
150 144
151 if (!sbitmap_any_bit_set(&hctx->ctx_map)) 145 if (!sbitmap_any_bit_set(&hctx->ctx_map))
152 break; 146 break;
153 147
154 ret = blk_mq_get_dispatch_budget(hctx); 148 if (!blk_mq_get_dispatch_budget(hctx))
155 if (ret == BLK_STS_RESOURCE)
156 break; 149 break;
157 150
158 rq = blk_mq_dequeue_from_ctx(hctx, ctx); 151 rq = blk_mq_dequeue_from_ctx(hctx, ctx);
159 if (!rq) { 152 if (!rq) {
160 blk_mq_put_dispatch_budget(hctx); 153 blk_mq_put_dispatch_budget(hctx);
161 break; 154 break;
162 } else if (ret != BLK_STS_OK) {
163 blk_mq_end_request(rq, ret);
164 continue;
165 } 155 }
166 156
167 /* 157 /*
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 13cdccef543c..c9fa4b294664 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1137,13 +1137,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1137 } 1137 }
1138 } 1138 }
1139 1139
1140 if (!got_budget) { 1140 if (!got_budget && !blk_mq_get_dispatch_budget(hctx))
1141 ret = blk_mq_get_dispatch_budget(hctx); 1141 break;
1142 if (ret == BLK_STS_RESOURCE)
1143 break;
1144 if (ret != BLK_STS_OK)
1145 goto fail_rq;
1146 }
1147 1142
1148 list_del_init(&rq->queuelist); 1143 list_del_init(&rq->queuelist);
1149 1144
@@ -1170,7 +1165,6 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1170 break; 1165 break;
1171 } 1166 }
1172 1167
1173 fail_rq:
1174 if (unlikely(ret != BLK_STS_OK)) { 1168 if (unlikely(ret != BLK_STS_OK)) {
1175 errors++; 1169 errors++;
1176 blk_mq_end_request(rq, BLK_STS_IOERR); 1170 blk_mq_end_request(rq, BLK_STS_IOERR);
@@ -1642,12 +1636,10 @@ static void __blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
1642 if (!blk_mq_get_driver_tag(rq, NULL, false)) 1636 if (!blk_mq_get_driver_tag(rq, NULL, false))
1643 goto insert; 1637 goto insert;
1644 1638
1645 ret = blk_mq_get_dispatch_budget(hctx); 1639 if (!blk_mq_get_dispatch_budget(hctx)) {
1646 if (ret == BLK_STS_RESOURCE) {
1647 blk_mq_put_driver_tag(rq); 1640 blk_mq_put_driver_tag(rq);
1648 goto insert; 1641 goto insert;
1649 } else if (ret != BLK_STS_OK) 1642 }
1650 goto fail_rq;
1651 1643
1652 new_cookie = request_to_qc_t(hctx, rq); 1644 new_cookie = request_to_qc_t(hctx, rq);
1653 1645
@@ -1665,7 +1657,6 @@ static void __blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
1665 __blk_mq_requeue_request(rq); 1657 __blk_mq_requeue_request(rq);
1666 goto insert; 1658 goto insert;
1667 default: 1659 default:
1668 fail_rq:
1669 *cookie = BLK_QC_T_NONE; 1660 *cookie = BLK_QC_T_NONE;
1670 blk_mq_end_request(rq, ret); 1661 blk_mq_end_request(rq, ret);
1671 return; 1662 return;
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 522b420dedc0..f97aceff76e9 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -147,14 +147,13 @@ static inline void blk_mq_put_dispatch_budget(struct blk_mq_hw_ctx *hctx)
147 q->mq_ops->put_budget(hctx); 147 q->mq_ops->put_budget(hctx);
148} 148}
149 149
150static inline blk_status_t blk_mq_get_dispatch_budget( 150static inline bool blk_mq_get_dispatch_budget(struct blk_mq_hw_ctx *hctx)
151 struct blk_mq_hw_ctx *hctx)
152{ 151{
153 struct request_queue *q = hctx->queue; 152 struct request_queue *q = hctx->queue;
154 153
155 if (q->mq_ops->get_budget) 154 if (q->mq_ops->get_budget)
156 return q->mq_ops->get_budget(hctx); 155 return q->mq_ops->get_budget(hctx);
157 return BLK_STS_OK; 156 return true;
158} 157}
159 158
160#endif 159#endif
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 22a7e4c47207..286ea983c9e3 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1955,27 +1955,22 @@ static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx)
1955 put_device(&sdev->sdev_gendev); 1955 put_device(&sdev->sdev_gendev);
1956} 1956}
1957 1957
1958static blk_status_t scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) 1958static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx)
1959{ 1959{
1960 struct request_queue *q = hctx->queue; 1960 struct request_queue *q = hctx->queue;
1961 struct scsi_device *sdev = q->queuedata; 1961 struct scsi_device *sdev = q->queuedata;
1962 blk_status_t ret;
1963
1964 ret = prep_to_mq(scsi_prep_state_check(sdev, NULL));
1965 if (ret == BLK_STS_RESOURCE || ret != BLK_STS_OK)
1966 return ret;
1967 1962
1968 if (!get_device(&sdev->sdev_gendev)) 1963 if (!get_device(&sdev->sdev_gendev))
1969 goto out; 1964 goto out;
1970 if (!scsi_dev_queue_ready(q, sdev)) 1965 if (!scsi_dev_queue_ready(q, sdev))
1971 goto out_put_device; 1966 goto out_put_device;
1972 1967
1973 return BLK_STS_OK; 1968 return true;
1974 1969
1975out_put_device: 1970out_put_device:
1976 put_device(&sdev->sdev_gendev); 1971 put_device(&sdev->sdev_gendev);
1977out: 1972out:
1978 return BLK_STS_RESOURCE; 1973 return false;
1979} 1974}
1980 1975
1981static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, 1976static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index f2e3079eecdd..674641527da7 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -92,7 +92,7 @@ struct blk_mq_queue_data {
92 92
93typedef blk_status_t (queue_rq_fn)(struct blk_mq_hw_ctx *, 93typedef blk_status_t (queue_rq_fn)(struct blk_mq_hw_ctx *,
94 const struct blk_mq_queue_data *); 94 const struct blk_mq_queue_data *);
95typedef blk_status_t (get_budget_fn)(struct blk_mq_hw_ctx *); 95typedef bool (get_budget_fn)(struct blk_mq_hw_ctx *);
96typedef void (put_budget_fn)(struct blk_mq_hw_ctx *); 96typedef void (put_budget_fn)(struct blk_mq_hw_ctx *);
97typedef enum blk_eh_timer_return (timeout_fn)(struct request *, bool); 97typedef enum blk_eh_timer_return (timeout_fn)(struct request *, bool);
98typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int); 98typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int);