Back to home page

LXR

 
 

    


0001 #ifndef WB_THROTTLE_H
0002 #define WB_THROTTLE_H
0003 
0004 #include <linux/kernel.h>
0005 #include <linux/atomic.h>
0006 #include <linux/wait.h>
0007 #include <linux/timer.h>
0008 #include <linux/ktime.h>
0009 
0010 #include "blk-stat.h"
0011 
0012 enum wbt_flags {
0013     WBT_TRACKED     = 1,    /* write, tracked for throttling */
0014     WBT_READ        = 2,    /* read */
0015     WBT_KSWAPD      = 4,    /* write, from kswapd */
0016 
0017     WBT_NR_BITS     = 3,    /* number of bits */
0018 };
0019 
0020 enum {
0021     WBT_NUM_RWQ     = 2,
0022 };
0023 
0024 /*
0025  * Enable states. Either off, or on by default (done at init time),
0026  * or on through manual setup in sysfs.
0027  */
0028 enum {
0029     WBT_STATE_ON_DEFAULT    = 1,
0030     WBT_STATE_ON_MANUAL = 2,
0031 };
0032 
0033 static inline void wbt_clear_state(struct blk_issue_stat *stat)
0034 {
0035     stat->time &= BLK_STAT_TIME_MASK;
0036 }
0037 
0038 static inline enum wbt_flags wbt_stat_to_mask(struct blk_issue_stat *stat)
0039 {
0040     return (stat->time & BLK_STAT_MASK) >> BLK_STAT_SHIFT;
0041 }
0042 
0043 static inline void wbt_track(struct blk_issue_stat *stat, enum wbt_flags wb_acct)
0044 {
0045     stat->time |= ((u64) wb_acct) << BLK_STAT_SHIFT;
0046 }
0047 
0048 static inline bool wbt_is_tracked(struct blk_issue_stat *stat)
0049 {
0050     return (stat->time >> BLK_STAT_SHIFT) & WBT_TRACKED;
0051 }
0052 
0053 static inline bool wbt_is_read(struct blk_issue_stat *stat)
0054 {
0055     return (stat->time >> BLK_STAT_SHIFT) & WBT_READ;
0056 }
0057 
0058 struct rq_wait {
0059     wait_queue_head_t wait;
0060     atomic_t inflight;
0061 };
0062 
0063 struct rq_wb {
0064     /*
0065      * Settings that govern how we throttle
0066      */
0067     unsigned int wb_background;     /* background writeback */
0068     unsigned int wb_normal;         /* normal writeback */
0069     unsigned int wb_max;            /* max throughput writeback */
0070     int scale_step;
0071     bool scaled_max;
0072 
0073     short enable_state;         /* WBT_STATE_* */
0074 
0075     /*
0076      * Number of consecutive periods where we don't have enough
0077      * information to make a firm scale up/down decision.
0078      */
0079     unsigned int unknown_cnt;
0080 
0081     u64 win_nsec;               /* default window size */
0082     u64 cur_win_nsec;           /* current window size */
0083 
0084     struct timer_list window_timer;
0085 
0086     s64 sync_issue;
0087     void *sync_cookie;
0088 
0089     unsigned int wc;
0090     unsigned int queue_depth;
0091 
0092     unsigned long last_issue;       /* last non-throttled issue */
0093     unsigned long last_comp;        /* last non-throttled comp */
0094     unsigned long min_lat_nsec;
0095     struct request_queue *queue;
0096     struct rq_wait rq_wait[WBT_NUM_RWQ];
0097 };
0098 
0099 static inline unsigned int wbt_inflight(struct rq_wb *rwb)
0100 {
0101     unsigned int i, ret = 0;
0102 
0103     for (i = 0; i < WBT_NUM_RWQ; i++)
0104         ret += atomic_read(&rwb->rq_wait[i].inflight);
0105 
0106     return ret;
0107 }
0108 
0109 #ifdef CONFIG_BLK_WBT
0110 
0111 void __wbt_done(struct rq_wb *, enum wbt_flags);
0112 void wbt_done(struct rq_wb *, struct blk_issue_stat *);
0113 enum wbt_flags wbt_wait(struct rq_wb *, struct bio *, spinlock_t *);
0114 int wbt_init(struct request_queue *);
0115 void wbt_exit(struct request_queue *);
0116 void wbt_update_limits(struct rq_wb *);
0117 void wbt_requeue(struct rq_wb *, struct blk_issue_stat *);
0118 void wbt_issue(struct rq_wb *, struct blk_issue_stat *);
0119 void wbt_disable_default(struct request_queue *);
0120 
0121 void wbt_set_queue_depth(struct rq_wb *, unsigned int);
0122 void wbt_set_write_cache(struct rq_wb *, bool);
0123 
0124 u64 wbt_default_latency_nsec(struct request_queue *);
0125 
0126 #else
0127 
0128 static inline void __wbt_done(struct rq_wb *rwb, enum wbt_flags flags)
0129 {
0130 }
0131 static inline void wbt_done(struct rq_wb *rwb, struct blk_issue_stat *stat)
0132 {
0133 }
0134 static inline enum wbt_flags wbt_wait(struct rq_wb *rwb, struct bio *bio,
0135                       spinlock_t *lock)
0136 {
0137     return 0;
0138 }
0139 static inline int wbt_init(struct request_queue *q)
0140 {
0141     return -EINVAL;
0142 }
0143 static inline void wbt_exit(struct request_queue *q)
0144 {
0145 }
0146 static inline void wbt_update_limits(struct rq_wb *rwb)
0147 {
0148 }
0149 static inline void wbt_requeue(struct rq_wb *rwb, struct blk_issue_stat *stat)
0150 {
0151 }
0152 static inline void wbt_issue(struct rq_wb *rwb, struct blk_issue_stat *stat)
0153 {
0154 }
0155 static inline void wbt_disable_default(struct request_queue *q)
0156 {
0157 }
0158 static inline void wbt_set_queue_depth(struct rq_wb *rwb, unsigned int depth)
0159 {
0160 }
0161 static inline void wbt_set_write_cache(struct rq_wb *rwb, bool wc)
0162 {
0163 }
0164 static inline u64 wbt_default_latency_nsec(struct request_queue *q)
0165 {
0166     return 0;
0167 }
0168 
0169 #endif /* CONFIG_BLK_WBT */
0170 
0171 #endif