aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.h
diff options
context:
space:
mode:
authorMatt Gates <matthew.gates@hp.com>2012-05-01 12:43:11 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-10 04:17:26 -0400
commite16a33adc0e59aa96a483fd2923d77e674f013c1 (patch)
tree832c2b44baa4dd48553d156b0340dfcc5bbee624 /drivers/scsi/hpsa.h
parent254f796b9f22b1944c64caabc356a56caaa2facd (diff)
[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 486a7c099246..79c36aaa2a37 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -246,9 +246,6 @@ static void SA5_submit_command(struct ctlr_info *h,
246 c->Header.Tag.lower); 246 c->Header.Tag.lower);
247 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); 247 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
248 (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); 248 (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
249 h->commands_outstanding++;
250 if (h->commands_outstanding > h->max_outstanding)
251 h->max_outstanding = h->commands_outstanding;
252} 249}
253 250
254/* 251/*
@@ -287,7 +284,7 @@ static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
287static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q) 284static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
288{ 285{
289 struct reply_pool *rq = &h->reply_queue[q]; 286 struct reply_pool *rq = &h->reply_queue[q];
290 unsigned long register_value = FIFO_EMPTY; 287 unsigned long flags, register_value = FIFO_EMPTY;
291 288
292 /* msi auto clears the interrupt pending bit. */ 289 /* msi auto clears the interrupt pending bit. */
293 if (!(h->msi_vector || h->msix_vector)) { 290 if (!(h->msi_vector || h->msix_vector)) {
@@ -305,7 +302,9 @@ static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
305 if ((rq->head[rq->current_entry] & 1) == rq->wraparound) { 302 if ((rq->head[rq->current_entry] & 1) == rq->wraparound) {
306 register_value = rq->head[rq->current_entry]; 303 register_value = rq->head[rq->current_entry];
307 rq->current_entry++; 304 rq->current_entry++;
305 spin_lock_irqsave(&h->lock, flags);
308 h->commands_outstanding--; 306 h->commands_outstanding--;
307 spin_unlock_irqrestore(&h->lock, flags);
309 } else { 308 } else {
310 register_value = FIFO_EMPTY; 309 register_value = FIFO_EMPTY;
311 } 310 }
@@ -338,9 +337,13 @@ static unsigned long SA5_completed(struct ctlr_info *h,
338{ 337{
339 unsigned long register_value 338 unsigned long register_value
340 = readl(h->vaddr + SA5_REPLY_PORT_OFFSET); 339 = readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
340 unsigned long flags;
341 341
342 if (register_value != FIFO_EMPTY) 342 if (register_value != FIFO_EMPTY) {
343 spin_lock_irqsave(&h->lock, flags);
343 h->commands_outstanding--; 344 h->commands_outstanding--;
345 spin_unlock_irqrestore(&h->lock, flags);
346 }
344 347
345#ifdef HPSA_DEBUG 348#ifdef HPSA_DEBUG
346 if (register_value != FIFO_EMPTY) 349 if (register_value != FIFO_EMPTY)