aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/iocontext.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-12-13 18:33:38 -0500
committerJens Axboe <axboe@kernel.dk>2011-12-13 18:33:38 -0500
commitdc86900e0a8f665122de6faadd27fb4c6d2b3e4d (patch)
treeec24aa4b076f54fcfb0558d5113f5c5e0f4bc173 /include/linux/iocontext.h
parent283287a52e3c3f7f8f9da747f4b8c5202740d776 (diff)
block, cfq: move ioc ioprio/cgroup changed handling to cic
ioprio/cgroup change was handled by marking the changed state in ioc and, on the following access to the ioc, performing RCU-protected iteration through all cic's grabbing the matching queue_lock. This patch moves the changed state to each cic. When ioprio or cgroup changes, the respective bit is set on all cic's of the ioc and when each of those cic (not ioc) is accessed, change is applied for that specific ioc-queue pair. This also fixes the following two race conditions between setting and clearing of changed states. * Missing barrier between assign/load of ioprio and ioprio_changed allowed applying old ioprio. * Change requests could happen between application of change and clearing of changed variables. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux/iocontext.h')
-rw-r--r--include/linux/iocontext.h14
1 files changed, 9 insertions, 5 deletions
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index 079aea8fd8a8..2c2b6da96b3c 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -13,6 +13,11 @@ struct cfq_ttime {
13 unsigned long ttime_mean; 13 unsigned long ttime_mean;
14}; 14};
15 15
16enum {
17 CIC_IOPRIO_CHANGED,
18 CIC_CGROUP_CHANGED,
19};
20
16struct cfq_io_context { 21struct cfq_io_context {
17 void *key; 22 void *key;
18 struct request_queue *q; 23 struct request_queue *q;
@@ -26,6 +31,8 @@ struct cfq_io_context {
26 struct list_head queue_list; 31 struct list_head queue_list;
27 struct hlist_node cic_list; 32 struct hlist_node cic_list;
28 33
34 unsigned long changed;
35
29 void (*dtor)(struct io_context *); /* destructor */ 36 void (*dtor)(struct io_context *); /* destructor */
30 void (*exit)(struct io_context *); /* called on task exit */ 37 void (*exit)(struct io_context *); /* called on task exit */
31 38
@@ -44,11 +51,6 @@ struct io_context {
44 spinlock_t lock; 51 spinlock_t lock;
45 52
46 unsigned short ioprio; 53 unsigned short ioprio;
47 unsigned short ioprio_changed;
48
49#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
50 unsigned short cgroup_changed;
51#endif
52 54
53 /* 55 /*
54 * For request batching 56 * For request batching
@@ -81,6 +83,8 @@ void put_io_context(struct io_context *ioc);
81void exit_io_context(struct task_struct *task); 83void exit_io_context(struct task_struct *task);
82struct io_context *get_task_io_context(struct task_struct *task, 84struct io_context *get_task_io_context(struct task_struct *task,
83 gfp_t gfp_flags, int node); 85 gfp_t gfp_flags, int node);
86void ioc_ioprio_changed(struct io_context *ioc, int ioprio);
87void ioc_cgroup_changed(struct io_context *ioc);
84#else 88#else
85struct io_context; 89struct io_context;
86static inline void put_io_context(struct io_context *ioc) { } 90static inline void put_io_context(struct io_context *ioc) { }