From: Patrick Mansfield <patmans@us.ibm.com>
To: James Bottomley <James.Bottomley@steeleye.com>,
linux-scsi@vger.kernel.org
Subject: [PATCH] scsi-misc-2.5 user per-device spare command
Date: Thu, 24 Apr 2003 10:03:17 -0700 [thread overview]
Message-ID: <20030424100317.A32134@beaverton.ibm.com> (raw)
In-Reply-To: <20030424100229.A32098@beaverton.ibm.com>; from patmans@us.ibm.com on Thu, Apr 24, 2003 at 10:02:29AM -0700
Patch against scsi-misc-2.5
Use a per-device spare command rather than a per-host spare.
Use the sdev->sdev_lock (or queue_lock) to protect use of the spare
command rather than the free_list_lock.
diff -purN -X /home/patman/dontdiff rmcmd_lock-2.5-cur/drivers/scsi/hosts.h rmhost_flock-2.5-cur/drivers/scsi/hosts.h
--- rmcmd_lock-2.5-cur/drivers/scsi/hosts.h Sat Apr 12 16:25:38 2003
+++ rmhost_flock-2.5-cur/drivers/scsi/hosts.h Thu Apr 24 09:14:47 2003
@@ -378,8 +378,6 @@ struct Scsi_Host
struct list_head my_devices;
struct scsi_host_cmd_pool *cmd_pool;
- spinlock_t free_list_lock;
- struct list_head free_list; /* backup store of cmd structs */
struct list_head starved_list;
spinlock_t default_lock;
diff -purN -X /home/patman/dontdiff rmcmd_lock-2.5-cur/drivers/scsi/scsi.c rmhost_flock-2.5-cur/drivers/scsi/scsi.c
--- rmcmd_lock-2.5-cur/drivers/scsi/scsi.c Thu Apr 24 09:14:04 2003
+++ rmhost_flock-2.5-cur/drivers/scsi/scsi.c Thu Apr 24 09:14:47 2003
@@ -254,26 +254,20 @@ static struct scsi_host_cmd_pool scsi_cm
static DECLARE_MUTEX(host_cmd_pool_mutex);
-static struct scsi_cmnd *scsi_alloc_cmd(struct Scsi_Host *shost,
+static struct scsi_cmnd *scsi_alloc_cmd(struct scsi_device *sdev,
int gfp_mask)
{
struct scsi_cmnd *cmd;
- cmd = kmem_cache_alloc(shost->cmd_pool->slab,
- gfp_mask | shost->cmd_pool->gfp_mask);
-
- if (unlikely(!cmd)) {
- unsigned long flags;
-
- spin_lock_irqsave(&shost->free_list_lock, flags);
- if (likely(!list_empty(&shost->free_list))) {
- cmd = list_entry(shost->free_list.next,
- struct scsi_cmnd, list);
- list_del_init(&cmd->list);
- }
- spin_unlock_irqrestore(&shost->free_list_lock, flags);
- }
-
+ /*
+ * Use any spare command first.
+ */
+ cmd = sdev->spare_cmd;
+ if (cmd != NULL)
+ sdev->spare_cmd = NULL;
+ else
+ cmd = kmem_cache_alloc(sdev->host->cmd_pool->slab,
+ gfp_mask | sdev->host->cmd_pool->gfp_mask);
return cmd;
}
@@ -292,7 +286,7 @@ static struct scsi_cmnd *scsi_alloc_cmd(
*/
struct scsi_cmnd *__scsi_get_command(struct scsi_device *dev, int gfp_mask)
{
- struct scsi_cmnd *cmd = scsi_alloc_cmd(dev->host, gfp_mask);
+ struct scsi_cmnd *cmd = scsi_alloc_cmd(dev, gfp_mask);
if (likely(cmd != NULL)) {
memset(cmd, 0, sizeof(*cmd));
@@ -347,21 +341,13 @@ struct scsi_cmnd *scsi_get_command(struc
*/
void __scsi_put_command(struct scsi_cmnd *cmd)
{
- struct Scsi_Host *shost = cmd->device->host;
- unsigned long flags;
-
/* serious error if the command hasn't come from a device list */
BUG_ON(list_empty(&cmd->list));
- list_del_init(&cmd->list);
- spin_lock_irqsave(&shost->free_list_lock, flags);
- if (unlikely(list_empty(&shost->free_list))) {
- list_add(&cmd->list, &shost->free_list);
- cmd = NULL;
- }
- spin_unlock_irqrestore(&shost->free_list_lock, flags);
-
- if (likely(cmd != NULL))
- kmem_cache_free(shost->cmd_pool->slab, cmd);
+ list_del(&cmd->list);
+ if (!cmd->device->spare_cmd)
+ cmd->device->spare_cmd = cmd;
+ else
+ kmem_cache_free(cmd->device->host->cmd_pool->slab, cmd);
}
/*
@@ -384,6 +370,41 @@ void scsi_put_command(struct scsi_cmnd *
}
/*
+ * Function: scsi_setup_sdev_spare_command()
+ *
+ * Purpose: Setup the spare commands for a scsi_device
+ *
+ * Arguments: sdev - host to allocate spares for
+ *
+ * Returns: 0 if no error, else -ENOMEM.
+ */
+int scsi_setup_sdev_spare_command(struct scsi_device *sdev)
+{
+ sdev->spare_cmd = kmem_cache_alloc(sdev->host->cmd_pool->slab,
+ GFP_KERNEL | sdev->host->cmd_pool->gfp_mask);
+ if (sdev->spare_cmd)
+ return 0;
+ else
+ return -ENOMEM;
+}
+
+/*
+ * Function: scsi_destroy_sdev_spare_command()
+ *
+ * Purpose: destroy the spare commands for a scsi_device
+ *
+ * Arguments: sdev - host to free spares from
+ *
+ * Returns: 0 if no error, else -ENOMEM.
+ */
+void scsi_destroy_sdev_spare_command(struct scsi_device *sdev)
+{
+ if (sdev->spare_cmd)
+ kmem_cache_free(sdev->host->cmd_pool->slab, sdev->spare_cmd);
+ sdev->spare_cmd = NULL;
+}
+
+/*
* Function: scsi_setup_command_freelist()
*
* Purpose: Setup the command freelist for a scsi host.
@@ -395,10 +416,6 @@ void scsi_put_command(struct scsi_cmnd *
int scsi_setup_command_freelist(struct Scsi_Host *shost)
{
struct scsi_host_cmd_pool *pool;
- struct scsi_cmnd *cmd;
-
- 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
@@ -413,25 +430,11 @@ int scsi_setup_command_freelist(struct S
if (!pool->slab)
goto fail;
}
-
pool->users++;
shost->cmd_pool = pool;
up(&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;
- list_add(&cmd->list, &shost->free_list);
return 0;
- fail2:
- if (!--pool->users)
- kmem_cache_destroy(pool->slab);
- return -ENOMEM;
fail:
up(&host_cmd_pool_mutex);
return -ENOMEM;
@@ -447,14 +450,6 @@ int scsi_setup_command_freelist(struct S
*/
void scsi_destroy_command_freelist(struct Scsi_Host *shost)
{
- while (!list_empty(&shost->free_list)) {
- struct scsi_cmnd *cmd;
-
- cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
- list_del_init(&cmd->list);
- kmem_cache_free(shost->cmd_pool->slab, cmd);
- }
-
down(&host_cmd_pool_mutex);
if (!--shost->cmd_pool->users)
kmem_cache_destroy(shost->cmd_pool->slab);
diff -purN -X /home/patman/dontdiff rmcmd_lock-2.5-cur/drivers/scsi/scsi.h rmhost_flock-2.5-cur/drivers/scsi/scsi.h
--- rmcmd_lock-2.5-cur/drivers/scsi/scsi.h Thu Apr 24 09:14:04 2003
+++ rmhost_flock-2.5-cur/drivers/scsi/scsi.h Thu Apr 24 09:14:47 2003
@@ -411,6 +411,8 @@ extern void scsi_exit_queue(void);
* Prototypes for functions in scsi.c
*/
extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt);
+extern int scsi_setup_sdev_spare_command(struct scsi_device *sdev);
+extern void scsi_destroy_sdev_spare_command(struct scsi_device *sdev);
extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
extern struct scsi_cmnd *__scsi_get_command(struct scsi_device *dev, int flags);
@@ -550,6 +552,7 @@ struct scsi_device {
spinlock_t sdev_lock; /* also the request queue_lock */
struct list_head cmd_list; /* queue of in use SCSI Command structures */
struct list_head starved_entry;
+ struct scsi_cmnd *spare_cmd;
Scsi_Cmnd *current_cmnd; /* currently active command */
unsigned short queue_depth; /* How deep of a queue we want */
unsigned short last_queue_full_depth; /* These two are used by */
diff -purN -X /home/patman/dontdiff rmcmd_lock-2.5-cur/drivers/scsi/scsi_scan.c rmhost_flock-2.5-cur/drivers/scsi/scsi_scan.c
--- rmcmd_lock-2.5-cur/drivers/scsi/scsi_scan.c Thu Apr 24 09:14:04 2003
+++ rmhost_flock-2.5-cur/drivers/scsi/scsi_scan.c Thu Apr 24 09:14:47 2003
@@ -422,9 +422,13 @@ static struct scsi_device *scsi_alloc_sd
sdev->borken = 1;
spin_lock_init(&sdev->sdev_lock);
+
+ if (scsi_setup_sdev_spare_command(sdev))
+ goto out_free_dev;
+
sdev->request_queue = scsi_alloc_queue(sdev);
if (!sdev->request_queue)
- goto out_free_dev;
+ goto out_free_cmd;
sdev->request_queue->queuedata = sdev;
scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
@@ -465,6 +469,8 @@ static struct scsi_device *scsi_alloc_sd
out_free_queue:
scsi_free_queue(sdev->request_queue);
+out_free_cmd:
+ scsi_destroy_sdev_spare_command(sdev);
out_free_dev:
kfree(sdev);
out:
@@ -487,6 +493,7 @@ static void scsi_free_sdev(struct scsi_d
list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings);
+ scsi_destroy_sdev_spare_command(sdev);
if (sdev->request_queue)
scsi_free_queue(sdev->request_queue);
if (sdev->host->hostt->slave_destroy)
next prev parent reply other threads:[~2003-04-24 16:54 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-04-24 17:02 [PATCH] scsi-misc-2.5 remove scsi_device list_lock Patrick Mansfield
2003-04-24 17:03 ` Patrick Mansfield [this message]
2003-04-24 17:03 ` [PATCH] scsi-misc-2.5 fold scsi_alloc_cmd into __scsi_get_command Patrick Mansfield
2003-04-25 10:12 ` [PATCH] scsi-misc-2.5 user per-device spare command Christoph Hellwig
2003-04-25 14:12 ` Luben Tuikov
2003-04-25 16:50 ` Patrick Mansfield
2003-04-25 16:56 ` Christoph Hellwig
2003-04-25 17:45 ` Luben Tuikov
2003-04-25 18:00 ` Patrick Mansfield
2003-04-25 18:36 ` Luben Tuikov
2003-04-25 16:37 ` Patrick Mansfield
2003-04-25 16:50 ` Christoph Hellwig
2003-04-25 16:57 ` James Bottomley
2003-04-25 20:49 ` Patrick Mansfield
2003-04-25 17:38 ` Luben Tuikov
2003-04-25 10:12 ` [PATCH] scsi-misc-2.5 remove scsi_device list_lock Christoph Hellwig
2003-04-25 10:47 ` Jens Axboe
2003-04-25 16:53 ` Patrick Mansfield
2003-04-25 17:20 ` Jens Axboe
2003-04-25 14:00 ` Luben Tuikov
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=20030424100317.A32134@beaverton.ibm.com \
--to=patmans@us.ibm.com \
--cc=James.Bottomley@steeleye.com \
--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