public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Matthew Wilcox <matthew@wil.cx>
To: linux-scsi@vger.kernel.org
Subject: [RFC 1/2] scsi core: alloc_cmnd
Date: Fri, 19 Oct 2007 12:33:31 -0600	[thread overview]
Message-ID: <20071019183331.GC30807@parisc-linux.org> (raw)


This fairly naive patch introduces alloc_cmnd and destroy_cmnd.  I'm not
exactly happy about passing down the gfp_mask -- I'd prefer to be able
to allocate scsi_cmnds before we grab the queue_lock (and hence get
rid of the possibility we might need to GFP_ATOMIC), but I don't see
anywhere to do that.  Maybe there's a simple change we can make to the
block layer to allow it.

Merely-an-RFC-by: Matthew Wilcox <willy@linux.intel.com>

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 1929488..30698da 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -160,8 +160,11 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
 {
 	struct scsi_cmnd *cmd;
 
-	cmd = kmem_cache_alloc(shost->cmd_pool->slab,
-			gfp_mask | shost->cmd_pool->gfp_mask);
+	if (shost->hostt->alloc_cmnd)
+		cmd = shost->hostt->alloc_cmnd(shost, gfp_mask);
+	else
+		cmd = kmem_cache_alloc(shost->cmd_pool->slab,
+					gfp_mask | shost->cmd_pool->gfp_mask);
 
 	if (unlikely(!cmd)) {
 		unsigned long flags;
@@ -230,8 +233,12 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd,
 	}
 	spin_unlock_irqrestore(&shost->free_list_lock, flags);
 
-	if (likely(cmd != NULL))
-		kmem_cache_free(shost->cmd_pool->slab, cmd);
+	if (likely(cmd != NULL)) {
+		if (shost->hostt->destroy_cmnd)
+			shost->hostt->destroy_cmnd(cmd);
+		else
+			kmem_cache_free(shost->cmd_pool->slab, cmd);
+	}
 
 	put_device(dev);
 }
@@ -280,31 +287,37 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
 	spin_lock_init(&shost->free_list_lock);
 	INIT_LIST_HEAD(&shost->free_list);
 
-	/*
-	 * Select a command slab for this host and create it if not
-	 * yet existant.
-	 */
-	mutex_lock(&host_cmd_pool_mutex);
-	pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool);
-	if (!pool->users) {
-		pool->slab = kmem_cache_create(pool->name,
-				sizeof(struct scsi_cmnd), 0,
-				pool->slab_flags, NULL);
-		if (!pool->slab)
-			goto fail;
-	}
+	if (shost->hostt->alloc_cmnd) {
+		cmd = shost->hostt->alloc_cmnd(shost, GFP_KERNEL);
+		if (!cmd)
+			return -ENOMEM;
+	} else {
+		/*
+		 * Select a command slab for this host and create it if not
+		 * yet existant.
+		 */
+		mutex_lock(&host_cmd_pool_mutex);
+		pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool);
+		if (!pool->users) {
+			pool->slab = kmem_cache_create(pool->name,
+					sizeof(struct scsi_cmnd), 0,
+					pool->slab_flags, NULL);
+			if (!pool->slab)
+				goto fail;
+		}
 
-	pool->users++;
-	shost->cmd_pool = pool;
-	mutex_unlock(&host_cmd_pool_mutex);
+		pool->users++;
+		shost->cmd_pool = pool;
+		mutex_unlock(&host_cmd_pool_mutex);
+		/*
+		 * Get one backup command for this host.
+		 */
+		cmd = kmem_cache_alloc(shost->cmd_pool->slab,
+				GFP_KERNEL | shost->cmd_pool->gfp_mask);
+		if (!cmd)
+			goto fail2;
+	}
 
-	/*
-	 * Get one backup command for this host.
-	 */
-	cmd = kmem_cache_alloc(shost->cmd_pool->slab,
-			GFP_KERNEL | shost->cmd_pool->gfp_mask);
-	if (!cmd)
-		goto fail2;
 	list_add(&cmd->list, &shost->free_list);		
 	return 0;
 
@@ -315,15 +328,13 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
  fail:
 	mutex_unlock(&host_cmd_pool_mutex);
 	return -ENOMEM;
-
 }
 
-/*
- * Function:	scsi_destroy_command_freelist()
- *
- * Purpose:	Release the command freelist for a scsi host.
+/**
+ * scsi_destroy_command_freelist - Release the command freelist for a scsi host
+ * @shost: Destroy the freelist for this host
  *
- * Arguments:	shost	- host that's freelist is going to be destroyed
+ * The @shost is being destroyed, so make sure we've freed this resource.
  */
 void scsi_destroy_command_freelist(struct Scsi_Host *shost)
 {
@@ -332,9 +343,15 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost)
 
 		cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
 		list_del_init(&cmd->list);
-		kmem_cache_free(shost->cmd_pool->slab, cmd);
+		if (shost->hostt->destroy_cmnd)
+			shost->hostt->destroy_cmnd(cmd);
+		else
+			kmem_cache_free(shost->cmd_pool->slab, cmd);
 	}
 
+	if (shost->hostt->destroy_cmnd)
+		return;
+
 	mutex_lock(&host_cmd_pool_mutex);
 	if (!--shost->cmd_pool->users)
 		kmem_cache_destroy(shost->cmd_pool->slab);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 7d210cd..19e2241 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -284,6 +284,15 @@ struct scsi_host_template {
 	void (* scan_start)(struct Scsi_Host *);
 
 	/*
+	 * Fill in this pair of functions to allow the driver to allocate
+	 * extra per-command memory.
+	 *
+	 * Status: OPTIONAL (for now ...)
+	 */
+	struct scsi_cmnd *(*alloc_cmnd)(struct Scsi_Host *, gfp_t);
+	void (*destroy_cmnd)(struct scsi_cmnd *);
+
+	/*
 	 * fill in this function to allow the queue depth of this host
 	 * to be changeable (on a per device basis).  returns either
 	 * the current queue depth setting (may be different from what
-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

             reply	other threads:[~2007-10-19 18:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-19 18:33 Matthew Wilcox [this message]
2007-10-23 16:49 ` [RFC 1/2] scsi core: alloc_cmnd Boaz Harrosh
2007-10-23 17:48   ` Matthew Wilcox
2007-10-23 18:46     ` Boaz Harrosh
2007-10-23 19:15       ` Matthew Wilcox
2007-10-23 19:49         ` Boaz Harrosh
2007-10-23 19:27     ` Christoph Hellwig
2007-10-23 20:24 ` Christoph Hellwig

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=20071019183331.GC30807@parisc-linux.org \
    --to=matthew@wil.cx \
    --cc=linux-scsi@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