aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-ioc.c
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 /block/blk-ioc.c
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 'block/blk-ioc.c')
-rw-r--r--block/blk-ioc.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index b13ed96776c2..6f59fbad93d9 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -188,6 +188,51 @@ struct io_context *get_task_io_context(struct task_struct *task,
188} 188}
189EXPORT_SYMBOL(get_task_io_context); 189EXPORT_SYMBOL(get_task_io_context);
190 190
191void ioc_set_changed(struct io_context *ioc, int which)
192{
193 struct cfq_io_context *cic;
194 struct hlist_node *n;
195
196 hlist_for_each_entry(cic, n, &ioc->cic_list, cic_list)
197 set_bit(which, &cic->changed);
198}
199
200/**
201 * ioc_ioprio_changed - notify ioprio change
202 * @ioc: io_context of interest
203 * @ioprio: new ioprio
204 *
205 * @ioc's ioprio has changed to @ioprio. Set %CIC_IOPRIO_CHANGED for all
206 * cic's. iosched is responsible for checking the bit and applying it on
207 * request issue path.
208 */
209void ioc_ioprio_changed(struct io_context *ioc, int ioprio)
210{
211 unsigned long flags;
212
213 spin_lock_irqsave(&ioc->lock, flags);
214 ioc->ioprio = ioprio;
215 ioc_set_changed(ioc, CIC_IOPRIO_CHANGED);
216 spin_unlock_irqrestore(&ioc->lock, flags);
217}
218
219/**
220 * ioc_cgroup_changed - notify cgroup change
221 * @ioc: io_context of interest
222 *
223 * @ioc's cgroup has changed. Set %CIC_CGROUP_CHANGED for all cic's.
224 * iosched is responsible for checking the bit and applying it on request
225 * issue path.
226 */
227void ioc_cgroup_changed(struct io_context *ioc)
228{
229 unsigned long flags;
230
231 spin_lock_irqsave(&ioc->lock, flags);
232 ioc_set_changed(ioc, CIC_CGROUP_CHANGED);
233 spin_unlock_irqrestore(&ioc->lock, flags);
234}
235
191static int __init blk_ioc_init(void) 236static int __init blk_ioc_init(void)
192{ 237{
193 iocontext_cachep = kmem_cache_create("blkdev_ioc", 238 iocontext_cachep = kmem_cache_create("blkdev_ioc",