diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 20:23:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 20:23:49 -0500 |
commit | 3419b45039c6b799c974a8019361c045e7ca232c (patch) | |
tree | 36a63602036cc50f34fadcbd5d5d8fca94e44297 /include | |
parent | 01504f5e9e071f1dde1062e3be15f54d4555308f (diff) | |
parent | c1c534609fe8a859f9c8108a5591e6e8a97e34d1 (diff) |
Merge branch 'for-4.4/io-poll' of git://git.kernel.dk/linux-block
Pull block IO poll support from Jens Axboe:
"Various groups have been doing experimentation around IO polling for
(really) fast devices. The code has been reviewed and has been
sitting on the side for a few releases, but this is now good enough
for coordinated benchmarking and further experimentation.
Currently O_DIRECT sync read/write are supported. A framework is in
the works that allows scalable stats tracking so we can auto-tune
this. And we'll add libaio support as well soon. Fow now, it's an
opt-in feature for test purposes"
* 'for-4.4/io-poll' of git://git.kernel.dk/linux-block:
direct-io: be sure to assign dio->bio_bdev for both paths
directio: add block polling support
NVMe: add blk polling support
block: add block polling support
blk-mq: return tag/queue combo in the make_request_fn handlers
block: change ->make_request_fn() and users to return a queue cookie
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/blk-mq.h | 10 | ||||
-rw-r--r-- | include/linux/blk_types.h | 24 | ||||
-rw-r--r-- | include/linux/blkdev.h | 7 | ||||
-rw-r--r-- | include/linux/fs.h | 2 | ||||
-rw-r--r-- | include/linux/lightnvm.h | 2 |
5 files changed, 41 insertions, 4 deletions
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 83cc9d4e5455..daf17d70aeca 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
@@ -59,6 +59,9 @@ struct blk_mq_hw_ctx { | |||
59 | 59 | ||
60 | struct blk_mq_cpu_notifier cpu_notifier; | 60 | struct blk_mq_cpu_notifier cpu_notifier; |
61 | struct kobject kobj; | 61 | struct kobject kobj; |
62 | |||
63 | unsigned long poll_invoked; | ||
64 | unsigned long poll_success; | ||
62 | }; | 65 | }; |
63 | 66 | ||
64 | struct blk_mq_tag_set { | 67 | struct blk_mq_tag_set { |
@@ -97,6 +100,8 @@ typedef void (exit_request_fn)(void *, struct request *, unsigned int, | |||
97 | typedef void (busy_iter_fn)(struct blk_mq_hw_ctx *, struct request *, void *, | 100 | typedef void (busy_iter_fn)(struct blk_mq_hw_ctx *, struct request *, void *, |
98 | bool); | 101 | bool); |
99 | typedef void (busy_tag_iter_fn)(struct request *, void *, bool); | 102 | typedef void (busy_tag_iter_fn)(struct request *, void *, bool); |
103 | typedef int (poll_fn)(struct blk_mq_hw_ctx *, unsigned int); | ||
104 | |||
100 | 105 | ||
101 | struct blk_mq_ops { | 106 | struct blk_mq_ops { |
102 | /* | 107 | /* |
@@ -114,6 +119,11 @@ struct blk_mq_ops { | |||
114 | */ | 119 | */ |
115 | timeout_fn *timeout; | 120 | timeout_fn *timeout; |
116 | 121 | ||
122 | /* | ||
123 | * Called to poll for completion of a specific tag. | ||
124 | */ | ||
125 | poll_fn *poll; | ||
126 | |||
117 | softirq_done_fn *complete; | 127 | softirq_done_fn *complete; |
118 | 128 | ||
119 | /* | 129 | /* |
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index e8130138f29d..641e5a3ed58c 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h | |||
@@ -244,4 +244,28 @@ enum rq_flag_bits { | |||
244 | #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT) | 244 | #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT) |
245 | #define REQ_NO_TIMEOUT (1ULL << __REQ_NO_TIMEOUT) | 245 | #define REQ_NO_TIMEOUT (1ULL << __REQ_NO_TIMEOUT) |
246 | 246 | ||
247 | typedef unsigned int blk_qc_t; | ||
248 | #define BLK_QC_T_NONE -1U | ||
249 | #define BLK_QC_T_SHIFT 16 | ||
250 | |||
251 | static inline bool blk_qc_t_valid(blk_qc_t cookie) | ||
252 | { | ||
253 | return cookie != BLK_QC_T_NONE; | ||
254 | } | ||
255 | |||
256 | static inline blk_qc_t blk_tag_to_qc_t(unsigned int tag, unsigned int queue_num) | ||
257 | { | ||
258 | return tag | (queue_num << BLK_QC_T_SHIFT); | ||
259 | } | ||
260 | |||
261 | static inline unsigned int blk_qc_t_to_queue_num(blk_qc_t cookie) | ||
262 | { | ||
263 | return cookie >> BLK_QC_T_SHIFT; | ||
264 | } | ||
265 | |||
266 | static inline unsigned int blk_qc_t_to_tag(blk_qc_t cookie) | ||
267 | { | ||
268 | return cookie & 0xffff; | ||
269 | } | ||
270 | |||
247 | #endif /* __LINUX_BLK_TYPES_H */ | 271 | #endif /* __LINUX_BLK_TYPES_H */ |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d045ca8487af..3fe27f8d91f0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -209,7 +209,7 @@ static inline unsigned short req_get_ioprio(struct request *req) | |||
209 | struct blk_queue_ctx; | 209 | struct blk_queue_ctx; |
210 | 210 | ||
211 | typedef void (request_fn_proc) (struct request_queue *q); | 211 | typedef void (request_fn_proc) (struct request_queue *q); |
212 | typedef void (make_request_fn) (struct request_queue *q, struct bio *bio); | 212 | typedef blk_qc_t (make_request_fn) (struct request_queue *q, struct bio *bio); |
213 | typedef int (prep_rq_fn) (struct request_queue *, struct request *); | 213 | typedef int (prep_rq_fn) (struct request_queue *, struct request *); |
214 | typedef void (unprep_rq_fn) (struct request_queue *, struct request *); | 214 | typedef void (unprep_rq_fn) (struct request_queue *, struct request *); |
215 | 215 | ||
@@ -487,6 +487,7 @@ struct request_queue { | |||
487 | #define QUEUE_FLAG_DEAD 19 /* queue tear-down finished */ | 487 | #define QUEUE_FLAG_DEAD 19 /* queue tear-down finished */ |
488 | #define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ | 488 | #define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ |
489 | #define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ | 489 | #define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ |
490 | #define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */ | ||
490 | 491 | ||
491 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 492 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
492 | (1 << QUEUE_FLAG_STACKABLE) | \ | 493 | (1 << QUEUE_FLAG_STACKABLE) | \ |
@@ -761,7 +762,7 @@ static inline void rq_flush_dcache_pages(struct request *rq) | |||
761 | 762 | ||
762 | extern int blk_register_queue(struct gendisk *disk); | 763 | extern int blk_register_queue(struct gendisk *disk); |
763 | extern void blk_unregister_queue(struct gendisk *disk); | 764 | extern void blk_unregister_queue(struct gendisk *disk); |
764 | extern void generic_make_request(struct bio *bio); | 765 | extern blk_qc_t generic_make_request(struct bio *bio); |
765 | extern void blk_rq_init(struct request_queue *q, struct request *rq); | 766 | extern void blk_rq_init(struct request_queue *q, struct request *rq); |
766 | extern void blk_put_request(struct request *); | 767 | extern void blk_put_request(struct request *); |
767 | extern void __blk_put_request(struct request_queue *, struct request *); | 768 | extern void __blk_put_request(struct request_queue *, struct request *); |
@@ -814,6 +815,8 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *, | |||
814 | extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, | 815 | extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, |
815 | struct request *, int, rq_end_io_fn *); | 816 | struct request *, int, rq_end_io_fn *); |
816 | 817 | ||
818 | bool blk_poll(struct request_queue *q, blk_qc_t cookie); | ||
819 | |||
817 | static inline struct request_queue *bdev_get_queue(struct block_device *bdev) | 820 | static inline struct request_queue *bdev_get_queue(struct block_device *bdev) |
818 | { | 821 | { |
819 | return bdev->bd_disk->queue; /* this is never NULL */ | 822 | return bdev->bd_disk->queue; /* this is never NULL */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 9a1cb8c605e0..6230eb2a9cca 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2613,7 +2613,7 @@ static inline void remove_inode_hash(struct inode *inode) | |||
2613 | extern void inode_sb_list_add(struct inode *inode); | 2613 | extern void inode_sb_list_add(struct inode *inode); |
2614 | 2614 | ||
2615 | #ifdef CONFIG_BLOCK | 2615 | #ifdef CONFIG_BLOCK |
2616 | extern void submit_bio(int, struct bio *); | 2616 | extern blk_qc_t submit_bio(int, struct bio *); |
2617 | extern int bdev_read_only(struct block_device *); | 2617 | extern int bdev_read_only(struct block_device *); |
2618 | #endif | 2618 | #endif |
2619 | extern int set_blocksize(struct block_device *, int); | 2619 | extern int set_blocksize(struct block_device *, int); |
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index 5ebd70d12f35..69c9057e1ab8 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h | |||
@@ -426,7 +426,7 @@ static inline struct ppa_addr block_to_ppa(struct nvm_dev *dev, | |||
426 | return ppa; | 426 | return ppa; |
427 | } | 427 | } |
428 | 428 | ||
429 | typedef void (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *); | 429 | typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *); |
430 | typedef sector_t (nvm_tgt_capacity_fn)(void *); | 430 | typedef sector_t (nvm_tgt_capacity_fn)(void *); |
431 | typedef int (nvm_tgt_end_io_fn)(struct nvm_rq *, int); | 431 | typedef int (nvm_tgt_end_io_fn)(struct nvm_rq *, int); |
432 | typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int); | 432 | typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int); |