diff options
author | Robert Elliott <elliott@hp.com> | 2015-01-23 17:43:41 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2015-02-02 12:57:41 -0500 |
commit | 33811026a0a4208dd5725183d37fc92d5e88b0a2 (patch) | |
tree | 3ee9c60da0de30a40ea02be9db13b5c75fcb0ea4 /drivers/scsi | |
parent | 281a7fd03ea37c979bbba4d8376595c0288e3252 (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.c | 7 | ||||
-rw-r--r-- | drivers/scsi/hpsa.h | 1 |
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 |