diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2009-12-03 12:59:50 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-12-03 13:28:52 -0500 |
commit | 8682e1f15f26dae9a9e8af794d179055fbd81166 (patch) | |
tree | d6e87631f91527656490df9b28be107fb5e974b0 | |
parent | 220841906fccafaf4094e87bdb6d252e20cf8c7c (diff) |
blkio: Provide some isolation between groups
o Do not allow following three operations across groups for isolation.
- selection of co-operating queues
- preemtpions across groups
- request merging across groups.
o Async queues are currently global and not per group. Allow preemption of
an async queue if a sync queue in other group gets backlogged.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | block/cfq-iosched.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7d345e772d88..3a62ce95daec 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -1461,6 +1461,9 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, | |||
1461 | struct cfq_io_context *cic; | 1461 | struct cfq_io_context *cic; |
1462 | struct cfq_queue *cfqq; | 1462 | struct cfq_queue *cfqq; |
1463 | 1463 | ||
1464 | /* Deny merge if bio and rq don't belong to same cfq group */ | ||
1465 | if ((RQ_CFQQ(rq))->cfqg != cfq_get_cfqg(cfqd, 0)) | ||
1466 | return false; | ||
1464 | /* | 1467 | /* |
1465 | * Disallow merge of a sync bio into an async request. | 1468 | * Disallow merge of a sync bio into an async request. |
1466 | */ | 1469 | */ |
@@ -1698,6 +1701,10 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd, | |||
1698 | if (!cfqq) | 1701 | if (!cfqq) |
1699 | return NULL; | 1702 | return NULL; |
1700 | 1703 | ||
1704 | /* If new queue belongs to different cfq_group, don't choose it */ | ||
1705 | if (cur_cfqq->cfqg != cfqq->cfqg) | ||
1706 | return NULL; | ||
1707 | |||
1701 | /* | 1708 | /* |
1702 | * It only makes sense to merge sync queues. | 1709 | * It only makes sense to merge sync queues. |
1703 | */ | 1710 | */ |
@@ -2950,22 +2957,12 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
2950 | if (!cfqq) | 2957 | if (!cfqq) |
2951 | return false; | 2958 | return false; |
2952 | 2959 | ||
2953 | if (cfq_slice_used(cfqq)) | ||
2954 | return true; | ||
2955 | |||
2956 | if (cfq_class_idle(new_cfqq)) | 2960 | if (cfq_class_idle(new_cfqq)) |
2957 | return false; | 2961 | return false; |
2958 | 2962 | ||
2959 | if (cfq_class_idle(cfqq)) | 2963 | if (cfq_class_idle(cfqq)) |
2960 | return true; | 2964 | return true; |
2961 | 2965 | ||
2962 | /* Allow preemption only if we are idling on sync-noidle tree */ | ||
2963 | if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD && | ||
2964 | cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD && | ||
2965 | new_cfqq->service_tree->count == 2 && | ||
2966 | RB_EMPTY_ROOT(&cfqq->sort_list)) | ||
2967 | return true; | ||
2968 | |||
2969 | /* | 2966 | /* |
2970 | * if the new request is sync, but the currently running queue is | 2967 | * if the new request is sync, but the currently running queue is |
2971 | * not, let the sync request have priority. | 2968 | * not, let the sync request have priority. |
@@ -2973,6 +2970,19 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
2973 | if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) | 2970 | if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) |
2974 | return true; | 2971 | return true; |
2975 | 2972 | ||
2973 | if (new_cfqq->cfqg != cfqq->cfqg) | ||
2974 | return false; | ||
2975 | |||
2976 | if (cfq_slice_used(cfqq)) | ||
2977 | return true; | ||
2978 | |||
2979 | /* Allow preemption only if we are idling on sync-noidle tree */ | ||
2980 | if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD && | ||
2981 | cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD && | ||
2982 | new_cfqq->service_tree->count == 2 && | ||
2983 | RB_EMPTY_ROOT(&cfqq->sort_list)) | ||
2984 | return true; | ||
2985 | |||
2976 | /* | 2986 | /* |
2977 | * So both queues are sync. Let the new request get disk time if | 2987 | * So both queues are sync. Let the new request get disk time if |
2978 | * it's a metadata request and the current queue is doing regular IO. | 2988 | * it's a metadata request and the current queue is doing regular IO. |