diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2006-12-13 07:02:26 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2006-12-13 07:02:26 -0500 |
commit | 7749a8d423c483a51983b666613acda1a4dd9c1b (patch) | |
tree | 5a2a20640cca9ca519324b7933005f6fd9c4a6a5 | |
parent | 445722f97a0ecd3aed3f53d9f0dcaacaef8c6223 (diff) |
[PATCH] Propagate down request sync flag
We need to do this, otherwise the io schedulers don't get access to the
sync flag. Then they cannot tell the difference between a regular write
and an O_DIRECT write, which can cause a performance loss.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | block/cfq-iosched.c | 18 | ||||
-rw-r--r-- | block/ll_rw_blk.c | 28 |
2 files changed, 32 insertions, 14 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 78c6b312bd30..533a2938ffd6 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -219,9 +219,12 @@ static int cfq_queue_empty(request_queue_t *q) | |||
219 | return !cfqd->busy_queues; | 219 | return !cfqd->busy_queues; |
220 | } | 220 | } |
221 | 221 | ||
222 | static inline pid_t cfq_queue_pid(struct task_struct *task, int rw) | 222 | static inline pid_t cfq_queue_pid(struct task_struct *task, int rw, int is_sync) |
223 | { | 223 | { |
224 | if (rw == READ || rw == WRITE_SYNC) | 224 | /* |
225 | * Use the per-process queue, for read requests and syncronous writes | ||
226 | */ | ||
227 | if (!(rw & REQ_RW) || is_sync) | ||
225 | return task->pid; | 228 | return task->pid; |
226 | 229 | ||
227 | return CFQ_KEY_ASYNC; | 230 | return CFQ_KEY_ASYNC; |
@@ -473,7 +476,7 @@ static struct request * | |||
473 | cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio) | 476 | cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio) |
474 | { | 477 | { |
475 | struct task_struct *tsk = current; | 478 | struct task_struct *tsk = current; |
476 | pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio)); | 479 | pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio), bio_sync(bio)); |
477 | struct cfq_queue *cfqq; | 480 | struct cfq_queue *cfqq; |
478 | 481 | ||
479 | cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio); | 482 | cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio); |
@@ -1748,6 +1751,9 @@ static int cfq_may_queue(request_queue_t *q, int rw) | |||
1748 | struct cfq_data *cfqd = q->elevator->elevator_data; | 1751 | struct cfq_data *cfqd = q->elevator->elevator_data; |
1749 | struct task_struct *tsk = current; | 1752 | struct task_struct *tsk = current; |
1750 | struct cfq_queue *cfqq; | 1753 | struct cfq_queue *cfqq; |
1754 | unsigned int key; | ||
1755 | |||
1756 | key = cfq_queue_pid(tsk, rw, rw & REQ_RW_SYNC); | ||
1751 | 1757 | ||
1752 | /* | 1758 | /* |
1753 | * don't force setup of a queue from here, as a call to may_queue | 1759 | * don't force setup of a queue from here, as a call to may_queue |
@@ -1755,7 +1761,7 @@ static int cfq_may_queue(request_queue_t *q, int rw) | |||
1755 | * so just lookup a possibly existing queue, or return 'may queue' | 1761 | * so just lookup a possibly existing queue, or return 'may queue' |
1756 | * if that fails | 1762 | * if that fails |
1757 | */ | 1763 | */ |
1758 | cfqq = cfq_find_cfq_hash(cfqd, cfq_queue_pid(tsk, rw), tsk->ioprio); | 1764 | cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio); |
1759 | if (cfqq) { | 1765 | if (cfqq) { |
1760 | cfq_init_prio_data(cfqq); | 1766 | cfq_init_prio_data(cfqq); |
1761 | cfq_prio_boost(cfqq); | 1767 | cfq_prio_boost(cfqq); |
@@ -1798,10 +1804,10 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) | |||
1798 | struct task_struct *tsk = current; | 1804 | struct task_struct *tsk = current; |
1799 | struct cfq_io_context *cic; | 1805 | struct cfq_io_context *cic; |
1800 | const int rw = rq_data_dir(rq); | 1806 | const int rw = rq_data_dir(rq); |
1801 | pid_t key = cfq_queue_pid(tsk, rw); | 1807 | const int is_sync = rq_is_sync(rq); |
1808 | pid_t key = cfq_queue_pid(tsk, rw, is_sync); | ||
1802 | struct cfq_queue *cfqq; | 1809 | struct cfq_queue *cfqq; |
1803 | unsigned long flags; | 1810 | unsigned long flags; |
1804 | int is_sync = key != CFQ_KEY_ASYNC; | ||
1805 | 1811 | ||
1806 | might_sleep_if(gfp_mask & __GFP_WAIT); | 1812 | might_sleep_if(gfp_mask & __GFP_WAIT); |
1807 | 1813 | ||
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index a541b42c08e3..79807dbc306e 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -2058,15 +2058,16 @@ static void freed_request(request_queue_t *q, int rw, int priv) | |||
2058 | * Returns NULL on failure, with queue_lock held. | 2058 | * Returns NULL on failure, with queue_lock held. |
2059 | * Returns !NULL on success, with queue_lock *not held*. | 2059 | * Returns !NULL on success, with queue_lock *not held*. |
2060 | */ | 2060 | */ |
2061 | static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, | 2061 | static struct request *get_request(request_queue_t *q, int rw_flags, |
2062 | gfp_t gfp_mask) | 2062 | struct bio *bio, gfp_t gfp_mask) |
2063 | { | 2063 | { |
2064 | struct request *rq = NULL; | 2064 | struct request *rq = NULL; |
2065 | struct request_list *rl = &q->rq; | 2065 | struct request_list *rl = &q->rq; |
2066 | struct io_context *ioc = NULL; | 2066 | struct io_context *ioc = NULL; |
2067 | const int rw = rw_flags & 0x01; | ||
2067 | int may_queue, priv; | 2068 | int may_queue, priv; |
2068 | 2069 | ||
2069 | may_queue = elv_may_queue(q, rw); | 2070 | may_queue = elv_may_queue(q, rw_flags); |
2070 | if (may_queue == ELV_MQUEUE_NO) | 2071 | if (may_queue == ELV_MQUEUE_NO) |
2071 | goto rq_starved; | 2072 | goto rq_starved; |
2072 | 2073 | ||
@@ -2114,7 +2115,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, | |||
2114 | 2115 | ||
2115 | spin_unlock_irq(q->queue_lock); | 2116 | spin_unlock_irq(q->queue_lock); |
2116 | 2117 | ||
2117 | rq = blk_alloc_request(q, rw, priv, gfp_mask); | 2118 | rq = blk_alloc_request(q, rw_flags, priv, gfp_mask); |
2118 | if (unlikely(!rq)) { | 2119 | if (unlikely(!rq)) { |
2119 | /* | 2120 | /* |
2120 | * Allocation failed presumably due to memory. Undo anything | 2121 | * Allocation failed presumably due to memory. Undo anything |
@@ -2162,12 +2163,13 @@ out: | |||
2162 | * | 2163 | * |
2163 | * Called with q->queue_lock held, and returns with it unlocked. | 2164 | * Called with q->queue_lock held, and returns with it unlocked. |
2164 | */ | 2165 | */ |
2165 | static struct request *get_request_wait(request_queue_t *q, int rw, | 2166 | static struct request *get_request_wait(request_queue_t *q, int rw_flags, |
2166 | struct bio *bio) | 2167 | struct bio *bio) |
2167 | { | 2168 | { |
2169 | const int rw = rw_flags & 0x01; | ||
2168 | struct request *rq; | 2170 | struct request *rq; |
2169 | 2171 | ||
2170 | rq = get_request(q, rw, bio, GFP_NOIO); | 2172 | rq = get_request(q, rw_flags, bio, GFP_NOIO); |
2171 | while (!rq) { | 2173 | while (!rq) { |
2172 | DEFINE_WAIT(wait); | 2174 | DEFINE_WAIT(wait); |
2173 | struct request_list *rl = &q->rq; | 2175 | struct request_list *rl = &q->rq; |
@@ -2175,7 +2177,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw, | |||
2175 | prepare_to_wait_exclusive(&rl->wait[rw], &wait, | 2177 | prepare_to_wait_exclusive(&rl->wait[rw], &wait, |
2176 | TASK_UNINTERRUPTIBLE); | 2178 | TASK_UNINTERRUPTIBLE); |
2177 | 2179 | ||
2178 | rq = get_request(q, rw, bio, GFP_NOIO); | 2180 | rq = get_request(q, rw_flags, bio, GFP_NOIO); |
2179 | 2181 | ||
2180 | if (!rq) { | 2182 | if (!rq) { |
2181 | struct io_context *ioc; | 2183 | struct io_context *ioc; |
@@ -2910,6 +2912,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) | |||
2910 | int el_ret, nr_sectors, barrier, err; | 2912 | int el_ret, nr_sectors, barrier, err; |
2911 | const unsigned short prio = bio_prio(bio); | 2913 | const unsigned short prio = bio_prio(bio); |
2912 | const int sync = bio_sync(bio); | 2914 | const int sync = bio_sync(bio); |
2915 | int rw_flags; | ||
2913 | 2916 | ||
2914 | nr_sectors = bio_sectors(bio); | 2917 | nr_sectors = bio_sectors(bio); |
2915 | 2918 | ||
@@ -2984,10 +2987,19 @@ static int __make_request(request_queue_t *q, struct bio *bio) | |||
2984 | 2987 | ||
2985 | get_rq: | 2988 | get_rq: |
2986 | /* | 2989 | /* |
2990 | * This sync check and mask will be re-done in init_request_from_bio(), | ||
2991 | * but we need to set it earlier to expose the sync flag to the | ||
2992 | * rq allocator and io schedulers. | ||
2993 | */ | ||
2994 | rw_flags = bio_data_dir(bio); | ||
2995 | if (sync) | ||
2996 | rw_flags |= REQ_RW_SYNC; | ||
2997 | |||
2998 | /* | ||
2987 | * Grab a free request. This is might sleep but can not fail. | 2999 | * Grab a free request. This is might sleep but can not fail. |
2988 | * Returns with the queue unlocked. | 3000 | * Returns with the queue unlocked. |
2989 | */ | 3001 | */ |
2990 | req = get_request_wait(q, bio_data_dir(bio), bio); | 3002 | req = get_request_wait(q, rw_flags, bio); |
2991 | 3003 | ||
2992 | /* | 3004 | /* |
2993 | * After dropping the lock and possibly sleeping here, our request | 3005 | * After dropping the lock and possibly sleeping here, our request |