[SCSI] avoid useless free_list lock roundtrips
authorChristoph Hellwig <hch@infradead.org>
Thu, 20 Feb 2014 22:20:53 +0000 (14:20 -0800)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 15 Mar 2014 17:19:24 +0000 (10:19 -0700)
Avoid hitting the host-wide free_list lock unless we need to put a command
back onto the freelist.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/scsi.c

index d8afec8317cf394f698a8ecc4c63be0cd0de9c9c..fb86479ffd4ae214bdf304a344e99f25d25fab8f 100644 (file)
@@ -320,13 +320,14 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd,
 {
        unsigned long flags;
 
-       /* changing locks here, don't need to restore the irq state */
-       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_lock_irqsave(&shost->free_list_lock, flags);
+               if (list_empty(&shost->free_list)) {
+                       list_add(&cmd->list, &shost->free_list);
+                       cmd = NULL;
+               }
+               spin_unlock_irqrestore(&shost->free_list_lock, flags);
        }
-       spin_unlock_irqrestore(&shost->free_list_lock, flags);
 
        if (likely(cmd != NULL))
                scsi_pool_free_command(shost->cmd_pool, cmd);