Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef WB_THROTTLE_H
0003 #define WB_THROTTLE_H
0004 
0005 #include <linux/kernel.h>
0006 #include <linux/atomic.h>
0007 #include <linux/wait.h>
0008 #include <linux/timer.h>
0009 #include <linux/ktime.h>
0010 
0011 #include "blk-stat.h"
0012 #include "blk-rq-qos.h"
0013 
0014 enum wbt_flags {
0015     WBT_TRACKED     = 1,    /* write, tracked for throttling */
0016     WBT_READ        = 2,    /* read */
0017     WBT_KSWAPD      = 4,    /* write, from kswapd */
0018     WBT_DISCARD     = 8,    /* discard */
0019 
0020     WBT_NR_BITS     = 4,    /* number of bits */
0021 };
0022 
0023 enum {
0024     WBT_RWQ_BG      = 0,
0025     WBT_RWQ_KSWAPD,
0026     WBT_RWQ_DISCARD,
0027     WBT_NUM_RWQ,
0028 };
0029 
0030 /*
0031  * Enable states. Either off, or on by default (done at init time),
0032  * or on through manual setup in sysfs.
0033  */
0034 enum {
0035     WBT_STATE_ON_DEFAULT    = 1,
0036     WBT_STATE_ON_MANUAL = 2,
0037     WBT_STATE_OFF_DEFAULT
0038 };
0039 
0040 struct rq_wb {
0041     /*
0042      * Settings that govern how we throttle
0043      */
0044     unsigned int wb_background;     /* background writeback */
0045     unsigned int wb_normal;         /* normal writeback */
0046 
0047     short enable_state;         /* WBT_STATE_* */
0048 
0049     /*
0050      * Number of consecutive periods where we don't have enough
0051      * information to make a firm scale up/down decision.
0052      */
0053     unsigned int unknown_cnt;
0054 
0055     u64 win_nsec;               /* default window size */
0056     u64 cur_win_nsec;           /* current window size */
0057 
0058     struct blk_stat_callback *cb;
0059 
0060     u64 sync_issue;
0061     void *sync_cookie;
0062 
0063     unsigned int wc;
0064 
0065     unsigned long last_issue;       /* last non-throttled issue */
0066     unsigned long last_comp;        /* last non-throttled comp */
0067     unsigned long min_lat_nsec;
0068     struct rq_qos rqos;
0069     struct rq_wait rq_wait[WBT_NUM_RWQ];
0070     struct rq_depth rq_depth;
0071 };
0072 
0073 static inline struct rq_wb *RQWB(struct rq_qos *rqos)
0074 {
0075     return container_of(rqos, struct rq_wb, rqos);
0076 }
0077 
0078 static inline unsigned int wbt_inflight(struct rq_wb *rwb)
0079 {
0080     unsigned int i, ret = 0;
0081 
0082     for (i = 0; i < WBT_NUM_RWQ; i++)
0083         ret += atomic_read(&rwb->rq_wait[i].inflight);
0084 
0085     return ret;
0086 }
0087 
0088 
0089 #ifdef CONFIG_BLK_WBT
0090 
0091 int wbt_init(struct request_queue *);
0092 void wbt_disable_default(struct request_queue *);
0093 void wbt_enable_default(struct request_queue *);
0094 
0095 u64 wbt_get_min_lat(struct request_queue *q);
0096 void wbt_set_min_lat(struct request_queue *q, u64 val);
0097 
0098 void wbt_set_write_cache(struct request_queue *, bool);
0099 
0100 u64 wbt_default_latency_nsec(struct request_queue *);
0101 
0102 #else
0103 
0104 static inline int wbt_init(struct request_queue *q)
0105 {
0106     return -EINVAL;
0107 }
0108 static inline void wbt_disable_default(struct request_queue *q)
0109 {
0110 }
0111 static inline void wbt_enable_default(struct request_queue *q)
0112 {
0113 }
0114 static inline void wbt_set_write_cache(struct request_queue *q, bool wc)
0115 {
0116 }
0117 static inline u64 wbt_get_min_lat(struct request_queue *q)
0118 {
0119     return 0;
0120 }
0121 static inline void wbt_set_min_lat(struct request_queue *q, u64 val)
0122 {
0123 }
0124 static inline u64 wbt_default_latency_nsec(struct request_queue *q)
0125 {
0126     return 0;
0127 }
0128 
0129 #endif /* CONFIG_BLK_WBT */
0130 
0131 #endif