diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2009-12-03 12:59:51 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-12-03 13:28:52 -0500 |
commit | 24610333d578478d354144ab4709a203684afc5f (patch) | |
tree | d258c695cfa320845212f71e8900af4d90538d6b | |
parent | 8682e1f15f26dae9a9e8af794d179055fbd81166 (diff) |
blkio: Drop the reference to queue once the task changes cgroup
o If a task changes cgroup, drop reference to the cfqq associated with io
context and set cfqq pointer stored in ioc to NULL so that upon next request
arrival we will allocate a new queue in new group.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | block/cfq-iosched.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 3a62ce95daec..3d99e45789bd 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -2608,6 +2608,41 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
2608 | cfqq->pid = pid; | 2608 | cfqq->pid = pid; |
2609 | } | 2609 | } |
2610 | 2610 | ||
2611 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
2612 | static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic) | ||
2613 | { | ||
2614 | struct cfq_queue *sync_cfqq = cic_to_cfqq(cic, 1); | ||
2615 | struct cfq_data *cfqd = cic->key; | ||
2616 | unsigned long flags; | ||
2617 | struct request_queue *q; | ||
2618 | |||
2619 | if (unlikely(!cfqd)) | ||
2620 | return; | ||
2621 | |||
2622 | q = cfqd->queue; | ||
2623 | |||
2624 | spin_lock_irqsave(q->queue_lock, flags); | ||
2625 | |||
2626 | if (sync_cfqq) { | ||
2627 | /* | ||
2628 | * Drop reference to sync queue. A new sync queue will be | ||
2629 | * assigned in new group upon arrival of a fresh request. | ||
2630 | */ | ||
2631 | cfq_log_cfqq(cfqd, sync_cfqq, "changed cgroup"); | ||
2632 | cic_set_cfqq(cic, NULL, 1); | ||
2633 | cfq_put_queue(sync_cfqq); | ||
2634 | } | ||
2635 | |||
2636 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
2637 | } | ||
2638 | |||
2639 | static void cfq_ioc_set_cgroup(struct io_context *ioc) | ||
2640 | { | ||
2641 | call_for_each_cic(ioc, changed_cgroup); | ||
2642 | ioc->cgroup_changed = 0; | ||
2643 | } | ||
2644 | #endif /* CONFIG_CFQ_GROUP_IOSCHED */ | ||
2645 | |||
2611 | static struct cfq_queue * | 2646 | static struct cfq_queue * |
2612 | cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync, | 2647 | cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync, |
2613 | struct io_context *ioc, gfp_t gfp_mask) | 2648 | struct io_context *ioc, gfp_t gfp_mask) |
@@ -2840,6 +2875,10 @@ out: | |||
2840 | if (unlikely(ioc->ioprio_changed)) | 2875 | if (unlikely(ioc->ioprio_changed)) |
2841 | cfq_ioc_set_ioprio(ioc); | 2876 | cfq_ioc_set_ioprio(ioc); |
2842 | 2877 | ||
2878 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
2879 | if (unlikely(ioc->cgroup_changed)) | ||
2880 | cfq_ioc_set_cgroup(ioc); | ||
2881 | #endif | ||
2843 | return cic; | 2882 | return cic; |
2844 | err_free: | 2883 | err_free: |
2845 | cfq_cic_free(cic); | 2884 | cfq_cic_free(cic); |