* [PATCH 000 of 5] Introductory patches for bio refactor.
@ 2007-08-16 5:13 NeilBrown
2007-08-16 5:13 ` [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge NeilBrown
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: NeilBrown @ 2007-08-16 5:13 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, Tejun Heo
Hi Jens,
I wonder if you would accept these patches the block layer.
They are, as far as I can tell, quite uncontroversial and provide
good cleanups.
The first is a minor bug-fix.
The next to replace helper function that take a bio (always the first
bio of a request), to instead take a request.
The last two combine to replace rq_for_each_bio with
rq_for_each_segment which makes blk_recalc_rq_segments a lot
cleaner, and improves (to a lesser degree) every other place that
used rq_for_each_bio.
The net result is a decrease in object code size (for my x86-64 compile)
for block/built-in.o of 96 bytes, though there is some growth out in
drivers making and over-all decrease of only 48 bytes.
Thanks,
NeilBrown
[PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge.
[PATCH 002 of 5] Replace bio_data with blk_rq_data
[PATCH 003 of 5] Replace bio_cur_sectors with blk_rq_cur_sectors.
[PATCH 004 of 5] Introduce rq_for_each_segment replacing rq_for_each_bio
[PATCH 005 of 5] Merge blk_recount_segments into blk_recalc_rq_segments
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge. 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown @ 2007-08-16 5:13 ` NeilBrown 2007-08-16 7:01 ` Jens Axboe 2007-08-16 5:13 ` [PATCH 002 of 5] Replace bio_data with blk_rq_data NeilBrown ` (4 subsequent siblings) 5 siblings, 1 reply; 14+ messages in thread From: NeilBrown @ 2007-08-16 5:13 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo ll_merge_requests_fn can update bi_hw_*_size in one case where we end up not merging. This is wrong. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./block/ll_rw_blk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c --- .prev/block/ll_rw_blk.c 2007-08-16 14:57:39.000000000 +1000 +++ ./block/ll_rw_blk.c 2007-08-16 15:02:29.000000000 +1000 @@ -1518,11 +1518,13 @@ static int ll_merge_requests_fn(struct r /* * propagate the combined length to the end of the requests */ + total_hw_segments--; + if (total_hw_segments > q->max_hw_segments) + return 0; if (req->nr_hw_segments == 1) req->bio->bi_hw_front_size = len; if (next->nr_hw_segments == 1) next->biotail->bi_hw_back_size = len; - total_hw_segments--; } if (total_hw_segments > q->max_hw_segments) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge. 2007-08-16 5:13 ` [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge NeilBrown @ 2007-08-16 7:01 ` Jens Axboe 0 siblings, 0 replies; 14+ messages in thread From: Jens Axboe @ 2007-08-16 7:01 UTC (permalink / raw) To: NeilBrown; +Cc: linux-kernel, Tejun Heo On Thu, Aug 16 2007, NeilBrown wrote: > > ll_merge_requests_fn can update bi_hw_*_size in one case where we end > up not merging. This is wrong. This looks good, obviously. Applied. -- Jens Axboe ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown 2007-08-16 5:13 ` [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge NeilBrown @ 2007-08-16 5:13 ` NeilBrown 2007-08-16 7:02 ` Jens Axboe 2007-08-16 5:13 ` [PATCH 003 of 5] Replace bio_cur_sectors with blk_rq_cur_sectors NeilBrown ` (3 subsequent siblings) 5 siblings, 1 reply; 14+ messages in thread From: NeilBrown @ 2007-08-16 5:13 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo Almost every call to bio_data is for the first bio in a request. A future patch will add some accounting information to 'struct request' which will need to be used to find the start of the request in the bio. So replace bio_data with blk_rq_data which takes a 'struct request *' The one exception is in dm-emc were using page_address(bio->bi_io_vec[0].bv_page); is appropriate. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./block/ll_rw_blk.c | 16 ++++++++++++---- ./drivers/block/floppy.c | 2 +- ./drivers/ide/ide-cd.c | 11 ++++++----- ./drivers/ide/ide-io.c | 2 +- ./drivers/md/dm-emc.c | 2 +- ./drivers/message/fusion/mptsas.c | 4 ++-- ./drivers/scsi/libsas/sas_expander.c | 4 ++-- ./include/linux/bio.h | 4 +--- ./include/linux/blkdev.h | 1 + 9 files changed, 27 insertions(+), 19 deletions(-) diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c --- .prev/block/ll_rw_blk.c 2007-08-16 15:02:29.000000000 +1000 +++ ./block/ll_rw_blk.c 2007-08-16 15:02:30.000000000 +1000 @@ -2907,8 +2907,8 @@ static void init_request_from_bio(struct req->current_nr_sectors = req->hard_cur_sectors = bio_cur_sectors(bio); req->nr_phys_segments = bio_phys_segments(req->q, bio); req->nr_hw_segments = bio_hw_segments(req->q, bio); - req->buffer = bio_data(bio); /* see ->buffer comment above */ req->bio = req->biotail = bio; + req->buffer = blk_rq_data(req); /* see ->buffer comment above */ req->ioprio = bio_prio(bio); req->rq_disk = bio->bi_bdev->bd_disk; req->start_time = jiffies; @@ -2977,7 +2977,7 @@ static int __make_request(struct request * it didn't need a bounce buffer then it better * not touch req->buffer either... */ - req->buffer = bio_data(bio); + req->buffer = blk_rq_data(req); req->current_nr_sectors = bio_cur_sectors(bio); req->hard_cur_sectors = req->current_nr_sectors; req->sector = req->hard_sector = bio->bi_sector; @@ -3373,7 +3373,7 @@ static void blk_recalc_rq_sectors(struct rq->nr_sectors = rq->hard_nr_sectors; rq->hard_cur_sectors = bio_cur_sectors(rq->bio); rq->current_nr_sectors = rq->hard_cur_sectors; - rq->buffer = bio_data(rq->bio); + rq->buffer = blk_rq_data(rq); } /* @@ -3678,14 +3678,22 @@ void blk_rq_bio_prep(struct request_queu rq->current_nr_sectors = bio_cur_sectors(bio); rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); - rq->buffer = bio_data(bio); rq->data_len = bio->bi_size; rq->bio = rq->biotail = bio; + rq->buffer = blk_rq_data(rq); } EXPORT_SYMBOL(blk_rq_bio_prep); +void *blk_rq_data(struct request *rq) +{ + return page_address(bio_page(rq->bio)) + + bio_offset(rq->bio); +} +EXPORT_SYMBOL(blk_rq_data); + + int kblockd_schedule_work(struct work_struct *work) { return queue_work(kblockd_workqueue, work); diff .prev/drivers/block/floppy.c ./drivers/block/floppy.c --- .prev/drivers/block/floppy.c 2007-08-16 14:57:31.000000000 +1000 +++ ./drivers/block/floppy.c 2007-08-16 15:02:30.000000000 +1000 @@ -2456,7 +2456,7 @@ static int buffer_chain_size(void) int i; char *base; - base = bio_data(current_req->bio); + base = blk_rq_data(current_req); size = 0; rq_for_each_bio(bio, current_req) { diff .prev/drivers/ide/ide-cd.c ./drivers/ide/ide-cd.c --- .prev/drivers/ide/ide-cd.c 2007-08-16 14:57:31.000000000 +1000 +++ ./drivers/ide/ide-cd.c 2007-08-16 15:02:30.000000000 +1000 @@ -1381,10 +1381,11 @@ static ide_startstop_t cdrom_start_seek start it over entirely, or even put it back on the request queue. */ static void restore_request (struct request *rq) { - if (rq->buffer != bio_data(rq->bio)) { - sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE; + if (rq->buffer != blk_rq_data(rq)) { + sector_t n = (rq->buffer - (char *)blk_rq_data(rq)) + / SECTOR_SIZE; - rq->buffer = bio_data(rq->bio); + rq->buffer = blk_rq_data(rq); rq->nr_sectors += n; rq->sector -= n; } @@ -1659,7 +1660,7 @@ static void post_transform_command(struc return; if (req->bio) - ibuf = bio_data(req->bio); + ibuf = blk_rq_data(req); else ibuf = req->data; @@ -1768,7 +1769,7 @@ static ide_startstop_t cdrom_newpc_intr( * bio backed? */ if (rq->bio) { - ptr = bio_data(rq->bio); + ptr = blk_rq_data(rq); blen = bio_iovec(rq->bio)->bv_len; } diff .prev/drivers/ide/ide-io.c ./drivers/ide/ide-io.c --- .prev/drivers/ide/ide-io.c 2007-08-16 14:57:31.000000000 +1000 +++ ./drivers/ide/ide-io.c 2007-08-16 15:02:30.000000000 +1000 @@ -1426,7 +1426,7 @@ static ide_startstop_t ide_dma_timeout_r rq->sector = rq->bio->bi_sector; rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; rq->hard_cur_sectors = rq->current_nr_sectors; - rq->buffer = bio_data(rq->bio); + rq->buffer = blk_rq_data(rq); out: return ret; } diff .prev/drivers/md/dm-emc.c ./drivers/md/dm-emc.c --- .prev/drivers/md/dm-emc.c 2007-08-16 14:57:31.000000000 +1000 +++ ./drivers/md/dm-emc.c 2007-08-16 15:02:30.000000000 +1000 @@ -167,7 +167,7 @@ static struct request *emc_trespass_get( return NULL; } - page22 = (unsigned char *)bio_data(bio); + page22 = (unsigned char *)page_address(bio->bi_io_vec[0].bv_page); memset(page22, 0, data_size); memcpy(page22, h->short_trespass ? diff .prev/drivers/message/fusion/mptsas.c ./drivers/message/fusion/mptsas.c --- .prev/drivers/message/fusion/mptsas.c 2007-08-16 14:57:31.000000000 +1000 +++ ./drivers/message/fusion/mptsas.c 2007-08-16 15:02:30.000000000 +1000 @@ -1382,7 +1382,7 @@ static int mptsas_smp_handler(struct Scs mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT; flagsLength |= (req->data_len - 4); - dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio), + dma_addr_out = pci_map_single(ioc->pcidev, blk_rq_data(req), req->data_len, PCI_DMA_BIDIRECTIONAL); if (!dma_addr_out) goto put_mf; @@ -1392,7 +1392,7 @@ static int mptsas_smp_handler(struct Scs /* response */ flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; flagsLength |= rsp->data_len + 4; - dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), + dma_addr_in = pci_map_single(ioc->pcidev, blk_rq_data(rsp), rsp->data_len, PCI_DMA_BIDIRECTIONAL); if (!dma_addr_in) goto unmap; diff .prev/drivers/scsi/libsas/sas_expander.c ./drivers/scsi/libsas/sas_expander.c --- .prev/drivers/scsi/libsas/sas_expander.c 2007-08-16 14:57:31.000000000 +1000 +++ ./drivers/scsi/libsas/sas_expander.c 2007-08-16 15:02:30.000000000 +1000 @@ -1924,8 +1924,8 @@ int sas_smp_handler(struct Scsi_Host *sh return -EINVAL; } - ret = smp_execute_task(dev, bio_data(req->bio), req->data_len, - bio_data(rsp->bio), rsp->data_len); + ret = smp_execute_task(dev, blk_rq_data(req), req->data_len, + blk_rq_data(rsp), rsp->data_len); return ret; } diff .prev/include/linux/bio.h ./include/linux/bio.h --- .prev/include/linux/bio.h 2007-08-16 14:57:31.000000000 +1000 +++ ./include/linux/bio.h 2007-08-16 15:02:30.000000000 +1000 @@ -167,8 +167,7 @@ struct bio { } while (0) /* - * various member access, note that bio_data should of course not be used - * on highmem page vectors + * various member access */ #define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)])) #define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx) @@ -177,7 +176,6 @@ struct bio { #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) #define bio_sectors(bio) ((bio)->bi_size >> 9) #define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9) -#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio))) #define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) #define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC)) #define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) diff .prev/include/linux/blkdev.h ./include/linux/blkdev.h --- .prev/include/linux/blkdev.h 2007-08-16 14:57:31.000000000 +1000 +++ ./include/linux/blkdev.h 2007-08-16 15:02:30.000000000 +1000 @@ -700,6 +700,7 @@ extern int blk_execute_rq(struct request extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, struct request *, int, rq_end_io_fn *); extern int blk_verify_command(unsigned char *, int); +extern void *blk_rq_data(struct request *); static inline struct request_queue *bdev_get_queue(struct block_device *bdev) { ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 5:13 ` [PATCH 002 of 5] Replace bio_data with blk_rq_data NeilBrown @ 2007-08-16 7:02 ` Jens Axboe 2007-08-16 7:15 ` Neil Brown 0 siblings, 1 reply; 14+ messages in thread From: Jens Axboe @ 2007-08-16 7:02 UTC (permalink / raw) To: NeilBrown; +Cc: linux-kernel, Tejun Heo On Thu, Aug 16 2007, NeilBrown wrote: > > Almost every call to bio_data is for the first bio > in a request. A future patch will add some accounting > information to 'struct request' which will need to be > used to find the start of the request in the bio. > So replace bio_data with blk_rq_data which takes a 'struct request *' > > The one exception is in dm-emc were using > page_address(bio->bi_io_vec[0].bv_page); > is appropriate. This (and 3+4) just look like preparatory patches if we want to merge the full patchset, not bug fixes. I seem to recall you had more bug fixes or cleanups in your patchset, maybe I was mistaken. So nak for now for 2-4, I'd apply 5 but it depends on the previous. -- Jens Axboe ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 7:02 ` Jens Axboe @ 2007-08-16 7:15 ` Neil Brown 2007-08-16 7:21 ` Jens Axboe 0 siblings, 1 reply; 14+ messages in thread From: Neil Brown @ 2007-08-16 7:15 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo On Thursday August 16, jens.axboe@oracle.com wrote: > On Thu, Aug 16 2007, NeilBrown wrote: > > > > Almost every call to bio_data is for the first bio > > in a request. A future patch will add some accounting > > information to 'struct request' which will need to be > > used to find the start of the request in the bio. > > So replace bio_data with blk_rq_data which takes a 'struct request *' > > > > The one exception is in dm-emc were using > > page_address(bio->bi_io_vec[0].bv_page); > > is appropriate. > > This (and 3+4) just look like preparatory patches if we want to merge > the full patchset, not bug fixes. I seem to recall you had more bug > fixes or cleanups in your patchset, maybe I was mistaken. So nak for now > for 2-4, I'd apply 5 but it depends on the previous. > I don't remember other bug fixes, but I'll look through and check. 2 and 3 are very simple changes that - I think - make it clearer what is happening. And I felt 5 was a sufficient improvement to justify it and 4... I'll go hunting and see what other preliminaries I can find. NeilBrown ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 7:15 ` Neil Brown @ 2007-08-16 7:21 ` Jens Axboe 2007-08-16 11:15 ` Neil Brown 0 siblings, 1 reply; 14+ messages in thread From: Jens Axboe @ 2007-08-16 7:21 UTC (permalink / raw) To: Neil Brown; +Cc: linux-kernel, Tejun Heo On Thu, Aug 16 2007, Neil Brown wrote: > On Thursday August 16, jens.axboe@oracle.com wrote: > > On Thu, Aug 16 2007, NeilBrown wrote: > > > > > > Almost every call to bio_data is for the first bio > > > in a request. A future patch will add some accounting > > > information to 'struct request' which will need to be > > > used to find the start of the request in the bio. > > > So replace bio_data with blk_rq_data which takes a 'struct request *' > > > > > > The one exception is in dm-emc were using > > > page_address(bio->bi_io_vec[0].bv_page); > > > is appropriate. > > > > This (and 3+4) just look like preparatory patches if we want to merge > > the full patchset, not bug fixes. I seem to recall you had more bug > > fixes or cleanups in your patchset, maybe I was mistaken. So nak for now > > for 2-4, I'd apply 5 but it depends on the previous. > > > > I don't remember other bug fixes, but I'll look through and check. OK, I'm properly remembering incorrectly then. > 2 and 3 are very simple changes that - I think - make it clearer what > is happening. To be honest, I don't see much win in using blk_rq_data() over bio_data() at all. I'd much much rather just see it go away! > And I felt 5 was a sufficient improvement to justify it and 4... 5 is nice, I would like to apply that :-) > I'll go hunting and see what other preliminaries I can find. Thanks! -- Jens Axboe ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 7:21 ` Jens Axboe @ 2007-08-16 11:15 ` Neil Brown 2007-08-16 11:19 ` Jens Axboe 2007-08-16 11:22 ` Jens Axboe 0 siblings, 2 replies; 14+ messages in thread From: Neil Brown @ 2007-08-16 11:15 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo On Thursday August 16, jens.axboe@oracle.com wrote: > > 2 and 3 are very simple changes that - I think - make it clearer what > > is happening. > > To be honest, I don't see much win in using blk_rq_data() over > bio_data() at all. I'd much much rather just see it go away! > Well, as it is always the data at the (current) head of the request... But I can make it go a way if you like.. What does it become? bvec_kmap ?? > > And I felt 5 was a sufficient improvement to justify it and 4... > > 5 is nice, I would like to apply that :-) > OK, here comes '5' at the top of a small set of patches. Take it and any of the following that you like. NeilBrown ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 11:15 ` Neil Brown @ 2007-08-16 11:19 ` Jens Axboe 2007-08-16 11:22 ` Jens Axboe 1 sibling, 0 replies; 14+ messages in thread From: Jens Axboe @ 2007-08-16 11:19 UTC (permalink / raw) To: Neil Brown; +Cc: linux-kernel, Tejun Heo On Thu, Aug 16 2007, Neil Brown wrote: > On Thursday August 16, jens.axboe@oracle.com wrote: > > > 2 and 3 are very simple changes that - I think - make it clearer what > > > is happening. > > > > To be honest, I don't see much win in using blk_rq_data() over > > bio_data() at all. I'd much much rather just see it go away! > > > > Well, as it is always the data at the (current) head of the request... > > But I can make it go a way if you like.. What does it become? > bvec_kmap ?? Yeah, it then just becomes a kmap. And ->buffer goes away completely. > > > And I felt 5 was a sufficient improvement to justify it and 4... > > > > 5 is nice, I would like to apply that :-) > > > > OK, here comes '5' at the top of a small set of patches. Take it and > any of the following that you like. Thanks. -- Jens Axboe ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 002 of 5] Replace bio_data with blk_rq_data 2007-08-16 11:15 ` Neil Brown 2007-08-16 11:19 ` Jens Axboe @ 2007-08-16 11:22 ` Jens Axboe 1 sibling, 0 replies; 14+ messages in thread From: Jens Axboe @ 2007-08-16 11:22 UTC (permalink / raw) To: Neil Brown; +Cc: linux-kernel, Tejun Heo On Thu, Aug 16 2007, Neil Brown wrote: > On Thursday August 16, jens.axboe@oracle.com wrote: > > > 2 and 3 are very simple changes that - I think - make it clearer what > > > is happening. > > > > To be honest, I don't see much win in using blk_rq_data() over > > bio_data() at all. I'd much much rather just see it go away! > > > > Well, as it is always the data at the (current) head of the request... So is bio_data(bio), and bio_data(rq->bio) is by definition the head of the request. If anything, you are making it less flexible. Hence my suggestion to just kill it off completely, it's a long over due cleanup. -- Jens Axboe ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 003 of 5] Replace bio_cur_sectors with blk_rq_cur_sectors. 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown 2007-08-16 5:13 ` [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge NeilBrown 2007-08-16 5:13 ` [PATCH 002 of 5] Replace bio_data with blk_rq_data NeilBrown @ 2007-08-16 5:13 ` NeilBrown 2007-08-16 5:13 ` [PATCH 004 of 5] Introduce rq_for_each_segment replacing rq_for_each_bio NeilBrown ` (2 subsequent siblings) 5 siblings, 0 replies; 14+ messages in thread From: NeilBrown @ 2007-08-16 5:13 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo All calls to bio_cur_sectors are for the first bio in a 'struct request'. A future patch will make the discovery of this number dependant on information in the request. So change the function to take a 'struct request *' instread of a 'struct bio *', and make it a real function as more code will need to be added. One place wants the current bytes rather than sectors, so the 'real function' we create is blk_rq_cur_bytes, and blk_rq_cur_sectors divides this value by 512. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./block/ll_rw_blk.c | 18 ++++++++++++------ ./drivers/ide/ide-cd.c | 11 ++++++----- ./drivers/ide/ide-io.c | 2 +- ./include/linux/bio.h | 1 - ./include/linux/blkdev.h | 5 +++++ 5 files changed, 24 insertions(+), 13 deletions(-) diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c --- .prev/block/ll_rw_blk.c 2007-08-16 15:02:30.000000000 +1000 +++ ./block/ll_rw_blk.c 2007-08-16 15:02:30.000000000 +1000 @@ -2904,10 +2904,11 @@ static void init_request_from_bio(struct req->errors = 0; req->hard_sector = req->sector = bio->bi_sector; req->hard_nr_sectors = req->nr_sectors = bio_sectors(bio); - req->current_nr_sectors = req->hard_cur_sectors = bio_cur_sectors(bio); + req->bio = req->biotail = bio; + req->current_nr_sectors = req->hard_cur_sectors = + blk_rq_cur_sectors(req); req->nr_phys_segments = bio_phys_segments(req->q, bio); req->nr_hw_segments = bio_hw_segments(req->q, bio); - req->bio = req->biotail = bio; req->buffer = blk_rq_data(req); /* see ->buffer comment above */ req->ioprio = bio_prio(bio); req->rq_disk = bio->bi_bdev->bd_disk; @@ -2978,7 +2979,7 @@ static int __make_request(struct request * not touch req->buffer either... */ req->buffer = blk_rq_data(req); - req->current_nr_sectors = bio_cur_sectors(bio); + req->current_nr_sectors = blk_rq_cur_sectors(req); req->hard_cur_sectors = req->current_nr_sectors; req->sector = req->hard_sector = bio->bi_sector; req->nr_sectors = req->hard_nr_sectors += nr_sectors; @@ -3371,7 +3372,7 @@ static void blk_recalc_rq_sectors(struct (rq->sector <= rq->hard_sector)) { rq->sector = rq->hard_sector; rq->nr_sectors = rq->hard_nr_sectors; - rq->hard_cur_sectors = bio_cur_sectors(rq->bio); + rq->hard_cur_sectors = blk_rq_cur_sectors(rq); rq->current_nr_sectors = rq->hard_cur_sectors; rq->buffer = blk_rq_data(rq); } @@ -3675,13 +3676,13 @@ void blk_rq_bio_prep(struct request_queu rq->nr_phys_segments = bio_phys_segments(q, bio); rq->nr_hw_segments = bio_hw_segments(q, bio); - rq->current_nr_sectors = bio_cur_sectors(bio); - rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); rq->data_len = bio->bi_size; rq->bio = rq->biotail = bio; rq->buffer = blk_rq_data(rq); + rq->current_nr_sectors = blk_rq_cur_sectors(rq); + rq->hard_cur_sectors = rq->current_nr_sectors; } EXPORT_SYMBOL(blk_rq_bio_prep); @@ -3693,6 +3694,11 @@ void *blk_rq_data(struct request *rq) } EXPORT_SYMBOL(blk_rq_data); +int blk_rq_cur_bytes(struct request *rq) +{ + return bio_iovec(rq->bio)->bv_len; +} +EXPORT_SYMBOL(blk_rq_cur_bytes); int kblockd_schedule_work(struct work_struct *work) { diff .prev/drivers/ide/ide-cd.c ./drivers/ide/ide-cd.c --- .prev/drivers/ide/ide-cd.c 2007-08-16 15:02:30.000000000 +1000 +++ ./drivers/ide/ide-cd.c 2007-08-16 15:02:30.000000000 +1000 @@ -1173,7 +1173,8 @@ static ide_startstop_t cdrom_read_intr ( /* First, figure out if we need to bit-bucket any of the leading sectors. */ - nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer); + nskip = min_t(int, rq->current_nr_sectors - blk_rq_cur_sectors(rq), + sectors_to_transfer); while (nskip > 0) { /* We need to throw away a sector. */ @@ -1273,7 +1274,7 @@ static int cdrom_read_from_buffer (ide_d represent the number of sectors to skip at the start of a transfer will fail. I think that this will never happen, but let's be paranoid and check. */ - if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) && + if (rq->current_nr_sectors < blk_rq_cur_sectors(rq) && (rq->sector & (sectors_per_frame - 1))) { printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n", drive->name, (long)rq->sector); @@ -1308,7 +1309,7 @@ static ide_startstop_t cdrom_start_read_ nskip = rq->sector & (sectors_per_frame - 1); if (nskip > 0) { /* Sanity check... */ - if (rq->current_nr_sectors != bio_cur_sectors(rq->bio) && + if (rq->current_nr_sectors != blk_rq_cur_sectors(rq) && (rq->sector & (sectors_per_frame - 1))) { printk(KERN_ERR "%s: cdrom_start_read_continuation: buffer botch (%u)\n", drive->name, rq->current_nr_sectors); @@ -1389,7 +1390,7 @@ static void restore_request (struct requ rq->nr_sectors += n; rq->sector -= n; } - rq->hard_cur_sectors = rq->current_nr_sectors = bio_cur_sectors(rq->bio); + rq->hard_cur_sectors = rq->current_nr_sectors = blk_rq_cur_sectors(rq); rq->hard_nr_sectors = rq->nr_sectors; rq->hard_sector = rq->sector; rq->q->prep_rq_fn(rq->q, rq); @@ -1770,7 +1771,7 @@ static ide_startstop_t cdrom_newpc_intr( */ if (rq->bio) { ptr = blk_rq_data(rq); - blen = bio_iovec(rq->bio)->bv_len; + blen = blk_rq_cur_bytes(rq); } if (!ptr) { diff .prev/drivers/ide/ide-io.c ./drivers/ide/ide-io.c --- .prev/drivers/ide/ide-io.c 2007-08-16 15:02:30.000000000 +1000 +++ ./drivers/ide/ide-io.c 2007-08-16 15:02:30.000000000 +1000 @@ -1424,7 +1424,7 @@ static ide_startstop_t ide_dma_timeout_r goto out; rq->sector = rq->bio->bi_sector; - rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; + rq->current_nr_sectors = blk_rq_cur_sectors(rq); rq->hard_cur_sectors = rq->current_nr_sectors; rq->buffer = blk_rq_data(rq); out: diff .prev/include/linux/bio.h ./include/linux/bio.h --- .prev/include/linux/bio.h 2007-08-16 15:02:30.000000000 +1000 +++ ./include/linux/bio.h 2007-08-16 15:02:30.000000000 +1000 @@ -175,7 +175,6 @@ struct bio { #define bio_offset(bio) bio_iovec((bio))->bv_offset #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) #define bio_sectors(bio) ((bio)->bi_size >> 9) -#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9) #define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) #define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC)) #define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) diff .prev/include/linux/blkdev.h ./include/linux/blkdev.h --- .prev/include/linux/blkdev.h 2007-08-16 15:02:30.000000000 +1000 +++ ./include/linux/blkdev.h 2007-08-16 15:02:30.000000000 +1000 @@ -701,6 +701,11 @@ extern void blk_execute_rq_nowait(struct struct request *, int, rq_end_io_fn *); extern int blk_verify_command(unsigned char *, int); extern void *blk_rq_data(struct request *); +extern int blk_rq_cur_bytes(struct request *); +static inline int blk_rq_cur_sectors(struct request *rq) +{ + return blk_rq_cur_bytes(rq) >> 9; +} static inline struct request_queue *bdev_get_queue(struct block_device *bdev) { ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 004 of 5] Introduce rq_for_each_segment replacing rq_for_each_bio 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown ` (2 preceding siblings ...) 2007-08-16 5:13 ` [PATCH 003 of 5] Replace bio_cur_sectors with blk_rq_cur_sectors NeilBrown @ 2007-08-16 5:13 ` NeilBrown 2007-08-16 5:13 ` [PATCH 005 of 5] Merge blk_recount_segments into blk_recalc_rq_segments NeilBrown 2007-08-16 6:37 ` [PATCH 000 of 5] Introductory patches for bio refactor Jens Axboe 5 siblings, 0 replies; 14+ messages in thread From: NeilBrown @ 2007-08-16 5:13 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo (almost) every usage of rq_for_each_bio wraps a usage of bio_for_each_segment, so these can be combined into rq_for_each_segment. We get it to fill in a bio_vec structure rather than provide a pointer, as future changes to make bi_io_vec immutable will require that. The one place where rq_for_each_bio remains will be changed to use rq_for_each_segment in a subsequent patch. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./block/ll_rw_blk.c | 54 +++++++++++-------------- ./drivers/block/floppy.c | 84 ++++++++++++++++++--------------------- ./drivers/block/lguest_blk.c | 25 +++++------ ./drivers/block/nbd.c | 67 +++++++++++++++---------------- ./drivers/block/xen-blkfront.c | 57 ++++++++++++-------------- ./drivers/ide/ide-floppy.c | 62 +++++++++++++--------------- ./drivers/s390/block/dasd_diag.c | 40 ++++++++---------- ./drivers/s390/block/dasd_eckd.c | 47 ++++++++++----------- ./drivers/s390/block/dasd_fba.c | 47 ++++++++++----------- ./drivers/s390/char/tape_34xx.c | 33 ++++++--------- ./drivers/s390/char/tape_3590.c | 41 ++++++++----------- ./include/linux/blkdev.h | 18 ++++++++ 12 files changed, 280 insertions(+), 295 deletions(-) diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c --- .prev/block/ll_rw_blk.c 2007-08-16 15:02:30.000000000 +1000 +++ ./block/ll_rw_blk.c 2007-08-16 15:02:31.000000000 +1000 @@ -1313,9 +1313,11 @@ static int blk_hw_contig_segment(struct int blk_rq_map_sg(struct request_queue *q, struct request *rq, struct scatterlist *sg) { - struct bio_vec *bvec, *bvprv; - struct bio *bio; - int nsegs, i, cluster; + struct bio_vec bvec; + struct bio_vec bvprv = { 0 }; + struct req_iterator i; + int nsegs; + int cluster; nsegs = 0; cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); @@ -1323,36 +1325,30 @@ int blk_rq_map_sg(struct request_queue * /* * for each bio in rq */ - bvprv = NULL; - rq_for_each_bio(bio, rq) { - /* - * for each segment in bio - */ - bio_for_each_segment(bvec, bio, i) { - int nbytes = bvec->bv_len; + rq_for_each_segment(rq, i, bvec) { + int nbytes = bvec.bv_len; - if (bvprv && cluster) { - if (sg[nsegs - 1].length + nbytes > q->max_segment_size) - goto new_segment; - - if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) - goto new_segment; - if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) - goto new_segment; + if (bvprv.bv_page && cluster) { + if (sg[nsegs - 1].length + nbytes > q->max_segment_size) + goto new_segment; + + if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) + goto new_segment; + if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bvec)) + goto new_segment; - sg[nsegs - 1].length += nbytes; - } else { + sg[nsegs - 1].length += nbytes; + } else { new_segment: - memset(&sg[nsegs],0,sizeof(struct scatterlist)); - sg[nsegs].page = bvec->bv_page; - sg[nsegs].length = nbytes; - sg[nsegs].offset = bvec->bv_offset; + memset(&sg[nsegs], 0, sizeof(struct scatterlist)); + sg[nsegs].page = bvec.bv_page; + sg[nsegs].length = nbytes; + sg[nsegs].offset = bvec.bv_offset; - nsegs++; - } - bvprv = bvec; - } /* segments in bio */ - } /* bios in rq */ + nsegs++; + } + bvprv = bvec; + } return nsegs; } diff .prev/drivers/block/floppy.c ./drivers/block/floppy.c --- .prev/drivers/block/floppy.c 2007-08-16 15:02:30.000000000 +1000 +++ ./drivers/block/floppy.c 2007-08-16 15:02:31.000000000 +1000 @@ -2450,23 +2450,20 @@ static void rw_interrupt(void) /* Compute maximal contiguous buffer size. */ static int buffer_chain_size(void) { - struct bio *bio; - struct bio_vec *bv; + struct bio_vec bv; int size; - int i; + struct req_iterator i; char *base; base = blk_rq_data(current_req); size = 0; - rq_for_each_bio(bio, current_req) { - bio_for_each_segment(bv, bio, i) { - if (page_address(bv->bv_page) + bv->bv_offset != - base + size) - break; + rq_for_each_segment(current_req, i, bv) { + if (page_address(bv.bv_page) + bv.bv_offset != + base + size) + break; - size += bv->bv_len; - } + size += bv.bv_len; } return size >> 9; @@ -2492,12 +2489,11 @@ static int transfer_size(int ssize, int static void copy_buffer(int ssize, int max_sector, int max_sector_2) { int remaining; /* number of transferred 512-byte sectors */ - struct bio_vec *bv; - struct bio *bio; + struct bio_vec bv; char *buffer; char *dma_buffer; int size; - int i; + struct req_iterator i; max_sector = transfer_size(ssize, min(max_sector, max_sector_2), @@ -2530,43 +2526,41 @@ static void copy_buffer(int ssize, int m size = current_req->current_nr_sectors << 9; - rq_for_each_bio(bio, current_req) { - bio_for_each_segment(bv, bio, i) { - if (!remaining) - break; + rq_for_each_segment(current_req, i, bv) { + if (!remaining) + break; - size = bv->bv_len; - SUPBOUND(size, remaining); + size = bv.bv_len; + SUPBOUND(size, remaining); - buffer = page_address(bv->bv_page) + bv->bv_offset; + buffer = page_address(bv.bv_page) + bv.bv_offset; #ifdef FLOPPY_SANITY_CHECK - if (dma_buffer + size > - floppy_track_buffer + (max_buffer_sectors << 10) || - dma_buffer < floppy_track_buffer) { - DPRINT("buffer overrun in copy buffer %d\n", - (int)((floppy_track_buffer - - dma_buffer) >> 9)); - printk("fsector_t=%d buffer_min=%d\n", - fsector_t, buffer_min); - printk("current_count_sectors=%ld\n", - current_count_sectors); - if (CT(COMMAND) == FD_READ) - printk("read\n"); - if (CT(COMMAND) == FD_WRITE) - printk("write\n"); - break; - } - if (((unsigned long)buffer) % 512) - DPRINT("%p buffer not aligned\n", buffer); -#endif + if (dma_buffer + size > + floppy_track_buffer + (max_buffer_sectors << 10) || + dma_buffer < floppy_track_buffer) { + DPRINT("buffer overrun in copy buffer %d\n", + (int)((floppy_track_buffer - + dma_buffer) >> 9)); + printk(KERN_DEBUG "fsector_t=%d buffer_min=%d\n", + fsector_t, buffer_min); + printk(KERN_DEBUG "current_count_sectors=%ld\n", + current_count_sectors); if (CT(COMMAND) == FD_READ) - memcpy(buffer, dma_buffer, size); - else - memcpy(dma_buffer, buffer, size); - - remaining -= size; - dma_buffer += size; + printk(KERN_DEBUG "read\n"); + if (CT(COMMAND) == FD_WRITE) + printk(KERN_DEBUG "write\n"); + break; } + if (((unsigned long)buffer) % 512) + DPRINT("%p buffer not aligned\n", buffer); +#endif + if (CT(COMMAND) == FD_READ) + memcpy(buffer, dma_buffer, size); + else + memcpy(dma_buffer, buffer, size); + + remaining -= size; + dma_buffer += size; } #ifdef FLOPPY_SANITY_CHECK if (remaining) { diff .prev/drivers/block/lguest_blk.c ./drivers/block/lguest_blk.c --- .prev/drivers/block/lguest_blk.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/block/lguest_blk.c 2007-08-16 15:02:31.000000000 +1000 @@ -142,25 +142,24 @@ static irqreturn_t lgb_irq(int irq, void * return the total length. */ static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma) { - unsigned int i = 0, idx, len = 0; - struct bio *bio; + unsigned int i = 0; + unsigned int len = 0; + struct req_iterator idx; + struct bio_vec bvec; - rq_for_each_bio(bio, req) { - struct bio_vec *bvec; - bio_for_each_segment(bvec, bio, idx) { + rq_for_each_segment(req, idx, bvec) { /* We told the block layer not to give us too many. */ - BUG_ON(i == LGUEST_MAX_DMA_SECTIONS); + BUG_ON(i == LGUEST_MAX_DMA_SECTIONS); /* If we had a zero-length segment, it would look like * the end of the data referred to by the "struct * lguest_dma", so make sure that doesn't happen. */ - BUG_ON(!bvec->bv_len); + BUG_ON(!bvec.bv_len); /* Convert page & offset to a physical address */ - dma->addr[i] = page_to_phys(bvec->bv_page) - + bvec->bv_offset; - dma->len[i] = bvec->bv_len; - len += bvec->bv_len; - i++; - } + dma->addr[i] = page_to_phys(bvec.bv_page) + + bvec.bv_offset; + dma->len[i] = bvec.bv_len; + len += bvec.bv_len; + i++; } /* If the array isn't full, we mark the end with a 0 length */ if (i < LGUEST_MAX_DMA_SECTIONS) diff .prev/drivers/block/nbd.c ./drivers/block/nbd.c --- .prev/drivers/block/nbd.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/block/nbd.c 2007-08-16 15:02:31.000000000 +1000 @@ -180,7 +180,8 @@ static inline int sock_send_bvec(struct static int nbd_send_req(struct nbd_device *lo, struct request *req) { - int result, i, flags; + int result; + int flags; struct nbd_request request; unsigned long size = req->nr_sectors << 9; struct socket *sock = lo->sock; @@ -205,27 +206,28 @@ static int nbd_send_req(struct nbd_devic } if (nbd_cmd(req) == NBD_CMD_WRITE) { - struct bio *bio; /* * we are really probing at internals to determine * whether to set MSG_MORE or not... */ - rq_for_each_bio(bio, req) { - struct bio_vec *bvec; - bio_for_each_segment(bvec, bio, i) { - flags = 0; - if ((i < (bio->bi_vcnt - 1)) || bio->bi_next) - flags = MSG_MORE; - dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", - lo->disk->disk_name, req, - bvec->bv_len); - result = sock_send_bvec(sock, bvec, flags); - if (result <= 0) { - printk(KERN_ERR "%s: Send data failed (result %d)\n", - lo->disk->disk_name, - result); - goto error_out; - } + struct req_iterator i; + struct bio_vec bvec; + + rq_for_each_segment(req, i, bvec) { + flags = 0; + if (!rq_iter_last(req, i)) + flags = MSG_MORE; + dprintk(DBG_TX, + "%s: request %p: sending %d bytes data\n", + lo->disk->disk_name, req, + bvec.bv_len); + result = sock_send_bvec(sock, &bvec, flags); + if (result <= 0) { + printk(KERN_ERR + "%s: Send data failed (result %d)\n", + lo->disk->disk_name, + result); + goto error_out; } } } @@ -317,22 +319,21 @@ static struct request *nbd_read_stat(str dprintk(DBG_RX, "%s: request %p: got reply\n", lo->disk->disk_name, req); if (nbd_cmd(req) == NBD_CMD_READ) { - int i; - struct bio *bio; - rq_for_each_bio(bio, req) { - struct bio_vec *bvec; - bio_for_each_segment(bvec, bio, i) { - result = sock_recv_bvec(sock, bvec); - if (result <= 0) { - printk(KERN_ERR "%s: Receive data failed (result %d)\n", - lo->disk->disk_name, - result); - req->errors++; - return req; - } - dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", - lo->disk->disk_name, req, bvec->bv_len); + struct req_iterator i; + struct bio_vec bvec; + + rq_for_each_segment(req, i, bvec) { + result = sock_recv_bvec(sock, &bvec); + if (result <= 0) { + printk(KERN_ERR + "%s: Receive data failed (result %d)\n", + lo->disk->disk_name, + result); + req->errors++; + return req; } + dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", + lo->disk->disk_name, req, bvec.bv_len); } } return req; diff .prev/drivers/block/xen-blkfront.c ./drivers/block/xen-blkfront.c --- .prev/drivers/block/xen-blkfront.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/block/xen-blkfront.c 2007-08-16 15:02:31.000000000 +1000 @@ -150,9 +150,8 @@ static int blkif_queue_request(struct re struct blkfront_info *info = req->rq_disk->private_data; unsigned long buffer_mfn; struct blkif_request *ring_req; - struct bio *bio; - struct bio_vec *bvec; - int idx; + struct bio_vec bvec; + struct req_iterator idx; unsigned long id; unsigned int fsect, lsect; int ref; @@ -186,34 +185,32 @@ static int blkif_queue_request(struct re ring_req->operation = BLKIF_OP_WRITE_BARRIER; ring_req->nr_segments = 0; - rq_for_each_bio (bio, req) { - bio_for_each_segment (bvec, bio, idx) { - BUG_ON(ring_req->nr_segments - == BLKIF_MAX_SEGMENTS_PER_REQUEST); - buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); - fsect = bvec->bv_offset >> 9; - lsect = fsect + (bvec->bv_len >> 9) - 1; - /* install a grant reference. */ - ref = gnttab_claim_grant_reference(&gref_head); - BUG_ON(ref == -ENOSPC); + rq_for_each_segment(req, idx, bvec) { + BUG_ON(ring_req->nr_segments + == BLKIF_MAX_SEGMENTS_PER_REQUEST); + buffer_mfn = pfn_to_mfn(page_to_pfn(bvec.bv_page)); + fsect = bvec.bv_offset >> 9; + lsect = fsect + (bvec.bv_len >> 9) - 1; + /* install a grant reference. */ + ref = gnttab_claim_grant_reference(&gref_head); + BUG_ON(ref == -ENOSPC); + + gnttab_grant_foreign_access_ref( + ref, + info->xbdev->otherend_id, + buffer_mfn, + rq_data_dir(req) ); + + info->shadow[id].frame[ring_req->nr_segments] = + mfn_to_pfn(buffer_mfn); + + ring_req->seg[ring_req->nr_segments] = + (struct blkif_request_segment) { + .gref = ref, + .first_sect = fsect, + .last_sect = lsect }; - gnttab_grant_foreign_access_ref( - ref, - info->xbdev->otherend_id, - buffer_mfn, - rq_data_dir(req) ); - - info->shadow[id].frame[ring_req->nr_segments] = - mfn_to_pfn(buffer_mfn); - - ring_req->seg[ring_req->nr_segments] = - (struct blkif_request_segment) { - .gref = ref, - .first_sect = fsect, - .last_sect = lsect }; - - ring_req->nr_segments++; - } + ring_req->nr_segments++; } info->ring.req_prod_pvt++; diff .prev/drivers/ide/ide-floppy.c ./drivers/ide/ide-floppy.c --- .prev/drivers/ide/ide-floppy.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/ide/ide-floppy.c 2007-08-16 15:02:31.000000000 +1000 @@ -605,27 +605,26 @@ static int idefloppy_do_end_request(ide_ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) { struct request *rq = pc->rq; - struct bio_vec *bvec; - struct bio *bio; + struct bio_vec bvec; unsigned long flags; char *data; - int count, i, done = 0; + int count; + int done = 0; + struct req_iterator i; - rq_for_each_bio(bio, rq) { - bio_for_each_segment(bvec, bio, i) { - if (!bcount) - break; + rq_for_each_segment(rq, i, bvec) { + if (!bcount) + break; - count = min(bvec->bv_len, bcount); + count = min(bvec.bv_len, bcount); - data = bvec_kmap_irq(bvec, &flags); - drive->hwif->atapi_input_bytes(drive, data, count); - bvec_kunmap_irq(data, &flags); - - bcount -= count; - pc->b_count += count; - done += count; - } + data = bvec_kmap_irq(&bvec, &flags); + drive->hwif->atapi_input_bytes(drive, data, count); + bvec_kunmap_irq(data, &flags); + + bcount -= count; + pc->b_count += count; + done += count; } idefloppy_do_end_request(drive, 1, done >> 9); @@ -639,27 +638,26 @@ static void idefloppy_input_buffers (ide static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) { struct request *rq = pc->rq; - struct bio *bio; - struct bio_vec *bvec; + struct bio_vec bvec; + struct req_iterator i; unsigned long flags; - int count, i, done = 0; + int count; + int done = 0; char *data; - rq_for_each_bio(bio, rq) { - bio_for_each_segment(bvec, bio, i) { - if (!bcount) - break; + rq_for_each_segment(rq, i, bvec) { + if (!bcount) + break; - count = min(bvec->bv_len, bcount); + count = min(bvec.bv_len, bcount); - data = bvec_kmap_irq(bvec, &flags); - drive->hwif->atapi_output_bytes(drive, data, count); - bvec_kunmap_irq(data, &flags); - - bcount -= count; - pc->b_count += count; - done += count; - } + data = bvec_kmap_irq(&bvec, &flags); + drive->hwif->atapi_output_bytes(drive, data, count); + bvec_kunmap_irq(data, &flags); + + bcount -= count; + pc->b_count += count; + done += count; } idefloppy_do_end_request(drive, 1, done >> 9); diff .prev/drivers/s390/block/dasd_diag.c ./drivers/s390/block/dasd_diag.c --- .prev/drivers/s390/block/dasd_diag.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/s390/block/dasd_diag.c 2007-08-16 15:02:31.000000000 +1000 @@ -471,14 +471,13 @@ dasd_diag_build_cp(struct dasd_device * struct dasd_ccw_req *cqr; struct dasd_diag_req *dreq; struct dasd_diag_bio *dbio; - struct bio *bio; - struct bio_vec *bv; + struct bio_vec bv; char *dst; unsigned int count, datasize; sector_t recid, first_rec, last_rec; unsigned int blksize, off; unsigned char rw_cmd; - int i; + struct req_iterator i; if (rq_data_dir(req) == READ) rw_cmd = MDSK_READ_REQ; @@ -492,13 +491,11 @@ dasd_diag_build_cp(struct dasd_device * last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift; /* Check struct bio and count the number of blocks for the request. */ count = 0; - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - if (bv->bv_len & (blksize - 1)) - /* Fba can only do full blocks. */ - return ERR_PTR(-EINVAL); - count += bv->bv_len >> (device->s2b_shift + 9); - } + rq_for_each_segment(req, i, bv) { + if (bv.bv_len & (blksize - 1)) + /* Fba can only do full blocks. */ + return ERR_PTR(-EINVAL); + count += bv.bv_len >> (device->s2b_shift + 9); } /* Paranoia. */ if (count != last_rec - first_rec + 1) @@ -515,20 +512,19 @@ dasd_diag_build_cp(struct dasd_device * dreq->block_count = count; dbio = dreq->bio; recid = first_rec; - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; off += blksize) { - memset(dbio, 0, sizeof (struct dasd_diag_bio)); - dbio->type = rw_cmd; - dbio->block_number = recid + 1; - dbio->buffer = dst; - dbio++; - dst += blksize; - recid++; - } + rq_for_each_segment(req, i, bv) { + dst = page_address(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; off += blksize) { + memset(dbio, 0, sizeof(struct dasd_diag_bio)); + dbio->type = rw_cmd; + dbio->block_number = recid + 1; + dbio->buffer = dst; + dbio++; + dst += blksize; + recid++; } } + cqr->retries = DIAG_MAX_RETRIES; cqr->buildclk = get_clock(); if (req->cmd_flags & REQ_FAILFAST) diff .prev/drivers/s390/block/dasd_eckd.c ./drivers/s390/block/dasd_eckd.c --- .prev/drivers/s390/block/dasd_eckd.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/s390/block/dasd_eckd.c 2007-08-16 15:02:31.000000000 +1000 @@ -1176,8 +1176,7 @@ dasd_eckd_build_cp(struct dasd_device * struct LO_eckd_data *LO_data; struct dasd_ccw_req *cqr; struct ccw1 *ccw; - struct bio *bio; - struct bio_vec *bv; + struct bio_vec bv; char *dst; unsigned int blksize, blk_per_trk, off; int count, cidaw, cplength, datasize; @@ -1185,7 +1184,7 @@ dasd_eckd_build_cp(struct dasd_device * sector_t first_trk, last_trk; unsigned int first_offs, last_offs; unsigned char cmd, rcmd; - int i; + struct req_iterator i; private = (struct dasd_eckd_private *) device->private; if (rq_data_dir(req) == READ) @@ -1206,18 +1205,16 @@ dasd_eckd_build_cp(struct dasd_device * /* Check struct bio and count the number of blocks for the request. */ count = 0; cidaw = 0; - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - if (bv->bv_len & (blksize - 1)) - /* Eckd can only do full blocks. */ - return ERR_PTR(-EINVAL); - count += bv->bv_len >> (device->s2b_shift + 9); + rq_for_each_segment(req, i, bv) { + if (bv.bv_len & (blksize - 1)) + /* Eckd can only do full blocks. */ + return ERR_PTR(-EINVAL); + count += bv.bv_len >> (device->s2b_shift + 9); #if defined(CONFIG_64BIT) - if (idal_is_needed (page_address(bv->bv_page), - bv->bv_len)) - cidaw += bv->bv_len >> (device->s2b_shift + 9); + if (idal_is_needed (page_address(bv.bv_page), + bv.bv_len)) + cidaw += bv.bv_len >> (device->s2b_shift + 9); #endif - } } /* Paranoia. */ if (count != last_rec - first_rec + 1) @@ -1257,17 +1254,17 @@ dasd_eckd_build_cp(struct dasd_device * locate_record(ccw++, LO_data++, first_trk, first_offs + 1, last_rec - recid + 1, cmd, device, blksize); } - rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; + rq_for_each_segment(req, i, bv) { + dst = page_address(bv.bv_page) + bv.bv_offset; if (dasd_page_cache) { char *copy = kmem_cache_alloc(dasd_page_cache, GFP_DMA | __GFP_NOWARN); if (copy && rq_data_dir(req) == WRITE) - memcpy(copy + bv->bv_offset, dst, bv->bv_len); + memcpy(copy + bv.bv_offset, dst, bv.bv_len); if (copy) - dst = copy + bv->bv_offset; + dst = copy + bv.bv_offset; } - for (off = 0; off < bv->bv_len; off += blksize) { + for (off = 0; off < bv.bv_len; off += blksize) { sector_t trkid = recid; unsigned int recoffs = sector_div(trkid, blk_per_trk); rcmd = cmd; @@ -1328,12 +1325,12 @@ dasd_eckd_free_cp(struct dasd_ccw_req *c { struct dasd_eckd_private *private; struct ccw1 *ccw; - struct bio *bio; - struct bio_vec *bv; + struct bio_vec bv; char *dst, *cda; unsigned int blksize, blk_per_trk, off; sector_t recid; - int i, status; + int status; + struct req_iterator i; if (!dasd_page_cache) goto out; @@ -1346,9 +1343,9 @@ dasd_eckd_free_cp(struct dasd_ccw_req *c ccw++; if (private->uses_cdl == 0 || recid > 2*blk_per_trk) ccw++; - rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; off += blksize) { + rq_for_each_segment(req, i, bv) { + dst = page_address(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; off += blksize) { /* Skip locate record. */ if (private->uses_cdl && recid <= 2*blk_per_trk) ccw++; @@ -1359,7 +1356,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *c cda = (char *)((addr_t) ccw->cda); if (dst != cda) { if (rq_data_dir(req) == READ) - memcpy(dst, cda, bv->bv_len); + memcpy(dst, cda, bv.bv_len); kmem_cache_free(dasd_page_cache, (void *)((addr_t)cda & PAGE_MASK)); } diff .prev/drivers/s390/block/dasd_fba.c ./drivers/s390/block/dasd_fba.c --- .prev/drivers/s390/block/dasd_fba.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/s390/block/dasd_fba.c 2007-08-16 15:02:31.000000000 +1000 @@ -234,14 +234,13 @@ dasd_fba_build_cp(struct dasd_device * d struct LO_fba_data *LO_data; struct dasd_ccw_req *cqr; struct ccw1 *ccw; - struct bio *bio; - struct bio_vec *bv; + struct bio_vec bv; char *dst; int count, cidaw, cplength, datasize; sector_t recid, first_rec, last_rec; unsigned int blksize, off; unsigned char cmd; - int i; + struct req_iterator i; private = (struct dasd_fba_private *) device->private; if (rq_data_dir(req) == READ) { @@ -257,18 +256,16 @@ dasd_fba_build_cp(struct dasd_device * d /* Check struct bio and count the number of blocks for the request. */ count = 0; cidaw = 0; - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - if (bv->bv_len & (blksize - 1)) - /* Fba can only do full blocks. */ - return ERR_PTR(-EINVAL); - count += bv->bv_len >> (device->s2b_shift + 9); + rq_for_each_segment(req, i, bv) { + if (bv.bv_len & (blksize - 1)) + /* Fba can only do full blocks. */ + return ERR_PTR(-EINVAL); + count += bv.bv_len >> (device->s2b_shift + 9); #if defined(CONFIG_64BIT) - if (idal_is_needed (page_address(bv->bv_page), - bv->bv_len)) - cidaw += bv->bv_len / blksize; + if (idal_is_needed (page_address(bv.bv_page), + bv.bv_len)) + cidaw += bv.bv_len / blksize; #endif - } } /* Paranoia. */ if (count != last_rec - first_rec + 1) @@ -304,17 +301,17 @@ dasd_fba_build_cp(struct dasd_device * d locate_record(ccw++, LO_data++, rq_data_dir(req), 0, count); } recid = first_rec; - rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; + rq_for_each_segment(req, i, bv) { + dst = page_address(bv.bv_page) + bv.bv_offset; if (dasd_page_cache) { char *copy = kmem_cache_alloc(dasd_page_cache, GFP_DMA | __GFP_NOWARN); if (copy && rq_data_dir(req) == WRITE) - memcpy(copy + bv->bv_offset, dst, bv->bv_len); + memcpy(copy + bv.bv_offset, dst, bv.bv_len); if (copy) - dst = copy + bv->bv_offset; + dst = copy + bv.bv_offset; } - for (off = 0; off < bv->bv_len; off += blksize) { + for (off = 0; off < bv.bv_len; off += blksize) { /* Locate record for stupid devices. */ if (private->rdc_data.mode.bits.data_chain == 0) { ccw[-1].flags |= CCW_FLAG_CC; @@ -359,11 +356,11 @@ dasd_fba_free_cp(struct dasd_ccw_req *cq { struct dasd_fba_private *private; struct ccw1 *ccw; - struct bio *bio; - struct bio_vec *bv; + struct bio_vec bv; char *dst, *cda; unsigned int blksize, off; - int i, status; + int status; + struct req_iterator i; if (!dasd_page_cache) goto out; @@ -374,9 +371,9 @@ dasd_fba_free_cp(struct dasd_ccw_req *cq ccw++; if (private->rdc_data.mode.bits.data_chain != 0) ccw++; - rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; off += blksize) { + rq_for_each_segment(req, i, bv) { + dst = page_address(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; off += blksize) { /* Skip locate record. */ if (private->rdc_data.mode.bits.data_chain == 0) ccw++; @@ -387,7 +384,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cq cda = (char *)((addr_t) ccw->cda); if (dst != cda) { if (rq_data_dir(req) == READ) - memcpy(dst, cda, bv->bv_len); + memcpy(dst, cda, bv.bv_len); kmem_cache_free(dasd_page_cache, (void *)((addr_t)cda & PAGE_MASK)); } diff .prev/drivers/s390/char/tape_34xx.c ./drivers/s390/char/tape_34xx.c --- .prev/drivers/s390/char/tape_34xx.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/s390/char/tape_34xx.c 2007-08-16 15:02:31.000000000 +1000 @@ -1134,21 +1134,18 @@ tape_34xx_bread(struct tape_device *devi { struct tape_request *request; struct ccw1 *ccw; - int count = 0, i; + int count = 0; + struct req_iterator i; unsigned off; char *dst; - struct bio_vec *bv; - struct bio *bio; + struct bio_vec bv; struct tape_34xx_block_id * start_block; DBF_EVENT(6, "xBREDid:"); /* Count the number of blocks for the request. */ - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { + rq_for_each_segment(req, i, bv) count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); - } - } /* Allocate the ccw request. */ request = tape_alloc_request(3+count+1, 8); @@ -1175,18 +1172,16 @@ tape_34xx_bread(struct tape_device *devi ccw = tape_ccw_cc(ccw, NOP, 0, NULL); ccw = tape_ccw_cc(ccw, NOP, 0, NULL); - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - dst = kmap(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; - off += TAPEBLOCK_HSEC_SIZE) { - ccw->flags = CCW_FLAG_CC; - ccw->cmd_code = READ_FORWARD; - ccw->count = TAPEBLOCK_HSEC_SIZE; - set_normalized_cda(ccw, (void*) __pa(dst)); - ccw++; - dst += TAPEBLOCK_HSEC_SIZE; - } + rq_for_each_segment(req, i, bv) { + dst = kmap(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; + off += TAPEBLOCK_HSEC_SIZE) { + ccw->flags = CCW_FLAG_CC; + ccw->cmd_code = READ_FORWARD; + ccw->count = TAPEBLOCK_HSEC_SIZE; + set_normalized_cda(ccw, (void *) __pa(dst)); + ccw++; + dst += TAPEBLOCK_HSEC_SIZE; } } diff .prev/drivers/s390/char/tape_3590.c ./drivers/s390/char/tape_3590.c --- .prev/drivers/s390/char/tape_3590.c 2007-08-16 14:57:22.000000000 +1000 +++ ./drivers/s390/char/tape_3590.c 2007-08-16 15:02:31.000000000 +1000 @@ -623,21 +623,20 @@ tape_3590_bread(struct tape_device *devi { struct tape_request *request; struct ccw1 *ccw; - int count = 0, start_block, i; + int count = 0; + int start_block; + struct req_iterator i; unsigned off; char *dst; - struct bio_vec *bv; - struct bio *bio; + struct bio_vec bv; DBF_EVENT(6, "xBREDid:"); start_block = req->sector >> TAPEBLOCK_HSEC_S2B; DBF_EVENT(6, "start_block = %i\n", start_block); - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); - } - } + rq_for_each_segment(req, i, bv) + count += bv.bv_len >> (TAPEBLOCK_HSEC_S2B + 9); + request = tape_alloc_request(2 + count + 1, 4); if (IS_ERR(request)) return request; @@ -653,21 +652,19 @@ tape_3590_bread(struct tape_device *devi */ ccw = tape_ccw_cc(ccw, NOP, 0, NULL); - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; - off += TAPEBLOCK_HSEC_SIZE) { - ccw->flags = CCW_FLAG_CC; - ccw->cmd_code = READ_FORWARD; - ccw->count = TAPEBLOCK_HSEC_SIZE; - set_normalized_cda(ccw, (void *) __pa(dst)); - ccw++; - dst += TAPEBLOCK_HSEC_SIZE; - } - if (off > bv->bv_len) - BUG(); + rq_for_each_segment(req, i, bv) { + dst = page_address(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; + off += TAPEBLOCK_HSEC_SIZE) { + ccw->flags = CCW_FLAG_CC; + ccw->cmd_code = READ_FORWARD; + ccw->count = TAPEBLOCK_HSEC_SIZE; + set_normalized_cda(ccw, (void *) __pa(dst)); + ccw++; + dst += TAPEBLOCK_HSEC_SIZE; } + if (off > bv.bv_len) + BUG(); } ccw = tape_ccw_end(ccw, NOP, 0, NULL); DBF_EVENT(6, "xBREDccwg\n"); diff .prev/include/linux/blkdev.h ./include/linux/blkdev.h --- .prev/include/linux/blkdev.h 2007-08-16 15:02:30.000000000 +1000 +++ ./include/linux/blkdev.h 2007-08-16 15:02:31.000000000 +1000 @@ -637,6 +637,24 @@ static inline void blk_queue_bounce(stru } #endif /* CONFIG_MMU */ +struct req_iterator { + int i; + struct bio *bio; +}; + +#define _bio_for_each_segment(bvec, bio, i) \ + for (i = (bio)->bi_idx; \ + i < (bio)->bi_vcnt; \ + i++) if ((bvec = *bio_iovec_idx(bio, i)), 1) + +#define rq_for_each_segment(rq, _iter, bvec) \ + for (_iter.bio = (rq)->bio; \ + _iter.bio; \ + _iter.bio = _iter.bio->bi_next) \ + _bio_for_each_segment(bvec, _iter.bio, _iter.i) + +#define rq_iter_last(rq, _iter) (_iter.bio->bi_next == NULL && \ + _iter.i == _iter.bio->bi_vcnt - 1) #define rq_for_each_bio(_bio, rq) \ if ((rq->bio)) \ for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next) ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 005 of 5] Merge blk_recount_segments into blk_recalc_rq_segments 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown ` (3 preceding siblings ...) 2007-08-16 5:13 ` [PATCH 004 of 5] Introduce rq_for_each_segment replacing rq_for_each_bio NeilBrown @ 2007-08-16 5:13 ` NeilBrown 2007-08-16 6:37 ` [PATCH 000 of 5] Introductory patches for bio refactor Jens Axboe 5 siblings, 0 replies; 14+ messages in thread From: NeilBrown @ 2007-08-16 5:13 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-kernel, Tejun Heo blk_recalc_rq_segments calls blk_recount_segments on each bio, then does some extra calculations to handle segments that overlap two bios. If we merge the code from blk_recount_segments into blk_recalc_rq_segments, we can process the whole request one bio_vec at a time, and not need the messy cross-bio calculations. Then blk_recount_segments can be implemented by calling blk_recalc_rq_segments, passing it a simple on-stack request which stores just the bio. This function is only temporary and will go away completely by the end of this patch series. This allows us to remove rq_for_each_bio Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./block/ll_rw_blk.c | 125 ++++++++++++++++++++--------------------------- ./include/linux/blkdev.h | 3 - 2 files changed, 55 insertions(+), 73 deletions(-) diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c --- .prev/block/ll_rw_blk.c 2007-08-16 15:02:31.000000000 +1000 +++ ./block/ll_rw_blk.c 2007-08-16 15:02:31.000000000 +1000 @@ -42,6 +42,7 @@ static void drive_stat_acct(struct reque static void init_request_from_bio(struct request *req, struct bio *bio); static int __make_request(struct request_queue *q, struct bio *bio); static struct io_context *current_io_context(gfp_t gfp_flags, int node); +static void blk_recalc_rq_segments(struct request *rq); /* * For the allocated request tables @@ -1209,65 +1210,91 @@ EXPORT_SYMBOL(blk_dump_rq_flags); void blk_recount_segments(struct request_queue *q, struct bio *bio) { - struct bio_vec *bv, *bvprv = NULL; - int i, nr_phys_segs, nr_hw_segs, seg_size, hw_seg_size, cluster; + struct request rq; + struct bio *nxt = bio->bi_next; + rq.q = q; + rq.bio = rq.biotail = bio; + bio->bi_next = NULL; + blk_recalc_rq_segments(&rq); + bio->bi_next = nxt; + bio->bi_phys_segments = rq.nr_phys_segments; + bio->bi_hw_segments = rq.nr_hw_segments; + bio->bi_flags |= (1 << BIO_SEG_VALID); +} +EXPORT_SYMBOL(blk_recount_segments); + +static void blk_recalc_rq_segments(struct request *rq) +{ + int nr_phys_segs; + int nr_hw_segs; + unsigned int phys_size; + unsigned int hw_size; + struct bio_vec bv; + struct bio_vec bvprv = {0}; + int seg_size; + int hw_seg_size; + int cluster; + struct req_iterator i; int high, highprv = 1; + struct request_queue *q = rq->q; - if (unlikely(!bio->bi_io_vec)) + if (!rq->bio) return; cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); - hw_seg_size = seg_size = nr_phys_segs = nr_hw_segs = 0; - bio_for_each_segment(bv, bio, i) { + hw_seg_size = seg_size = 0; + phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0; + rq_for_each_segment(rq, i, bv) { /* * the trick here is making sure that a high page is never * considered part of another segment, since that might * change with the bounce page. */ - high = page_to_pfn(bv->bv_page) > q->bounce_pfn; + high = page_to_pfn(bv.bv_page) > q->bounce_pfn; if (high || highprv) goto new_hw_segment; if (cluster) { - if (seg_size + bv->bv_len > q->max_segment_size) + if (seg_size + bv.bv_len > q->max_segment_size) goto new_segment; - if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) + if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bv)) goto new_segment; - if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) + if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bv)) goto new_segment; - if (BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) + if (BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv.bv_len)) goto new_hw_segment; - seg_size += bv->bv_len; - hw_seg_size += bv->bv_len; + seg_size += bv.bv_len; + hw_seg_size += bv.bv_len; bvprv = bv; continue; } new_segment: - if (BIOVEC_VIRT_MERGEABLE(bvprv, bv) && - !BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) { - hw_seg_size += bv->bv_len; - } else { + if (BIOVEC_VIRT_MERGEABLE(&bvprv, &bv) && + !BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv.bv_len)) + hw_seg_size += bv.bv_len; + else { new_hw_segment: - if (hw_seg_size > bio->bi_hw_front_size) - bio->bi_hw_front_size = hw_seg_size; - hw_seg_size = BIOVEC_VIRT_START_SIZE(bv) + bv->bv_len; + if (nr_hw_segs == 1 && + hw_seg_size > rq->bio->bi_hw_front_size) + rq->bio->bi_hw_front_size = hw_seg_size; + hw_seg_size = BIOVEC_VIRT_START_SIZE(&bv) + bv.bv_len; nr_hw_segs++; } nr_phys_segs++; bvprv = bv; - seg_size = bv->bv_len; + seg_size = bv.bv_len; highprv = high; } - if (hw_seg_size > bio->bi_hw_back_size) - bio->bi_hw_back_size = hw_seg_size; - if (nr_hw_segs == 1 && hw_seg_size > bio->bi_hw_front_size) - bio->bi_hw_front_size = hw_seg_size; - bio->bi_phys_segments = nr_phys_segs; - bio->bi_hw_segments = nr_hw_segs; - bio->bi_flags |= (1 << BIO_SEG_VALID); + + if (nr_hw_segs == 1 && + hw_seg_size > rq->bio->bi_hw_front_size) + rq->bio->bi_hw_front_size = hw_seg_size; + if (hw_seg_size > rq->biotail->bi_hw_back_size) + rq->biotail->bi_hw_back_size = hw_seg_size; + rq->nr_phys_segments = nr_phys_segs; + rq->nr_hw_segments = nr_hw_segs; } -EXPORT_SYMBOL(blk_recount_segments); static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, struct bio *nxt) @@ -3313,48 +3340,6 @@ void submit_bio(int rw, struct bio *bio) EXPORT_SYMBOL(submit_bio); -static void blk_recalc_rq_segments(struct request *rq) -{ - struct bio *bio, *prevbio = NULL; - int nr_phys_segs, nr_hw_segs; - unsigned int phys_size, hw_size; - struct request_queue *q = rq->q; - - if (!rq->bio) - return; - - phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0; - rq_for_each_bio(bio, rq) { - /* Force bio hw/phys segs to be recalculated. */ - bio->bi_flags &= ~(1 << BIO_SEG_VALID); - - nr_phys_segs += bio_phys_segments(q, bio); - nr_hw_segs += bio_hw_segments(q, bio); - if (prevbio) { - int pseg = phys_size + prevbio->bi_size + bio->bi_size; - int hseg = hw_size + prevbio->bi_size + bio->bi_size; - - if (blk_phys_contig_segment(q, prevbio, bio) && - pseg <= q->max_segment_size) { - nr_phys_segs--; - phys_size += prevbio->bi_size + bio->bi_size; - } else - phys_size = 0; - - if (blk_hw_contig_segment(q, prevbio, bio) && - hseg <= q->max_segment_size) { - nr_hw_segs--; - hw_size += prevbio->bi_size + bio->bi_size; - } else - hw_size = 0; - } - prevbio = bio; - } - - rq->nr_phys_segments = nr_phys_segs; - rq->nr_hw_segments = nr_hw_segs; -} - static void blk_recalc_rq_sectors(struct request *rq, int nsect) { if (blk_fs_request(rq)) { diff .prev/include/linux/blkdev.h ./include/linux/blkdev.h --- .prev/include/linux/blkdev.h 2007-08-16 15:02:31.000000000 +1000 +++ ./include/linux/blkdev.h 2007-08-16 15:02:31.000000000 +1000 @@ -655,9 +655,6 @@ struct req_iterator { #define rq_iter_last(rq, _iter) (_iter.bio->bi_next == NULL && \ _iter.i == _iter.bio->bi_vcnt - 1) -#define rq_for_each_bio(_bio, rq) \ - if ((rq->bio)) \ - for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next) extern int blk_register_queue(struct gendisk *disk); extern void blk_unregister_queue(struct gendisk *disk); ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 000 of 5] Introductory patches for bio refactor. 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown ` (4 preceding siblings ...) 2007-08-16 5:13 ` [PATCH 005 of 5] Merge blk_recount_segments into blk_recalc_rq_segments NeilBrown @ 2007-08-16 6:37 ` Jens Axboe 5 siblings, 0 replies; 14+ messages in thread From: Jens Axboe @ 2007-08-16 6:37 UTC (permalink / raw) To: NeilBrown; +Cc: linux-kernel, Tejun Heo On Thu, Aug 16 2007, NeilBrown wrote: > > Hi Jens, > I wonder if you would accept these patches the block layer. > They are, as far as I can tell, quite uncontroversial and provide > good cleanups. > > The first is a minor bug-fix. > The next to replace helper function that take a bio (always the first > bio of a request), to instead take a request. > > The last two combine to replace rq_for_each_bio with > rq_for_each_segment which makes blk_recalc_rq_segments a lot > cleaner, and improves (to a lesser degree) every other place that > used rq_for_each_bio. > > The net result is a decrease in object code size (for my x86-64 compile) > for block/built-in.o of 96 bytes, though there is some growth out in > drivers making and over-all decrease of only 48 bytes. Thanks for seperating these out Neil, will go over them this morning! -- Jens Axboe ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2007-08-16 11:24 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-08-16 5:13 [PATCH 000 of 5] Introductory patches for bio refactor NeilBrown 2007-08-16 5:13 ` [PATCH 001 of 5] Don't update bi_hw_*_size if we aren't going to merge NeilBrown 2007-08-16 7:01 ` Jens Axboe 2007-08-16 5:13 ` [PATCH 002 of 5] Replace bio_data with blk_rq_data NeilBrown 2007-08-16 7:02 ` Jens Axboe 2007-08-16 7:15 ` Neil Brown 2007-08-16 7:21 ` Jens Axboe 2007-08-16 11:15 ` Neil Brown 2007-08-16 11:19 ` Jens Axboe 2007-08-16 11:22 ` Jens Axboe 2007-08-16 5:13 ` [PATCH 003 of 5] Replace bio_cur_sectors with blk_rq_cur_sectors NeilBrown 2007-08-16 5:13 ` [PATCH 004 of 5] Introduce rq_for_each_segment replacing rq_for_each_bio NeilBrown 2007-08-16 5:13 ` [PATCH 005 of 5] Merge blk_recount_segments into blk_recalc_rq_segments NeilBrown 2007-08-16 6:37 ` [PATCH 000 of 5] Introductory patches for bio refactor Jens Axboe
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.