From: Peter Osterlund <petero2@telia.com>
To: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: linux-kernel@vger.kernel.org, Jens Axboe <axboe@suse.de>
Subject: Re: [2.6.13] pktcdvd: IO-errors
Date: 02 Oct 2005 14:11:47 +0200 [thread overview]
Message-ID: <m3k6gw86f0.fsf@telia.com> (raw)
In-Reply-To: <Pine.LNX.4.60.0509292116260.11615@poirot.grange>
Guennadi Liakhovetski <g.liakhovetski@gmx.de> writes:
> On Wed, 28 Sep 2005, Peter Osterlund wrote:
>
> > That patch changes the logic that decides when the driver should
> > change between reading and writing. However, the read/write/sync
> > sequence that makes your drive fail in 2.6.13 could theoretically
> > happen in 2.6.12 as well if you are unlucky.
>
> Well, I didn't test it extensively - it was the first time I tried it
> under 2.6.13.
>
> > I think some trial and error will be required to figure out what
> > causes your drive to fail. If you apply this patch to 2.6.12, does it
> > still work?
>
> Yes, it does...
OK, in that case this patch for 2.6.12 should work as well, because
all it does compared to the previous patch is to remove the now unused
high_prio_read variables. Can you confirm that it works?
(Continue reading, more after this patch.)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -467,14 +467,12 @@ static int pkt_set_speed(struct pktcdvd_
* Queue a bio for processing by the low-level CD device. Must be called
* from process context.
*/
-static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_prio_read)
+static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
{
spin_lock(&pd->iosched.lock);
if (bio_data_dir(bio) == READ) {
pkt_add_list_last(bio, &pd->iosched.read_queue,
&pd->iosched.read_queue_tail);
- if (high_prio_read)
- pd->iosched.high_prio_read = 1;
} else {
pkt_add_list_last(bio, &pd->iosched.write_queue,
&pd->iosched.write_queue_tail);
@@ -490,15 +488,16 @@ static void pkt_queue_bio(struct pktcdvd
* requirements for CDRW drives:
* - A cache flush command must be inserted before a read request if the
* previous request was a write.
- * - Switching between reading and writing is slow, so don't it more often
+ * - Switching between reading and writing is slow, so don't do it more often
* than necessary.
+ * - Optimize for throughput at the expense of latency. This means that streaming
+ * writes will never be interrupted by a read, but if the drive has to seek
+ * before the next write, switch to reading instead if there are any pending
+ * read requests.
* - Set the read speed according to current usage pattern. When only reading
* from the device, it's best to use the highest possible read speed, but
* when switching often between reading and writing, it's better to have the
* same read and write speeds.
- * - Reads originating from user space should have higher priority than reads
- * originating from pkt_gather_data, because some process is usually waiting
- * on reads of the first kind.
*/
static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
{
@@ -512,21 +511,18 @@ static void pkt_iosched_process_queue(st
for (;;) {
struct bio *bio;
- int reads_queued, writes_queued, high_prio_read;
+ int reads_queued, writes_queued;
spin_lock(&pd->iosched.lock);
reads_queued = (pd->iosched.read_queue != NULL);
writes_queued = (pd->iosched.write_queue != NULL);
- if (!reads_queued)
- pd->iosched.high_prio_read = 0;
- high_prio_read = pd->iosched.high_prio_read;
spin_unlock(&pd->iosched.lock);
if (!reads_queued && !writes_queued)
break;
if (pd->iosched.writing) {
- if (high_prio_read || (!writes_queued && reads_queued)) {
+ if (!writes_queued && reads_queued) {
if (atomic_read(&pd->cdrw.pending_bios) > 0) {
VPRINTK("pktcdvd: write, waiting\n");
break;
@@ -559,8 +555,9 @@ static void pkt_iosched_process_queue(st
if (bio_data_dir(bio) == READ)
pd->iosched.successive_reads += bio->bi_size >> 10;
- else
+ else {
pd->iosched.successive_reads = 0;
+ }
if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) {
if (pd->read_speed == pd->write_speed) {
pd->read_speed = MAX_SPEED;
@@ -765,7 +762,7 @@ static void pkt_gather_data(struct pktcd
atomic_inc(&pkt->io_wait);
bio->bi_rw = READ;
- pkt_queue_bio(pd, bio, 0);
+ pkt_queue_bio(pd, bio);
frames_read++;
}
@@ -1062,7 +1059,7 @@ static void pkt_start_write(struct pktcd
atomic_set(&pkt->io_wait, 1);
pkt->w_bio->bi_rw = WRITE;
- pkt_queue_bio(pd, pkt->w_bio, 0);
+ pkt_queue_bio(pd, pkt->w_bio);
}
static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
@@ -2120,7 +2117,7 @@ static int pkt_make_request(request_queu
cloned_bio->bi_private = psd;
cloned_bio->bi_end_io = pkt_end_io_read_cloned;
pd->stats.secs_r += bio->bi_size >> 9;
- pkt_queue_bio(pd, cloned_bio, 1);
+ pkt_queue_bio(pd, cloned_bio);
return 0;
}
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -159,7 +159,6 @@ struct packet_iosched
struct bio *read_queue_tail;
struct bio *write_queue;
struct bio *write_queue_tail;
- int high_prio_read; /* An important read request has been queued */
int successive_reads;
};
With that patch for 2.6.12, the diff compared to 2.6.13 now looks like
below. Can you confirm that reverse applying this patch for 2.6.13
also works?
--- linux-2612/drivers/block/pktcdvd.c 2005-10-02 13:52:22.000000000 +0200
+++ /home/petero/ftp/kernel/2.6/linux/drivers/block/pktcdvd.c 2005-10-01 13:31:50.000000000 +0200
@@ -522,7 +522,13 @@
break;
if (pd->iosched.writing) {
- if (!writes_queued && reads_queued) {
+ int need_write_seek = 1;
+ spin_lock(&pd->iosched.lock);
+ bio = pd->iosched.write_queue;
+ spin_unlock(&pd->iosched.lock);
+ if (bio && (bio->bi_sector == pd->iosched.last_write))
+ need_write_seek = 0;
+ if (need_write_seek && reads_queued) {
if (atomic_read(&pd->cdrw.pending_bios) > 0) {
VPRINTK("pktcdvd: write, waiting\n");
break;
@@ -557,6 +563,7 @@
pd->iosched.successive_reads += bio->bi_size >> 10;
else {
pd->iosched.successive_reads = 0;
+ pd->iosched.last_write = bio->bi_sector + bio_sectors(bio);
}
if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) {
if (pd->read_speed == pd->write_speed) {
@@ -1244,8 +1251,7 @@
VPRINTK("kcdrwd: wake up\n");
/* make swsusp happy with our thread */
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) {
if (!pkt->sleep_time)
--- linux-2612/include/linux/pktcdvd.h 2005-10-02 13:47:21.000000000 +0200
+++ /home/petero/ftp/kernel/2.6/linux/include/linux/pktcdvd.h 2005-10-01 13:32:08.000000000 +0200
@@ -159,6 +159,7 @@
struct bio *read_queue_tail;
struct bio *write_queue;
struct bio *write_queue_tail;
+ sector_t last_write; /* The sector where the last write ended */
int successive_reads;
};
--
Peter Osterlund - petero2@telia.com
http://web.telia.com/~u89404340
next prev parent reply other threads:[~2005-10-02 12:12 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-24 19:32 [2.6.13] pktcdvd: IO-errors Guennadi Liakhovetski
2005-09-25 9:09 ` Peter Osterlund
2005-09-25 21:06 ` Guennadi Liakhovetski
2005-09-26 18:36 ` Peter Osterlund
2005-09-26 19:29 ` Guennadi Liakhovetski
2005-09-26 19:48 ` Peter Osterlund
2005-09-26 22:06 ` Guennadi Liakhovetski
2005-09-28 21:02 ` Peter Osterlund
2005-09-29 19:18 ` Guennadi Liakhovetski
2005-10-02 12:11 ` Peter Osterlund [this message]
2005-10-08 22:37 ` Guennadi Liakhovetski
2005-10-09 21:23 ` Guennadi Liakhovetski
2005-10-09 21:54 ` Peter Osterlund
2005-10-10 5:05 ` Guennadi Liakhovetski
2005-10-10 17:48 ` Guennadi Liakhovetski
2005-10-10 20:48 ` Guennadi Liakhovetski
2005-10-11 21:31 ` Guennadi Liakhovetski
2005-10-11 21:58 ` Peter Osterlund
2005-10-15 15:36 ` Peter Osterlund
2005-10-17 21:11 ` Guennadi Liakhovetski
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=m3k6gw86f0.fsf@telia.com \
--to=petero2@telia.com \
--cc=axboe@suse.de \
--cc=g.liakhovetski@gmx.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 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.