diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/DAC960.c linux/drivers/block/DAC960.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/DAC960.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/DAC960.c Wed Nov 28 08:52:26 2001 @@ -1946,7 +1946,7 @@ Initialize the I/O Request Queue. */ RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber); - blk_init_queue(RequestQueue, DAC960_RequestFunction, "dac960"); + blk_init_queue(RequestQueue, DAC960_RequestFunction); blk_queue_headactive(RequestQueue, 0); RequestQueue->queuedata = Controller; RequestQueue->max_segments = Controller->DriverScatterGatherLimit; diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/blkpg.c linux/drivers/block/blkpg.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/blkpg.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/blkpg.c Wed Nov 28 09:08:40 2001 @@ -285,10 +285,6 @@ case BLKELVSET: return -ENOTTY; - case BLKHASHPROF: - case BLKHASHCLEAR: - return bio_ioctl(dev, cmd, arg); - case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ intval = BLOCK_SIZE; diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/cciss.c linux/drivers/block/cciss.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/cciss.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/cciss.c Wed Nov 28 08:51:50 2001 @@ -1866,7 +1866,7 @@ q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; - blk_init_queue(q, do_cciss_request, hba[i]->devname); + blk_init_queue(q, do_cciss_request); blk_queue_headactive(q, 0); blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); q->max_segments = MAXSGENTRIES; diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/cpqarray.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/cpqarray.c Wed Nov 28 08:51:57 2001 @@ -467,7 +467,7 @@ q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; - blk_init_queue(q, do_ida_request, hba[i]->devname); + blk_init_queue(q, do_ida_request); blk_queue_headactive(q, 0); blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); q->max_segments = SG_MAX; diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/elevator.c linux/drivers/block/elevator.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/elevator.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/elevator.c Wed Nov 28 09:03:26 2001 @@ -20,7 +20,6 @@ * * Jens: * - Rework again to work with bio instead of buffer_heads - * - added merge by hash-lookup * - loose bi_dev comparisons, partition handling is right now * - completely modularize elevator setup and teardown * @@ -106,102 +105,54 @@ return 0; } -/* - * find a struct request that has a bio linked that we can merge with - */ -inline struct request *bio_get_hash_rq(kdev_t dev, sector_t sector, int vc) -{ - struct bio *bio = bio_hash_find(dev, sector, vc); - struct request *rq = NULL; - - /* - * bio is pinned until we bio_put it - */ - if (bio) { - rq = bio->bi_hash_desc; - - BUG_ON(!rq); - - bio_put(bio); - } - - return rq; -} - int elevator_linus_merge(request_queue_t *q, struct request **req, struct list_head *head, struct bio *bio) { unsigned int count = bio_sectors(bio); - struct elv_linus_data *edat = q->elevator.elevator_data; - unsigned int vc = q->hash_valid_counter; - struct list_head *entry; + struct list_head *entry = &q->queue_head; + int ret = ELEVATOR_NO_MERGE; struct request *__rq; - /* - * first try a back merge, then front, then give up and scan. this - * will of course fail for different size bios on the same queue, - * however that isn't really an issue - */ - if (likely(edat->flags & ELV_LINUS_BACK_MERGE)) { - __rq = bio_get_hash_rq(bio->bi_dev, bio->bi_sector - count, vc); - if (__rq) { - if (!elv_rq_merge_ok(q, __rq, bio)) - goto front; - - /* - * looks ok to merge - */ - if (__rq->sector + __rq->nr_sectors == bio->bi_sector) { - *req = __rq; - return ELEVATOR_BACK_MERGE; - } - } - } - -front: - if (likely(edat->flags & ELV_LINUS_FRONT_MERGE)) { - __rq = bio_get_hash_rq(bio->bi_dev, bio->bi_sector + count, vc); - if (__rq) { - if (!elv_rq_merge_ok(q, __rq, bio)) - goto scan; - - /* - * looks ok to merge - */ - if (__rq->sector - count == bio->bi_sector) { - *req = __rq; - return ELEVATOR_FRONT_MERGE; - } - } - } - - /* - * no merge possible, scan for insertion - */ -scan: entry = &q->queue_head; while ((entry = entry->prev) != head) { __rq = list_entry_rq(entry); prefetch(list_entry_rq(entry->prev)); + /* + * simply "aging" of requests in queue + */ + if (__rq->elevator_sequence-- <= 0) + break; + if (unlikely(__rq->waiting || __rq->special)) continue; if (unlikely(!__rq->inactive)) break; if (!*req && bio_rq_in_between(bio, __rq, &q->queue_head)) *req = __rq; + if (!elv_rq_merge_ok(q, __rq, bio)) + continue; + + if (__rq->elevator_sequence < count) + break; /* - * simple "aging" of requests in queue + * we can merge and sequence is ok, check if it's possible */ - if (__rq->elevator_sequence-- <= 0) + if (__rq->sector + __rq->nr_sectors == bio->bi_sector) { + ret = ELEVATOR_BACK_MERGE; + *req = __rq; break; - else if (__rq->elevator_sequence < count) + } else if (__rq->sector - count == bio->bi_sector) { + ret = ELEVATOR_FRONT_MERGE; + __rq->elevator_sequence -= count; + *req = __rq; break; + } } - return ELEVATOR_NO_MERGE; + return ret; } void elevator_linus_merge_cleanup(request_queue_t *q, struct request *req, int count) @@ -231,10 +182,6 @@ void elv_add_request_fn(request_queue_t *q, struct request *rq, struct list_head *insert_here) { - /* - * insert into queue pending list, merge hash, and possible latency - * list - */ list_add(&rq->queuelist, insert_here); } @@ -248,78 +195,60 @@ int elv_linus_init(request_queue_t *q, elevator_t *e) { - struct elv_linus_data *edata; - - edata = kmalloc(sizeof(struct elv_linus_data), GFP_ATOMIC); - if (!edata) - return -ENOMEM; - - /* - * default to doing both front and back merges - */ - edata->flags = ELV_LINUS_BACK_MERGE | ELV_LINUS_FRONT_MERGE; - e->elevator_data = edata; return 0; } void elv_linus_exit(request_queue_t *q, elevator_t *e) { - kfree(e->elevator_data); } /* * See if we can find a request that this buffer can be coalesced with. */ int elevator_noop_merge(request_queue_t *q, struct request **req, - struct list_head * head, struct bio *bio) + struct list_head *head, struct bio *bio) { + unsigned int count = bio_sectors(bio); + struct list_head *entry = &q->queue_head; struct request *__rq; - int count, ret; - unsigned int vc; - count = bio_sectors(bio); - ret = ELEVATOR_NO_MERGE; - vc = q->hash_valid_counter; + entry = &q->queue_head; + while ((entry = entry->prev) != head) { + __rq = list_entry_rq(entry); + + prefetch(list_entry_rq(entry->prev)); - __rq = bio_get_hash_rq(bio->bi_dev, bio->bi_sector - count, vc); - if (__rq) { + if (unlikely(__rq->waiting || __rq->special)) + continue; + if (unlikely(!__rq->inactive)) + break; if (!elv_rq_merge_ok(q, __rq, bio)) - goto front; + continue; + /* + * we can merge and sequence is ok, check if it's possible + */ if (__rq->sector + __rq->nr_sectors == bio->bi_sector) { - ret = ELEVATOR_BACK_MERGE; *req = __rq; - goto out; - } - } - -front: - __rq = bio_get_hash_rq(bio->bi_dev, bio->bi_sector + count, vc); - if (__rq) { - if (!elv_rq_merge_ok(q, __rq, bio)) - goto out; - - if (__rq->sector - count == bio->bi_sector) { - ret = ELEVATOR_FRONT_MERGE; + return ELEVATOR_BACK_MERGE; + } else if (__rq->sector - count == bio->bi_sector) { *req = __rq; - goto out; + return ELEVATOR_FRONT_MERGE; } } -out: - return ret; + return ELEVATOR_NO_MERGE; } void elevator_noop_merge_cleanup(request_queue_t *q, struct request *req, int count) {} void elevator_noop_merge_req(struct request *req, struct request *next) {} -int elevator_init(request_queue_t *q, elevator_t *e, elevator_t type,char *name) +int elevator_init(request_queue_t *q, elevator_t *e, elevator_t type) { *e = type; INIT_LIST_HEAD(&q->queue_head); - strncpy(e->queue_name, name, 15); if (e->elevator_init_fn) return e->elevator_init_fn(q, e); diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/floppy.c linux/drivers/block/floppy.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/floppy.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/floppy.c Wed Nov 28 08:52:06 2001 @@ -4170,7 +4170,7 @@ blk_size[MAJOR_NR] = floppy_sizes; blksize_size[MAJOR_NR] = floppy_blocksizes; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, "floppy"); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); config_types(); diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/ll_rw_blk.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/ll_rw_blk.c Wed Nov 28 09:04:24 2001 @@ -549,14 +549,14 @@ * blk_init_queue() must be paired with a blk_cleanup_queue() call * when the block device is deactivated (such as at module unload). **/ -int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, char *name) +int blk_init_queue(request_queue_t *q, request_fn_proc *rfn) { int ret; if (blk_init_free_list(q)) return -ENOMEM; - if ((ret = elevator_init(q, &q->elevator, ELEVATOR_LINUS, name))) { + if ((ret = elevator_init(q, &q->elevator, ELEVATOR_LINUS))) { blk_cleanup_queue(q); return ret; } @@ -709,17 +709,6 @@ req->q = NULL; /* - * should only happen on freereq logic in __make_request, in which - * case we don't want to prune these entries from the hash - */ -#if 1 - if (req->bio) - bio_hash_remove(req->bio); - if (req->biotail) - bio_hash_remove(req->biotail); -#endif - - /* * Request may not have originated from ll_rw_blk. if not, * assume it has free buffers and check waiters */ @@ -756,11 +745,6 @@ if (q->merge_requests_fn(q, req, next)) { q->elevator.elevator_merge_req_fn(req, next); - bio_hash_remove(req->biotail); - - /* - * will handle dangling hash too - */ blkdev_dequeue_request(next); req->biotail->bi_next = next->bio; @@ -768,8 +752,6 @@ next->bio = next->biotail = NULL; - bio_hash_add_unique(req->biotail, req, q->hash_valid_counter); - req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; blkdev_release_request(next); @@ -857,10 +839,8 @@ * the back of the queue and invalidate the entire existing merge hash * for this device */ - if (barrier && !freereq) { + if (barrier && !freereq) latency = 0; - bio_hash_invalidate(q, bio->bi_dev); - } insert_here = head->prev; if (blk_queue_empty(q) || barrier) { @@ -887,8 +867,6 @@ break; elevator->elevator_merge_cleanup_fn(q, req, nr_sectors); - bio_hash_remove(req->biotail); - req->biotail->bi_next = bio; req->biotail = bio; req->nr_sectors = req->hard_nr_sectors += nr_sectors; @@ -903,8 +881,6 @@ break; elevator->elevator_merge_cleanup_fn(q, req, nr_sectors); - bio_hash_remove(req->bio); - bio->bi_next = req->bio; req->bio = bio; /* @@ -987,7 +963,6 @@ } spin_unlock_irq(&q->queue_lock); - bio_hash_add_unique(bio, req, q->hash_valid_counter); return 0; end_io: @@ -1035,13 +1010,13 @@ * * The caller of generic_make_request must make sure that bi_io_vec * are set to describe the memory buffer, and that bi_dev and bi_sector are - & set to describe the device address, and the + * set to describe the device address, and the * bi_end_io and optionally bi_private are set to describe how * completion notification should be signaled. * * generic_make_request and the drivers it calls may use bi_next if this * bio happens to be merged with someone else, and may change bi_dev and - * bi_rsector for remaps as it sees fit. So the values of these fields + * bi_sector for remaps as it sees fit. So the values of these fields * should NOT be depended on after the call to generic_make_request. * * */ @@ -1121,11 +1096,6 @@ BIO_BUG_ON(nr_sectors != (bh->b_size >> 9)); - /* - * I/O is complete -- remove from hash, end buffer_head, put bio - */ - bio_hash_remove(bio); - bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags)); bio_put(bio); @@ -1317,9 +1287,9 @@ /** * end_that_request_first - end I/O on one buffer. - * &q: queue that finished request * @req: the request being processed * @uptodate: 0 for I/O error + * @nr_sectors: number of sectors to end I/O on * * Description: * Ends I/O on the first buffer attached to @req, and sets it up @@ -1354,7 +1324,6 @@ bio->bi_next = nxt; if ((bio = req->bio) != NULL) { - bio_hash_add_unique(bio,req,req->q->hash_valid_counter); req->hard_sector += nsect; req->hard_nr_sectors -= nsect; req->sector = req->hard_sector; diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/block/nbd.c linux/drivers/block/nbd.c --- /opt/kernel/linux-2.5.1-pre2/drivers/block/nbd.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/block/nbd.c Wed Nov 28 08:52:14 2001 @@ -501,7 +501,7 @@ #endif blksize_size[MAJOR_NR] = nbd_blksizes; blk_size[MAJOR_NR] = nbd_sizes; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request, "nbd"); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request); blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); for (i = 0; i < MAX_NBD; i++) { nbd_dev[i].refcnt = 0; diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c --- /opt/kernel/linux-2.5.1-pre2/drivers/ide/ide-probe.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/ide/ide-probe.c Wed Nov 28 08:52:55 2001 @@ -597,7 +597,7 @@ int max_sectors; q->queuedata = HWGROUP(drive); - blk_init_queue(q, do_ide_request, drive->name); + blk_init_queue(q, do_ide_request); /* IDE can do up to 128K per request, pdc4030 needs smaller limit */ #ifdef CONFIG_BLK_DEV_PDC4030 diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/ide/ide.c linux/drivers/ide/ide.c --- /opt/kernel/linux-2.5.1-pre2/drivers/ide/ide.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/ide/ide.c Wed Nov 28 09:09:18 2001 @@ -2834,8 +2834,6 @@ case BLKELVSET: case BLKBSZGET: case BLKBSZSET: - case BLKHASHPROF: - case BLKHASHCLEAR: return blk_ioctl(inode->i_rdev, cmd, arg); case HDIO_GET_BUSSTATE: diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/message/i2o/i2o_block.c linux/drivers/message/i2o/i2o_block.c --- /opt/kernel/linux-2.5.1-pre2/drivers/message/i2o/i2o_block.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/message/i2o/i2o_block.c Wed Nov 28 09:16:20 2001 @@ -410,7 +410,7 @@ * unlocked. */ - while (end_that_request_first(req, !req->errors)) + while (end_that_request_first(req, !req->errors, req->hard_cur_sectors)) ; /* @@ -459,12 +459,6 @@ struct i2ob_device *dev = &i2ob_dev[(unit&0xF0)]; /* - * Pull the lock over ready - */ - - spin_lock_prefetch(&io_request_lock); - - /* * FAILed message */ if(m[0] & (1<<13)) @@ -1405,7 +1399,6 @@ */ static int i2ob_init_iop(unsigned int unit) { - char name[16]; int i; i2ob_queues[unit] = (struct i2ob_iop_queue*) @@ -1429,8 +1422,7 @@ i2ob_queues[unit]->i2ob_qhead = &i2ob_queues[unit]->request_queue[0]; atomic_set(&i2ob_queues[unit]->queue_depth, 0); - sprintf(name, "i2o%d", unit); - blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request, name); + blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request); blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0); i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit]; @@ -1829,7 +1821,7 @@ blk_size[MAJOR_NR] = i2ob_sizes; blk_dev[MAJOR_NR].queue = i2ob_get_queue; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request, "i2o"); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request); blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); for (i = 0; i < MAX_I2OB << 4; i++) { diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/message/i2o/i2o_scsi.c linux/drivers/message/i2o/i2o_scsi.c --- /opt/kernel/linux-2.5.1-pre2/drivers/message/i2o/i2o_scsi.c Mon Oct 22 17:39:56 2001 +++ linux/drivers/message/i2o/i2o_scsi.c Wed Nov 28 09:17:43 2001 @@ -151,11 +151,10 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg) { Scsi_Cmnd *current_command; + spinlock_t *lock; u32 *m = (u32 *)msg; u8 as,ds,st; - spin_lock_prefetch(&io_request_lock); - if(m[0] & (1<<13)) { printk("IOP fail.\n"); @@ -190,12 +189,13 @@ { /* Create a scsi error for this */ current_command = (Scsi_Cmnd *)m[3]; + lock = ¤t_command->host->host_lock; printk("Aborted %ld\n", current_command->serial_number); - spin_lock_irq(&io_request_lock); + spin_lock_irq(lock); current_command->result = DID_ERROR << 16; current_command->scsi_done(current_command); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(lock); /* Now flush the message by making it a NOP */ m[0]&=0x00FFFFFF; @@ -284,9 +284,10 @@ * It worked maybe ? */ current_command->result = DID_OK << 16 | ds; - spin_lock(&io_request_lock); + lock = ¤t_command->host->host_lock; + spin_lock(lock); current_command->scsi_done(current_command); - spin_unlock(&io_request_lock); + spin_unlock(lock); return; } diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- /opt/kernel/linux-2.5.1-pre2/drivers/scsi/scsi.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/scsi/scsi.c Wed Nov 28 08:52:46 2001 @@ -188,12 +188,9 @@ */ void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) { - char name[16]; - request_queue_t *q = &SDpnt->request_queue; - sprintf(name, "scsi%d%d%d", SDpnt->id, SDpnt->lun, SDpnt->channel); - blk_init_queue(q, scsi_request_fn, name); + blk_init_queue(q, scsi_request_fn); blk_queue_headactive(q, 0); q->queuedata = (void *) SDpnt; #ifdef DMA_CHUNK_SIZE diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- /opt/kernel/linux-2.5.1-pre2/drivers/scsi/sd.c Wed Nov 28 09:13:59 2001 +++ linux/drivers/scsi/sd.c Wed Nov 28 09:09:26 2001 @@ -236,8 +236,6 @@ case BLKELVSET: case BLKBSZGET: case BLKBSZSET: - case BLKHASHPROF: - case BLKHASHCLEAR: return blk_ioctl(inode->i_rdev, cmd, arg); case BLKRRPART: /* Re-read partition tables */ diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/fs/bio.c linux/fs/bio.c --- /opt/kernel/linux-2.5.1-pre2/fs/bio.c Wed Nov 28 09:13:59 2001 +++ linux/fs/bio.c Wed Nov 28 09:06:08 2001 @@ -40,9 +40,6 @@ static DECLARE_WAIT_QUEUE_HEAD(bio_pool_wait); static DECLARE_WAIT_QUEUE_HEAD(biovec_pool_wait); -struct bio_hash_bucket *bio_hash_table; -unsigned int bio_hash_bits, bio_hash_mask; - static unsigned int bio_pool_free; #define BIOVEC_NR_POOLS 6 @@ -63,269 +60,12 @@ #define BIO_MAX_PAGES (bvec_pool_sizes[BIOVEC_NR_POOLS - 1]) -#ifdef BIO_HASH_PROFILING -static struct bio_hash_stats bio_stats; -#endif - -/* - * optimized for 2^BIO_HASH_SCALE kB block size - */ -#define BIO_HASH_SCALE 3 -#define BIO_HASH_BLOCK(sector) ((sector) >> BIO_HASH_SCALE) - -/* - * pending further testing, grabbed from fs/buffer.c hash so far... - */ -#define __bio_hash(dev,block) \ - (((((dev)<<(bio_hash_bits - 6)) ^ ((dev)<<(bio_hash_bits - 9))) ^ \ - (((block)<<(bio_hash_bits - 6)) ^ ((block) >> 13) ^ \ - ((block) << (bio_hash_bits - 12)))) & bio_hash_mask) - -#define bio_hash(dev, sector) &((bio_hash_table + __bio_hash(dev, BIO_HASH_BLOCK((sector))))->hash) - -#define bio_hash_bucket(dev, sector) (bio_hash_table + __bio_hash(dev, BIO_HASH_BLOCK((sector)))) - -#define __BIO_HASH_RWLOCK(dev, sector) \ - &((bio_hash_table + __bio_hash((dev), BIO_HASH_BLOCK((sector))))->lock) -#define BIO_HASH_RWLOCK(bio) \ - __BIO_HASH_RWLOCK((bio)->bi_dev, (bio)->bi_sector) - /* * TODO: change this to use slab reservation scheme once that infrastructure * is in place... */ #define BIO_POOL_SIZE (256) -void __init bio_hash_init(unsigned long mempages) -{ - unsigned long htable_size, order; - int i; - - /* - * need to experiment on size of hash - */ - mempages >>= 2; - - htable_size = mempages * sizeof(struct bio_hash_bucket *); - for (order = 0; (PAGE_SIZE << order) < htable_size; order++) - ; - - do { - unsigned long tmp = (PAGE_SIZE << order) / sizeof(struct bio_hash_bucket); - - bio_hash_bits = 0; - while ((tmp >>= 1UL) != 0UL) - bio_hash_bits++; - - bio_hash_table = (struct bio_hash_bucket *) __get_free_pages(GFP_ATOMIC, order); - } while (bio_hash_table == NULL && --order > 0); - - if (!bio_hash_table) - panic("Failed to allocate page hash table\n"); - - printk("Bio-cache hash table entries: %ld (order: %ld, %ld bytes)\n", - BIO_HASH_SIZE, order, (PAGE_SIZE << order)); - - for (i = 0; i < BIO_HASH_SIZE; i++) { - struct bio_hash_bucket *hb = &bio_hash_table[i]; - - rwlock_init(&hb->lock); - hb->hash = NULL; - } - - bio_hash_mask = BIO_HASH_SIZE - 1; -} - -inline void __bio_hash_remove(struct bio *bio) -{ - bio_hash_t *entry = &bio->bi_hash; - bio_hash_t **pprev = entry->pprev_hash; - - if (pprev) { - bio_hash_t *nxt = entry->next_hash; - - if (nxt) - nxt->pprev_hash = pprev; - - *pprev = nxt; -#if 1 - entry->next_hash = NULL; -#endif - entry->pprev_hash = NULL; - entry->valid_counter = 0; - bio->bi_hash_desc = NULL; -#ifdef BIO_HASH_PROFILING - atomic_dec(&bio_stats.nr_entries); -#endif - } -} - -inline void bio_hash_remove(struct bio *bio) -{ - rwlock_t *hash_lock = BIO_HASH_RWLOCK(bio); - unsigned long flags; - - write_lock_irqsave(hash_lock, flags); - __bio_hash_remove(bio); - write_unlock_irqrestore(hash_lock, flags); -} - -inline void __bio_hash_add(struct bio *bio, bio_hash_t **hash, - void *hash_desc, unsigned int vc) -{ - bio_hash_t *entry = &bio->bi_hash; - bio_hash_t *nxt = *hash; - - BUG_ON(entry->pprev_hash); - - *hash = entry; - entry->next_hash = nxt; - entry->pprev_hash = hash; - entry->valid_counter = vc; - - if (nxt) - nxt->pprev_hash = &entry->next_hash; - - bio->bi_hash_desc = hash_desc; - -#ifdef BIO_HASH_PROFILING - atomic_inc(&bio_stats.nr_inserts); - atomic_inc(&bio_stats.nr_entries); - { - int entries = atomic_read(&bio_stats.nr_entries); - if (entries > atomic_read(&bio_stats.max_entries)) - atomic_set(&bio_stats.max_entries, entries); - } -#endif -} - -inline void bio_hash_add(struct bio *bio, void *hash_desc, unsigned int vc) -{ - struct bio_hash_bucket *hb =bio_hash_bucket(bio->bi_dev,bio->bi_sector); - unsigned long flags; - - write_lock_irqsave(&hb->lock, flags); - __bio_hash_add(bio, &hb->hash, hash_desc, vc); - write_unlock_irqrestore(&hb->lock, flags); -} - -inline struct bio *__bio_hash_find(kdev_t dev, sector_t sector, - bio_hash_t **hash, unsigned int vc) -{ - bio_hash_t *next = *hash, *entry; - struct bio *bio; - int nr = 0; - -#ifdef BIO_HASH_PROFILING - atomic_inc(&bio_stats.nr_lookups); -#endif - while ((entry = next)) { - next = entry->next_hash; - prefetch(next); - bio = bio_hash_entry(entry); - - if (entry->valid_counter == vc) { - if (bio->bi_sector == sector && bio->bi_dev == dev) { -#ifdef BIO_HASH_PROFILING - if (nr > atomic_read(&bio_stats.max_bucket_size)) - atomic_set(&bio_stats.max_bucket_size, nr); - if (nr <= MAX_PROFILE_BUCKETS) - atomic_inc(&bio_stats.bucket_size[nr]); - atomic_inc(&bio_stats.nr_hits); -#endif - bio_get(bio); - return bio; - } - } - nr++; - } - - return NULL; -} - -inline struct bio *bio_hash_find(kdev_t dev, sector_t sector, unsigned int vc) -{ - struct bio_hash_bucket *hb = bio_hash_bucket(dev, sector); - unsigned long flags; - struct bio *bio; - - read_lock_irqsave(&hb->lock, flags); - bio = __bio_hash_find(dev, sector, &hb->hash, vc); - read_unlock_irqrestore(&hb->lock, flags); - - return bio; -} - -inline int __bio_hash_add_unique(struct bio *bio, bio_hash_t **hash, - void *hash_desc, unsigned int vc) -{ - struct bio *alias = __bio_hash_find(bio->bi_dev, bio->bi_sector, hash, vc); - - if (!alias) { - __bio_hash_add(bio, hash, hash_desc, vc); - return 0; - } - - /* - * release reference to alias - */ - bio_put(alias); - return 1; -} - -inline int bio_hash_add_unique(struct bio *bio, void *hash_desc, unsigned int vc) -{ - struct bio_hash_bucket *hb =bio_hash_bucket(bio->bi_dev,bio->bi_sector); - unsigned long flags; - int ret = 1; - - if (!bio->bi_hash.pprev_hash) { - write_lock_irqsave(&hb->lock, flags); - ret = __bio_hash_add_unique(bio, &hb->hash, hash_desc, vc); - write_unlock_irqrestore(&hb->lock, flags); - } - - return ret; -} - -/* - * increment validity counter on barrier inserts. if it wraps, we must - * prune all existing entries for this device to be completely safe - * - * q->queue_lock must be held by caller - */ -void bio_hash_invalidate(request_queue_t *q, kdev_t dev) -{ - bio_hash_t *hash; - struct bio *bio; - int i; - - if (++q->hash_valid_counter) - return; - - /* - * it wrapped... - */ - for (i = 0; i < (1 << bio_hash_bits); i++) { - struct bio_hash_bucket *hb = &bio_hash_table[i]; - unsigned long flags; - - write_lock_irqsave(&hb->lock, flags); - while ((hash = hb->hash) != NULL) { - bio = bio_hash_entry(hash); - if (bio->bi_dev != dev) - __bio_hash_remove(bio); - } - write_unlock_irqrestore(&hb->lock, flags); - } - - /* - * entries pruned, reset validity counter - */ - q->hash_valid_counter = 1; -} - - /* * if need be, add bio_pool_get_irq() to match... */ @@ -515,13 +255,11 @@ if (bio) { gotit: bio->bi_next = NULL; - bio->bi_hash.pprev_hash = NULL; atomic_set(&bio->bi_cnt, 1); bio->bi_io_vec = NULL; bio->bi_flags = 0; bio->bi_rw = 0; bio->bi_end_io = NULL; - bio->bi_hash_desc = NULL; bio->bi_destructor = dest; } @@ -562,8 +300,6 @@ */ static inline void bio_free(struct bio *bio) { - BUG_ON(bio_is_hashed(bio)); - bio->bi_destructor(bio); } @@ -737,7 +473,6 @@ * all done */ if (done) { - bio_hash_remove(bio); bio_put(bio); return 0; } @@ -962,29 +697,6 @@ biovec_init_pool(); -#ifdef BIO_HASH_PROFILING - memset(&bio_stats, 0, sizeof(bio_stats)); -#endif - - return 0; -} - -int bio_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg) -{ -#ifdef BIO_HASH_PROFILING - switch (cmd) { - case BLKHASHPROF: - if (copy_to_user((struct bio_hash_stats *) arg, &bio_stats, sizeof(bio_stats))) - return -EFAULT; - break; - case BLKHASHCLEAR: - memset(&bio_stats, 0, sizeof(bio_stats)); - break; - default: - return -ENOTTY; - } - -#endif return 0; } @@ -993,7 +705,4 @@ EXPORT_SYMBOL(bio_alloc); EXPORT_SYMBOL(bio_put); EXPORT_SYMBOL(ll_rw_kio); -EXPORT_SYMBOL(bio_hash_remove); -EXPORT_SYMBOL(bio_hash_add); -EXPORT_SYMBOL(bio_hash_add_unique); EXPORT_SYMBOL(bio_endio); diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/fs/minix/inode.c linux/fs/minix/inode.c --- /opt/kernel/linux-2.5.1-pre2/fs/minix/inode.c Sun Sep 30 21:26:08 2001 +++ linux/fs/minix/inode.c Wed Nov 28 08:35:05 2001 @@ -292,7 +292,7 @@ return 0; } -static int minix_get_block(struct inode *inode, long block, +static int minix_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { if (INODE_VERSION(inode) == MINIX_V1) diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/include/linux/bio.h linux/include/linux/bio.h --- /opt/kernel/linux-2.5.1-pre2/include/linux/bio.h Wed Nov 28 09:13:59 2001 +++ linux/include/linux/bio.h Wed Nov 28 09:06:25 2001 @@ -30,26 +30,6 @@ #endif /* - * hash profiling stuff.. - */ -#define BIO_HASH_PROFILING - -#define BLKHASHPROF _IOR(0x12,108,sizeof(struct bio_hash_stats)) -#define BLKHASHCLEAR _IO(0x12,109) - -#define MAX_PROFILE_BUCKETS 64 - -struct bio_hash_stats { - atomic_t nr_lookups; - atomic_t nr_hits; - atomic_t nr_inserts; - atomic_t nr_entries; - atomic_t max_entries; - atomic_t max_bucket_size; - atomic_t bucket_size[MAX_PROFILE_BUCKETS + 1]; -}; - -/* * was unsigned short, but we might as well be ready for > 64kB I/O pages */ struct bio_vec { @@ -67,28 +47,6 @@ struct bio_vec bvl_vec[0]; /* the iovec array */ }; -typedef struct bio_hash_s { - struct bio_hash_s *next_hash; - struct bio_hash_s **pprev_hash; - unsigned long valid_counter; -} bio_hash_t; - -struct bio_hash_bucket { - rwlock_t lock; - bio_hash_t *hash; -} __attribute__((__aligned__(16))); - -#define BIO_HASH_BITS (bio_hash_bits) -#define BIO_HASH_SIZE (1UL << BIO_HASH_BITS) - -/* - * shamelessly stolen from the list.h implementation - */ -#define hash_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) -#define bio_hash_entry(ptr) \ - hash_entry((ptr), struct bio, bi_hash) - /* * main unit of I/O for the block layer and lower layers (ie drivers and * stacking drivers) @@ -96,7 +54,6 @@ struct bio { sector_t bi_sector; struct bio *bi_next; /* request queue link */ - bio_hash_t bi_hash; atomic_t bi_cnt; /* pin count */ kdev_t bi_dev; /* will be block device */ struct bio_vec_list *bi_io_vec; @@ -107,8 +64,6 @@ int (*bi_end_io)(struct bio *bio, int nr_sectors); void *bi_private; - void *bi_hash_desc; /* cookie for hash */ - void (*bi_destructor)(struct bio *); /* destructor */ }; @@ -125,8 +80,6 @@ #define BIO_PREBUILT 3 /* not merged big */ #define BIO_CLONED 4 /* doesn't own data */ -#define bio_is_hashed(bio) ((bio)->bi_hash.pprev_hash) - /* * bio bi_rw flags * @@ -209,17 +162,6 @@ extern struct bio *bio_alloc(int, int); extern void bio_put(struct bio *); -/* - * the hash stuff is pretty closely tied to the request queue (needed for - * locking etc anyway, and it's in no way an attempt at a generic hash) - */ -struct request_queue; - -extern inline void bio_hash_remove(struct bio *); -extern inline void bio_hash_add(struct bio *, void *, unsigned int); -extern inline struct bio *bio_hash_find(kdev_t, sector_t, unsigned int); -extern inline int bio_hash_add_unique(struct bio *, void *, unsigned int); -extern void bio_hash_invalidate(struct request_queue *, kdev_t); extern int bio_endio(struct bio *, int, int); extern struct bio *bio_clone(struct bio *, int); diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/include/linux/blk.h linux/include/linux/blk.h --- /opt/kernel/linux-2.5.1-pre2/include/linux/blk.h Wed Nov 28 09:13:59 2001 +++ linux/include/linux/blk.h Wed Nov 28 09:08:14 2001 @@ -83,11 +83,6 @@ static inline void blkdev_dequeue_request(struct request *req) { - if (req->bio) - bio_hash_remove(req->bio); - if (req->biotail) - bio_hash_remove(req->biotail); - list_del(&req->queuelist); } diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/include/linux/blkdev.h linux/include/linux/blkdev.h --- /opt/kernel/linux-2.5.1-pre2/include/linux/blkdev.h Wed Nov 28 09:13:59 2001 +++ linux/include/linux/blkdev.h Wed Nov 28 09:08:14 2001 @@ -128,8 +128,6 @@ unsigned int max_segment_size; wait_queue_head_t queue_wait; - - unsigned int hash_valid_counter; }; #define RQ_INACTIVE (-1) @@ -166,11 +164,6 @@ if (rq) { rq->inactive = 0; wmb(); - - if (rq->bio) - bio_hash_remove(rq->bio); - if (rq->biotail) - bio_hash_remove(rq->biotail); } return rq; @@ -187,7 +180,7 @@ { struct page *page = bio_page(*bio); - if (page - page->zone->zone_mem_map > q->bounce_pfn) + if ((page - page->zone->zone_mem_map) + (page->zone->zone_start_paddr >> PAGE_SHIFT) < q->bounce_pfn) create_bounce(bio, q->bounce_gfp); } @@ -235,7 +228,7 @@ /* * Access functions for manipulating queue properties */ -extern int blk_init_queue(request_queue_t *, request_fn_proc *, char *); +extern int blk_init_queue(request_queue_t *, request_fn_proc *); extern void blk_cleanup_queue(request_queue_t *); extern void blk_queue_make_request(request_queue_t *, make_request_fn *); extern void blk_queue_bounce_limit(request_queue_t *, unsigned long long); diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/include/linux/elevator.h linux/include/linux/elevator.h --- /opt/kernel/linux-2.5.1-pre2/include/linux/elevator.h Wed Nov 28 09:13:59 2001 +++ linux/include/linux/elevator.h Wed Nov 28 08:51:34 2001 @@ -33,13 +33,6 @@ elevator_init_fn *elevator_init_fn; elevator_exit_fn *elevator_exit_fn; - - /* - * per-elevator private data - */ - void *elevator_data; - - char queue_name[16]; }; int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct bio *); @@ -66,7 +59,7 @@ #define BLKELVGET _IOR(0x12,106,sizeof(blkelv_ioctl_arg_t)) #define BLKELVSET _IOW(0x12,107,sizeof(blkelv_ioctl_arg_t)) -extern int elevator_init(request_queue_t *, elevator_t *, elevator_t, char *); +extern int elevator_init(request_queue_t *, elevator_t *, elevator_t); extern void elevator_exit(request_queue_t *, elevator_t *); /* diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/include/linux/fs.h linux/include/linux/fs.h --- /opt/kernel/linux-2.5.1-pre2/include/linux/fs.h Wed Nov 28 09:13:59 2001 +++ linux/include/linux/fs.h Wed Nov 28 09:07:50 2001 @@ -205,7 +205,6 @@ extern void update_atime (struct inode *); #define UPDATE_ATIME(inode) update_atime (inode) -extern void bio_hash_init(unsigned long); extern void buffer_init(unsigned long); extern void inode_init(unsigned long); extern void mnt_init(unsigned long); diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/init/main.c linux/init/main.c --- /opt/kernel/linux-2.5.1-pre2/init/main.c Wed Nov 28 09:13:59 2001 +++ linux/init/main.c Wed Nov 28 09:08:12 2001 @@ -600,7 +600,6 @@ vfs_caches_init(mempages); buffer_init(mempages); page_cache_init(mempages); - bio_hash_init(mempages); #if defined(CONFIG_ARCH_S390) ccwcache_init(); #endif diff -ur -X /home/axboe/exclude /opt/kernel/linux-2.5.1-pre2/mm/highmem.c linux/mm/highmem.c --- /opt/kernel/linux-2.5.1-pre2/mm/highmem.c Wed Nov 28 09:13:59 2001 +++ linux/mm/highmem.c Wed Nov 28 09:14:50 2001 @@ -289,7 +289,6 @@ spin_unlock_irqrestore(&emergency_lock, flags); } - bio_hash_remove(bio); bio_put(bio); }