All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christophe Saout <christophe@saout.de>
To: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Cc: linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: Possibly wrong BIO usage in ide_multwrite
Date: Mon, 5 Jan 2004 05:03:37 +0100	[thread overview]
Message-ID: <20040105040337.GB6393@leto.cs.pocnet.net> (raw)
In-Reply-To: <200401032302.32914.bzolnier@elka.pw.edu.pl>

Hi again,

here another experiment.

I have started moving the code over to using the cbio mechanism. I
have only touched ide-disk.c though, I'm not sure about ide-taskfile.c.

So basically I've replaced bio_kmap_irq with rq_map_buffer in
ide_map_buffer and changed the manual rq->current_nr_sectors/nr_sectors
fiddling with process_that_request_first. I can then recognize whether
a bio border has been crossed if rq->cbio differs from rq->bio since
the rq->current_nr_sectors already might refer to the next bio and won't
drop to zero.

The modifications work here with and without multmode and with all kinds
of bios. Haven't been able to test error conditions since I don't have
broken hardware. ;-)

I also didn't touch ide-taskfile.c which has most probably also been
broken by the ide_map_buffer change. And I stumbled across the code
calling end_request with a null sector count, ide_end_request will then
take hard_nr_sectors which will end the whole request even if only one
bio was finished, huh? Am I missing something here?

And when is bio == NULL in ide_map_buffer? Where can this happen?


bio to cbio
--- linux.orig/drivers/ide/ide-disk.c	2004-01-04 23:43:59.000000000 +0100
+++ linux/drivers/ide/ide-disk.c	2004-01-05 04:17:25.522691784 +0100
@@ -172,11 +172,11 @@
 		(unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect);
 #endif
 	ide_unmap_buffer(rq, to, &flags);
-	rq->sector += nsect;
+	process_that_request_first(rq, nsect);
 	rq->errors = 0;
-	i = (rq->nr_sectors -= nsect);
-	if (((long)(rq->current_nr_sectors -= nsect)) <= 0)
-		ide_end_request(drive, 1, rq->hard_cur_sectors);
+	i = rq->nr_sectors;
+	if (rq->bio != rq->cbio)
+		ide_end_request(drive, 1, bio_sectors(rq->bio));
 	/*
 	 * Another BH Page walker and DATA INTEGRITY Questioned on ERROR.
 	 * If passed back up on multimode read, BAD DATA could be ACKED
@@ -195,7 +195,7 @@
  * write_intr() is the handler for disk write interrupts
  */
 static ide_startstop_t write_intr (ide_drive_t *drive)
-{
+{ 
 	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct request *rq	= hwgroup->rq;
@@ -213,12 +213,11 @@
 			rq->nr_sectors-1);
 #endif
 		if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) {
-			rq->sector++;
+			process_that_request_first(rq, 1);
 			rq->errors = 0;
-			i = --rq->nr_sectors;
-			--rq->current_nr_sectors;
-			if (((long)rq->current_nr_sectors) <= 0)
-				ide_end_request(drive, 1, rq->hard_cur_sectors);
+			i = rq->nr_sectors;
+			if (rq->bio != rq->cbio)
+				ide_end_request(drive, 1, bio_sectors(rq->bio));
 			if (i > 0) {
 				unsigned long flags;
 				char *to = ide_map_buffer(rq, &flags);
@@ -245,53 +244,25 @@
  * and IRQ context. The IRQ can happen any time after we've output the
  * full "mcount" number of sectors, so we must make sure we update the
  * state _before_ we output the final part of the data!
- *
- * The update and return to BH is a BLOCK Layer Fakey to get more data
- * to satisfy the hardware atomic segment.  If the hardware atomic segment
- * is shorter or smaller than the BH segment then we should be OKAY.
- * This is only valid if we can rewind the rq->current_nr_sectors counter.
  */
 int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
 {
  	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
- 	struct request *rq	= &hwgroup->wrq;
+ 	struct request *rq	= hwgroup->rq;
 
   	do {
   		char *buffer;
-  		int nsect = rq->current_nr_sectors;
 		unsigned long flags;
+  		int nsect = rq->current_nr_sectors;
  
 		if (nsect > mcount)
 			nsect = mcount;
 		mcount -= nsect;
 		buffer = ide_map_buffer(rq, &flags);
 
-		rq->sector += nsect;
-		rq->nr_sectors -= nsect;
-		rq->current_nr_sectors -= nsect;
-
-		/* Do we move to the next bh after this? */
-		if (!rq->current_nr_sectors) {
-			struct bio *bio = rq->bio;
-
-			/*
-			 * only move to next bio, when we have processed
-			 * all bvecs in this one.
-			 */
-			if (++bio->bi_idx >= bio->bi_vcnt) {
-				bio->bi_idx = 0;
-				bio = bio->bi_next;
-			}
-
-			/* end early early we ran out of requests */
-			if (!bio) {
-				mcount = 0;
-			} else {
-				rq->bio = bio;
-				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
-				rq->hard_cur_sectors = rq->current_nr_sectors;
-			}
-		}
+		process_that_request_first(rq, nsect);
+		if (!rq->cbio)
+			mcount = 0;
 
 		/*
 		 * Ok, we're all setup for the interrupt
@@ -311,7 +282,7 @@
 {
 	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
 	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= &hwgroup->wrq;
+	struct request *rq	= hwgroup->rq;
 	u8 stat;
 
 	stat = hwif->INB(IDE_STATUS_REG);
@@ -333,12 +304,11 @@
 			 *	we can end the original request.
 			 */
 			if (!rq->nr_sectors) {	/* all done? */
-				rq = hwgroup->rq;
-				ide_end_request(drive, 1, rq->nr_sectors);
+				ide_end_request(drive, 1, rq->hard_nr_sectors);
 				return ide_stopped;
 			}
 		}
-		/* the original code did this here (?) */
+	 	/* the original code did this here (?) */
 		return ide_stopped;
 	}
 	return DRIVER(drive)->error(drive, "multwrite_intr", stat);
@@ -517,7 +487,9 @@
 	 *
 	 * MAJOR DATA INTEGRITY BUG !!! only if we error 
 	 */
+#if 0
 			hwgroup->wrq = *rq; /* scratchpad */
+#endif
 			ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
 			if (ide_multwrite(drive, drive->mult_count)) {
 				unsigned long flags;
--- linux.orig/include/linux/ide.h	2004-01-04 23:43:59.000000000 +0100
+++ linux/include/linux/ide.h	2004-01-05 04:17:38.287751200 +0100
@@ -835,7 +835,7 @@
 	 * fs request
 	 */
 	if (rq->bio)
-		return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
+		return rq_map_buffer(rq, flags);
 
 	/*
 	 * task request
@@ -846,7 +846,7 @@
 static inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned long *flags)
 {
 	if (rq->bio)
-		bio_kunmap_irq(buffer, flags);
+		rq_unmap_buffer(buffer, flags);
 }
 #endif /* !CONFIG_IDE_TASKFILE_IO */
 
@@ -1057,8 +1057,10 @@
 	struct request *rq;
 		/* failsafe timer */
 	struct timer_list timer;
+#if 0
 		/* local copy of current write rq */
 	struct request wrq;
+#endif
 		/* timeout value during long polls */
 	unsigned long poll_timeout;
 		/* queried upon timeouts */

  parent reply	other threads:[~2004-01-05  4:03 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-01 17:18 Possibly wrong BIO usage in ide_multwrite Christophe Saout
2004-01-01 11:27 ` Bartlomiej Zolnierkiewicz
2004-01-02  3:20   ` Christophe Saout
2004-01-02  4:43     ` CPRM ?? " Andre Hedrick
2004-01-02 11:30       ` Jens Axboe
2004-01-03  7:53         ` Andre Hedrick
2004-01-03 10:57           ` Jens Axboe
2004-01-03 19:55             ` Andre Hedrick
2004-01-04 10:42               ` Jens Axboe
2004-01-04 22:02                 ` Andre Hedrick
2004-01-05 10:17                   ` Jens Axboe
2004-01-02 12:45       ` Christophe Saout
2004-01-03  7:51         ` Andre Hedrick
2004-01-03 22:02     ` Bartlomiej Zolnierkiewicz
2004-01-04 17:30       ` Christophe Saout
2004-01-05 16:12         ` Bartlomiej Zolnierkiewicz
2004-01-05 16:48           ` Christophe Saout
2004-01-05 19:37           ` Frederik Deweerdt
2004-01-05 20:13             ` Bartlomiej Zolnierkiewicz
2004-01-05  3:52       ` Christophe Saout
2004-01-05 17:08         ` Bartlomiej Zolnierkiewicz
2004-01-05 22:51           ` Christophe Saout
2004-01-05 23:59             ` Bartlomiej Zolnierkiewicz
2004-01-06 11:33               ` Christophe Saout
2004-01-06 14:38                 ` Bartlomiej Zolnierkiewicz
2004-01-06 15:21                   ` Christophe Saout
2004-01-05  4:03       ` Christophe Saout [this message]
2004-01-05 16:47         ` Bartlomiej Zolnierkiewicz
2004-01-05 16:49           ` Jens Axboe
2004-01-05 17:13             ` Bartlomiej Zolnierkiewicz
2004-01-05 18:16               ` Jens Axboe
2004-01-05 18:27                 ` Bartlomiej Zolnierkiewicz
2004-01-01 23:02 ` Andre Hedrick

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=20040105040337.GB6393@leto.cs.pocnet.net \
    --to=christophe@saout.de \
    --cc=B.Zolnierkiewicz@elka.pw.edu.pl \
    --cc=linux-ide@vger.kernel.org \
    --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.