All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Jens Axboe <jens.axboe@oracle.com>,
	James Bottomley <James.Bottomley@SteelEye.com>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>,
	FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>,
	linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
	dougg@torque.net
Subject: [PATCH 2/3] SG: Convert SCSI to use scatterlist helpers for sg chaining
Date: Thu, 20 Dec 2007 16:03:03 +0200	[thread overview]
Message-ID: <476A7617.4010307@panasas.com> (raw)
In-Reply-To: <476A743D.2080506@panasas.com>

From: Jens Axboe <jens.axboe@oracle.com>

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/scsi/libsrp.c        |    2 +-
 drivers/scsi/scsi_error.c    |    4 +-
 drivers/scsi/scsi_lib.c      |  150 +++++-------------------------------------
 drivers/usb/storage/isd200.c |    4 +-
 include/scsi/scsi_cmnd.h     |    9 +--
 5 files changed, 24 insertions(+), 145 deletions(-)

diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 8a8562a..b81350d 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -427,7 +427,7 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
 	sc->SCp.ptr = info;
 	memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE);
 	sc->sdb.length = len;
-	sc->sdb.sglist = (void *) (unsigned long) addr;
+	sc->sdb.sgt.sgl = (void *) (unsigned long) addr;
 	sc->tag = tag;
 	err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun,
 				     cmd->tag);
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 5c8ba6a..1fd2a8c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -629,9 +629,9 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
 		                       sizeof(scmd->sense_buffer), sense_bytes);
 		sg_init_one(&ses->sense_sgl, scmd->sense_buffer,
 							      scmd->sdb.length);
-		scmd->sdb.sglist = &ses->sense_sgl;
+		scmd->sdb.sgt.sgl = &ses->sense_sgl;
 		scmd->sc_data_direction = DMA_FROM_DEVICE;
-		scmd->sdb.sg_count = 1;
+		scmd->sdb.sgt.nents = 1;
 		memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
 		scmd->cmnd[0] = REQUEST_SENSE;
 		scmd->cmnd[4] = scmd->sdb.length;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index a6aae56..c7107f1 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -750,136 +750,15 @@ static inline unsigned int scsi_sgtable_index(unsigned short nents)
 	return index;
 }
 
-static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb,
-					unsigned short sg_count, gfp_t gfp_mask)
+static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
 {
-	struct scsi_host_sg_pool *sgp;
-	struct scatterlist *sgl, *prev, *ret;
-	unsigned int index;
-	int this, left;
-
-	left = sg_count;
-	ret = prev = NULL;
-	do {
-		this = left;
-		if (this > SCSI_MAX_SG_SEGMENTS) {
-			this = SCSI_MAX_SG_SEGMENTS - 1;
-			index = SG_MEMPOOL_NR - 1;
-		} else
-			index = scsi_sgtable_index(this);
-
-		left -= this;
-
-		sgp = scsi_sg_pools + index;
-
-		sgl = mempool_alloc(sgp->pool, gfp_mask);
-		if (unlikely(!sgl))
-			goto enomem;
-
-		sg_init_table(sgl, sgp->size);
-
-		/*
-		 * first loop through, set initial index and return value
-		 */
-		if (!ret)
-			ret = sgl;
-
-		/*
-		 * chain previous sglist, if any. we know the previous
-		 * sglist must be the biggest one, or we would not have
-		 * ended up doing another loop.
-		 */
-		if (prev)
-			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
-
-		/*
-		 * if we have nothing left, mark the last segment as
-		 * end-of-list
-		 */
-		if (!left)
-			sg_mark_end(&sgl[this - 1]);
-
-		/*
-		 * don't allow subsequent mempool allocs to sleep, it would
-		 * violate the mempool principle.
-		 */
-		gfp_mask &= ~__GFP_WAIT;
-		gfp_mask |= __GFP_HIGH;
-		prev = sgl;
-	} while (left);
-
-	/*
-	 * ->use_sg may get modified after dma mapping has potentially
-	 * shrunk the number of segments, so keep a copy of it for free.
-	 */
-	sdb->alloc_sg_count = sdb->sg_count = sg_count;
-	sdb->sglist = ret;
-	return 0;
-enomem:
-	if (ret) {
-		/*
-		 * Free entries chained off ret. Since we were trying to
-		 * allocate another sglist, we know that all entries are of
-		 * the max size.
-		 */
-		sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
-		prev = ret;
-		ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
-
-		while ((sgl = sg_chain_ptr(ret)) != NULL) {
-			ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
-			mempool_free(sgl, sgp->pool);
-		}
-
-		mempool_free(prev, sgp->pool);
-	}
-	return -ENOMEM;
+	return mempool_alloc(scsi_sg_pools[scsi_sgtable_index(nents)].pool,
+								    gfp_mask);
 }
 
-static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
+static void scsi_sg_free(struct scatterlist *sgl, unsigned int nents)
 {
-	struct scatterlist *sgl = sdb->sglist;
-	struct scsi_host_sg_pool *sgp;
-
-	/*
-	 * if this is the biggest size sglist, check if we have
-	 * chained parts we need to free
-	 */
-	if (sdb->alloc_sg_count > SCSI_MAX_SG_SEGMENTS) {
-		unsigned short this, left;
-		struct scatterlist *next;
-		unsigned int index;
-
-		left = sdb->alloc_sg_count - (SCSI_MAX_SG_SEGMENTS - 1);
-		next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
-		while (left && next) {
-			sgl = next;
-			this = left;
-			if (this > SCSI_MAX_SG_SEGMENTS) {
-				this = SCSI_MAX_SG_SEGMENTS - 1;
-				index = SG_MEMPOOL_NR - 1;
-			} else
-				index = scsi_sgtable_index(this);
-
-			left -= this;
-
-			sgp = scsi_sg_pools + index;
-
-			if (left)
-				next = sg_chain_ptr(&sgl[sgp->size - 1]);
-
-			mempool_free(sgl, sgp->pool);
-		}
-
-		/*
-		 * Restore original, will be freed below
-		 */
-		sgl = sdb->sglist;
-		sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
-	} else
-		sgp = scsi_sg_pools + scsi_sgtable_index(sdb->alloc_sg_count);
-
-	mempool_free(sgl, sgp->pool);
+	mempool_free(sgl, scsi_sg_pools[scsi_sgtable_index(nents)].pool);
 }
 
 /*
@@ -901,15 +780,15 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
  */
 void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-	if (cmd->sdb.sglist)
-		scsi_free_sgtable(&cmd->sdb);
+	if (cmd->sdb.sgt.sgl)
+		__sg_free_table(&cmd->sdb.sgt, scsi_sg_free);
 
 	memset(&cmd->sdb, 0, sizeof(cmd->sdb));
 
 	if (scsi_bidi_cmnd(cmd)) {
 		struct scsi_data_buffer *bidi_sdb =
 			cmd->request->next_rq->special;
-		scsi_free_sgtable(bidi_sdb);
+		__sg_free_table(&bidi_sdb->sgt, scsi_sg_free);
 		kmem_cache_free(scsi_bidi_sdb_cache, bidi_sdb);
 		cmd->request->next_rq->special = NULL;
 	}
@@ -1135,9 +1014,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
 								 gfp_t gfp_mask)
 {
-	int count;
+	int count, ret;
 
-	if (scsi_alloc_sgtable(sdb, req->nr_phys_segments, gfp_mask)) {
+	ret = __sg_alloc_table(&sdb->sgt, req->nr_phys_segments, gfp_mask,
+								 scsi_sg_alloc);
+	if (unlikely(ret)) {
+		__sg_free_table(&sdb->sgt, scsi_sg_free);
 		return BLKPREP_DEFER;
 	}
 
@@ -1151,9 +1033,9 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
 	 * Next, walk the list, and fill in the addresses and sizes of
 	 * each segment.
 	 */
-	count = blk_rq_map_sg(req->q, req, sdb->sglist);
-	BUG_ON(count > sdb->sg_count);
-	sdb->sg_count = count;
+	count = blk_rq_map_sg(req->q, req, sdb->sgt.sgl);
+	BUG_ON(count > sdb->sgt.nents);
+	sdb->sgt.nents = count;
 	return BLKPREP_OK;
 }
 
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 2d9a32b..0214ddb 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -415,9 +415,9 @@ static void isd200_set_srb(struct isd200_info *info,
 		sg_init_one(&info->sg, buff, bufflen);
 
 	srb->sc_data_direction = dir;
-	srb->sdb.sglist = buff ? &info->sg : NULL;
+	srb->sdb.sgt.sgl = buff ? &info->sg : NULL;
 	srb->sdb.length = bufflen;
-	srb->sdb.sg_count = buff ? 1 : 0;
+	srb->sdb.sgt.nents = buff ? 1 : 0;
 }
 
 static void isd200_srb_set_bufflen(struct scsi_cmnd *srb, unsigned bufflen)
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index cd2851a..9933bbe 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -8,16 +8,13 @@
 #include <linux/timer.h>
 #include <linux/scatterlist.h>
 
-struct scatterlist;
 struct Scsi_Host;
 struct scsi_device;
 
 struct scsi_data_buffer {
-	struct scatterlist *sglist;
+	struct sg_table sgt;
 	unsigned length;
 	int resid;
-	unsigned short sg_count;
-	unsigned short alloc_sg_count; /* private to scsi_lib */
 };
 
 /* embedded in scsi_cmnd */
@@ -136,12 +133,12 @@ extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
 
 static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
 {
-	return cmd->sdb.sg_count;
+	return cmd->sdb.sgt.nents;
 }
 
 static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
 {
-	return cmd->sdb.sglist;
+	return cmd->sdb.sgt.sgl;
 }
 
 static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
-- 
1.5.3.3



  parent reply	other threads:[~2007-12-20 14:03 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-20  5:45 [PATCH 0/5] sg_ring for scsi Rusty Russell
2007-12-20  5:48 ` [PATCH 1/5] sg_ring: sg_ring.h Rusty Russell
2007-12-20  5:49   ` [PATCH 2/5] dma_map_sg_ring() helper Rusty Russell
2007-12-20  5:50     ` [PATCH 3/5] blk_rq_map_sg_ring as a counterpart to blk_rq_map_sg Rusty Russell
2007-12-20  5:51       ` [PATCH 4/5] sg_ring: Convert core scsi code to sg_ring Rusty Russell
2007-12-20  5:53         ` [PATCH 5/5] sg_ring: Convert scsi_debug Rusty Russell
2007-12-20  7:06     ` [PATCH 2/5] dma_map_sg_ring() helper FUJITA Tomonori
2007-12-20  7:42       ` David Miller
2007-12-20 22:58         ` Rusty Russell
2007-12-21  0:00           ` FUJITA Tomonori
2007-12-21  0:35             ` Rusty Russell
2007-12-21  0:40               ` David Miller
2007-12-21  2:22                 ` FUJITA Tomonori
2007-12-21  2:47                 ` Rusty Russell
2007-12-20  7:07 ` [PATCH 0/5] sg_ring for scsi FUJITA Tomonori
2007-12-20  7:53   ` Rusty Russell
2007-12-20  7:58     ` David Miller
2007-12-20  7:58       ` Jens Axboe
2007-12-20 23:13       ` Rusty Russell
2007-12-21  0:30         ` David Miller
2007-12-21  2:28         ` FUJITA Tomonori
2007-12-21  3:26           ` Rusty Russell
2007-12-21  4:37             ` FUJITA Tomonori
2007-12-26  0:27               ` Rusty Russell
2007-12-27  2:09                 ` FUJITA Tomonori
2007-12-27 11:52                   ` Rusty Russell
2007-12-21 12:13         ` Herbert Xu
2007-12-21 12:13           ` Herbert Xu
2007-12-20  7:58     ` Jens Axboe
2007-12-20 13:55       ` Boaz Harrosh
2007-12-20 13:55         ` Boaz Harrosh
2007-12-20 14:00         ` [PATCH 1/3] SG: Move functions to lib/scatterlist.c and add sg chaining allocator helpers Boaz Harrosh
2007-12-20 14:00           ` Boaz Harrosh
2007-12-20 14:21           ` Boaz Harrosh
2007-12-20 14:21             ` Boaz Harrosh
2007-12-21 12:15           ` Herbert Xu
2007-12-21 12:15             ` Herbert Xu
2007-12-20 14:03         ` Boaz Harrosh [this message]
2007-12-20 14:26           ` [PATCH 2/3] SG: Convert SCSI to use scatterlist helpers for sg chaining Boaz Harrosh
2007-12-20 14:06         ` [PATCH 3/3] SG: Update ide/ to use sg_table Boaz Harrosh

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=476A7617.4010307@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=James.Bottomley@SteelEye.com \
    --cc=akpm@linux-foundation.org \
    --cc=dougg@torque.net \
    --cc=fujita.tomonori@lab.ntt.co.jp \
    --cc=jens.axboe@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    /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 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.