#include <linux/module.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/blktrace_api.h>
#include "blk.h"
#include "blk-cgroup-rwstat.h"
#include "blk-stat.h"
#include "blk-throttle.h"
#define THROTL_GRP_QUANTUM …
#define THROTL_QUANTUM …
#define DFL_THROTL_SLICE_HD …
#define DFL_THROTL_SLICE_SSD …
#define MAX_THROTL_SLICE …
static struct workqueue_struct *kthrotld_workqueue;
#define rb_entry_tg(node) …
struct throtl_data
{ … };
static void throtl_pending_timer_fn(struct timer_list *t);
static inline struct blkcg_gq *tg_to_blkg(struct throtl_grp *tg)
{ … }
static struct throtl_grp *sq_to_tg(struct throtl_service_queue *sq)
{ … }
static struct throtl_data *sq_to_td(struct throtl_service_queue *sq)
{ … }
static uint64_t tg_bps_limit(struct throtl_grp *tg, int rw)
{ … }
static unsigned int tg_iops_limit(struct throtl_grp *tg, int rw)
{ … }
#define throtl_log(sq, fmt, args...) …
static inline unsigned int throtl_bio_data_size(struct bio *bio)
{ … }
static void throtl_qnode_init(struct throtl_qnode *qn, struct throtl_grp *tg)
{ … }
static void throtl_qnode_add_bio(struct bio *bio, struct throtl_qnode *qn,
struct list_head *queued)
{ … }
static struct bio *throtl_peek_queued(struct list_head *queued)
{ … }
static struct bio *throtl_pop_queued(struct list_head *queued,
struct throtl_grp **tg_to_put)
{ … }
static void throtl_service_queue_init(struct throtl_service_queue *sq)
{ … }
static struct blkg_policy_data *throtl_pd_alloc(struct gendisk *disk,
struct blkcg *blkcg, gfp_t gfp)
{ … }
static void throtl_pd_init(struct blkg_policy_data *pd)
{ … }
static void tg_update_has_rules(struct throtl_grp *tg)
{ … }
static void throtl_pd_online(struct blkg_policy_data *pd)
{ … }
static void throtl_pd_free(struct blkg_policy_data *pd)
{ … }
static struct throtl_grp *
throtl_rb_first(struct throtl_service_queue *parent_sq)
{ … }
static void throtl_rb_erase(struct rb_node *n,
struct throtl_service_queue *parent_sq)
{ … }
static void update_min_dispatch_time(struct throtl_service_queue *parent_sq)
{ … }
static void tg_service_queue_add(struct throtl_grp *tg)
{ … }
static void throtl_enqueue_tg(struct throtl_grp *tg)
{ … }
static void throtl_dequeue_tg(struct throtl_grp *tg)
{ … }
static void throtl_schedule_pending_timer(struct throtl_service_queue *sq,
unsigned long expires)
{ … }
static bool throtl_schedule_next_dispatch(struct throtl_service_queue *sq,
bool force)
{ … }
static inline void throtl_start_new_slice_with_credit(struct throtl_grp *tg,
bool rw, unsigned long start)
{ … }
static inline void throtl_start_new_slice(struct throtl_grp *tg, bool rw,
bool clear_carryover)
{ … }
static inline void throtl_set_slice_end(struct throtl_grp *tg, bool rw,
unsigned long jiffy_end)
{ … }
static inline void throtl_extend_slice(struct throtl_grp *tg, bool rw,
unsigned long jiffy_end)
{ … }
static bool throtl_slice_used(struct throtl_grp *tg, bool rw)
{ … }
static unsigned int calculate_io_allowed(u32 iops_limit,
unsigned long jiffy_elapsed)
{ … }
static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed)
{ … }
static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw)
{ … }
static void __tg_update_carryover(struct throtl_grp *tg, bool rw)
{ … }
static void tg_update_carryover(struct throtl_grp *tg)
{ … }
static unsigned long tg_within_iops_limit(struct throtl_grp *tg, struct bio *bio,
u32 iops_limit)
{ … }
static unsigned long tg_within_bps_limit(struct throtl_grp *tg, struct bio *bio,
u64 bps_limit)
{ … }
static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio,
unsigned long *wait)
{ … }
static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio)
{ … }
static void throtl_add_bio_tg(struct bio *bio, struct throtl_qnode *qn,
struct throtl_grp *tg)
{ … }
static void tg_update_disptime(struct throtl_grp *tg)
{ … }
static void start_parent_slice_with_credit(struct throtl_grp *child_tg,
struct throtl_grp *parent_tg, bool rw)
{ … }
static void tg_dispatch_one_bio(struct throtl_grp *tg, bool rw)
{ … }
static int throtl_dispatch_tg(struct throtl_grp *tg)
{ … }
static int throtl_select_dispatch(struct throtl_service_queue *parent_sq)
{ … }
static void throtl_pending_timer_fn(struct timer_list *t)
{ … }
static void blk_throtl_dispatch_work_fn(struct work_struct *work)
{ … }
static u64 tg_prfill_conf_u64(struct seq_file *sf, struct blkg_policy_data *pd,
int off)
{ … }
static u64 tg_prfill_conf_uint(struct seq_file *sf, struct blkg_policy_data *pd,
int off)
{ … }
static int tg_print_conf_u64(struct seq_file *sf, void *v)
{ … }
static int tg_print_conf_uint(struct seq_file *sf, void *v)
{ … }
static void tg_conf_updated(struct throtl_grp *tg, bool global)
{ … }
static int blk_throtl_init(struct gendisk *disk)
{ … }
static ssize_t tg_set_conf(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off, bool is_u64)
{ … }
static ssize_t tg_set_conf_u64(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{ … }
static ssize_t tg_set_conf_uint(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{ … }
static int tg_print_rwstat(struct seq_file *sf, void *v)
{ … }
static u64 tg_prfill_rwstat_recursive(struct seq_file *sf,
struct blkg_policy_data *pd, int off)
{ … }
static int tg_print_rwstat_recursive(struct seq_file *sf, void *v)
{ … }
static struct cftype throtl_legacy_files[] = …;
static u64 tg_prfill_limit(struct seq_file *sf, struct blkg_policy_data *pd,
int off)
{ … }
static int tg_print_limit(struct seq_file *sf, void *v)
{ … }
static ssize_t tg_set_limit(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{ … }
static struct cftype throtl_files[] = …;
static void throtl_shutdown_wq(struct request_queue *q)
{ … }
struct blkcg_policy blkcg_policy_throtl = …;
void blk_throtl_cancel_bios(struct gendisk *disk)
{ … }
bool __blk_throtl_bio(struct bio *bio)
{ … }
void blk_throtl_exit(struct gendisk *disk)
{ … }
static int __init throtl_init(void)
{ … }
module_init(…) …;