[PARPORT] Re: New queueing code

From: Andrea Arcangeli (andrea@suse.de)
Date: Sun Apr 02 2000 - 22:41:35 EDT

  • Next message: Jens Axboe: "[PARPORT] Re: New queueing code"

    On Mon, 3 Apr 2000, Andrea Arcangeli wrote:

    >This time I looked into paride and I found out at least one major problem.

    Could you try if this new patch against 2.3.99-pre4-pre2 (aka
    testing/pre4-2.bz2) helps? It should fix paride and it includes the patch
    for allow dumb devices to handle merged requests (that paride still
    needs). Coalescing capabilities of paride should remains the same since
    the merging is still done, but by the highlevel layer.

    Binary files 2.3.99-pre4-pre2aa/ID and blkdev/ID differ
    diff -urN 2.3.99-pre4-pre2aa/drivers/block/ll_rw_blk.c blkdev/drivers/block/ll_rw_blk.c
    --- 2.3.99-pre4-pre2aa/drivers/block/ll_rw_blk.c Mon Apr 3 03:22:28 2000
    +++ blkdev/drivers/block/ll_rw_blk.c Mon Apr 3 03:53:57 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. */
    @@ -911,23 +911,21 @@
             int nsect;
     
             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) {
    + nsect = 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->hard_sector += nsect;
    + req->hard_nr_sectors -= nsect;
    + req->sector = req->hard_sector;
    + req->nr_sectors = req->hard_nr_sectors;
    +
                             req->current_nr_sectors = bh->b_size >> 9;
                             if (req->nr_sectors < req->current_nr_sectors) {
                                     req->nr_sectors = req->current_nr_sectors;
    diff -urN 2.3.99-pre4-pre2aa/drivers/block/paride/pcd.c blkdev/drivers/block/paride/pcd.c
    --- 2.3.99-pre4-pre2aa/drivers/block/paride/pcd.c Thu Feb 17 13:57:00 2000
    +++ blkdev/drivers/block/paride/pcd.c Mon Apr 3 03:23:20 2000
    @@ -765,7 +765,7 @@
                             pcd_unit = unit;
                     }
                     pcd_sector = CURRENT->sector;
    - pcd_count = CURRENT->nr_sectors;
    + pcd_count = CURRENT->current_nr_sectors;
                     pcd_buf = CURRENT->buffer;
                     pcd_busy = 1;
                     ps_set_intr(do_pcd_read,0,0,nice);
    diff -urN 2.3.99-pre4-pre2aa/drivers/block/paride/pd.c blkdev/drivers/block/paride/pd.c
    --- 2.3.99-pre4-pre2aa/drivers/block/paride/pd.c Thu Feb 17 13:57:00 2000
    +++ blkdev/drivers/block/paride/pd.c Mon Apr 3 03:53:13 2000
    @@ -385,9 +385,62 @@
             }
     }
     
    +static inline int pd_new_segment(request_queue_t *q, struct request *req, int max_segments)
    +{
    + if (max_segments > cluster)
    + max_segments = cluster;
    +
    + if (req->nr_segments < max_segments) {
    + req->nr_segments++;
    + q->elevator.nr_segments++;
    + return 1;
    + }
    + return 0;
    +}
    +
    +static int pd_back_merge_fn(request_queue_t *q, struct request *req,
    + struct buffer_head *bh, int max_segments)
    +{
    + if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
    + return 1;
    + return pd_new_segment(q, req, max_segments);
    +}
    +
    +static int pd_front_merge_fn(request_queue_t *q, struct request *req,
    + struct buffer_head *bh, int max_segments)
    +{
    + if (bh->b_data + bh->b_size == req->bh->b_data)
    + return 1;
    + return pd_new_segment(q, req, max_segments);
    +}
    +
    +static int pd_merge_requests_fn(request_queue_t *q, struct request *req,
    + struct request *next, int max_segments)
    +{
    + int total_segments = req->nr_segments + next->nr_segments;
    + int same_segment;
    +
    + if (max_segments > cluster)
    + max_segments = cluster;
    +
    + same_segment = 0;
    + if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {
    + total_segments--;
    + same_segment = 1;
    + }
    +
    + if (total_segments > max_segments)
    + return 0;
    +
    + q->elevator.nr_segments -= same_segment;
    + req->nr_segments = total_segments;
    + return 1;
    +}
    +
     int pd_init (void)
     
     { int i;
    + request_queue_t * q;
     
             if (disable) return -1;
             if (devfs_register_blkdev(MAJOR_NR,name,&pd_fops)) {
    @@ -395,7 +448,11 @@
                             name,major);
                     return -1;
             }
    - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
    + q = BLK_DEFAULT_QUEUE(MAJOR_NR);
    + blk_init_queue(q, DEVICE_REQUEST);
    + q->back_merge_fn = pd_back_merge_fn;
    + q->front_merge_fn = pd_front_merge_fn;
    + q->merge_requests_fn = pd_merge_requests_fn;
             read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
             
             pd_gendisk.major = major;
    @@ -865,7 +922,6 @@
     static void do_pd_request (request_queue_t * q)
     
     { struct buffer_head * bh;
    - struct request * req;
             int unit;
     
             if (pd_busy) return;
    @@ -876,12 +932,10 @@
             pd_dev = MINOR(CURRENT->rq_dev);
             pd_unit = unit = DEVICE_NR(CURRENT->rq_dev);
             pd_block = CURRENT->sector;
    - pd_count = CURRENT->nr_sectors;
    + pd_run = CURRENT->nr_sectors;
    + pd_count = CURRENT->current_nr_sectors;
     
             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)) {
    @@ -890,14 +944,6 @@
             }
     
             pd_cmd = CURRENT->cmd;
    - pd_run = pd_count;
    - while ((pd_run <= cluster) &&
    - (req = blkdev_next_request(req)) &&
    - (pd_block+pd_run == req->sector) &&
    - (pd_cmd == req->cmd) &&
    - (pd_dev == MINOR(req->rq_dev)))
    - pd_run += req->nr_sectors;
    -
             pd_poffs = pd_hd[pd_dev].start_sect;
             pd_block += pd_poffs;
             pd_buf = CURRENT->buffer;
    @@ -932,7 +978,7 @@
                     printk("%s: OUCH: request list changed unexpectedly\n",
                             PD.name);
     
    - pd_count = CURRENT->nr_sectors;
    + pd_count = CURRENT->current_nr_sectors;
             pd_buf = CURRENT->buffer;
             spin_unlock_irqrestore(&io_request_lock,saved_flags);
     }
    diff -urN 2.3.99-pre4-pre2aa/drivers/block/paride/pf.c blkdev/drivers/block/paride/pf.c
    --- 2.3.99-pre4-pre2aa/drivers/block/paride/pf.c Thu Feb 17 13:57:00 2000
    +++ blkdev/drivers/block/paride/pf.c Mon Apr 3 03:52:57 2000
    @@ -339,9 +339,62 @@
             }
     }
     
    +static inline int pf_new_segment(request_queue_t *q, struct request *req, int max_segments)
    +{
    + if (max_segments > cluster)
    + max_segments = cluster;
    +
    + if (req->nr_segments < max_segments) {
    + req->nr_segments++;
    + q->elevator.nr_segments++;
    + return 1;
    + }
    + return 0;
    +}
    +
    +static int pf_back_merge_fn(request_queue_t *q, struct request *req,
    + struct buffer_head *bh, int max_segments)
    +{
    + if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
    + return 1;
    + return pf_new_segment(q, req, max_segments);
    +}
    +
    +static int pf_front_merge_fn(request_queue_t *q, struct request *req,
    + struct buffer_head *bh, int max_segments)
    +{
    + if (bh->b_data + bh->b_size == req->bh->b_data)
    + return 1;
    + return pf_new_segment(q, req, max_segments);
    +}
    +
    +static int pf_merge_requests_fn(request_queue_t *q, struct request *req,
    + struct request *next, int max_segments)
    +{
    + int total_segments = req->nr_segments + next->nr_segments;
    + int same_segment;
    +
    + if (max_segments > cluster)
    + max_segments = cluster;
    +
    + same_segment = 0;
    + if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {
    + total_segments--;
    + same_segment = 1;
    + }
    +
    + if (total_segments > max_segments)
    + return 0;
    +
    + q->elevator.nr_segments -= same_segment;
    + req->nr_segments = total_segments;
    + return 1;
    +}
    +
     int pf_init (void) /* preliminary initialisation */
     
     { int i;
    + request_queue_t * q;
     
             if (disable) return -1;
     
    @@ -355,7 +408,11 @@
                             major);
                     return -1;
             }
    - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
    + q = BLK_DEFAULT_QUEUE(MAJOR_NR);
    + blk_init_queue(q, DEVICE_REQUEST);
    + q->back_merge_fn = pf_back_merge_fn;
    + q->front_merge_fn = pf_front_merge_fn;
    + q->merge_requests_fn = pf_merge_requests_fn;
             read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
             
             for (i=0;i<PF_UNITS;i++) pf_blocksizes[i] = 1024;
    @@ -849,7 +906,6 @@
     static void do_pf_request (request_queue_t * q)
     
     { struct buffer_head * bh;
    - struct request * req;
             int unit;
     
             if (pf_busy) return;
    @@ -859,12 +915,10 @@
     
             pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
             pf_block = CURRENT->sector;
    - pf_count = CURRENT->nr_sectors;
    + pf_run = CURRENT->nr_sectors;
    + pf_count = CURRENT->current_nr_sectors;
     
             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);
    @@ -872,14 +926,6 @@
             }
     
             pf_cmd = CURRENT->cmd;
    - pf_run = pf_count;
    - while ((pf_run <= cluster) &&
    - (req = blkdev_next_request(req)) &&
    - (pf_block+pf_run == req->sector) &&
    - (pf_cmd == req->cmd) &&
    - (pf_unit == DEVICE_NR(req->rq_dev)))
    - pf_run += req->nr_sectors;
    -
             pf_buf = CURRENT->buffer;
             pf_retries = 0;
     
    @@ -912,7 +958,7 @@
                     printk("%s: OUCH: request list changed unexpectedly\n",
                             PF.name);
     
    - pf_count = CURRENT->nr_sectors;
    + pf_count = CURRENT->current_nr_sectors;
             pf_buf = CURRENT->buffer;
             spin_unlock_irqrestore(&io_request_lock,saved_flags);
     }
    diff -urN 2.3.99-pre4-pre2aa/include/linux/blkdev.h blkdev/include/linux/blkdev.h
    --- 2.3.99-pre4-pre2aa/include/linux/blkdev.h Mon Apr 3 03:09:06 2000
    +++ blkdev/include/linux/blkdev.h Mon Apr 3 03:42:04 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 : Mon Apr 03 2000 - 04:33:27 EDT