projects/linux·blob master · refs

95 lines · 2.3 KiB

1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _LINUX_BLK_PLUG_H
3#define _LINUX_BLK_PLUG_H
4
5#include <linux/sched.h>
6
7struct blk_plug_cb;
8typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *cb, bool from_schedule);
9
10struct rq_list {
11 struct request *head;
12 struct request *tail;
13};
14
15#ifdef CONFIG_BLOCK
16/*
17 * blk_plug permits building a queue of related requests by holding the I/O
18 * fragments for a short period. This allows merging of sequential requests
19 * into single larger request. As the requests are moved from a per-task list to
20 * the device's request_queue in a batch, this results in improved scalability
21 * as the lock contention for request_queue lock is reduced.
22 *
23 * It is ok not to disable preemption when adding the request to the plug list
24 * or when attempting a merge. For details, please see schedule() where
25 * blk_flush_plug() is called.
26 */
27struct blk_plug {
28 struct rq_list mq_list; /* blk-mq requests */
29
30 /* if ios_left is > 1, we can batch tag/rq allocations */
31 struct rq_list cached_rqs;
32 u64 cur_ktime;
33 unsigned short nr_ios;
34
35 unsigned short rq_count;
36
37 bool multiple_queues;
38 bool has_elevator;
39
40 struct list_head cb_list; /* md requires an unplug callback */
41};
42
43void blk_start_plug(struct blk_plug *);
44void blk_start_plug_nr_ios(struct blk_plug *, unsigned short);
45void blk_finish_plug(struct blk_plug *);
46
47void __blk_flush_plug(struct blk_plug *plug, bool from_schedule);
48static inline void blk_flush_plug(struct blk_plug *plug, bool async)
49{
50 if (plug)
51 __blk_flush_plug(plug, async);
52}
53
54static __always_inline void blk_plug_invalidate_ts(void)
55{
56 if (unlikely(current->flags & PF_BLOCK_TS)) {
57 current->plug->cur_ktime = 0;
58 current->flags &= ~PF_BLOCK_TS;
59 }
60}
61
62struct blk_plug_cb {
63 struct list_head list;
64 blk_plug_cb_fn callback;
65 void *data;
66};
67
68struct blk_plug_cb *blk_check_plugged(blk_plug_cb_fn unplug, void *data,
69 int size);
70#else /* CONFIG_BLOCK */
71struct blk_plug {
72};
73
74static inline void blk_start_plug(struct blk_plug *plug)
75{
76}
77
78static inline void blk_start_plug_nr_ios(struct blk_plug *plug,
79 unsigned short nr_ios)
80{
81}
82
83static inline void blk_finish_plug(struct blk_plug *plug)
84{
85}
86
87static inline void blk_flush_plug(struct blk_plug *plug, bool async)
88{
89}
90
91static inline void blk_plug_invalidate_ts(void)
92{
93}
94#endif /* CONFIG_BLOCK */
95#endif /* _LINUX_BLK_PLUG_H */