diff options
author | James Smart <james.smart@emulex.com> | 2014-04-04 21:51:44 +0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-06-02 20:28:39 +0400 |
commit | 07eab624e5cf471450ed7b8c4ba8521e910dc9cf (patch) | |
tree | e9783c2eac57bca706fee652a4a35b5a1e15e3f3 /drivers/scsi/lpfc | |
parent | bcece5f557d533a85b24cf4f4416c821219fb7b7 (diff) | |
download | linux-07eab624e5cf471450ed7b8c4ba8521e910dc9cf.tar.xz |
lpfc: Fix locking for postbufq when freeing
Fix locking for postbufq when freeing
Signed-off-by: James Smart <james.smart@emulex.com>
Reviewed-By: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b2671dd520db..512f91ed5d25 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -836,19 +836,28 @@ lpfc_hba_free_post_buf(struct lpfc_hba *phba) struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; struct lpfc_dmabuf *mp, *next_mp; + LIST_HEAD(buflist); + int count; if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) lpfc_sli_hbqbuf_free_all(phba); else { /* Cleanup preposted buffers on the ELS ring */ - spin_lock_irq(&phba->hbalock); pring = &psli->ring[LPFC_ELS_RING]; - list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { + spin_lock_irq(&phba->hbalock); + list_splice_init(&pring->postbufq, &buflist); + spin_unlock_irq(&phba->hbalock); + + count = 0; + list_for_each_entry_safe(mp, next_mp, &buflist, list) { list_del(&mp->list); - pring->postbufq_cnt--; + count++; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } + + spin_lock_irq(&phba->hbalock); + pring->postbufq_cnt -= count; spin_unlock_irq(&phba->hbalock); } } |