summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
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)
union u64bit temp64;
dma_addr_t cmd_dma_handle, err_dma_handle;
int refcount;
- unsigned long offset = 0;
+ unsigned long offset;
- /* There is some *extremely* small but non-zero chance that that
+ /*
+ * There is some *extremely* small but non-zero chance that that
* multiple threads could get in here, and one thread could
* be scanning through the list of bits looking for a free
* one, but the free ones are always behind him, and other
@@ -4662,6 +4663,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
* infrequently as to be indistinguishable from never.
*/
+ offset = h->last_allocation; /* benignly racy */
for (;;) {
i = find_next_zero_bit(h->cmd_pool_bits, h->nr_cmds, offset);
if (unlikely(i == h->nr_cmds)) {
@@ -4679,6 +4681,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
h->cmd_pool_bits + (i / BITS_PER_LONG));
break; /* it's ours now. */
}
+ h->last_allocation = i; /* benignly racy */
/* Zero out all of commandlist except the last field, refcount */
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 {
struct CfgTable __iomem *cfgtable;
int interrupts_enabled;
int max_commands;
+ int last_allocation;
atomic_t commands_outstanding;
# define PERF_MODE_INT 0
# define DOORBELL_INT 1