diff options
| -rw-r--r-- | block/blk-mq.c | 52 | ||||
| -rw-r--r-- | drivers/block/virtio_blk.c | 3 | ||||
| -rw-r--r-- | include/linux/blk-mq.h | 3 |
3 files changed, 49 insertions, 9 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 01d8735db8d3..92284af4e0df 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -1058,8 +1058,46 @@ static void blk_mq_hctx_notify(void *data, unsigned long action, | |||
| 1058 | blk_mq_put_ctx(ctx); | 1058 | blk_mq_put_ctx(ctx); |
| 1059 | } | 1059 | } |
| 1060 | 1060 | ||
| 1061 | static void blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx, | 1061 | static int blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx, |
| 1062 | void (*init)(void *, struct blk_mq_hw_ctx *, | 1062 | int (*init)(void *, struct blk_mq_hw_ctx *, |
| 1063 | struct request *, unsigned int), | ||
| 1064 | void *data) | ||
| 1065 | { | ||
| 1066 | unsigned int i; | ||
| 1067 | int ret = 0; | ||
| 1068 | |||
| 1069 | for (i = 0; i < hctx->queue_depth; i++) { | ||
| 1070 | struct request *rq = hctx->rqs[i]; | ||
| 1071 | |||
| 1072 | ret = init(data, hctx, rq, i); | ||
| 1073 | if (ret) | ||
| 1074 | break; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | return ret; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | int blk_mq_init_commands(struct request_queue *q, | ||
| 1081 | int (*init)(void *, struct blk_mq_hw_ctx *, | ||
| 1082 | struct request *, unsigned int), | ||
| 1083 | void *data) | ||
| 1084 | { | ||
| 1085 | struct blk_mq_hw_ctx *hctx; | ||
| 1086 | unsigned int i; | ||
| 1087 | int ret = 0; | ||
| 1088 | |||
| 1089 | queue_for_each_hw_ctx(q, hctx, i) { | ||
| 1090 | ret = blk_mq_init_hw_commands(hctx, init, data); | ||
| 1091 | if (ret) | ||
| 1092 | break; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | return ret; | ||
| 1096 | } | ||
| 1097 | EXPORT_SYMBOL(blk_mq_init_commands); | ||
| 1098 | |||
| 1099 | static void blk_mq_free_hw_commands(struct blk_mq_hw_ctx *hctx, | ||
| 1100 | void (*free)(void *, struct blk_mq_hw_ctx *, | ||
| 1063 | struct request *, unsigned int), | 1101 | struct request *, unsigned int), |
| 1064 | void *data) | 1102 | void *data) |
| 1065 | { | 1103 | { |
| @@ -1068,12 +1106,12 @@ static void blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx, | |||
| 1068 | for (i = 0; i < hctx->queue_depth; i++) { | 1106 | for (i = 0; i < hctx->queue_depth; i++) { |
| 1069 | struct request *rq = hctx->rqs[i]; | 1107 | struct request *rq = hctx->rqs[i]; |
| 1070 | 1108 | ||
| 1071 | init(data, hctx, rq, i); | 1109 | free(data, hctx, rq, i); |
| 1072 | } | 1110 | } |
| 1073 | } | 1111 | } |
| 1074 | 1112 | ||
| 1075 | void blk_mq_init_commands(struct request_queue *q, | 1113 | void blk_mq_free_commands(struct request_queue *q, |
| 1076 | void (*init)(void *, struct blk_mq_hw_ctx *, | 1114 | void (*free)(void *, struct blk_mq_hw_ctx *, |
| 1077 | struct request *, unsigned int), | 1115 | struct request *, unsigned int), |
| 1078 | void *data) | 1116 | void *data) |
| 1079 | { | 1117 | { |
| @@ -1081,9 +1119,9 @@ void blk_mq_init_commands(struct request_queue *q, | |||
| 1081 | unsigned int i; | 1119 | unsigned int i; |
| 1082 | 1120 | ||
| 1083 | queue_for_each_hw_ctx(q, hctx, i) | 1121 | queue_for_each_hw_ctx(q, hctx, i) |
| 1084 | blk_mq_init_hw_commands(hctx, init, data); | 1122 | blk_mq_free_hw_commands(hctx, free, data); |
| 1085 | } | 1123 | } |
| 1086 | EXPORT_SYMBOL(blk_mq_init_commands); | 1124 | EXPORT_SYMBOL(blk_mq_free_commands); |
| 1087 | 1125 | ||
| 1088 | static void blk_mq_free_rq_map(struct blk_mq_hw_ctx *hctx) | 1126 | static void blk_mq_free_rq_map(struct blk_mq_hw_ctx *hctx) |
| 1089 | { | 1127 | { |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index b1cb3f4c4db4..0eace43cea11 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -490,13 +490,14 @@ static struct blk_mq_reg virtio_mq_reg = { | |||
| 490 | .flags = BLK_MQ_F_SHOULD_MERGE, | 490 | .flags = BLK_MQ_F_SHOULD_MERGE, |
| 491 | }; | 491 | }; |
| 492 | 492 | ||
| 493 | static void virtblk_init_vbr(void *data, struct blk_mq_hw_ctx *hctx, | 493 | static int virtblk_init_vbr(void *data, struct blk_mq_hw_ctx *hctx, |
| 494 | struct request *rq, unsigned int nr) | 494 | struct request *rq, unsigned int nr) |
| 495 | { | 495 | { |
| 496 | struct virtio_blk *vblk = data; | 496 | struct virtio_blk *vblk = data; |
| 497 | struct virtblk_req *vbr = rq->special; | 497 | struct virtblk_req *vbr = rq->special; |
| 498 | 498 | ||
| 499 | sg_init_table(vbr->sg, vblk->sg_elems); | 499 | sg_init_table(vbr->sg, vblk->sg_elems); |
| 500 | return 0; | ||
| 500 | } | 501 | } |
| 501 | 502 | ||
| 502 | static int virtblk_probe(struct virtio_device *vdev) | 503 | static int virtblk_probe(struct virtio_device *vdev) |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 18ba8a627f46..33ff10ebcabb 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
| @@ -117,7 +117,8 @@ enum { | |||
| 117 | struct request_queue *blk_mq_init_queue(struct blk_mq_reg *, void *); | 117 | struct request_queue *blk_mq_init_queue(struct blk_mq_reg *, void *); |
| 118 | int blk_mq_register_disk(struct gendisk *); | 118 | int blk_mq_register_disk(struct gendisk *); |
| 119 | void blk_mq_unregister_disk(struct gendisk *); | 119 | void blk_mq_unregister_disk(struct gendisk *); |
| 120 | void blk_mq_init_commands(struct request_queue *, void (*init)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data); | 120 | int blk_mq_init_commands(struct request_queue *, int (*init)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data); |
| 121 | void blk_mq_free_commands(struct request_queue *, void (*free)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data); | ||
| 121 | 122 | ||
| 122 | void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule); | 123 | void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule); |
| 123 | 124 | ||
