1 /* SPDX-License-Identifier: GPL-2.0 */ 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 #include "blk-rq-qos.h" 13 14 enum wbt_flags { 15 WBT_TRACKED = 1, /* write, tracked for throttling */ 16 WBT_READ = 2, /* read */ 17 WBT_KSWAPD = 4, /* write, from kswapd */ 18 WBT_DISCARD = 8, /* discard */ 19 20 WBT_NR_BITS = 4, /* number of bits */ 21 }; 22 23 enum { 24 WBT_RWQ_BG = 0, 25 WBT_RWQ_KSWAPD, 26 WBT_RWQ_DISCARD, 27 WBT_NUM_RWQ, 28 }; 29 30 /* 31 * If current state is WBT_STATE_ON/OFF_DEFAULT, it can be covered to any other 32 * state, if current state is WBT_STATE_ON/OFF_MANUAL, it can only be covered 33 * to WBT_STATE_OFF/ON_MANUAL. 34 */ 35 enum { 36 WBT_STATE_ON_DEFAULT = 1, /* on by default */ 37 WBT_STATE_ON_MANUAL = 2, /* on manually by sysfs */ 38 WBT_STATE_OFF_DEFAULT = 3, /* off by default */ 39 WBT_STATE_OFF_MANUAL = 4, /* off manually by sysfs */ 40 }; 41 42 struct rq_wb { 43 /* 44 * Settings that govern how we throttle 45 */ 46 unsigned int wb_background; /* background writeback */ 47 unsigned int wb_normal; /* normal writeback */ 48 49 short enable_state; /* WBT_STATE_* */ 50 51 /* 52 * Number of consecutive periods where we don't have enough 53 * information to make a firm scale up/down decision. 54 */ 55 unsigned int unknown_cnt; 56 57 u64 win_nsec; /* default window size */ 58 u64 cur_win_nsec; /* current window size */ 59 60 struct blk_stat_callback *cb; 61 62 u64 sync_issue; 63 void *sync_cookie; 64 65 unsigned int wc; 66 67 unsigned long last_issue; /* last non-throttled issue */ 68 unsigned long last_comp; /* last non-throttled comp */ 69 unsigned long min_lat_nsec; 70 struct rq_qos rqos; 71 struct rq_wait rq_wait[WBT_NUM_RWQ]; 72 struct rq_depth rq_depth; 73 }; 74 75 static inline struct rq_wb *RQWB(struct rq_qos *rqos) 76 { 77 return container_of(rqos, struct rq_wb, rqos); 78 } 79 80 static inline unsigned int wbt_inflight(struct rq_wb *rwb) 81 { 82 unsigned int i, ret = 0; 83 84 for (i = 0; i < WBT_NUM_RWQ; i++) 85 ret += atomic_read(&rwb->rq_wait[i].inflight); 86 87 return ret; 88 } 89 90 91 #ifdef CONFIG_BLK_WBT 92 93 int wbt_init(struct request_queue *); 94 void wbt_disable_default(struct request_queue *); 95 void wbt_enable_default(struct request_queue *); 96 97 u64 wbt_get_min_lat(struct request_queue *q); 98 void wbt_set_min_lat(struct request_queue *q, u64 val); 99 bool wbt_disabled(struct request_queue *); 100 101 void wbt_set_write_cache(struct request_queue *, bool); 102 103 u64 wbt_default_latency_nsec(struct request_queue *); 104 105 #else 106 107 static inline int wbt_init(struct request_queue *q) 108 { 109 return -EINVAL; 110 } 111 static inline void wbt_disable_default(struct request_queue *q) 112 { 113 } 114 static inline void wbt_enable_default(struct request_queue *q) 115 { 116 } 117 static inline void wbt_set_write_cache(struct request_queue *q, bool wc) 118 { 119 } 120 static inline u64 wbt_get_min_lat(struct request_queue *q) 121 { 122 return 0; 123 } 124 static inline void wbt_set_min_lat(struct request_queue *q, u64 val) 125 { 126 } 127 static inline u64 wbt_default_latency_nsec(struct request_queue *q) 128 { 129 return 0; 130 } 131 static inline bool wbt_disabled(struct request_queue *q) 132 { 133 return true; 134 } 135 136 #endif /* CONFIG_BLK_WBT */ 137 138 #endif 139