mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Stephen Cameron <steve.cameron@hp.com>
To: linux-kernel@vger.kernel.org
Subject: [PATCH] 2.5.44-ac3, cciss, more scatter gather elements
Date: Fri, 25 Oct 2002 13:59:14 -0600	[thread overview]
Message-ID: <20021025135914.A1224@zuul.cca.cpqcorp.net> (raw)


Add blk_rq_map_sg_one_by_one function to ll_rw_blk.c in order to allow a low 
level driver to map scatter gather elements from the block subsystem one 
at a time into device specific data structures instead of having to take 
a copy of all of them all at once and then afterwards copy them into a device 
specific format. 

To follow, a patch to the cciss driver using this interface which
allows up to 256 scatter gather elements (current limit is 31). 

-- steve

 drivers/block/ll_rw_blk.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/blkdev.h    |    4 +++
 2 files changed, 63 insertions

--- lx2544ac3/drivers/block/ll_rw_blk.c~blkdev_sg	Fri Oct 25 13:46:08 2002
+++ lx2544ac3-scameron/drivers/block/ll_rw_blk.c	Fri Oct 25 13:46:08 2002
@@ -766,6 +766,64 @@ inline int blk_hw_contig_segment(request
 }
 
 /*
+ * Map a request to a single scatterlist, one by one.  As each scatterlist is
+ * constructed consume_sg is called so the scattlerlist may be used.  The idea
+ * is the caller won't have to allocate all the space needed for a potentially
+ * large number of sg elements, instead the consume_sg callback function
+ * consumes each element as it's made.  sg_state is a pointer meant to be
+ * used by consume_sg to remember its state between calls.
+ */
+int blk_rq_map_sg_one_by_one(request_queue_t *q, struct request *rq,
+		consume_sg_callback consume_sg, void *sg_state)
+{
+	struct scatterlist sg;
+	struct bio_vec *bvec, *bvprv;
+	struct bio *bio;
+	int nsegs, i, cluster;
+
+	nsegs = 0;
+	cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
+
+	/*
+	 * 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;
+
+			if (bvprv && cluster) {
+				if (sg.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.length += nbytes;
+			} else {
+new_segment:
+				if (bvprv) consume_sg(&sg, sg_state);
+				memset(&sg,0,sizeof(struct scatterlist));
+				sg.page = bvec->bv_page;
+				sg.length = nbytes;
+				sg.offset = bvec->bv_offset;
+				nsegs++;
+			}
+			bvprv = bvec;
+		} /* segments in bio */
+	} /* bios in rq */
+
+	if (bvprv) consume_sg(&sg, sg_state);
+
+	return nsegs;
+}
+
+/*
  * map a request to scatterlist, return number of sg entries setup. Caller
  * must make sure sg can hold rq->nr_phys_segments entries
  */
@@ -2112,6 +2170,7 @@ EXPORT_SYMBOL(blk_queue_max_hw_segments)
 EXPORT_SYMBOL(blk_queue_max_segment_size);
 EXPORT_SYMBOL(blk_queue_hardsect_size);
 EXPORT_SYMBOL(blk_queue_segment_boundary);
+EXPORT_SYMBOL(blk_rq_map_sg_one_by_one);
 EXPORT_SYMBOL(blk_rq_map_sg);
 EXPORT_SYMBOL(blk_nohighio);
 EXPORT_SYMBOL(blk_dump_rq_flags);
--- lx2544ac3/include/linux/blkdev.h~blkdev_sg	Fri Oct 25 13:46:08 2002
+++ lx2544ac3-scameron/include/linux/blkdev.h	Fri Oct 25 13:46:08 2002
@@ -341,6 +341,10 @@ extern void blk_queue_prep_rq(request_qu
 extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
 
+typedef void (*consume_sg_callback)(struct scatterlist *, void *);
+extern int blk_rq_map_sg_one_by_one(request_queue_t *, struct request *,
+	consume_sg_callback consume_sg, void * sg_state);
+
 extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
 extern void blk_dump_rq_flags(struct request *, char *);
 extern void generic_unplug_device(void *);

.

             reply	other threads:[~2002-10-25 19:57 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-10-25 19:59 Stephen Cameron [this message]
2002-10-25 20:24 ` Jens Axboe
2002-10-25 20:00 Stephen Cameron
2002-10-25 20:47 Cameron, Steve
2002-10-25 21:11 ` Jens Axboe
2002-10-25 21:24   ` Jens Axboe
2002-10-25 21:25     ` Jens Axboe
2002-10-25 21:31       ` Jens Axboe
2002-10-25 22:06 Cameron, Steve
2002-10-28 15:24 ` Jens Axboe
2002-10-28 23:10 Stephen Cameron
2002-10-29  7:28 ` Jens Axboe
2002-10-30 20:23 Stephen Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20021025135914.A1224@zuul.cca.cpqcorp.net \
    --to=steve.cameron@hp.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®