diff -urN 2.4.0-test7/drivers/block/DAC960.c blkdev/drivers/block/DAC960.c --- 2.4.0-test7/drivers/block/DAC960.c Fri Aug 25 19:37:16 2000 +++ blkdev/drivers/block/DAC960.c Fri Aug 25 19:41:06 2000 @@ -1825,7 +1825,6 @@ Request->nr_segments < Controller->DriverScatterGatherLimit) { Request->nr_segments++; - RequestQueue->elevator.nr_segments++; return true; } return false; @@ -1849,7 +1848,6 @@ Request->nr_segments < Controller->DriverScatterGatherLimit) { Request->nr_segments++; - RequestQueue->elevator.nr_segments++; return true; } return false; @@ -1879,7 +1877,6 @@ if (TotalSegments > MaxSegments || TotalSegments > Controller->DriverScatterGatherLimit) return false; - RequestQueue->elevator.nr_segments -= SameSegment; Request->nr_segments = TotalSegments; return true; } diff -urN 2.4.0-test7/drivers/block/elevator.c blkdev/drivers/block/elevator.c --- 2.4.0-test7/drivers/block/elevator.c Fri Aug 25 19:37:16 2000 +++ blkdev/drivers/block/elevator.c Fri Aug 25 19:41:06 2000 @@ -51,50 +51,67 @@ } int elevator_linus_merge(request_queue_t *q, struct request **req, + struct list_head * head, struct buffer_head *bh, int rw, - int *max_sectors, int *max_segments) + int max_sectors, int max_segments) { - struct list_head *entry, *head = &q->queue_head; + struct list_head *entry; unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE; + int front = 0, back = 0; - entry = head; - if (q->head_active && !q->plugged) - head = head->next; - - while ((entry = entry->prev) != head) { + entry = &q->queue_head; + while ((entry = entry->prev) != head && !back && !front) { struct request *__rq = *req = blkdev_entry_to_request(entry); - if (__rq->sem) - continue; + if (__rq->cmd != rw) continue; - if (__rq->nr_sectors + count > *max_sectors) - continue; if (__rq->rq_dev != bh->b_rdev) continue; - if (__rq->sector + __rq->nr_sectors == bh->b_rsector) { + if (__rq->sector + __rq->nr_sectors == bh->b_rsector) + back = 1; + else if (__rq->sector - count == bh->b_rsector) + front = 1; + + if (__rq->nr_sectors + count > max_sectors) + continue; + if (__rq->sem) + continue; + + if (back) { ret = ELEVATOR_BACK_MERGE; break; } if (!__rq->elevator_sequence) break; - if (__rq->sector - count == bh->b_rsector) { - __rq->elevator_sequence--; + if (front) { ret = ELEVATOR_FRONT_MERGE; break; } } + return ret; +} + +void elevator_linus_merge_cleanup(request_queue_t *q, struct request *req, int ret, int front) +{ + struct list_head *entry = &req->queue, *head = &q->queue_head; + + if (front) + req->elevator_sequence--; + /* * second pass scan of requests that got passed over, if any */ - if (ret != ELEVATOR_NO_MERGE && *req) { - while ((entry = entry->next) != &q->queue_head) { - struct request *tmp = blkdev_entry_to_request(entry); - tmp->elevator_sequence--; - } + while ((entry = entry->next) != head) { + struct request *tmp = blkdev_entry_to_request(entry); + tmp->elevator_sequence--; } +} - return ret; +void elevator_linus_merge_req(struct request *req, struct request *next) +{ + if (next->elevator_sequence < req->elevator_sequence) + req->elevator_sequence = next->elevator_sequence; } /* @@ -111,38 +128,43 @@ * See if we can find a request that is buffer can be coalesced with. */ int elevator_noop_merge(request_queue_t *q, struct request **req, + struct list_head * head, struct buffer_head *bh, int rw, - int *max_sectors, int *max_segments) + int max_sectors, int max_segments) { - struct list_head *entry, *head = &q->queue_head; + struct list_head *entry; unsigned int count = bh->b_size >> 9; + int back = 0, front = 0; - if (q->head_active && !q->plugged) - head = head->next; - - entry = head; - while ((entry = entry->prev) != head) { + entry = &q->queue_head; + while ((entry = entry->prev) != head && !back && !front) { struct request *__rq = *req = blkdev_entry_to_request(entry); - if (__rq->sem) - continue; + if (__rq->cmd != rw) continue; - if (__rq->nr_sectors + count > *max_sectors) - continue; if (__rq->rq_dev != bh->b_rdev) continue; if (__rq->sector + __rq->nr_sectors == bh->b_rsector) + back = 1; + else if (__rq->sector - count == bh->b_rsector) + front = 1; + + if (__rq->nr_sectors + count > max_sectors) + continue; + if (__rq->sem) + continue; + + if (back) return ELEVATOR_BACK_MERGE; - if (__rq->sector - count == bh->b_rsector) + if (front) return ELEVATOR_FRONT_MERGE; } return ELEVATOR_NO_MERGE; } -/* - * The noop "elevator" does not do any accounting - */ -void elevator_noop_dequeue(struct request *req) {} +void elevator_noop_merge_cleanup(request_queue_t *q, struct request *req, int ret, int front) {} + +void elevator_noop_merge_req(struct request *req, struct request *next) {} int blkelvget_ioctl(elevator_t * elevator, blkelv_ioctl_arg_t * arg) { diff -urN 2.4.0-test7/drivers/block/ll_rw_blk.c blkdev/drivers/block/ll_rw_blk.c --- 2.4.0-test7/drivers/block/ll_rw_blk.c Fri Aug 25 19:37:16 2000 +++ blkdev/drivers/block/ll_rw_blk.c Fri Aug 25 19:41:06 2000 @@ -280,7 +280,6 @@ { if (req->nr_segments < max_segments) { req->nr_segments++; - q->elevator.nr_segments++; return 1; } return 0; @@ -317,7 +316,6 @@ if (total_segments > max_segments) return 0; - q->elevator.nr_segments -= same_segment; req->nr_segments = total_segments; return 1; } @@ -645,6 +643,7 @@ if(!(q->merge_requests_fn)(q, req, next, max_segments)) return; + q->elevator.elevator_merge_req_fn(req, next); req->bhtail->b_reqnext = next->bh; req->bhtail = next->bhtail; req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; @@ -733,27 +732,27 @@ */ spin_lock_irq(&io_request_lock); + if (list_empty(head)) { + q->plug_device_fn(q, bh->b_rdev); /* is atomic */ + goto get_rq; + } + /* * skip first entry, for devices with active queue head */ if (q->head_active && !q->plugged) head = head->next; - if (list_empty(head)) { - q->plug_device_fn(q, bh->b_rdev); /* is atomic */ - goto get_rq; - } - - el_ret = elevator->elevator_merge_fn(q, &req, bh, rw, &max_sectors, &max_segments); + el_ret = elevator->elevator_merge_fn(q, &req, head, bh, rw, max_sectors, max_segments); switch (el_ret) { case ELEVATOR_BACK_MERGE: if (!q->back_merge_fn(q, req, bh, max_segments)) break; + elevator->elevator_merge_cleanup_fn(q, req, el_ret, 0); req->bhtail->b_reqnext = bh; req->bhtail = bh; req->nr_sectors = req->hard_nr_sectors += count; - req->e = elevator; drive_stat_acct(req->rq_dev, req->cmd, count, 0); attempt_back_merge(q, req, max_sectors, max_segments); goto out; @@ -761,13 +760,13 @@ case ELEVATOR_FRONT_MERGE: if (!q->front_merge_fn(q, req, bh, max_segments)) break; + elevator->elevator_merge_cleanup_fn(q, req, el_ret, 1); bh->b_reqnext = req->bh; req->bh = bh; req->buffer = bh->b_data; req->current_nr_sectors = count; req->sector = req->hard_sector = sector; req->nr_sectors = req->hard_nr_sectors += count; - req->e = elevator; drive_stat_acct(req->rq_dev, req->cmd, count, 0); attempt_front_merge(q, head, req, max_sectors, max_segments); goto out; @@ -817,11 +816,8 @@ req->bh = bh; req->bhtail = bh; req->rq_dev = bh->b_rdev; - req->e = elevator; add_request(q, req, head, latency); out: - if (!q->plugged) - (q->request_fn)(q); spin_unlock_irq(&io_request_lock); return 0; end_io: @@ -1016,10 +1012,6 @@ void end_that_request_last(struct request *req) { - if (req->e) { - printk("end_that_request_last called with non-dequeued req\n"); - BUG(); - } if (req->sem != NULL) up(req->sem); diff -urN 2.4.0-test7/drivers/block/lvm.c blkdev/drivers/block/lvm.c --- 2.4.0-test7/drivers/block/lvm.c Thu Jul 20 21:31:02 2000 +++ blkdev/drivers/block/lvm.c Fri Aug 25 19:41:06 2000 @@ -195,7 +195,7 @@ #define DEVICE_REQUEST lvm_dummy_device_request static int lvm_make_request_fn(request_queue_t *, int, struct buffer_head*); -static void lvm_plug_device_noop(request_queue_t *, kdev_t); +static void lvm_dummy_plug_device(request_queue_t *, kdev_t); static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong); static int lvm_blk_open(struct inode *, struct file *); @@ -394,7 +394,7 @@ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn); - blk_queue_pluggable(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_plug_device_noop); + blk_queue_pluggable(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_dummy_plug_device); /* optional read root VGDA */ /* if ( *rootvg != 0) vg_read_with_pv_and_lv ( rootvg, &vg); @@ -1482,11 +1482,18 @@ } /* - * plug device function is a noop because plugging has to happen - * in the queue of the physical blockdevice to allow the - * elevator to do a better job. + * plugging has to happen in the queue of the physical blockdevice + * to allow the elevator to do a better job. */ -static void lvm_plug_device_noop(request_queue_t *q, kdev_t dev) { } +static void lvm_dummy_plug_device(request_queue_t *q, kdev_t dev) +{ + printk(KERN_EMERG + "%s -- oops, got lvm plug for %02d:%02d [sector: %lu]\n", + lvm_name, + MAJOR(CURRENT->rq_dev), + MINOR(CURRENT->rq_dev), + CURRENT->sector); +} /******************************************************************** * diff -urN 2.4.0-test7/drivers/i2o/i2o_block.c blkdev/drivers/i2o/i2o_block.c --- 2.4.0-test7/drivers/i2o/i2o_block.c Tue Jul 11 03:50:23 2000 +++ blkdev/drivers/i2o/i2o_block.c Fri Aug 25 19:41:06 2000 @@ -392,7 +392,6 @@ if (req->nr_segments < max_segments) { req->nr_segments++; - q->elevator.nr_segments++; return 1; } return 0; @@ -436,7 +435,6 @@ if (total_segments > max_segments) return 0; - q->elevator.nr_segments -= same_segment; req->nr_segments = total_segments; return 1; } diff -urN 2.4.0-test7/drivers/ide/ide-dma.c blkdev/drivers/ide/ide-dma.c --- 2.4.0-test7/drivers/ide/ide-dma.c Fri Jul 28 07:24:10 2000 +++ blkdev/drivers/ide/ide-dma.c Fri Aug 25 19:41:06 2000 @@ -224,6 +224,9 @@ unsigned char *virt_addr = bh->b_data; unsigned int size = bh->b_size; + if (nents >= PRD_ENTRIES) + return 0; + while ((bh = bh->b_reqnext) != NULL) { if ((virt_addr + size) != (unsigned char *) bh->b_data) break; @@ -266,7 +269,7 @@ cur_len = sg_dma_len(sg); while (cur_len) { - if (++count >= PRD_ENTRIES) { + if (count++ >= PRD_ENTRIES) { printk("%s: DMA table too small\n", drive->name); pci_unmap_sg(HWIF(drive)->pci_dev, HWIF(drive)->sg_table, diff -urN 2.4.0-test7/drivers/ide/ide-probe.c blkdev/drivers/ide/ide-probe.c --- 2.4.0-test7/drivers/ide/ide-probe.c Thu Aug 17 19:57:28 2000 +++ blkdev/drivers/ide/ide-probe.c Fri Aug 25 21:39:59 2000 @@ -761,9 +761,10 @@ for (unit = 0; unit < minors; ++unit) { *bs++ = BLOCK_SIZE; #ifdef CONFIG_BLK_DEV_PDC4030 - *max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : MAX_SECTORS); + *max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 256); #else - *max_sect++ = MAX_SECTORS; + /* IDE can do up to 128K per request. */ + *max_sect++ = 256; #endif *max_ra++ = MAX_READAHEAD; } diff -urN 2.4.0-test7/drivers/scsi/scsi_merge.c blkdev/drivers/scsi/scsi_merge.c --- 2.4.0-test7/drivers/scsi/scsi_merge.c Thu Apr 27 17:56:40 2000 +++ blkdev/drivers/scsi/scsi_merge.c Fri Aug 25 19:41:06 2000 @@ -324,7 +324,6 @@ req->nr_segments >= SHpnt->sg_tablesize) return 0; req->nr_segments++; - q->elevator.nr_segments++; return 1; } @@ -341,11 +340,8 @@ if (req->nr_hw_segments >= SHpnt->sg_tablesize || req->nr_segments >= SHpnt->sg_tablesize) return 0; - if (req->nr_segments >= max_segments) - return 0; req->nr_hw_segments++; req->nr_segments++; - q->elevator.nr_segments++; return 1; } #else @@ -361,7 +357,6 @@ * counter. */ req->nr_segments++; - q->elevator.nr_segments++; return 1; } else { return 0; @@ -417,8 +412,10 @@ SDpnt = (Scsi_Device *) q->queuedata; SHpnt = SDpnt->host; +#ifdef DMA_CHUNK_SIZE if (max_segments > 64) max_segments = 64; +#endif if (use_clustering) { /* @@ -471,8 +468,10 @@ SDpnt = (Scsi_Device *) q->queuedata; SHpnt = SDpnt->host; +#ifdef DMA_CHUNK_SIZE if (max_segments > 64) max_segments = 64; +#endif if (use_clustering) { /* @@ -601,10 +600,10 @@ SDpnt = (Scsi_Device *) q->queuedata; SHpnt = SDpnt->host; +#ifdef DMA_CHUNK_SIZE if (max_segments > 64) max_segments = 64; -#ifdef DMA_CHUNK_SIZE /* If it would not fit into prepared memory space for sg chain, * then don't allow the merge. */ @@ -664,7 +663,6 @@ * This one is OK. Let it go. */ req->nr_segments += next->nr_segments - 1; - q->elevator.nr_segments--; #ifdef DMA_CHUNK_SIZE req->nr_hw_segments += next->nr_hw_segments - 1; #endif diff -urN 2.4.0-test7/include/linux/blk.h blkdev/include/linux/blk.h --- 2.4.0-test7/include/linux/blk.h Sun Aug 20 14:58:25 2000 +++ blkdev/include/linux/blk.h Fri Aug 25 19:41:06 2000 @@ -87,10 +87,6 @@ static inline void blkdev_dequeue_request(struct request * req) { - if (req->e) { - req->e->dequeue_fn(req); - req->e = NULL; - } list_del(&req->queue); } diff -urN 2.4.0-test7/include/linux/blkdev.h blkdev/include/linux/blkdev.h --- 2.4.0-test7/include/linux/blkdev.h Sun Aug 20 14:58:25 2000 +++ blkdev/include/linux/blkdev.h Fri Aug 25 19:41:06 2000 @@ -47,7 +47,6 @@ struct buffer_head * bh; struct buffer_head * bhtail; request_queue_t *q; - elevator_t *e; }; #include @@ -175,9 +174,8 @@ extern int * max_segments[MAX_BLKDEV]; -#define MAX_SECTORS 254 - -#define MAX_SEGMENTS MAX_SECTORS +#define MAX_SECTORS 128 +#define MAX_SEGMENTS (MAX_SECTORS*8) #define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK) diff -urN 2.4.0-test7/include/linux/elevator.h blkdev/include/linux/elevator.h --- 2.4.0-test7/include/linux/elevator.h Fri Jul 28 07:24:15 2000 +++ blkdev/include/linux/elevator.h Fri Aug 25 19:41:06 2000 @@ -7,34 +7,35 @@ struct list_head *, struct list_head *, int); -typedef int (elevator_merge_fn) (request_queue_t *, struct request **, - struct buffer_head *, int, int *, int *); +typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct list_head *, + struct buffer_head *, int, int, int); -typedef void (elevator_dequeue_fn) (struct request *); +typedef void (elevator_merge_cleanup_fn) (request_queue_t *, struct request *, int, int); + +typedef void (elevator_merge_req_fn) (struct request *, struct request *); struct elevator_s { - int sequence; - int read_latency; int write_latency; - int max_bomb_segments; - - unsigned int nr_segments; - int read_pendings; elevator_fn * elevator_fn; elevator_merge_fn *elevator_merge_fn; - elevator_dequeue_fn *dequeue_fn; + elevator_merge_cleanup_fn *elevator_merge_cleanup_fn; + elevator_merge_req_fn *elevator_merge_req_fn; unsigned int queue_ID; }; void elevator_noop(struct request *, elevator_t *, struct list_head *, struct list_head *, int); -int elevator_noop_merge(request_queue_t *, struct request **, struct buffer_head *, int, int *, int *); -void elevator_noop_dequeue(struct request *); +int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int, int); +void elevator_noop_merge_cleanup(request_queue_t *, struct request *, int, int); +void elevator_noop_merge_req(struct request *, struct request *); + void elevator_linus(struct request *, elevator_t *, struct list_head *, struct list_head *, int); -int elevator_linus_merge(request_queue_t *, struct request **, struct buffer_head *, int, int *, int *); +int elevator_linus_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int, int); +void elevator_linus_merge_cleanup(request_queue_t *, struct request *, int, int); +void elevator_linus_merge_req(struct request *, struct request *); typedef struct blkelv_ioctl_arg_s { int queue_ID; @@ -80,36 +81,26 @@ return latency; } -#define ELEVATOR_NOOP \ -((elevator_t) { \ - 0, /* sequence */ \ - \ - 0, /* read_latency */ \ - 0, /* write_latency */ \ - 0, /* max_bomb_segments */ \ - \ - 0, /* nr_segments */ \ - 0, /* read_pendings */ \ - \ - elevator_noop, /* elevator_fn */ \ - elevator_noop_merge, /* elevator_merge_fn */ \ - elevator_noop_dequeue, /* dequeue_fn */ \ +#define ELEVATOR_NOOP \ +((elevator_t) { \ + 0, /* read_latency */ \ + 0, /* write_latency */ \ + \ + elevator_noop, /* elevator_fn */ \ + elevator_noop_merge, /* elevator_merge_fn */ \ + elevator_noop_merge_cleanup, /* elevator_merge_cleanup_fn */ \ + elevator_noop_merge_req, /* elevator_merge_req_fn */ \ }) -#define ELEVATOR_LINUS \ -((elevator_t) { \ - 0, /* not used */ \ - \ - 1000000, /* read passovers */ \ - 2000000, /* write passovers */ \ - 0, /* max_bomb_segments */ \ - \ - 0, /* not used */ \ - 0, /* not used */ \ - \ - elevator_linus, /* elevator_fn */ \ - elevator_linus_merge, /* elevator_merge_fn */ \ - elevator_noop_dequeue, /* dequeue_fn */ \ +#define ELEVATOR_LINUS \ +((elevator_t) { \ + 50000, /* read passovers */ \ + 100000, /* write passovers */ \ + \ + elevator_linus, /* elevator_fn */ \ + elevator_linus_merge, /* elevator_merge_fn */ \ + elevator_linus_merge_cleanup, /* elevator_merge_cleanup_fn */ \ + elevator_linus_merge_req, /* elevator_merge_req_fn */ \ }) #endif diff -urN 2.4.0-test7/mm/filemap.c blkdev/mm/filemap.c --- 2.4.0-test7/mm/filemap.c Fri Aug 25 19:37:32 2000 +++ blkdev/mm/filemap.c Fri Aug 25 19:41:06 2000 @@ -958,10 +958,6 @@ * accessed sequentially. */ if (ahead) { - if (reada_ok == 2) { - run_task_queue(&tq_disk); - } - filp->f_ralen += ahead; filp->f_rawin += filp->f_ralen; filp->f_raend = raend + ahead + 1;