blob: ac390a34c0e72c4c837f8620a74c37d73b3afb8f [file] [log] [blame]
Jens Axboefd0928d2008-01-24 08:52:45 +01001#ifndef IOCONTEXT_H
2#define IOCONTEXT_H
3
Jens Axboe4ac845a2008-01-24 08:44:49 +01004#include <linux/radix-tree.h>
Fabio Checconi34e6bbf2008-04-02 14:31:02 +02005#include <linux/rcupdate.h>
Tejun Heob2efa052011-12-14 00:33:39 +01006#include <linux/workqueue.h>
Jens Axboe4ac845a2008-01-24 08:44:49 +01007
Tejun Heodc869002011-12-14 00:33:38 +01008enum {
Tejun Heoc5869802011-12-14 00:33:41 +01009 ICQ_IOPRIO_CHANGED,
10 ICQ_CGROUP_CHANGED,
Tejun Heodc869002011-12-14 00:33:38 +010011};
12
Tejun Heoc5869802011-12-14 00:33:41 +010013struct io_cq {
14 struct request_queue *q;
15 struct io_context *ioc;
Jens Axboefd0928d2008-01-24 08:52:45 +010016
Tejun Heo7e5a8792011-12-14 00:33:42 +010017 /*
18 * q_node and ioc_node link io_cq through icq_list of q and ioc
19 * respectively. Both fields are unused once ioc_exit_icq() is
20 * called and shared with __rcu_icq_cache and __rcu_head which are
21 * used for RCU free of io_cq.
22 */
23 union {
24 struct list_head q_node;
25 struct kmem_cache *__rcu_icq_cache;
26 };
27 union {
28 struct hlist_node ioc_node;
29 struct rcu_head __rcu_head;
30 };
Jens Axboefd0928d2008-01-24 08:52:45 +010031
Tejun Heoc5869802011-12-14 00:33:41 +010032 unsigned long changed;
Jens Axboefd0928d2008-01-24 08:52:45 +010033};
34
35/*
Jens Axboed38ecf92008-01-24 08:53:35 +010036 * I/O subsystem state of the associated processes. It is refcounted
37 * and kmalloc'ed. These could be shared between processes.
Jens Axboefd0928d2008-01-24 08:52:45 +010038 */
39struct io_context {
Nikanth Karthikesand9c7d392009-06-10 12:57:06 -070040 atomic_long_t refcount;
Jens Axboed38ecf92008-01-24 08:53:35 +010041 atomic_t nr_tasks;
42
43 /* all the fields below are protected by this lock */
44 spinlock_t lock;
Jens Axboefd0928d2008-01-24 08:52:45 +010045
46 unsigned short ioprio;
Vivek Goyal31e4c282009-12-03 12:59:42 -050047
Jens Axboefd0928d2008-01-24 08:52:45 +010048 /*
49 * For request batching
50 */
Jens Axboefd0928d2008-01-24 08:52:45 +010051 int nr_batch_requests; /* Number of requests left in the batch */
Richard Kennedy58c24a62010-02-26 14:00:43 +010052 unsigned long last_waited; /* Time last woken after wait for request */
Jens Axboefd0928d2008-01-24 08:52:45 +010053
Tejun Heoc5869802011-12-14 00:33:41 +010054 struct radix_tree_root icq_tree;
55 struct io_cq __rcu *icq_hint;
56 struct hlist_head icq_list;
Tejun Heob2efa052011-12-14 00:33:39 +010057
58 struct work_struct release_work;
Jens Axboefd0928d2008-01-24 08:52:45 +010059};
60
Jens Axboed38ecf92008-01-24 08:53:35 +010061static inline struct io_context *ioc_task_link(struct io_context *ioc)
62{
63 /*
64 * if ref count is zero, don't allow sharing (ioc is going away, it's
65 * a race).
66 */
Nikanth Karthikesand9c7d392009-06-10 12:57:06 -070067 if (ioc && atomic_long_inc_not_zero(&ioc->refcount)) {
Li Zefancbb4f262009-07-31 08:55:48 +020068 atomic_inc(&ioc->nr_tasks);
Jens Axboed38ecf92008-01-24 08:53:35 +010069 return ioc;
Jens Axboed237e5c2008-04-15 09:25:33 +020070 }
Jens Axboed38ecf92008-01-24 08:53:35 +010071
72 return NULL;
73}
74
Louis Rillingb69f2292009-12-04 14:52:42 +010075struct task_struct;
Jens Axboeda9cbc82008-06-30 20:42:08 +020076#ifdef CONFIG_BLOCK
Tejun Heob2efa052011-12-14 00:33:39 +010077void put_io_context(struct io_context *ioc, struct request_queue *locked_q);
Louis Rillingb69f2292009-12-04 14:52:42 +010078void exit_io_context(struct task_struct *task);
Tejun Heo6e736be2011-12-14 00:33:38 +010079struct io_context *get_task_io_context(struct task_struct *task,
80 gfp_t gfp_flags, int node);
Tejun Heodc869002011-12-14 00:33:38 +010081void ioc_ioprio_changed(struct io_context *ioc, int ioprio);
82void ioc_cgroup_changed(struct io_context *ioc);
Jens Axboeda9cbc82008-06-30 20:42:08 +020083#else
Jens Axboeda9cbc82008-06-30 20:42:08 +020084struct io_context;
Tejun Heob2efa052011-12-14 00:33:39 +010085static inline void put_io_context(struct io_context *ioc,
86 struct request_queue *locked_q) { }
Tejun Heo42ec57a2011-12-14 00:33:37 +010087static inline void exit_io_context(struct task_struct *task) { }
Jens Axboeda9cbc82008-06-30 20:42:08 +020088#endif
89
Jens Axboefd0928d2008-01-24 08:52:45 +010090#endif