aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorRobert Elliott <elliott@hp.com>2015-01-23 17:43:41 -0500
committerJames Bottomley <JBottomley@Parallels.com>2015-02-02 12:57:41 -0500
commit33811026a0a4208dd5725183d37fc92d5e88b0a2 (patch)
tree3ee9c60da0de30a40ea02be9db13b5c75fcb0ea4 /drivers/scsi
parent281a7fd03ea37c979bbba4d8376595c0288e3252 (diff)
hpsa: optimize cmd_alloc function by remembering last allocation
Empirically, this improves performance slightly (~2% max IOPS) by allowing cmd_alloc to remember where it left off searching for free commands between calls instead of always starting its search at command 0. Reviewed-by: Scott Teel <scott.teel@pmcs.com> Signed-off-by: Robert Elliott <elliott@hp.com> Signed-off-by: Don Brace <don.brace@pmcs.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/hpsa.c7
-rw-r--r--drivers/scsi/hpsa.h1
2 files changed, 6 insertions, 2 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index c95a20c5269b..72abcf3bfabf 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4649,9 +4649,10 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
4649 union u64bit temp64; 4649 union u64bit temp64;
4650 dma_addr_t cmd_dma_handle, err_dma_handle; 4650 dma_addr_t cmd_dma_handle, err_dma_handle;
4651 int refcount; 4651 int refcount;
4652 unsigned long offset = 0; 4652 unsigned long offset;
4653 4653
4654 /* There is some *extremely* small but non-zero chance that that 4654 /*
4655 * There is some *extremely* small but non-zero chance that that
4655 * multiple threads could get in here, and one thread could 4656 * multiple threads could get in here, and one thread could
4656 * be scanning through the list of bits looking for a free 4657 * be scanning through the list of bits looking for a free
4657 * one, but the free ones are always behind him, and other 4658 * one, but the free ones are always behind him, and other
@@ -4662,6 +4663,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
4662 * infrequently as to be indistinguishable from never. 4663 * infrequently as to be indistinguishable from never.
4663 */ 4664 */
4664 4665
4666 offset = h->last_allocation; /* benignly racy */
4665 for (;;) { 4667 for (;;) {
4666 i = find_next_zero_bit(h->cmd_pool_bits, h->nr_cmds, offset); 4668 i = find_next_zero_bit(h->cmd_pool_bits, h->nr_cmds, offset);
4667 if (unlikely(i == h->nr_cmds)) { 4669 if (unlikely(i == h->nr_cmds)) {
@@ -4679,6 +4681,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
4679 h->cmd_pool_bits + (i / BITS_PER_LONG)); 4681 h->cmd_pool_bits + (i / BITS_PER_LONG));
4680 break; /* it's ours now. */ 4682 break; /* it's ours now. */
4681 } 4683 }
4684 h->last_allocation = i; /* benignly racy */
4682 4685
4683 /* Zero out all of commandlist except the last field, refcount */ 4686 /* Zero out all of commandlist except the last field, refcount */
4684 memset(c, 0, offsetof(struct CommandList, refcount)); 4687 memset(c, 0, offsetof(struct CommandList, refcount));
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 679e4d2272e0..981479a13935 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -133,6 +133,7 @@ struct ctlr_info {
133 struct CfgTable __iomem *cfgtable; 133 struct CfgTable __iomem *cfgtable;
134 int interrupts_enabled; 134 int interrupts_enabled;
135 int max_commands; 135 int max_commands;
136 int last_allocation;
136 atomic_t commands_outstanding; 137 atomic_t commands_outstanding;
137# define PERF_MODE_INT 0 138# define PERF_MODE_INT 0
138# define DOORBELL_INT 1 139# define DOORBELL_INT 1