diff options
author | Jens Axboe <axboe@suse.de> | 2006-01-09 10:02:34 -0500 |
---|---|---|
committer | Jens Axboe <axboe@suse.de> | 2006-01-09 10:02:34 -0500 |
commit | ff856bad67cb65cb4dc4ef88b808804fc4265782 (patch) | |
tree | 2db1e0be2be1e814cf8fe9bb8d3d7401fb24dd86 /include | |
parent | 5367f2d67c7d0bf1faae90e6e7b4e2ac3c9b5e0f (diff) |
[BLOCK] ll_rw_blk: Enable out-of-order request completions through softirq
Request completion can be a quite heavy process, since it needs to
iterate through the entire request and complete the bio's it holds.
This patch adds blk_complete_request() which moves this processing
into a dedicated block softirq.
Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/blkdev.h | 21 | ||||
-rw-r--r-- | include/linux/interrupt.h | 1 |
2 files changed, 19 insertions, 3 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index fb0985377421..804cc4ec9533 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -118,9 +118,9 @@ struct request_list { | |||
118 | * try to put the fields that are referenced together in the same cacheline | 118 | * try to put the fields that are referenced together in the same cacheline |
119 | */ | 119 | */ |
120 | struct request { | 120 | struct request { |
121 | struct list_head queuelist; /* looking for ->queue? you must _not_ | 121 | struct list_head queuelist; |
122 | * access it directly, use | 122 | struct list_head donelist; |
123 | * blkdev_dequeue_request! */ | 123 | |
124 | unsigned long flags; /* see REQ_ bits below */ | 124 | unsigned long flags; /* see REQ_ bits below */ |
125 | 125 | ||
126 | /* Maintain bio traversal state for part by part I/O submission. | 126 | /* Maintain bio traversal state for part by part I/O submission. |
@@ -141,6 +141,7 @@ struct request { | |||
141 | struct bio *biotail; | 141 | struct bio *biotail; |
142 | 142 | ||
143 | void *elevator_private; | 143 | void *elevator_private; |
144 | void *completion_data; | ||
144 | 145 | ||
145 | unsigned short ioprio; | 146 | unsigned short ioprio; |
146 | 147 | ||
@@ -291,6 +292,7 @@ typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *); | |||
291 | typedef void (activity_fn) (void *data, int rw); | 292 | typedef void (activity_fn) (void *data, int rw); |
292 | typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *); | 293 | typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *); |
293 | typedef void (prepare_flush_fn) (request_queue_t *, struct request *); | 294 | typedef void (prepare_flush_fn) (request_queue_t *, struct request *); |
295 | typedef void (softirq_done_fn)(struct request *); | ||
294 | 296 | ||
295 | enum blk_queue_state { | 297 | enum blk_queue_state { |
296 | Queue_down, | 298 | Queue_down, |
@@ -332,6 +334,7 @@ struct request_queue | |||
332 | activity_fn *activity_fn; | 334 | activity_fn *activity_fn; |
333 | issue_flush_fn *issue_flush_fn; | 335 | issue_flush_fn *issue_flush_fn; |
334 | prepare_flush_fn *prepare_flush_fn; | 336 | prepare_flush_fn *prepare_flush_fn; |
337 | softirq_done_fn *softirq_done_fn; | ||
335 | 338 | ||
336 | /* | 339 | /* |
337 | * Dispatch queue sorting | 340 | * Dispatch queue sorting |
@@ -646,6 +649,17 @@ extern int end_that_request_first(struct request *, int, int); | |||
646 | extern int end_that_request_chunk(struct request *, int, int); | 649 | extern int end_that_request_chunk(struct request *, int, int); |
647 | extern void end_that_request_last(struct request *, int); | 650 | extern void end_that_request_last(struct request *, int); |
648 | extern void end_request(struct request *req, int uptodate); | 651 | extern void end_request(struct request *req, int uptodate); |
652 | extern void blk_complete_request(struct request *); | ||
653 | |||
654 | static inline int rq_all_done(struct request *rq, unsigned int nr_bytes) | ||
655 | { | ||
656 | if (blk_fs_request(rq)) | ||
657 | return (nr_bytes >= (rq->hard_nr_sectors << 9)); | ||
658 | else if (blk_pc_request(rq)) | ||
659 | return nr_bytes >= rq->data_len; | ||
660 | |||
661 | return 0; | ||
662 | } | ||
649 | 663 | ||
650 | /* | 664 | /* |
651 | * end_that_request_first/chunk() takes an uptodate argument. we account | 665 | * end_that_request_first/chunk() takes an uptodate argument. we account |
@@ -694,6 +708,7 @@ extern void blk_queue_segment_boundary(request_queue_t *, unsigned long); | |||
694 | extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn); | 708 | extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn); |
695 | extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *); | 709 | extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *); |
696 | extern void blk_queue_dma_alignment(request_queue_t *, int); | 710 | extern void blk_queue_dma_alignment(request_queue_t *, int); |
711 | extern void blk_queue_softirq_done(request_queue_t *, softirq_done_fn *); | ||
697 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); | 712 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); |
698 | extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *); | 713 | extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *); |
699 | extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); | 714 | extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index e50a95fbeb11..f02204706984 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -112,6 +112,7 @@ enum | |||
112 | TIMER_SOFTIRQ, | 112 | TIMER_SOFTIRQ, |
113 | NET_TX_SOFTIRQ, | 113 | NET_TX_SOFTIRQ, |
114 | NET_RX_SOFTIRQ, | 114 | NET_RX_SOFTIRQ, |
115 | BLOCK_SOFTIRQ, | ||
115 | SCSI_SOFTIRQ, | 116 | SCSI_SOFTIRQ, |
116 | TASKLET_SOFTIRQ | 117 | TASKLET_SOFTIRQ |
117 | }; | 118 | }; |