===== drivers/block/ll_rw_blk.c 1.47 vs edited ===== --- 1.47/drivers/block/ll_rw_blk.c Thu Jun 26 09:20:08 2003 +++ edited/drivers/block/ll_rw_blk.c Thu Jun 26 10:52:17 2003 @@ -592,6 +592,8 @@ q->full = 0; q->can_throttle = 0; + memset(q->batch, 0, sizeof(struct queue_batch) * 2); + reset_stats(q); /* @@ -606,6 +608,48 @@ blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); } +#define MSEC(x) ((x) * 1000 / HZ) +#define BATCH_MAX_AGE 100 +int grab_batch_ownership(request_queue_t *q, int rw) +{ + struct task_struct *tsk = current; + unsigned long age; + struct queue_batch *batch = q->batch + rw; + + if (batch->batch_waiter) + return 0; + if (!batch->batch_owner) + goto grab; + batch->batch_waiter = tsk; + while(1) { + age = jiffies - batch->batch_jiffies; + if (!batch->batch_owner || MSEC(age) > BATCH_MAX_AGE) + break; + set_current_state(TASK_RUNNING); + spin_unlock_irq(&io_request_lock); + schedule(); + spin_lock_irq(&io_request_lock); + } + batch->batch_waiter = NULL; +grab: + batch->batch_owner = tsk; + batch->batch_jiffies = jiffies; + batch->batch_remaining = q->batch_requests; + return 1; +} + +void decrement_batch_request(request_queue_t *q, int rw) +{ + struct queue_batch *batch = q->batch + rw; + if (batch->batch_owner == current) { + batch->batch_remaining--; + if (!batch->batch_remaining || + MSEC(jiffies - batch->batch_jiffies) > BATCH_MAX_AGE) { + batch->batch_owner = NULL; + } + } +} + #define blkdev_free_rq(list) list_entry((list)->next, struct request, queue); /* * Get a free request. io_request_lock must be held and interrupts @@ -625,6 +669,7 @@ rq->cmd = rw; rq->special = NULL; rq->q = q; + decrement_batch_request(q, rw); } else q->full = 1; return rq; @@ -635,7 +680,7 @@ */ static inline struct request *get_request(request_queue_t *q, int rw) { - if (q->full) + if (q->full && q->batch[rw].batch_owner != current) return NULL; return __get_request(q, rw); } @@ -698,25 +743,28 @@ static struct request *__get_request_wait(request_queue_t *q, int rw) { - register struct request *rq; + register struct request *rq = NULL; unsigned long wait_start = jiffies; unsigned long time_waited; DECLARE_WAITQUEUE(wait, current); add_wait_queue_exclusive(&q->wait_for_requests, &wait); + spin_lock_irq(&io_request_lock); do { set_current_state(TASK_UNINTERRUPTIBLE); - spin_lock_irq(&io_request_lock); if (q->full || blk_oversized_queue(q)) { - __generic_unplug_device(q); + if (blk_oversized_queue(q)) + __generic_unplug_device(q); spin_unlock_irq(&io_request_lock); schedule(); spin_lock_irq(&io_request_lock); + if (!grab_batch_ownership(q, rw)) + continue; } rq = __get_request(q, rw); - spin_unlock_irq(&io_request_lock); } while (rq == NULL); + spin_unlock_irq(&io_request_lock); remove_wait_queue(&q->wait_for_requests, &wait); current->state = TASK_RUNNING; @@ -978,9 +1026,9 @@ list_add(&req->queue, &q->rq.free); if (q->rq.count >= q->batch_requests && !oversized_batch) { smp_mb(); - if (waitqueue_active(&q->wait_for_requests)) + if (waitqueue_active(&q->wait_for_requests)) { wake_up(&q->wait_for_requests); - else + } else clear_full_and_wake(q); } } ===== include/linux/blkdev.h 1.25 vs edited ===== --- 1.25/include/linux/blkdev.h Thu Jun 26 09:20:08 2003 +++ edited/include/linux/blkdev.h Thu Jun 26 10:50:17 2003 @@ -69,6 +69,15 @@ struct list_head free; }; +struct queue_batch +{ + struct task_struct *batch_owner; + struct task_struct *batch_waiter; + unsigned long batch_jiffies; + int batch_remaining; + +}; + struct request_queue { /* @@ -141,7 +150,7 @@ * threshold */ int full:1; - + /* * Boolean that indicates you will use blk_started_sectors * and blk_finished_sectors in addition to blk_started_io @@ -162,6 +171,9 @@ * Tasks wait here for free read and write requests */ wait_queue_head_t wait_for_requests; + + struct queue_batch batch[2]; + unsigned long max_wait; unsigned long min_wait; unsigned long total_wait; @@ -278,7 +290,7 @@ #define MAX_SEGMENTS 128 #define MAX_SECTORS 255 -#define MAX_QUEUE_SECTORS (2 << (20 - 9)) /* 4 mbytes when full sized */ +#define MAX_QUEUE_SECTORS (4 << (20 - 9)) /* 4 mbytes when full sized */ #define MAX_NR_REQUESTS 1024 /* 1024k when in 512 units, normally min is 1M in 1k units */ #define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)