#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
#include <linux/rbtree.h>
#include <linux/sbitmap.h>
#include <trace/events/block.h>
#include "elevator.h"
#include "blk.h"
#include "blk-mq.h"
#include "blk-mq-debugfs.h"
#include "blk-mq-sched.h"
static const int read_expire = …;
static const int write_expire = …;
static const int prio_aging_expire = …;
static const int writes_starved = …;
static const int fifo_batch = …;
enum dd_data_dir { … };
enum { … };
enum dd_prio { … };
enum { … };
struct io_stats_per_prio { … };
struct dd_per_prio { … };
struct deadline_data { … };
static const enum dd_prio ioprio_class_to_prio[] = …;
static inline struct rb_root *
deadline_rb_root(struct dd_per_prio *per_prio, struct request *rq)
{ … }
static u8 dd_rq_ioclass(struct request *rq)
{ … }
static inline struct request *deadline_from_pos(struct dd_per_prio *per_prio,
enum dd_data_dir data_dir, sector_t pos)
{ … }
static void
deadline_add_rq_rb(struct dd_per_prio *per_prio, struct request *rq)
{ … }
static inline void
deadline_del_rq_rb(struct dd_per_prio *per_prio, struct request *rq)
{ … }
static void deadline_remove_request(struct request_queue *q,
struct dd_per_prio *per_prio,
struct request *rq)
{ … }
static void dd_request_merged(struct request_queue *q, struct request *req,
enum elv_merge type)
{ … }
static void dd_merged_requests(struct request_queue *q, struct request *req,
struct request *next)
{ … }
static void
deadline_move_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
struct request *rq)
{ … }
static u32 dd_queued(struct deadline_data *dd, enum dd_prio prio)
{ … }
static inline bool deadline_check_fifo(struct dd_per_prio *per_prio,
enum dd_data_dir data_dir)
{ … }
static struct request *
deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
enum dd_data_dir data_dir)
{ … }
static struct request *
deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
enum dd_data_dir data_dir)
{ … }
static bool started_after(struct deadline_data *dd, struct request *rq,
unsigned long latest_start)
{ … }
static struct request *__dd_dispatch_request(struct deadline_data *dd,
struct dd_per_prio *per_prio,
unsigned long latest_start)
{ … }
static struct request *dd_dispatch_prio_aged_requests(struct deadline_data *dd,
unsigned long now)
{ … }
static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
{ … }
static int dd_to_word_depth(struct blk_mq_hw_ctx *hctx, unsigned int qdepth)
{ … }
static void dd_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
{ … }
static void dd_depth_updated(struct blk_mq_hw_ctx *hctx)
{ … }
static int dd_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
{ … }
static void dd_exit_sched(struct elevator_queue *e)
{ … }
static int dd_init_sched(struct request_queue *q, struct elevator_type *e)
{ … }
static int dd_request_merge(struct request_queue *q, struct request **rq,
struct bio *bio)
{ … }
static bool dd_bio_merge(struct request_queue *q, struct bio *bio,
unsigned int nr_segs)
{ … }
static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
blk_insert_t flags, struct list_head *free)
{ … }
static void dd_insert_requests(struct blk_mq_hw_ctx *hctx,
struct list_head *list,
blk_insert_t flags)
{ … }
static void dd_prepare_request(struct request *rq)
{ … }
static void dd_finish_request(struct request *rq)
{ … }
static bool dd_has_work_for_prio(struct dd_per_prio *per_prio)
{ … }
static bool dd_has_work(struct blk_mq_hw_ctx *hctx)
{ … }
#define SHOW_INT …
#define SHOW_JIFFIES …
SHOW_JIFFIES(deadline_read_expire_show, dd->fifo_expire[DD_READ]);
SHOW_JIFFIES(deadline_write_expire_show, dd->fifo_expire[DD_WRITE]);
SHOW_JIFFIES(deadline_prio_aging_expire_show, dd->prio_aging_expire);
SHOW_INT(deadline_writes_starved_show, dd->writes_starved);
SHOW_INT(deadline_front_merges_show, dd->front_merges);
SHOW_INT(deadline_async_depth_show, dd->async_depth);
SHOW_INT(deadline_fifo_batch_show, dd->fifo_batch);
#undef SHOW_INT
#undef SHOW_JIFFIES
#define STORE_FUNCTION …
#define STORE_INT …
#define STORE_JIFFIES …
STORE_JIFFIES(deadline_read_expire_store, &dd->fifo_expire[DD_READ], 0, INT_MAX);
STORE_JIFFIES(deadline_write_expire_store, &dd->fifo_expire[DD_WRITE], 0, INT_MAX);
STORE_JIFFIES(deadline_prio_aging_expire_store, &dd->prio_aging_expire, 0, INT_MAX);
STORE_INT(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX);
STORE_INT(deadline_front_merges_store, &dd->front_merges, 0, 1);
STORE_INT(deadline_async_depth_store, &dd->async_depth, 1, INT_MAX);
STORE_INT(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX);
#undef STORE_FUNCTION
#undef STORE_INT
#undef STORE_JIFFIES
#define DD_ATTR(name) …
static struct elv_fs_entry deadline_attrs[] = …;
#ifdef CONFIG_BLK_DEBUG_FS
#define DEADLINE_DEBUGFS_DDIR_ATTRS …
DEADLINE_DEBUGFS_DDIR_ATTRS(DD_RT_PRIO, DD_READ, read0);
DEADLINE_DEBUGFS_DDIR_ATTRS(DD_RT_PRIO, DD_WRITE, write0);
DEADLINE_DEBUGFS_DDIR_ATTRS(DD_BE_PRIO, DD_READ, read1);
DEADLINE_DEBUGFS_DDIR_ATTRS(DD_BE_PRIO, DD_WRITE, write1);
DEADLINE_DEBUGFS_DDIR_ATTRS(DD_IDLE_PRIO, DD_READ, read2);
DEADLINE_DEBUGFS_DDIR_ATTRS(DD_IDLE_PRIO, DD_WRITE, write2);
#undef DEADLINE_DEBUGFS_DDIR_ATTRS
static int deadline_batching_show(void *data, struct seq_file *m)
{ … }
static int deadline_starved_show(void *data, struct seq_file *m)
{ … }
static int dd_async_depth_show(void *data, struct seq_file *m)
{ … }
static int dd_queued_show(void *data, struct seq_file *m)
{ … }
static u32 dd_owned_by_driver(struct deadline_data *dd, enum dd_prio prio)
{ … }
static int dd_owned_by_driver_show(void *data, struct seq_file *m)
{ … }
#define DEADLINE_DISPATCH_ATTR …
DEADLINE_DISPATCH_ATTR;
DEADLINE_DISPATCH_ATTR;
DEADLINE_DISPATCH_ATTR;
#undef DEADLINE_DISPATCH_ATTR
#define DEADLINE_QUEUE_DDIR_ATTRS …
#define DEADLINE_NEXT_RQ_ATTR(name) …
static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = …;
#undef DEADLINE_QUEUE_DDIR_ATTRS
#endif
static struct elevator_type mq_deadline = …;
MODULE_ALIAS(…) …;
static int __init deadline_init(void)
{ … }
static void __exit deadline_exit(void)
{ … }
module_init(…) …;
module_exit(deadline_exit);
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;