[PARPORT] Re: New queueing code

From: Andrea Arcangeli (andrea@suse.de)
Date: Sat Apr 01 2000 - 11:20:43 EST

  • Next message: Erik Inge Bolsų: "[PARPORT] Re: New queueing code"

    On Sat, 1 Apr 2000, Andrea Arcangeli wrote:

    >But I bet the usual problem is that paride can't handle merged requests
    >(if that's the case it got broken while dropping the big switch from 2.3.x
    >make_request in 2.3.4_1_). Probably it would be safer to add a bitflag and
    >to enable merging only in the blockdevices that was included into the big
    >switch in 2.2.x (or that are been fixed in the 2.3.x cycle).
    >
    >I'll have a look at paride to see if the problem is the merged request
    >thing...

    Instead of looking into paride I preferred to rewrite the end_request to
    let automagically simple (not aware) device drivers to handle cleanly
    merged requests (without they can notice). This should remains backwards
    compatible with the aware device drivers and also things like nbd and loop
    that had to do hack like this:

            /*
             * This is a very dirty hack that we have to do to handle
             * merged requests because end_request stuff is a bit
             * broken. The fact we have to do this only if there
             * aren't errors looks even more silly.
             */
            if (!req->errors) {
                    req->sector += req->current_nr_sectors;
                    req->nr_sectors -= req->current_nr_sectors;
            }

    should keep working (without the need of removing the above hack). With
    the patch applied the above can be removed though.

    If this patch will fix paride probably we won't need to add a
    allow_merge_request bitflag to the blkdev_struct to be safe.
    e
    Could you try out if the below patch fixes paride?

    --- 2.3.99-pre3aa1-alpha/drivers/block/paride/pd.c.~1~ Thu Feb 17 13:57:00 2000
    +++ 2.3.99-pre3aa1-alpha/drivers/block/paride/pd.c Sat Apr 1 16:50:10 2000
    @@ -880,8 +880,6 @@
     
             bh = CURRENT->bh;
             req = CURRENT;
    - if (bh->b_reqnext)
    - printk("%s: OUCH: b_reqnext != NULL\n",PD.name);
     
             if ((pd_dev >= PD_DEVS) ||
                 ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) {
    --- 2.3.99-pre3aa1-alpha/drivers/block/paride/pf.c.~1~ Thu Feb 17 13:57:00 2000
    +++ 2.3.99-pre3aa1-alpha/drivers/block/paride/pf.c Sat Apr 1 16:50:36 2000
    @@ -863,8 +863,6 @@
     
             bh = CURRENT->bh;
             req = CURRENT;
    - if (bh->b_reqnext)
    - printk("%s: OUCH: b_reqnext != NULL\n",PF.name);
     
             if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
                     end_request(0);
    --- 2.3.99-pre3aa1-alpha/drivers/block/ll_rw_blk.c.~1~ Thu Mar 30 19:14:01 2000
    +++ 2.3.99-pre3aa1-alpha/drivers/block/ll_rw_blk.c Sat Apr 1 16:59:59 2000
    @@ -481,7 +481,7 @@
             elevator_merge_requests(&q->elevator, req, next);
             req->bhtail->b_reqnext = next->bh;
             req->bhtail = next->bhtail;
    - req->nr_sectors += next->nr_sectors;
    + req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
             next->rq_status = RQ_INACTIVE;
             list_del(&next->queue);
             wake_up (&wait_for_request);
    @@ -685,7 +685,7 @@
                                     break;
                             req->bhtail->b_reqnext = bh;
                             req->bhtail = bh;
    - req->nr_sectors += count;
    + req->nr_sectors = req->hard_nr_sectors += count;
                             drive_stat_acct(req, count, 0);
     
                             elevator_merge_after(elevator, req, latency);
    @@ -714,8 +714,8 @@
                                 req->bh = bh;
                                 req->buffer = bh->b_data;
                                 req->current_nr_sectors = count;
    - req->sector = sector;
    - req->nr_sectors += count;
    + req->sector = req->hard_sector = sector;
    + req->nr_sectors = req->hard_nr_sectors += count;
                             drive_stat_acct(req, count, 0);
     
                             elevator_merge_before(elevator, req, latency);
    @@ -754,8 +754,8 @@
     /* fill up the request-info, and add it to the queue */
             req->cmd = rw;
             req->errors = 0;
    - req->sector = sector;
    - req->nr_sectors = count;
    + req->hard_sector = req->sector = sector;
    + req->hard_nr_sectors = req->nr_sectors = count;
             req->current_nr_sectors = count;
             req->nr_segments = 1; /* Always 1 for a new request. */
             req->nr_hw_segments = 1; /* Always 1 for a new request. */
    @@ -908,36 +908,49 @@
     int end_that_request_first (struct request *req, int uptodate, char *name)
     {
             struct buffer_head * bh;
    - int nsect;
    + int ret = 0;
     
             req->errors = 0;
    - if (!uptodate) {
    + if (!uptodate)
                     printk("end_request: I/O error, dev %s (%s), sector %lu\n",
                             kdevname(req->rq_dev), name, req->sector);
    - if ((bh = req->bh) != NULL) {
    - nsect = bh->b_size >> 9;
    - req->nr_sectors--;
    - req->nr_sectors &= ~(nsect - 1);
    - req->sector += nsect;
    - req->sector &= ~(nsect - 1);
    - }
    - }
     
             if ((bh = req->bh) != NULL) {
    + /*
    + * Fixup current_nr_sectors: while it's supposed to be
    + * _read-only_ from a lowlevel point of view, some buggy
    + * driver is instead changing it for no good reason
    + * (so we can't rely on it to be correct from here!).
    + * Remove this fixup when none device driver will be
    + * clobbering current_nr_sectors anymore.
    + */
    + req->current_nr_sectors = bh->b_size >> 9;
    +
                     req->bh = bh->b_reqnext;
                     bh->b_reqnext = NULL;
                     bh->b_end_io(bh, uptodate);
                     if ((bh = req->bh) != NULL) {
    - req->current_nr_sectors = bh->b_size >> 9;
    - if (req->nr_sectors < req->current_nr_sectors) {
    - req->nr_sectors = req->current_nr_sectors;
    - printk("end_request: buffer-list destroyed\n");
    - }
    + int nsect;
    +
    + nsect = req->current_nr_sectors;
    + req->hard_sector += nsect;
    + req->hard_nr_sectors -= nsect;
    +
    + req->sector = req->hard_sector;
    + req->nr_sectors = req->hard_nr_sectors;
                             req->buffer = bh->b_data;
    - return 1;
    + req->current_nr_sectors = bh->b_size >> 9;
    +
    + nsect = req->current_nr_sectors - 1;
    + if (req->sector & nsect || req->nr_sectors & nsect)
    + printk(KERN_ERR
    + "end_request: sectors %lu nr_sectors %lu mask %x\n",
    + req->sector, req->nr_sectors, nsect);
    +
    + ret = 1;
                     }
             }
    - return 0;
    + return ret;
     }
     
     void end_that_request_last(struct request *req)
    --- 2.3.99-pre3aa1-alpha/include/linux/blkdev.h.~1~ Thu Mar 30 19:18:49 2000
    +++ 2.3.99-pre3aa1-alpha/include/linux/blkdev.h Sat Apr 1 17:04:24 2000
    @@ -32,6 +32,7 @@
             int errors;
             unsigned long sector;
             unsigned long nr_sectors;
    + unsigned long hard_sector, hard_nr_sectors;
             unsigned int nr_segments;
             unsigned int nr_hw_segments;
             unsigned long current_nr_sectors;

    Andrea

    -- To unsubscribe, send mail to: linux-parport-request@torque.net --
    -- with the single word "unsubscribe" in the body of the message. --



    This archive was generated by hypermail 2b29 : Sat Apr 01 2000 - 13:12:54 EST