diff options
Diffstat (limited to 'drivers/infiniband/hw/cxgb3/iwch_qp.c')
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_qp.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index ecd313f359a4..bea5839d89ee 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -822,8 +822,11 @@ static void __flush_qp(struct iwch_qp *qhp, struct iwch_cq *rchp, | |||
| 822 | flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count); | 822 | flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count); |
| 823 | spin_unlock(&qhp->lock); | 823 | spin_unlock(&qhp->lock); |
| 824 | spin_unlock_irqrestore(&rchp->lock, *flag); | 824 | spin_unlock_irqrestore(&rchp->lock, *flag); |
| 825 | if (flushed) | 825 | if (flushed) { |
| 826 | spin_lock_irqsave(&rchp->comp_handler_lock, *flag); | ||
| 826 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | 827 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); |
| 828 | spin_unlock_irqrestore(&rchp->comp_handler_lock, *flag); | ||
| 829 | } | ||
| 827 | 830 | ||
| 828 | /* locking hierarchy: cq lock first, then qp lock. */ | 831 | /* locking hierarchy: cq lock first, then qp lock. */ |
| 829 | spin_lock_irqsave(&schp->lock, *flag); | 832 | spin_lock_irqsave(&schp->lock, *flag); |
| @@ -833,8 +836,11 @@ static void __flush_qp(struct iwch_qp *qhp, struct iwch_cq *rchp, | |||
| 833 | flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count); | 836 | flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count); |
| 834 | spin_unlock(&qhp->lock); | 837 | spin_unlock(&qhp->lock); |
| 835 | spin_unlock_irqrestore(&schp->lock, *flag); | 838 | spin_unlock_irqrestore(&schp->lock, *flag); |
| 836 | if (flushed) | 839 | if (flushed) { |
| 840 | spin_lock_irqsave(&schp->comp_handler_lock, *flag); | ||
| 837 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | 841 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); |
| 842 | spin_unlock_irqrestore(&schp->comp_handler_lock, *flag); | ||
| 843 | } | ||
| 838 | 844 | ||
| 839 | /* deref */ | 845 | /* deref */ |
| 840 | if (atomic_dec_and_test(&qhp->refcnt)) | 846 | if (atomic_dec_and_test(&qhp->refcnt)) |
| @@ -853,11 +859,15 @@ static void flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
| 853 | if (qhp->ibqp.uobject) { | 859 | if (qhp->ibqp.uobject) { |
| 854 | cxio_set_wq_in_error(&qhp->wq); | 860 | cxio_set_wq_in_error(&qhp->wq); |
| 855 | cxio_set_cq_in_error(&rchp->cq); | 861 | cxio_set_cq_in_error(&rchp->cq); |
| 862 | spin_lock_irqsave(&rchp->comp_handler_lock, *flag); | ||
| 856 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | 863 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); |
| 864 | spin_unlock_irqrestore(&rchp->comp_handler_lock, *flag); | ||
| 857 | if (schp != rchp) { | 865 | if (schp != rchp) { |
| 858 | cxio_set_cq_in_error(&schp->cq); | 866 | cxio_set_cq_in_error(&schp->cq); |
| 867 | spin_lock_irqsave(&schp->comp_handler_lock, *flag); | ||
| 859 | (*schp->ibcq.comp_handler)(&schp->ibcq, | 868 | (*schp->ibcq.comp_handler)(&schp->ibcq, |
| 860 | schp->ibcq.cq_context); | 869 | schp->ibcq.cq_context); |
| 870 | spin_unlock_irqrestore(&schp->comp_handler_lock, *flag); | ||
| 861 | } | 871 | } |
| 862 | return; | 872 | return; |
| 863 | } | 873 | } |
