From: Peter Osterlund <petero2@telia.com>
To: Andrew Morton <akpm@osdl.org>
Cc: axboe@suse.de, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Speed up the cdrw packet writing driver
Date: 29 Aug 2004 14:17:34 +0200 [thread overview]
Message-ID: <m3isb2dtpd.fsf@telia.com> (raw)
In-Reply-To: 20040828142332.4bbce4fc.akpm@osdl.org
Andrew Morton <akpm@osdl.org> writes:
> Peter Osterlund <petero2@telia.com> wrote:
> >
> > OK, this should make sure that dirty data is flushed as fast as the
> > disks can handle, but is there anything that makes sure there will be
> > enough dirty data to flush for each disk?
>
> Page allocation is fairly decoupled from the dirty memory thresholds. The
> process which wants to write to the fast disk will skirt around the pages
> which are dirty against the slow disk and will reclaim clean pagecache
> instead. So the writer to the fast disk _should_ be able to allocate pages
> sufficiently quickly.
>
> The balance_dirty_pages() logic doesn't care (or know) about whether the
> pages are dirty against a slow device of a fast one - it just keeps the
> queues full while clamping the amount of dirty memory. I do think that
> it's possible for the writer to the fast device to get blocked in
> balance_dirty_pages() due to there being lots of dirty pages against a slow
> device.
>
> Or not - the fact that the fast device retires writes more quickly will
> cause waiters in balance_dirty_pages() to unblock promptly.
>
> Or not not - we'll probably get into the situation where almost all of the
> dirty pages are dirty against the slower device.
>
> hm. It needs some verification testing.
I ran some more tests with the patch below, which marks the queue
congested as Jens suggested. I started a dd process writing to the DVD
and got a stable 5.3MB/s writing speed. Then I waited until 400MB
memory was dirty and started a second dd process writing to the hard
disk. This dd process now writes at 45MB/s. The bio queue in the
packet driver stays at ~4000 entries during the test, so I think this
proves that the VM *can* handle two devices well even though they have
very different write bandwidths.
However, all is not well, because write performance on the DVD goes to
~200kb/s when I start the second dd process (because of lots of read
gathering in the packet driver) and as I noted in an earlier mail,
write performance is also bad if many files are written, even when
there are no concurrent writes to the hard disk.
If I dd directly to /dev/pktcdvd/0 instead of a file on a udf or ext2
filesystem, I don't see the DVD write speed slowdown when I start the
second dd process that writes to the hard disk. For some reason, dirty
data is flushed in a suboptimal order when the udf or ext2 filesystems
are involved.
---
linux-petero/drivers/block/ll_rw_blk.c | 6 ++++--
linux-petero/drivers/block/pktcdvd.c | 8 ++++++++
linux-petero/include/linux/blkdev.h | 2 ++
3 files changed, 14 insertions(+), 2 deletions(-)
diff -puN drivers/block/pktcdvd.c~packet-congest drivers/block/pktcdvd.c
--- linux/drivers/block/pktcdvd.c~packet-congest 2004-08-28 10:18:48.000000000 +0200
+++ linux-petero/drivers/block/pktcdvd.c 2004-08-29 13:21:20.000000000 +0200
@@ -981,6 +981,9 @@ try_next_bio:
}
spin_unlock(&pd->lock);
+ if (pd->bio_queue_size < 3600)
+ clear_queue_congested(pd->disk->queue, WRITE);
+
pkt->sleep_time = max(PACKET_WAIT_TIME, 1);
pkt_set_state(pkt, PACKET_WAITING_STATE);
atomic_set(&pkt->run_sm, 1);
@@ -2159,6 +2162,11 @@ static int pkt_make_request(request_queu
goto end_io;
}
+ if (pd->bio_queue_size >= 4096)
+ set_queue_congested(q, WRITE);
+ while (pd->bio_queue_size >= 4200)
+ blk_congestion_wait(WRITE, HZ / 10);
+
blk_queue_bounce(q, &bio);
zone = ZONE(bio->bi_sector, pd);
diff -puN drivers/block/ll_rw_blk.c~packet-congest drivers/block/ll_rw_blk.c
--- linux/drivers/block/ll_rw_blk.c~packet-congest 2004-08-28 19:27:46.000000000 +0200
+++ linux-petero/drivers/block/ll_rw_blk.c 2004-08-28 19:28:31.000000000 +0200
@@ -111,7 +111,7 @@ static void blk_queue_congestion_thresho
* congested queues, and wake up anyone who was waiting for requests to be
* put back.
*/
-static void clear_queue_congested(request_queue_t *q, int rw)
+void clear_queue_congested(request_queue_t *q, int rw)
{
enum bdi_state bit;
wait_queue_head_t *wqh = &congestion_wqh[rw];
@@ -122,18 +122,20 @@ static void clear_queue_congested(reques
if (waitqueue_active(wqh))
wake_up(wqh);
}
+EXPORT_SYMBOL(clear_queue_congested);
/*
* A queue has just entered congestion. Flag that in the queue's VM-visible
* state flags and increment the global gounter of congested queues.
*/
-static void set_queue_congested(request_queue_t *q, int rw)
+void set_queue_congested(request_queue_t *q, int rw)
{
enum bdi_state bit;
bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
set_bit(bit, &q->backing_dev_info.state);
}
+EXPORT_SYMBOL(set_queue_congested);
/**
* blk_get_backing_dev_info - get the address of a queue's backing_dev_info
diff -puN include/linux/blkdev.h~packet-congest include/linux/blkdev.h
--- linux/include/linux/blkdev.h~packet-congest 2004-08-29 13:08:50.000000000 +0200
+++ linux-petero/include/linux/blkdev.h 2004-08-29 13:11:30.000000000 +0200
@@ -518,6 +518,8 @@ extern void blk_recount_segments(request
extern int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *);
extern int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *);
extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *);
+extern void clear_queue_congested(request_queue_t *q, int rw);
+extern void set_queue_congested(request_queue_t *q, int rw);
extern void blk_start_queue(request_queue_t *q);
extern void blk_stop_queue(request_queue_t *q);
extern void __blk_stop_queue(request_queue_t *q);
_
--
Peter Osterlund - petero2@telia.com
http://w1.894.telia.com/~u89404340
prev parent reply other threads:[~2004-08-29 12:18 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-14 19:13 [PATCH] Speed up the cdrw packet writing driver Peter Osterlund
2004-08-23 11:43 ` Jens Axboe
2004-08-23 16:07 ` Peter Osterlund
2004-08-24 20:29 ` Jens Axboe
2004-08-24 21:04 ` Peter Osterlund
2004-08-24 21:47 ` Andrew Morton
2004-08-24 21:57 ` Lee Revell
2004-08-29 13:52 ` Alan Cox
2004-08-24 22:03 ` Peter Osterlund
2004-08-24 22:56 ` Andrew Morton
2004-08-25 5:38 ` Peter Osterlund
2004-08-25 6:50 ` Jens Axboe
2004-08-28 9:59 ` Peter Osterlund
2004-08-28 13:07 ` Jens Axboe
2004-08-28 18:42 ` Peter Osterlund
2004-08-28 19:45 ` Andrew Morton
2004-08-28 20:57 ` Peter Osterlund
2004-08-28 21:23 ` Andrew Morton
2004-08-29 12:17 ` Peter Osterlund [this message]
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=m3isb2dtpd.fsf@telia.com \
--to=petero2@telia.com \
--cc=akpm@osdl.org \
--cc=axboe@suse.de \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox