Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
e34cbd30 JA |
2 | #ifndef WB_THROTTLE_H |
3 | #define WB_THROTTLE_H | |
4 | ||
5 | #include <linux/kernel.h> | |
6 | #include <linux/atomic.h> | |
7 | #include <linux/wait.h> | |
8 | #include <linux/timer.h> | |
9 | #include <linux/ktime.h> | |
10 | ||
11 | #include "blk-stat.h" | |
12 | ||
13 | enum wbt_flags { | |
14 | WBT_TRACKED = 1, /* write, tracked for throttling */ | |
15 | WBT_READ = 2, /* read */ | |
16 | WBT_KSWAPD = 4, /* write, from kswapd */ | |
782f5697 | 17 | WBT_DISCARD = 8, /* discard */ |
e34cbd30 | 18 | |
782f5697 | 19 | WBT_NR_BITS = 4, /* number of bits */ |
e34cbd30 JA |
20 | }; |
21 | ||
22 | enum { | |
8bea6090 JA |
23 | WBT_RWQ_BG = 0, |
24 | WBT_RWQ_KSWAPD, | |
782f5697 | 25 | WBT_RWQ_DISCARD, |
8bea6090 | 26 | WBT_NUM_RWQ, |
e34cbd30 JA |
27 | }; |
28 | ||
d62118b6 JA |
29 | /* |
30 | * Enable states. Either off, or on by default (done at init time), | |
31 | * or on through manual setup in sysfs. | |
32 | */ | |
33 | enum { | |
34 | WBT_STATE_ON_DEFAULT = 1, | |
35 | WBT_STATE_ON_MANUAL = 2, | |
36 | }; | |
37 | ||
e34cbd30 JA |
38 | struct rq_wait { |
39 | wait_queue_head_t wait; | |
40 | atomic_t inflight; | |
41 | }; | |
42 | ||
43 | struct rq_wb { | |
44 | /* | |
45 | * Settings that govern how we throttle | |
46 | */ | |
47 | unsigned int wb_background; /* background writeback */ | |
48 | unsigned int wb_normal; /* normal writeback */ | |
49 | unsigned int wb_max; /* max throughput writeback */ | |
50 | int scale_step; | |
51 | bool scaled_max; | |
52 | ||
d62118b6 JA |
53 | short enable_state; /* WBT_STATE_* */ |
54 | ||
e34cbd30 JA |
55 | /* |
56 | * Number of consecutive periods where we don't have enough | |
57 | * information to make a firm scale up/down decision. | |
58 | */ | |
59 | unsigned int unknown_cnt; | |
60 | ||
61 | u64 win_nsec; /* default window size */ | |
62 | u64 cur_win_nsec; /* current window size */ | |
63 | ||
34dbad5d | 64 | struct blk_stat_callback *cb; |
e34cbd30 | 65 | |
544ccc8d | 66 | u64 sync_issue; |
e34cbd30 JA |
67 | void *sync_cookie; |
68 | ||
69 | unsigned int wc; | |
70 | unsigned int queue_depth; | |
71 | ||
72 | unsigned long last_issue; /* last non-throttled issue */ | |
73 | unsigned long last_comp; /* last non-throttled comp */ | |
74 | unsigned long min_lat_nsec; | |
d8a0cbfd | 75 | struct request_queue *queue; |
e34cbd30 | 76 | struct rq_wait rq_wait[WBT_NUM_RWQ]; |
e34cbd30 JA |
77 | }; |
78 | ||
79 | static inline unsigned int wbt_inflight(struct rq_wb *rwb) | |
80 | { | |
81 | unsigned int i, ret = 0; | |
82 | ||
83 | for (i = 0; i < WBT_NUM_RWQ; i++) | |
84 | ret += atomic_read(&rwb->rq_wait[i].inflight); | |
85 | ||
86 | return ret; | |
87 | } | |
88 | ||
e34cbd30 JA |
89 | #ifdef CONFIG_BLK_WBT |
90 | ||
a8a45941 | 91 | static inline void wbt_track(struct request *rq, enum wbt_flags flags) |
934031a1 | 92 | { |
544ccc8d | 93 | rq->wbt_flags |= flags; |
934031a1 OS |
94 | } |
95 | ||
e34cbd30 | 96 | void __wbt_done(struct rq_wb *, enum wbt_flags); |
a8a45941 | 97 | void wbt_done(struct rq_wb *, struct request *); |
e34cbd30 | 98 | enum wbt_flags wbt_wait(struct rq_wb *, struct bio *, spinlock_t *); |
8054b89f | 99 | int wbt_init(struct request_queue *); |
e34cbd30 JA |
100 | void wbt_exit(struct request_queue *); |
101 | void wbt_update_limits(struct rq_wb *); | |
a8a45941 OS |
102 | void wbt_requeue(struct rq_wb *, struct request *); |
103 | void wbt_issue(struct rq_wb *, struct request *); | |
fa224eed | 104 | void wbt_disable_default(struct request_queue *); |
8330cdb0 | 105 | void wbt_enable_default(struct request_queue *); |
e34cbd30 JA |
106 | |
107 | void wbt_set_queue_depth(struct rq_wb *, unsigned int); | |
108 | void wbt_set_write_cache(struct rq_wb *, bool); | |
109 | ||
80e091d1 JA |
110 | u64 wbt_default_latency_nsec(struct request_queue *); |
111 | ||
e34cbd30 JA |
112 | #else |
113 | ||
a8a45941 | 114 | static inline void wbt_track(struct request *rq, enum wbt_flags flags) |
934031a1 OS |
115 | { |
116 | } | |
e34cbd30 JA |
117 | static inline void __wbt_done(struct rq_wb *rwb, enum wbt_flags flags) |
118 | { | |
119 | } | |
a8a45941 | 120 | static inline void wbt_done(struct rq_wb *rwb, struct request *rq) |
e34cbd30 JA |
121 | { |
122 | } | |
123 | static inline enum wbt_flags wbt_wait(struct rq_wb *rwb, struct bio *bio, | |
124 | spinlock_t *lock) | |
125 | { | |
126 | return 0; | |
127 | } | |
8054b89f | 128 | static inline int wbt_init(struct request_queue *q) |
e34cbd30 JA |
129 | { |
130 | return -EINVAL; | |
131 | } | |
132 | static inline void wbt_exit(struct request_queue *q) | |
133 | { | |
134 | } | |
135 | static inline void wbt_update_limits(struct rq_wb *rwb) | |
136 | { | |
137 | } | |
a8a45941 | 138 | static inline void wbt_requeue(struct rq_wb *rwb, struct request *rq) |
e34cbd30 JA |
139 | { |
140 | } | |
a8a45941 | 141 | static inline void wbt_issue(struct rq_wb *rwb, struct request *rq) |
e34cbd30 JA |
142 | { |
143 | } | |
fa224eed | 144 | static inline void wbt_disable_default(struct request_queue *q) |
e34cbd30 JA |
145 | { |
146 | } | |
8330cdb0 JK |
147 | static inline void wbt_enable_default(struct request_queue *q) |
148 | { | |
149 | } | |
e34cbd30 JA |
150 | static inline void wbt_set_queue_depth(struct rq_wb *rwb, unsigned int depth) |
151 | { | |
152 | } | |
153 | static inline void wbt_set_write_cache(struct rq_wb *rwb, bool wc) | |
154 | { | |
155 | } | |
80e091d1 JA |
156 | static inline u64 wbt_default_latency_nsec(struct request_queue *q) |
157 | { | |
158 | return 0; | |
159 | } | |
e34cbd30 JA |
160 | |
161 | #endif /* CONFIG_BLK_WBT */ | |
162 | ||
163 | #endif |