diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2014-05-29 11:53:28 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-06-02 03:54:57 -0400 |
commit | 0b57075deb3c082db6fbf528f3f6a3854b81bd83 (patch) | |
tree | 1fa53e45ddec6e47f756f1f52b75bcd1d5e73c94 /drivers/scsi/hpsa.c | |
parent | b3a52e791efd341a9a4e9065c667041c822661f0 (diff) |
hpsa: Rearrange start_io to avoid one unlock/lock sequence in main io path
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Reviewed-by: Joe Handzik <joseph.t.handzik@hp.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3e501df02e35..0a30cc23e718 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -194,7 +194,8 @@ static int number_of_controllers; | |||
194 | static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id); | 194 | static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id); |
195 | static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id); | 195 | static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id); |
196 | static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); | 196 | static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); |
197 | static void start_io(struct ctlr_info *h); | 197 | static void lock_and_start_io(struct ctlr_info *h); |
198 | static void start_io(struct ctlr_info *h, unsigned long *flags); | ||
198 | 199 | ||
199 | #ifdef CONFIG_COMPAT | 200 | #ifdef CONFIG_COMPAT |
200 | static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg); | 201 | static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg); |
@@ -845,8 +846,8 @@ static void enqueue_cmd_and_start_io(struct ctlr_info *h, | |||
845 | spin_lock_irqsave(&h->lock, flags); | 846 | spin_lock_irqsave(&h->lock, flags); |
846 | addQ(&h->reqQ, c); | 847 | addQ(&h->reqQ, c); |
847 | h->Qdepth++; | 848 | h->Qdepth++; |
849 | start_io(h, &flags); | ||
848 | spin_unlock_irqrestore(&h->lock, flags); | 850 | spin_unlock_irqrestore(&h->lock, flags); |
849 | start_io(h); | ||
850 | } | 851 | } |
851 | 852 | ||
852 | static inline void removeQ(struct CommandList *c) | 853 | static inline void removeQ(struct CommandList *c) |
@@ -5459,13 +5460,12 @@ static void __iomem *remap_pci_mem(ulong base, ulong size) | |||
5459 | 5460 | ||
5460 | /* Takes cmds off the submission queue and sends them to the hardware, | 5461 | /* Takes cmds off the submission queue and sends them to the hardware, |
5461 | * then puts them on the queue of cmds waiting for completion. | 5462 | * then puts them on the queue of cmds waiting for completion. |
5463 | * Assumes h->lock is held | ||
5462 | */ | 5464 | */ |
5463 | static void start_io(struct ctlr_info *h) | 5465 | static void start_io(struct ctlr_info *h, unsigned long *flags) |
5464 | { | 5466 | { |
5465 | struct CommandList *c; | 5467 | struct CommandList *c; |
5466 | unsigned long flags; | ||
5467 | 5468 | ||
5468 | spin_lock_irqsave(&h->lock, flags); | ||
5469 | while (!list_empty(&h->reqQ)) { | 5469 | while (!list_empty(&h->reqQ)) { |
5470 | c = list_entry(h->reqQ.next, struct CommandList, list); | 5470 | c = list_entry(h->reqQ.next, struct CommandList, list); |
5471 | /* can't do anything if fifo is full */ | 5471 | /* can't do anything if fifo is full */ |
@@ -5490,10 +5490,18 @@ static void start_io(struct ctlr_info *h) | |||
5490 | h->commands_outstanding++; | 5490 | h->commands_outstanding++; |
5491 | 5491 | ||
5492 | /* Tell the controller execute command */ | 5492 | /* Tell the controller execute command */ |
5493 | spin_unlock_irqrestore(&h->lock, flags); | 5493 | spin_unlock_irqrestore(&h->lock, *flags); |
5494 | h->access.submit_command(h, c); | 5494 | h->access.submit_command(h, c); |
5495 | spin_lock_irqsave(&h->lock, flags); | 5495 | spin_lock_irqsave(&h->lock, *flags); |
5496 | } | 5496 | } |
5497 | } | ||
5498 | |||
5499 | static void lock_and_start_io(struct ctlr_info *h) | ||
5500 | { | ||
5501 | unsigned long flags; | ||
5502 | |||
5503 | spin_lock_irqsave(&h->lock, flags); | ||
5504 | start_io(h, &flags); | ||
5497 | spin_unlock_irqrestore(&h->lock, flags); | 5505 | spin_unlock_irqrestore(&h->lock, flags); |
5498 | } | 5506 | } |
5499 | 5507 | ||
@@ -5561,7 +5569,7 @@ static inline void finish_cmd(struct CommandList *c) | |||
5561 | else if (c->cmd_type == CMD_IOCTL_PEND) | 5569 | else if (c->cmd_type == CMD_IOCTL_PEND) |
5562 | complete(c->waiting); | 5570 | complete(c->waiting); |
5563 | if (unlikely(io_may_be_stalled)) | 5571 | if (unlikely(io_may_be_stalled)) |
5564 | start_io(h); | 5572 | lock_and_start_io(h); |
5565 | } | 5573 | } |
5566 | 5574 | ||
5567 | static inline u32 hpsa_tag_contains_index(u32 tag) | 5575 | static inline u32 hpsa_tag_contains_index(u32 tag) |