aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-03-05 16:15:26 -0500
committerJens Axboe <axboe@kernel.dk>2012-03-06 15:27:24 -0500
commitf6e8d01bee036460e03bd4f6a79d014f98ba712e (patch)
treeacaaab3667e0450f0f05464426c3540c89ce4e18 /block
parent3d48749d93a3dce732dd30a14002ab90ec4355f3 (diff)
block: add io_context->active_ref
Currently ioc->nr_tasks is used to decide two things - whether an ioc is done issuing IOs and whether it's shared by multiple tasks. This patch separate out the first into ioc->active_ref, which is acquired and released using {get|put}_io_context_active() respectively. This will be used to associate bio's with a given task. This patch doesn't introduce any visible behavior change. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/blk-ioc.c36
-rw-r--r--block/cfq-iosched.c4
2 files changed, 27 insertions, 13 deletions
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 10928740b5da..439ec21fd787 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -149,20 +149,20 @@ void put_io_context(struct io_context *ioc)
149} 149}
150EXPORT_SYMBOL(put_io_context); 150EXPORT_SYMBOL(put_io_context);
151 151
152/* Called by the exiting task */ 152/**
153void exit_io_context(struct task_struct *task) 153 * put_io_context_active - put active reference on ioc
154 * @ioc: ioc of interest
155 *
156 * Undo get_io_context_active(). If active reference reaches zero after
157 * put, @ioc can never issue further IOs and ioscheds are notified.
158 */
159void put_io_context_active(struct io_context *ioc)
154{ 160{
155 struct io_context *ioc;
156 struct io_cq *icq;
157 struct hlist_node *n; 161 struct hlist_node *n;
158 unsigned long flags; 162 unsigned long flags;
163 struct io_cq *icq;
159 164
160 task_lock(task); 165 if (!atomic_dec_and_test(&ioc->active_ref)) {
161 ioc = task->io_context;
162 task->io_context = NULL;
163 task_unlock(task);
164
165 if (!atomic_dec_and_test(&ioc->nr_tasks)) {
166 put_io_context(ioc); 166 put_io_context(ioc);
167 return; 167 return;
168 } 168 }
@@ -191,6 +191,20 @@ retry:
191 put_io_context(ioc); 191 put_io_context(ioc);
192} 192}
193 193
194/* Called by the exiting task */
195void exit_io_context(struct task_struct *task)
196{
197 struct io_context *ioc;
198
199 task_lock(task);
200 ioc = task->io_context;
201 task->io_context = NULL;
202 task_unlock(task);
203
204 atomic_dec(&ioc->nr_tasks);
205 put_io_context_active(ioc);
206}
207
194/** 208/**
195 * ioc_clear_queue - break any ioc association with the specified queue 209 * ioc_clear_queue - break any ioc association with the specified queue
196 * @q: request_queue being cleared 210 * @q: request_queue being cleared
@@ -223,7 +237,7 @@ int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node)
223 237
224 /* initialize */ 238 /* initialize */
225 atomic_long_set(&ioc->refcount, 1); 239 atomic_long_set(&ioc->refcount, 1);
226 atomic_set(&ioc->nr_tasks, 1); 240 atomic_set(&ioc->active_ref, 1);
227 spin_lock_init(&ioc->lock); 241 spin_lock_init(&ioc->lock);
228 INIT_RADIX_TREE(&ioc->icq_tree, GFP_ATOMIC | __GFP_HIGH); 242 INIT_RADIX_TREE(&ioc->icq_tree, GFP_ATOMIC | __GFP_HIGH);
229 INIT_HLIST_HEAD(&ioc->icq_list); 243 INIT_HLIST_HEAD(&ioc->icq_list);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9e386d9bcb79..9a4eac490e0b 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1865,7 +1865,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
1865 * task has exited, don't wait 1865 * task has exited, don't wait
1866 */ 1866 */
1867 cic = cfqd->active_cic; 1867 cic = cfqd->active_cic;
1868 if (!cic || !atomic_read(&cic->icq.ioc->nr_tasks)) 1868 if (!cic || !atomic_read(&cic->icq.ioc->active_ref))
1869 return; 1869 return;
1870 1870
1871 /* 1871 /*
@@ -2841,7 +2841,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
2841 2841
2842 if (cfqq->next_rq && (cfqq->next_rq->cmd_flags & REQ_NOIDLE)) 2842 if (cfqq->next_rq && (cfqq->next_rq->cmd_flags & REQ_NOIDLE))
2843 enable_idle = 0; 2843 enable_idle = 0;
2844 else if (!atomic_read(&cic->icq.ioc->nr_tasks) || 2844 else if (!atomic_read(&cic->icq.ioc->active_ref) ||
2845 !cfqd->cfq_slice_idle || 2845 !cfqd->cfq_slice_idle ||
2846 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq))) 2846 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
2847 enable_idle = 0; 2847 enable_idle = 0;