diff options
Diffstat (limited to 'drivers/infiniband/hw/bnxt_re/qplib_fp.c')
-rw-r--r-- | drivers/infiniband/hw/bnxt_re/qplib_fp.c | 109 |
1 files changed, 24 insertions, 85 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 3ea5b9624f6b..06b42c880fd4 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c | |||
@@ -88,75 +88,35 @@ static void __bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) | |||
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp, | 91 | static void bnxt_qplib_acquire_cq_flush_locks(struct bnxt_qplib_qp *qp, |
92 | unsigned long *flags) | 92 | unsigned long *flags) |
93 | __acquires(&qp->scq->hwq.lock) __acquires(&qp->rcq->hwq.lock) | 93 | __acquires(&qp->scq->flush_lock) __acquires(&qp->rcq->flush_lock) |
94 | { | 94 | { |
95 | spin_lock_irqsave(&qp->scq->hwq.lock, *flags); | 95 | spin_lock_irqsave(&qp->scq->flush_lock, *flags); |
96 | if (qp->scq == qp->rcq) | 96 | if (qp->scq == qp->rcq) |
97 | __acquire(&qp->rcq->hwq.lock); | 97 | __acquire(&qp->rcq->flush_lock); |
98 | else | 98 | else |
99 | spin_lock(&qp->rcq->hwq.lock); | 99 | spin_lock(&qp->rcq->flush_lock); |
100 | } | 100 | } |
101 | 101 | ||
102 | void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp, | 102 | static void bnxt_qplib_release_cq_flush_locks(struct bnxt_qplib_qp *qp, |
103 | unsigned long *flags) | 103 | unsigned long *flags) |
104 | __releases(&qp->scq->hwq.lock) __releases(&qp->rcq->hwq.lock) | 104 | __releases(&qp->scq->flush_lock) __releases(&qp->rcq->flush_lock) |
105 | { | 105 | { |
106 | if (qp->scq == qp->rcq) | 106 | if (qp->scq == qp->rcq) |
107 | __release(&qp->rcq->hwq.lock); | 107 | __release(&qp->rcq->flush_lock); |
108 | else | 108 | else |
109 | spin_unlock(&qp->rcq->hwq.lock); | 109 | spin_unlock(&qp->rcq->flush_lock); |
110 | spin_unlock_irqrestore(&qp->scq->hwq.lock, *flags); | 110 | spin_unlock_irqrestore(&qp->scq->flush_lock, *flags); |
111 | } | ||
112 | |||
113 | static struct bnxt_qplib_cq *bnxt_qplib_find_buddy_cq(struct bnxt_qplib_qp *qp, | ||
114 | struct bnxt_qplib_cq *cq) | ||
115 | { | ||
116 | struct bnxt_qplib_cq *buddy_cq = NULL; | ||
117 | |||
118 | if (qp->scq == qp->rcq) | ||
119 | buddy_cq = NULL; | ||
120 | else if (qp->scq == cq) | ||
121 | buddy_cq = qp->rcq; | ||
122 | else | ||
123 | buddy_cq = qp->scq; | ||
124 | return buddy_cq; | ||
125 | } | ||
126 | |||
127 | static void bnxt_qplib_lock_buddy_cq(struct bnxt_qplib_qp *qp, | ||
128 | struct bnxt_qplib_cq *cq) | ||
129 | __acquires(&buddy_cq->hwq.lock) | ||
130 | { | ||
131 | struct bnxt_qplib_cq *buddy_cq = NULL; | ||
132 | |||
133 | buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq); | ||
134 | if (!buddy_cq) | ||
135 | __acquire(&cq->hwq.lock); | ||
136 | else | ||
137 | spin_lock(&buddy_cq->hwq.lock); | ||
138 | } | ||
139 | |||
140 | static void bnxt_qplib_unlock_buddy_cq(struct bnxt_qplib_qp *qp, | ||
141 | struct bnxt_qplib_cq *cq) | ||
142 | __releases(&buddy_cq->hwq.lock) | ||
143 | { | ||
144 | struct bnxt_qplib_cq *buddy_cq = NULL; | ||
145 | |||
146 | buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq); | ||
147 | if (!buddy_cq) | ||
148 | __release(&cq->hwq.lock); | ||
149 | else | ||
150 | spin_unlock(&buddy_cq->hwq.lock); | ||
151 | } | 111 | } |
152 | 112 | ||
153 | void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) | 113 | void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) |
154 | { | 114 | { |
155 | unsigned long flags; | 115 | unsigned long flags; |
156 | 116 | ||
157 | bnxt_qplib_acquire_cq_locks(qp, &flags); | 117 | bnxt_qplib_acquire_cq_flush_locks(qp, &flags); |
158 | __bnxt_qplib_add_flush_qp(qp); | 118 | __bnxt_qplib_add_flush_qp(qp); |
159 | bnxt_qplib_release_cq_locks(qp, &flags); | 119 | bnxt_qplib_release_cq_flush_locks(qp, &flags); |
160 | } | 120 | } |
161 | 121 | ||
162 | static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp) | 122 | static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp) |
@@ -177,7 +137,7 @@ void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) | |||
177 | { | 137 | { |
178 | unsigned long flags; | 138 | unsigned long flags; |
179 | 139 | ||
180 | bnxt_qplib_acquire_cq_locks(qp, &flags); | 140 | bnxt_qplib_acquire_cq_flush_locks(qp, &flags); |
181 | __clean_cq(qp->scq, (u64)(unsigned long)qp); | 141 | __clean_cq(qp->scq, (u64)(unsigned long)qp); |
182 | qp->sq.hwq.prod = 0; | 142 | qp->sq.hwq.prod = 0; |
183 | qp->sq.hwq.cons = 0; | 143 | qp->sq.hwq.cons = 0; |
@@ -186,7 +146,7 @@ void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) | |||
186 | qp->rq.hwq.cons = 0; | 146 | qp->rq.hwq.cons = 0; |
187 | 147 | ||
188 | __bnxt_qplib_del_flush_qp(qp); | 148 | __bnxt_qplib_del_flush_qp(qp); |
189 | bnxt_qplib_release_cq_locks(qp, &flags); | 149 | bnxt_qplib_release_cq_flush_locks(qp, &flags); |
190 | } | 150 | } |
191 | 151 | ||
192 | static void bnxt_qpn_cqn_sched_task(struct work_struct *work) | 152 | static void bnxt_qpn_cqn_sched_task(struct work_struct *work) |
@@ -2107,9 +2067,6 @@ void bnxt_qplib_mark_qp_error(void *qp_handle) | |||
2107 | /* Must block new posting of SQ and RQ */ | 2067 | /* Must block new posting of SQ and RQ */ |
2108 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2068 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2109 | bnxt_qplib_cancel_phantom_processing(qp); | 2069 | bnxt_qplib_cancel_phantom_processing(qp); |
2110 | |||
2111 | /* Add qp to flush list of the CQ */ | ||
2112 | __bnxt_qplib_add_flush_qp(qp); | ||
2113 | } | 2070 | } |
2114 | 2071 | ||
2115 | /* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive) | 2072 | /* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive) |
@@ -2285,9 +2242,9 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, | |||
2285 | sw_sq_cons, cqe->wr_id, cqe->status); | 2242 | sw_sq_cons, cqe->wr_id, cqe->status); |
2286 | cqe++; | 2243 | cqe++; |
2287 | (*budget)--; | 2244 | (*budget)--; |
2288 | bnxt_qplib_lock_buddy_cq(qp, cq); | ||
2289 | bnxt_qplib_mark_qp_error(qp); | 2245 | bnxt_qplib_mark_qp_error(qp); |
2290 | bnxt_qplib_unlock_buddy_cq(qp, cq); | 2246 | /* Add qp to flush list of the CQ */ |
2247 | bnxt_qplib_add_flush_qp(qp); | ||
2291 | } else { | 2248 | } else { |
2292 | if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { | 2249 | if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { |
2293 | /* Before we complete, do WA 9060 */ | 2250 | /* Before we complete, do WA 9060 */ |
@@ -2403,9 +2360,7 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq, | |||
2403 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { | 2360 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { |
2404 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2361 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2405 | /* Add qp to flush list of the CQ */ | 2362 | /* Add qp to flush list of the CQ */ |
2406 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2363 | bnxt_qplib_add_flush_qp(qp); |
2407 | __bnxt_qplib_add_flush_qp(qp); | ||
2408 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2409 | } | 2364 | } |
2410 | } | 2365 | } |
2411 | 2366 | ||
@@ -2489,9 +2444,7 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq, | |||
2489 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { | 2444 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { |
2490 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2445 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2491 | /* Add qp to flush list of the CQ */ | 2446 | /* Add qp to flush list of the CQ */ |
2492 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2447 | bnxt_qplib_add_flush_qp(qp); |
2493 | __bnxt_qplib_add_flush_qp(qp); | ||
2494 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2495 | } | 2448 | } |
2496 | } | 2449 | } |
2497 | done: | 2450 | done: |
@@ -2501,11 +2454,9 @@ done: | |||
2501 | bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) | 2454 | bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) |
2502 | { | 2455 | { |
2503 | struct cq_base *hw_cqe, **hw_cqe_ptr; | 2456 | struct cq_base *hw_cqe, **hw_cqe_ptr; |
2504 | unsigned long flags; | ||
2505 | u32 sw_cons, raw_cons; | 2457 | u32 sw_cons, raw_cons; |
2506 | bool rc = true; | 2458 | bool rc = true; |
2507 | 2459 | ||
2508 | spin_lock_irqsave(&cq->hwq.lock, flags); | ||
2509 | raw_cons = cq->hwq.cons; | 2460 | raw_cons = cq->hwq.cons; |
2510 | sw_cons = HWQ_CMP(raw_cons, &cq->hwq); | 2461 | sw_cons = HWQ_CMP(raw_cons, &cq->hwq); |
2511 | hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr; | 2462 | hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr; |
@@ -2513,7 +2464,6 @@ bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) | |||
2513 | 2464 | ||
2514 | /* Check for Valid bit. If the CQE is valid, return false */ | 2465 | /* Check for Valid bit. If the CQE is valid, return false */ |
2515 | rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements); | 2466 | rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements); |
2516 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | ||
2517 | return rc; | 2467 | return rc; |
2518 | } | 2468 | } |
2519 | 2469 | ||
@@ -2602,9 +2552,7 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq, | |||
2602 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { | 2552 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { |
2603 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2553 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2604 | /* Add qp to flush list of the CQ */ | 2554 | /* Add qp to flush list of the CQ */ |
2605 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2555 | bnxt_qplib_add_flush_qp(qp); |
2606 | __bnxt_qplib_add_flush_qp(qp); | ||
2607 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2608 | } | 2556 | } |
2609 | } | 2557 | } |
2610 | 2558 | ||
@@ -2719,9 +2667,7 @@ do_rq: | |||
2719 | */ | 2667 | */ |
2720 | 2668 | ||
2721 | /* Add qp to flush list of the CQ */ | 2669 | /* Add qp to flush list of the CQ */ |
2722 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2670 | bnxt_qplib_add_flush_qp(qp); |
2723 | __bnxt_qplib_add_flush_qp(qp); | ||
2724 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2725 | done: | 2671 | done: |
2726 | return rc; | 2672 | return rc; |
2727 | } | 2673 | } |
@@ -2750,7 +2696,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, | |||
2750 | u32 budget = num_cqes; | 2696 | u32 budget = num_cqes; |
2751 | unsigned long flags; | 2697 | unsigned long flags; |
2752 | 2698 | ||
2753 | spin_lock_irqsave(&cq->hwq.lock, flags); | 2699 | spin_lock_irqsave(&cq->flush_lock, flags); |
2754 | list_for_each_entry(qp, &cq->sqf_head, sq_flush) { | 2700 | list_for_each_entry(qp, &cq->sqf_head, sq_flush) { |
2755 | dev_dbg(&cq->hwq.pdev->dev, | 2701 | dev_dbg(&cq->hwq.pdev->dev, |
2756 | "QPLIB: FP: Flushing SQ QP= %p", | 2702 | "QPLIB: FP: Flushing SQ QP= %p", |
@@ -2764,7 +2710,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, | |||
2764 | qp); | 2710 | qp); |
2765 | __flush_rq(&qp->rq, qp, &cqe, &budget); | 2711 | __flush_rq(&qp->rq, qp, &cqe, &budget); |
2766 | } | 2712 | } |
2767 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | 2713 | spin_unlock_irqrestore(&cq->flush_lock, flags); |
2768 | 2714 | ||
2769 | return num_cqes - budget; | 2715 | return num_cqes - budget; |
2770 | } | 2716 | } |
@@ -2773,11 +2719,9 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, | |||
2773 | int num_cqes, struct bnxt_qplib_qp **lib_qp) | 2719 | int num_cqes, struct bnxt_qplib_qp **lib_qp) |
2774 | { | 2720 | { |
2775 | struct cq_base *hw_cqe, **hw_cqe_ptr; | 2721 | struct cq_base *hw_cqe, **hw_cqe_ptr; |
2776 | unsigned long flags; | ||
2777 | u32 sw_cons, raw_cons; | 2722 | u32 sw_cons, raw_cons; |
2778 | int budget, rc = 0; | 2723 | int budget, rc = 0; |
2779 | 2724 | ||
2780 | spin_lock_irqsave(&cq->hwq.lock, flags); | ||
2781 | raw_cons = cq->hwq.cons; | 2725 | raw_cons = cq->hwq.cons; |
2782 | budget = num_cqes; | 2726 | budget = num_cqes; |
2783 | 2727 | ||
@@ -2853,20 +2797,15 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, | |||
2853 | bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ); | 2797 | bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ); |
2854 | } | 2798 | } |
2855 | exit: | 2799 | exit: |
2856 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | ||
2857 | return num_cqes - budget; | 2800 | return num_cqes - budget; |
2858 | } | 2801 | } |
2859 | 2802 | ||
2860 | void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type) | 2803 | void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type) |
2861 | { | 2804 | { |
2862 | unsigned long flags; | ||
2863 | |||
2864 | spin_lock_irqsave(&cq->hwq.lock, flags); | ||
2865 | if (arm_type) | 2805 | if (arm_type) |
2866 | bnxt_qplib_arm_cq(cq, arm_type); | 2806 | bnxt_qplib_arm_cq(cq, arm_type); |
2867 | /* Using cq->arm_state variable to track whether to issue cq handler */ | 2807 | /* Using cq->arm_state variable to track whether to issue cq handler */ |
2868 | atomic_set(&cq->arm_state, 1); | 2808 | atomic_set(&cq->arm_state, 1); |
2869 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | ||
2870 | } | 2809 | } |
2871 | 2810 | ||
2872 | void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp) | 2811 | void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp) |