summaryrefslogtreecommitdiff
path: root/drivers/scsi/hpsa.h
diff options
context:
space:
mode:
authorMatt Gates <matthew.gates@hp.com>2012-05-01 16:43:11 (GMT)
committerJames Bottomley <JBottomley@Parallels.com>2012-05-10 08:17:26 (GMT)
commite16a33adc0e59aa96a483fd2923d77e674f013c1 (patch)
tree832c2b44baa4dd48553d156b0340dfcc5bbee624 /drivers/scsi/hpsa.h
parent254f796b9f22b1944c64caabc356a56caaa2facd (diff)
downloadlinux-fsl-qoriq-e16a33adc0e59aa96a483fd2923d77e674f013c1.tar.xz
[SCSI] hpsa: refine interrupt handler locking for greater concurrency
Use spinlocks with finer granularity in the submission and completion paths to allow concurrent execution for multiple reply queues. In particular, do not hold a spin lock while submitting a request to the device, nor during most of the interrupt handler. Signed-off-by: Matt Gates <matthew.gates@hp.com> Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/hpsa.h')
-rw-r--r--drivers/scsi/hpsa.h13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 486a7c0..79c36aa 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -246,9 +246,6 @@ static void SA5_submit_command(struct ctlr_info *h,
c->Header.Tag.lower);
writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
(void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
- h->commands_outstanding++;
- if (h->commands_outstanding > h->max_outstanding)
- h->max_outstanding = h->commands_outstanding;
}
/*
@@ -287,7 +284,7 @@ static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
{
struct reply_pool *rq = &h->reply_queue[q];
- unsigned long register_value = FIFO_EMPTY;
+ unsigned long flags, register_value = FIFO_EMPTY;
/* msi auto clears the interrupt pending bit. */
if (!(h->msi_vector || h->msix_vector)) {
@@ -305,7 +302,9 @@ static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
if ((rq->head[rq->current_entry] & 1) == rq->wraparound) {
register_value = rq->head[rq->current_entry];
rq->current_entry++;
+ spin_lock_irqsave(&h->lock, flags);
h->commands_outstanding--;
+ spin_unlock_irqrestore(&h->lock, flags);
} else {
register_value = FIFO_EMPTY;
}
@@ -338,9 +337,13 @@ static unsigned long SA5_completed(struct ctlr_info *h,
{
unsigned long register_value
= readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
+ unsigned long flags;
- if (register_value != FIFO_EMPTY)
+ if (register_value != FIFO_EMPTY) {
+ spin_lock_irqsave(&h->lock, flags);
h->commands_outstanding--;
+ spin_unlock_irqrestore(&h->lock, flags);
+ }
#ifdef HPSA_DEBUG
if (register_value != FIFO_EMPTY)