Index: drivers/block/ll_rw_blk.c =================================================================== RCS file: /home/cvs/linux/drivers/block/ll_rw_blk.c,v retrieving revision 1.15 retrieving revision 1.17 diff -u -w -r1.15 -r1.17 --- drivers/block/ll_rw_blk.c 2001/03/28 11:38:49 1.15 +++ drivers/block/ll_rw_blk.c 2001/05/31 14:16:20 1.17 @@ -4,6 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1994, Karl Keyte: Added support for disk statistics * Elevator latency, (C) 2000 Andrea Arcangeli SuSE + * Merging for dyn. allocated majors, (C) 2001 Carsten Otte IBM */ /* @@ -119,6 +120,12 @@ */ int * max_segments[MAX_BLKDEV]; +/* + * rule to merge requests for major + * + */ +int blk_merge_rule[MAX_BLKDEV]; + static inline int get_max_sectors(kdev_t dev) { if (!max_sectors[MAJOR(dev)]) @@ -578,6 +585,7 @@ int rw_ahead, max_req, max_sectors, max_segments; unsigned long flags; int back, front; + int skip_first_req; count = bh->b_size >> 9; sector = bh->b_rsector; @@ -660,12 +668,29 @@ */ spin_lock_irqsave(&io_request_lock,flags); req = *get_queue(bh->b_rdev); + /* + * Do not skip merging first request in queue + */ + skip_first_req = 0; if (!req) { /* MD and loop can't handle plugging without deadlocking */ if (major != MD_MAJOR && major != LOOP_MAJOR && major != DDV_MAJOR && major != NBD_MAJOR) plug_device(blk_dev + major); /* is atomic */ } else switch (major) { + default: + /* + * For dynamicaly allocated majors, that are not defined in + * CASE_COALESCE_BUT_FIRST_REQUEST_MAYBE_BUSY or + * CASE_COALESCE_ALSO_FIRST_REQUEST have a look at blk_merge_rule + * to determine whether requests may be merged + */ + if ((blk_merge_rule[major] != BLK_MERGE_BUT_FIRST_REQUEST_MAY_BE_BUSY) && + (blk_merge_rule[major] != BLK_MERGE_ALSO_FIRST_REQUEST)) + break; + if (blk_merge_rule[major] == BLK_MERGE_ALSO_FIRST_REQUEST) + skip_first_req = 1; + /* fall through */ CASE_COALESCE_BUT_FIRST_REQUEST_MAYBE_BUSY /* * The scsi disk and cdrom drivers completely remove the request @@ -676,7 +701,7 @@ * All other drivers need to jump over the first entry, as that * entry may be busy being processed and we thus can't change it. */ - if (req == blk_dev[major].current_request) + if (req == blk_dev[major].current_request && skip_first_req == 0) if (!(req = req->next)) break; /* fall through */ Index: include/linux/blkdev.h =================================================================== RCS file: /home/cvs/linux/include/linux/blkdev.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -w -r1.4 -r1.5 --- include/linux/blkdev.h 2001/01/18 13:05:12 1.4 +++ include/linux/blkdev.h 2001/05/31 14:10:53 1.5 @@ -107,6 +107,15 @@ extern int * max_segments[MAX_BLKDEV]; +extern int blk_merge_rule[MAX_BLKDEV]; + +/* + * definitions which can be set into blk_merge_rule + */ +#define BLK_MERGE_NEVER 0 +#define BLK_MERGE_BUT_FIRST_REQUEST_MAY_BE_BUSY 1 +#define BLK_MERGE_ALSO_FIRST_REQUEST 2 + #define MAX_SECTORS 128 #define MAX_SEGMENTS MAX_SECTORS