Re: [RFC 3/6] bidi support: bidirectional request
James Bottomley wrote: > On Mon, 2007-01-22 at 01:25 +0200, Boaz Harrosh wrote: >> - Instantiate another request_io_part in request for bidi_read. >> - Define & Implement new API for accessing bidi parts. >> - API to Build bidi requests and map to sglists. >> - Define new end_that_request_block() function to end a complete request. > > Actually, this approach looks to be a bit too narrow. You seem to be > predicating on the idea that the bidirectional will transfer in and out > of the same area. For some of the frame in/frame out stuff, we probably > need the read and write areas for the bidirectional request to be > separated. Hmm, our proposal introduces two separate and independent i/o areas. One used for uni-directional transfers and for bidi data output, the other is used for bidi data input so we're in agreement. Benny - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 3/6] bidi support: bidirectional request
James Bottomley wrote: On Mon, 2007-01-22 at 01:25 +0200, Boaz Harrosh wrote: - Instantiate another request_io_part in request for bidi_read. - Define Implement new API for accessing bidi parts. - API to Build bidi requests and map to sglists. - Define new end_that_request_block() function to end a complete request. Actually, this approach looks to be a bit too narrow. You seem to be predicating on the idea that the bidirectional will transfer in and out of the same area. For some of the frame in/frame out stuff, we probably need the read and write areas for the bidirectional request to be separated. Hmm, our proposal introduces two separate and independent i/o areas. One used for uni-directional transfers and for bidi data output, the other is used for bidi data input so we're in agreement. Benny - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 3/6] bidi support: bidirectional request
On Mon, 2007-01-22 at 01:25 +0200, Boaz Harrosh wrote: > - Instantiate another request_io_part in request for bidi_read. > - Define & Implement new API for accessing bidi parts. > - API to Build bidi requests and map to sglists. > - Define new end_that_request_block() function to end a complete request. Actually, this approach looks to be a bit too narrow. You seem to be predicating on the idea that the bidirectional will transfer in and out of the same area. For some of the frame in/frame out stuff, we probably need the read and write areas for the bidirectional request to be separated. James - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 3/6] bidi support: bidirectional request
On Mon, 2007-01-22 at 01:25 +0200, Boaz Harrosh wrote: - Instantiate another request_io_part in request for bidi_read. - Define Implement new API for accessing bidi parts. - API to Build bidi requests and map to sglists. - Define new end_that_request_block() function to end a complete request. Actually, this approach looks to be a bit too narrow. You seem to be predicating on the idea that the bidirectional will transfer in and out of the same area. For some of the frame in/frame out stuff, we probably need the read and write areas for the bidirectional request to be separated. James - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC 3/6] bidi support: bidirectional request
- Instantiate another request_io_part in request for bidi_read. - Define & Implement new API for accessing bidi parts. - API to Build bidi requests and map to sglists. - Define new end_that_request_block() function to end a complete request. Signed-off-by: Benny Halevy <[EMAIL PROTECTED]> Signed-off-by: Boaz Harrosh <[EMAIL PROTECTED]> --- block/elevator.c |7 +--- block/ll_rw_blk.c | 113 ++-- include/linux/blkdev.h | 49 - 3 files changed, 149 insertions(+), 20 deletions(-) diff --git a/block/elevator.c b/block/elevator.c index 0e9ea69..53b552e 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -741,14 +741,9 @@ struct request *elv_next_request(request rq = NULL; break; } else if (ret == BLKPREP_KILL) { - int nr_bytes = rq_uni(rq)->hard_nr_sectors << 9; - - if (!nr_bytes) - nr_bytes = rq_uni(rq)->data_len; - blkdev_dequeue_request(rq); rq->cmd_flags |= REQ_QUIET; - end_that_request_chunk(rq, 0, nr_bytes); + end_that_request_block(rq, 0); end_that_request_last(rq, 0); } else { printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__, diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 7d46f6a..1358b35 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -261,6 +261,7 @@ static void rq_init(request_queue_t *q, rq->end_io_data = NULL; rq->completion_data = NULL; rq_init_io_part(>uni); + rq_init_io_part(>bidi_read); } /** @@ -1312,15 +1313,16 @@ static int blk_hw_contig_segment(request } /* - * map a request to scatterlist, return number of sg entries setup. Caller - * must make sure sg can hold rq->nr_phys_segments entries + * map a request_io_part to scatterlist, return number of sg entries setup. + * Caller must make sure sg can hold rq_io(rq, dir)->nr_phys_segments entries */ -int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg) +int blk_rq_map_sg_bidi(request_queue_t *q, struct request *rq, + struct scatterlist *sg, enum dma_data_direction dir) { struct bio_vec *bvec, *bvprv; struct bio *bio; int nsegs, i, cluster; - struct request_io_part* req_io = rq_uni(rq); + struct request_io_part* req_io = rq_io(rq, dir); nsegs = 0; cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); @@ -1362,6 +1364,17 @@ new_segment: return nsegs; } +EXPORT_SYMBOL(blk_rq_map_sg_bidi); + +/* + * map a request to scatterlist, return number of sg entries setup. Caller + * must make sure sg can hold rq->nr_phys_segments entries + */ +int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg) +{ + return blk_rq_map_sg_bidi(q, rq, sg, rq->data_dir); +} + EXPORT_SYMBOL(blk_rq_map_sg); /* @@ -2561,15 +2574,18 @@ int blk_rq_unmap_user(struct bio *bio) EXPORT_SYMBOL(blk_rq_unmap_user); /** - * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage + * blk_rq_map_kern_bidi - maps kernel data to a request_io_part, for BIDI usage * @q: request queue where request should be inserted * @rq:request to fill * @kbuf: the kernel buffer * @len: length of user data * @gfp_mask: memory allocation flags + * @dir:if it is a BIDIRECTIONAL request than DMA_TO_DEVICE to prepare + * the bidi_write side or DMA_FROM_DEVICE to prepare the bidi_read + * side, else it should be same as req->data_dir */ -int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf, - unsigned int len, gfp_t gfp_mask) +int blk_rq_map_kern_bidi(request_queue_t *q, struct request *rq, void *kbuf, + unsigned int len, gfp_t gfp_mask, enum dma_data_direction dir) { struct bio *bio; @@ -2582,14 +2598,30 @@ int blk_rq_map_kern(request_queue_t *q, if (IS_ERR(bio)) return PTR_ERR(bio); - if (rq_uni_write_dir(rq) == WRITE) + if (dma_write_dir(dir)) bio->bi_rw |= (1 << BIO_RW); - blk_rq_bio_prep(q, rq, bio); + blk_rq_bio_prep_bidi(q, rq, bio ,dir); rq->buffer = rq->data = NULL; return 0; } +EXPORT_SYMBOL(blk_rq_map_kern_bidi); + +/** + * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage + * @q: request queue where request should be inserted + * @rq:request to fill + * @kbuf: the kernel buffer + * @len: length of user data + * @gfp_mask: memory allocation flags + */ +int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf, + unsigned int len, gfp_t gfp_mask) +{ + return blk_rq_map_kern_bidi( q, rq, kbuf, len, gfp_mask,
[RFC 3/6] bidi support: bidirectional request
- Instantiate another request_io_part in request for bidi_read. - Define Implement new API for accessing bidi parts. - API to Build bidi requests and map to sglists. - Define new end_that_request_block() function to end a complete request. Signed-off-by: Benny Halevy [EMAIL PROTECTED] Signed-off-by: Boaz Harrosh [EMAIL PROTECTED] --- block/elevator.c |7 +--- block/ll_rw_blk.c | 113 ++-- include/linux/blkdev.h | 49 - 3 files changed, 149 insertions(+), 20 deletions(-) diff --git a/block/elevator.c b/block/elevator.c index 0e9ea69..53b552e 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -741,14 +741,9 @@ struct request *elv_next_request(request rq = NULL; break; } else if (ret == BLKPREP_KILL) { - int nr_bytes = rq_uni(rq)-hard_nr_sectors 9; - - if (!nr_bytes) - nr_bytes = rq_uni(rq)-data_len; - blkdev_dequeue_request(rq); rq-cmd_flags |= REQ_QUIET; - end_that_request_chunk(rq, 0, nr_bytes); + end_that_request_block(rq, 0); end_that_request_last(rq, 0); } else { printk(KERN_ERR %s: bad return=%d\n, __FUNCTION__, diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 7d46f6a..1358b35 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -261,6 +261,7 @@ static void rq_init(request_queue_t *q, rq-end_io_data = NULL; rq-completion_data = NULL; rq_init_io_part(rq-uni); + rq_init_io_part(rq-bidi_read); } /** @@ -1312,15 +1313,16 @@ static int blk_hw_contig_segment(request } /* - * map a request to scatterlist, return number of sg entries setup. Caller - * must make sure sg can hold rq-nr_phys_segments entries + * map a request_io_part to scatterlist, return number of sg entries setup. + * Caller must make sure sg can hold rq_io(rq, dir)-nr_phys_segments entries */ -int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg) +int blk_rq_map_sg_bidi(request_queue_t *q, struct request *rq, + struct scatterlist *sg, enum dma_data_direction dir) { struct bio_vec *bvec, *bvprv; struct bio *bio; int nsegs, i, cluster; - struct request_io_part* req_io = rq_uni(rq); + struct request_io_part* req_io = rq_io(rq, dir); nsegs = 0; cluster = q-queue_flags (1 QUEUE_FLAG_CLUSTER); @@ -1362,6 +1364,17 @@ new_segment: return nsegs; } +EXPORT_SYMBOL(blk_rq_map_sg_bidi); + +/* + * map a request to scatterlist, return number of sg entries setup. Caller + * must make sure sg can hold rq-nr_phys_segments entries + */ +int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg) +{ + return blk_rq_map_sg_bidi(q, rq, sg, rq-data_dir); +} + EXPORT_SYMBOL(blk_rq_map_sg); /* @@ -2561,15 +2574,18 @@ int blk_rq_unmap_user(struct bio *bio) EXPORT_SYMBOL(blk_rq_unmap_user); /** - * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage + * blk_rq_map_kern_bidi - maps kernel data to a request_io_part, for BIDI usage * @q: request queue where request should be inserted * @rq:request to fill * @kbuf: the kernel buffer * @len: length of user data * @gfp_mask: memory allocation flags + * @dir:if it is a BIDIRECTIONAL request than DMA_TO_DEVICE to prepare + * the bidi_write side or DMA_FROM_DEVICE to prepare the bidi_read + * side, else it should be same as req-data_dir */ -int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf, - unsigned int len, gfp_t gfp_mask) +int blk_rq_map_kern_bidi(request_queue_t *q, struct request *rq, void *kbuf, + unsigned int len, gfp_t gfp_mask, enum dma_data_direction dir) { struct bio *bio; @@ -2582,14 +2598,30 @@ int blk_rq_map_kern(request_queue_t *q, if (IS_ERR(bio)) return PTR_ERR(bio); - if (rq_uni_write_dir(rq) == WRITE) + if (dma_write_dir(dir)) bio-bi_rw |= (1 BIO_RW); - blk_rq_bio_prep(q, rq, bio); + blk_rq_bio_prep_bidi(q, rq, bio ,dir); rq-buffer = rq-data = NULL; return 0; } +EXPORT_SYMBOL(blk_rq_map_kern_bidi); + +/** + * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage + * @q: request queue where request should be inserted + * @rq:request to fill + * @kbuf: the kernel buffer + * @len: length of user data + * @gfp_mask: memory allocation flags + */ +int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf, + unsigned int len, gfp_t gfp_mask) +{ + return blk_rq_map_kern_bidi( q, rq, kbuf, len, gfp_mask, rq-data_dir); +} +