summaryrefslogtreecommitdiffstats
path: root/include/linux/blk-mq.h
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2014-04-15 15:59:10 -0400
committerJens Axboe <axboe@fb.com>2014-04-15 16:03:03 -0400
commite9b267d91f6ddbc694cb40aa962b0b2cec03971d (patch)
tree6b9fac74ad40dfc7b57f701a8ae0454c42a71554 /include/linux/blk-mq.h
parent8727af4b9d45c7503042e3fbd926c1a173876e9c (diff)
blk-mq: add ->init_request and ->exit_request methods
The current blk_mq_init_commands/blk_mq_free_commands interface has a two problems: 1) Because only the constructor is passed to blk_mq_init_commands there is no easy way to clean up when a comman initialization failed. The current code simply leaks the allocations done in the constructor. 2) There is no good place to call blk_mq_free_commands: before blk_cleanup_queue there is no guarantee that all outstanding commands have completed, so we can't free them yet. After blk_cleanup_queue the queue has usually been freed. This can be worked around by grabbing an unconditional reference before calling blk_cleanup_queue and dropping it after blk_mq_free_commands is done, although that's not exatly pretty and driver writers are guaranteed to get it wrong sooner or later. Both issues are easily fixed by making the request constructor and destructor normal blk_mq_ops methods. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'include/linux/blk-mq.h')
-rw-r--r--include/linux/blk-mq.h14
1 files changed, 12 insertions, 2 deletions
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index b6ee48740458..29c1a6e83814 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -67,6 +67,10 @@ typedef struct blk_mq_hw_ctx *(alloc_hctx_fn)(struct blk_mq_reg *,unsigned int);
67typedef void (free_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int); 67typedef void (free_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int);
68typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int); 68typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int);
69typedef void (exit_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int); 69typedef void (exit_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int);
70typedef int (init_request_fn)(void *, struct blk_mq_hw_ctx *,
71 struct request *, unsigned int);
72typedef void (exit_request_fn)(void *, struct blk_mq_hw_ctx *,
73 struct request *, unsigned int);
70 74
71struct blk_mq_ops { 75struct blk_mq_ops {
72 /* 76 /*
@@ -99,6 +103,14 @@ struct blk_mq_ops {
99 */ 103 */
100 init_hctx_fn *init_hctx; 104 init_hctx_fn *init_hctx;
101 exit_hctx_fn *exit_hctx; 105 exit_hctx_fn *exit_hctx;
106
107 /*
108 * Called for every command allocated by the block layer to allow
109 * the driver to set up driver specific data.
110 * Ditto for exit/teardown.
111 */
112 init_request_fn *init_request;
113 exit_request_fn *exit_request;
102}; 114};
103 115
104enum { 116enum {
@@ -118,8 +130,6 @@ enum {
118struct request_queue *blk_mq_init_queue(struct blk_mq_reg *, void *); 130struct request_queue *blk_mq_init_queue(struct blk_mq_reg *, void *);
119int blk_mq_register_disk(struct gendisk *); 131int blk_mq_register_disk(struct gendisk *);
120void blk_mq_unregister_disk(struct gendisk *); 132void blk_mq_unregister_disk(struct gendisk *);
121int blk_mq_init_commands(struct request_queue *, int (*init)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data);
122void blk_mq_free_commands(struct request_queue *, void (*free)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data);
123 133
124void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule); 134void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule);
125 135