xref: /linux/include/linux/iocontext.h (revision b69f2292063d2caf37ca9aec7d63ded203701bf3)
1fd0928dfSJens Axboe #ifndef IOCONTEXT_H
2fd0928dfSJens Axboe #define IOCONTEXT_H
3fd0928dfSJens Axboe 
44ac845a2SJens Axboe #include <linux/radix-tree.h>
534e6bbf2SFabio Checconi #include <linux/rcupdate.h>
64ac845a2SJens Axboe 
7fd0928dfSJens Axboe /*
8fd0928dfSJens Axboe  * This is the per-process anticipatory I/O scheduler state.
9fd0928dfSJens Axboe  */
10fd0928dfSJens Axboe struct as_io_context {
11fd0928dfSJens Axboe 	spinlock_t lock;
12fd0928dfSJens Axboe 
13fd0928dfSJens Axboe 	void (*dtor)(struct as_io_context *aic); /* destructor */
14fd0928dfSJens Axboe 	void (*exit)(struct as_io_context *aic); /* called on task exit */
15fd0928dfSJens Axboe 
16fd0928dfSJens Axboe 	unsigned long state;
17fd0928dfSJens Axboe 	atomic_t nr_queued; /* queued reads & sync writes */
18fd0928dfSJens Axboe 	atomic_t nr_dispatched; /* number of requests gone to the drivers */
19fd0928dfSJens Axboe 
20fd0928dfSJens Axboe 	/* IO History tracking */
21fd0928dfSJens Axboe 	/* Thinktime */
22fd0928dfSJens Axboe 	unsigned long last_end_request;
23fd0928dfSJens Axboe 	unsigned long ttime_total;
24fd0928dfSJens Axboe 	unsigned long ttime_samples;
25fd0928dfSJens Axboe 	unsigned long ttime_mean;
26fd0928dfSJens Axboe 	/* Layout pattern */
27fd0928dfSJens Axboe 	unsigned int seek_samples;
28fd0928dfSJens Axboe 	sector_t last_request_pos;
29fd0928dfSJens Axboe 	u64 seek_total;
30fd0928dfSJens Axboe 	sector_t seek_mean;
31fd0928dfSJens Axboe };
32fd0928dfSJens Axboe 
33fd0928dfSJens Axboe struct cfq_queue;
34fd0928dfSJens Axboe struct cfq_io_context {
35fd0928dfSJens Axboe 	void *key;
364ac845a2SJens Axboe 	unsigned long dead_key;
37fd0928dfSJens Axboe 
38fd0928dfSJens Axboe 	struct cfq_queue *cfqq[2];
39fd0928dfSJens Axboe 
40fd0928dfSJens Axboe 	struct io_context *ioc;
41fd0928dfSJens Axboe 
42fd0928dfSJens Axboe 	unsigned long last_end_request;
43fd0928dfSJens Axboe 
44fd0928dfSJens Axboe 	unsigned long ttime_total;
45fd0928dfSJens Axboe 	unsigned long ttime_samples;
46fd0928dfSJens Axboe 	unsigned long ttime_mean;
47fd0928dfSJens Axboe 
48fd0928dfSJens Axboe 	struct list_head queue_list;
49ffc4e759SJens Axboe 	struct hlist_node cic_list;
50fd0928dfSJens Axboe 
51fd0928dfSJens Axboe 	void (*dtor)(struct io_context *); /* destructor */
52fd0928dfSJens Axboe 	void (*exit)(struct io_context *); /* called on task exit */
5334e6bbf2SFabio Checconi 
5434e6bbf2SFabio Checconi 	struct rcu_head rcu_head;
55fd0928dfSJens Axboe };
56fd0928dfSJens Axboe 
57fd0928dfSJens Axboe /*
58d38ecf93SJens Axboe  * I/O subsystem state of the associated processes.  It is refcounted
59d38ecf93SJens Axboe  * and kmalloc'ed. These could be shared between processes.
60fd0928dfSJens Axboe  */
61fd0928dfSJens Axboe struct io_context {
62d9c7d394SNikanth Karthikesan 	atomic_long_t refcount;
63d38ecf93SJens Axboe 	atomic_t nr_tasks;
64d38ecf93SJens Axboe 
65d38ecf93SJens Axboe 	/* all the fields below are protected by this lock */
66d38ecf93SJens Axboe 	spinlock_t lock;
67fd0928dfSJens Axboe 
68fd0928dfSJens Axboe 	unsigned short ioprio;
69fd0928dfSJens Axboe 	unsigned short ioprio_changed;
70fd0928dfSJens Axboe 
7131e4c28dSVivek Goyal #ifdef CONFIG_BLK_CGROUP
7231e4c28dSVivek Goyal 	unsigned short cgroup_changed;
7331e4c28dSVivek Goyal #endif
7431e4c28dSVivek Goyal 
75fd0928dfSJens Axboe 	/*
76fd0928dfSJens Axboe 	 * For request batching
77fd0928dfSJens Axboe 	 */
78fd0928dfSJens Axboe 	unsigned long last_waited; /* Time last woken after wait for request */
79fd0928dfSJens Axboe 	int nr_batch_requests;     /* Number of requests left in the batch */
80fd0928dfSJens Axboe 
81fd0928dfSJens Axboe 	struct as_io_context *aic;
824ac845a2SJens Axboe 	struct radix_tree_root radix_root;
83ffc4e759SJens Axboe 	struct hlist_head cic_list;
84fd0928dfSJens Axboe 	void *ioc_data;
85fd0928dfSJens Axboe };
86fd0928dfSJens Axboe 
87d38ecf93SJens Axboe static inline struct io_context *ioc_task_link(struct io_context *ioc)
88d38ecf93SJens Axboe {
89d38ecf93SJens Axboe 	/*
90d38ecf93SJens Axboe 	 * if ref count is zero, don't allow sharing (ioc is going away, it's
91d38ecf93SJens Axboe 	 * a race).
92d38ecf93SJens Axboe 	 */
93d9c7d394SNikanth Karthikesan 	if (ioc && atomic_long_inc_not_zero(&ioc->refcount)) {
94cbb4f264SLi Zefan 		atomic_inc(&ioc->nr_tasks);
95d38ecf93SJens Axboe 		return ioc;
96d237e5c7SJens Axboe 	}
97d38ecf93SJens Axboe 
98d38ecf93SJens Axboe 	return NULL;
99d38ecf93SJens Axboe }
100d38ecf93SJens Axboe 
101*b69f2292SLouis Rilling struct task_struct;
102da9cbc87SJens Axboe #ifdef CONFIG_BLOCK
103da9cbc87SJens Axboe int put_io_context(struct io_context *ioc);
104*b69f2292SLouis Rilling void exit_io_context(struct task_struct *task);
105da9cbc87SJens Axboe struct io_context *get_io_context(gfp_t gfp_flags, int node);
106da9cbc87SJens Axboe struct io_context *alloc_io_context(gfp_t gfp_flags, int node);
107da9cbc87SJens Axboe void copy_io_context(struct io_context **pdst, struct io_context **psrc);
108da9cbc87SJens Axboe #else
109*b69f2292SLouis Rilling static inline void exit_io_context(struct task_struct *task)
110da9cbc87SJens Axboe {
111da9cbc87SJens Axboe }
112da9cbc87SJens Axboe 
113da9cbc87SJens Axboe struct io_context;
114da9cbc87SJens Axboe static inline int put_io_context(struct io_context *ioc)
115da9cbc87SJens Axboe {
116da9cbc87SJens Axboe 	return 1;
117da9cbc87SJens Axboe }
118da9cbc87SJens Axboe #endif
119da9cbc87SJens Axboe 
120fd0928dfSJens Axboe #endif
121