1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef BLK_MQ_SCHED_H |
3 | #define BLK_MQ_SCHED_H |
4 | |
5 | #include "elevator.h" |
6 | #include "blk-mq.h" |
7 | |
8 | #define MAX_SCHED_RQ (16 * BLKDEV_DEFAULT_RQ) |
9 | |
10 | bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio, |
11 | unsigned int nr_segs, struct request **merged_request); |
12 | bool blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio, |
13 | unsigned int nr_segs); |
14 | bool blk_mq_sched_try_insert_merge(struct request_queue *q, struct request *rq, |
15 | struct list_head *free); |
16 | void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx); |
17 | void __blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx); |
18 | |
19 | void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx); |
20 | |
21 | int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e); |
22 | void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e); |
23 | void blk_mq_sched_free_rqs(struct request_queue *q); |
24 | |
25 | static inline void blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx) |
26 | { |
27 | if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) |
28 | __blk_mq_sched_restart(hctx); |
29 | } |
30 | |
31 | static inline bool bio_mergeable(struct bio *bio) |
32 | { |
33 | return !(bio->bi_opf & REQ_NOMERGE_FLAGS); |
34 | } |
35 | |
36 | static inline bool |
37 | blk_mq_sched_allow_merge(struct request_queue *q, struct request *rq, |
38 | struct bio *bio) |
39 | { |
40 | if (rq->rq_flags & RQF_USE_SCHED) { |
41 | struct elevator_queue *e = q->elevator; |
42 | |
43 | if (e->type->ops.allow_merge) |
44 | return e->type->ops.allow_merge(q, rq, bio); |
45 | } |
46 | return true; |
47 | } |
48 | |
49 | static inline void blk_mq_sched_completed_request(struct request *rq, u64 now) |
50 | { |
51 | if (rq->rq_flags & RQF_USE_SCHED) { |
52 | struct elevator_queue *e = rq->q->elevator; |
53 | |
54 | if (e->type->ops.completed_request) |
55 | e->type->ops.completed_request(rq, now); |
56 | } |
57 | } |
58 | |
59 | static inline void blk_mq_sched_requeue_request(struct request *rq) |
60 | { |
61 | if (rq->rq_flags & RQF_USE_SCHED) { |
62 | struct request_queue *q = rq->q; |
63 | struct elevator_queue *e = q->elevator; |
64 | |
65 | if (e->type->ops.requeue_request) |
66 | e->type->ops.requeue_request(rq); |
67 | } |
68 | } |
69 | |
70 | static inline bool blk_mq_sched_has_work(struct blk_mq_hw_ctx *hctx) |
71 | { |
72 | struct elevator_queue *e = hctx->queue->elevator; |
73 | |
74 | if (e && e->type->ops.has_work) |
75 | return e->type->ops.has_work(hctx); |
76 | |
77 | return false; |
78 | } |
79 | |
80 | static inline bool blk_mq_sched_needs_restart(struct blk_mq_hw_ctx *hctx) |
81 | { |
82 | return test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state); |
83 | } |
84 | |
85 | #endif |
86 | |