From: Nick Piggin <nickpiggin@yahoo.com.au>
To: Andrew Morton <akpm@osdl.org>
Cc: Jens Axboe <axboe@suse.de>,
linux-kernel <linux-kernel@vger.kernel.org>,
"Chen, Kenneth W" <kenneth.w.chen@intel.com>
Subject: [patch 7/9] blk: efficiency improvements
Date: Tue, 12 Apr 2005 22:51:41 +1000 [thread overview]
Message-ID: <425BC45D.9030504@yahoo.com.au> (raw)
In-Reply-To: <425BC262.1070500@yahoo.com.au>
[-- Attachment #1: Type: text/plain, Size: 32 bytes --]
7/9
--
SUSE Labs, Novell Inc.
[-- Attachment #2: blk-efficient.patch --]
[-- Type: text/plain, Size: 3583 bytes --]
In the case where the request is not able to be merged by the elevator,
don't retake the lock and retry the merge mechanism after allocating a
new request.
Instead assume that the chance of a merge remains slim, and now that
we've done most of the work allocating a request we may as well just
go with it.
Also be rid of the GFP_ATOMIC allocation: we've got working mempools
for the block layer now, so let's save atomic memory for things like
networking.
Lastly, in get_request_wait, do an initial get_request call before
going into the waitqueue. This is reported to help efficiency.
Signed-off-by: Nick Piggin <nickpiggin@yahoo.com.au>
Index: linux-2.6/drivers/block/ll_rw_blk.c
===================================================================
--- linux-2.6.orig/drivers/block/ll_rw_blk.c 2005-04-12 22:26:14.000000000 +1000
+++ linux-2.6/drivers/block/ll_rw_blk.c 2005-04-12 22:26:14.000000000 +1000
@@ -1952,10 +1952,11 @@ out:
*/
static struct request *get_request_wait(request_queue_t *q, int rw)
{
- DEFINE_WAIT(wait);
struct request *rq;
- do {
+ rq = get_request(q, rw, GFP_NOIO);
+ while (!rq) {
+ DEFINE_WAIT(wait);
struct request_list *rl = &q->rq;
prepare_to_wait_exclusive(&rl->wait[rw], &wait,
@@ -1980,7 +1981,7 @@ static struct request *get_request_wait(
put_io_context(ioc);
}
finish_wait(&rl->wait[rw], &wait);
- } while (!rq);
+ }
return rq;
}
@@ -2557,7 +2558,7 @@ EXPORT_SYMBOL(__blk_attempt_remerge);
static int __make_request(request_queue_t *q, struct bio *bio)
{
- struct request *req, *freereq = NULL;
+ struct request *req;
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err;
sector_t sector;
@@ -2582,14 +2583,9 @@ static int __make_request(request_queue_
goto end_io;
}
-again:
spin_lock_irq(q->queue_lock);
- if (elv_queue_empty(q)) {
- blk_plug_device(q);
- goto get_rq;
- }
- if (barrier)
+ if (unlikely(barrier) || elv_queue_empty(q))
goto get_rq;
el_ret = elv_merge(q, &req, bio);
@@ -2632,40 +2628,23 @@ again:
elv_merged_request(q, req);
goto out;
- /*
- * elevator says don't/can't merge. get new request
- */
- case ELEVATOR_NO_MERGE:
- break;
-
+ /* ELV_NO_MERGE: elevator says don't/can't merge. */
default:
- printk("elevator returned crap (%d)\n", el_ret);
- BUG();
+ ;
}
+get_rq:
/*
- * Grab a free request from the freelist - if that is empty, check
- * if we are doing read ahead and abort instead of blocking for
- * a free slot.
+ * Grab a free request. This is might sleep but can not fail.
+ */
+ spin_unlock_irq(q->queue_lock);
+ req = get_request_wait(q, rw);
+ /*
+ * After dropping the lock and possibly sleeping here, our request
+ * may now be mergeable after it had proven unmergeable (above).
+ * We don't worry about that case for efficiency. It won't happen
+ * often, and the elevators are able to handle it.
*/
-get_rq:
- if (freereq) {
- req = freereq;
- freereq = NULL;
- } else {
- spin_unlock_irq(q->queue_lock);
- if ((freereq = get_request(q, rw, GFP_ATOMIC)) == NULL) {
- /*
- * READA bit set
- */
- err = -EWOULDBLOCK;
- if (bio_rw_ahead(bio))
- goto end_io;
-
- freereq = get_request_wait(q, rw);
- }
- goto again;
- }
req->flags |= REQ_CMD;
@@ -2693,10 +2672,11 @@ get_rq:
req->rq_disk = bio->bi_bdev->bd_disk;
req->start_time = jiffies;
+ spin_lock_irq(q->queue_lock);
+ if (elv_queue_empty(q))
+ blk_plug_device(q);
add_request(q, req);
out:
- if (freereq)
- __blk_put_request(q, freereq);
if (bio_sync(bio))
__generic_unplug_device(q);
next prev parent reply other threads:[~2005-04-12 13:02 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-12 12:43 [patch 0/9] various (mainly mempool fixes and block layer improvements) Nick Piggin
2005-04-12 12:48 ` [patch 1/9] GFP_ZERO fix Nick Piggin
2005-04-12 19:47 ` Andrew Morton
2005-04-13 1:02 ` Nick Piggin
2005-04-14 10:59 ` Manfred Spraul
2005-04-12 12:48 ` [patch 2/9] mempool gfp flag Nick Piggin
2005-04-12 19:50 ` Andrew Morton
2005-04-13 1:03 ` Nick Piggin
2005-04-12 12:49 ` [patch 3/9] no PF_MEMALLOC tinkering Nick Piggin
2005-04-12 19:57 ` Andrew Morton
2005-04-13 1:13 ` Nick Piggin
2005-04-12 12:49 ` [patch 4/9] blk: no memory barrier Nick Piggin
2005-04-12 12:50 ` [patch 5/9] blk: branch hints Nick Piggin
2005-04-12 12:50 ` [patch 6/9] blk: unplug later Nick Piggin
2005-04-12 19:58 ` Andrew Morton
2005-04-13 1:32 ` Nick Piggin
2005-04-13 10:20 ` Jens Axboe
2005-04-12 12:51 ` Nick Piggin [this message]
2005-04-12 12:52 ` [patch 0/9] blk: reduce locking Nick Piggin
2005-04-12 12:53 ` [patch doh/9] mempool simplify alloc Nick Piggin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=425BC45D.9030504@yahoo.com.au \
--to=nickpiggin@yahoo.com.au \
--cc=akpm@osdl.org \
--cc=axboe@suse.de \
--cc=kenneth.w.chen@intel.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.