aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/qib/qib_rc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_rc.c')
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c47
1 files changed, 13 insertions, 34 deletions
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index 40c0a373719c..a0931119bd78 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -868,7 +868,7 @@ done:
868 868
869/* 869/*
870 * Back up requester to resend the last un-ACKed request. 870 * Back up requester to resend the last un-ACKed request.
871 * The QP s_lock should be held and interrupts disabled. 871 * The QP r_lock and s_lock should be held and interrupts disabled.
872 */ 872 */
873static void qib_restart_rc(struct qib_qp *qp, u32 psn, int wait) 873static void qib_restart_rc(struct qib_qp *qp, u32 psn, int wait)
874{ 874{
@@ -911,7 +911,8 @@ static void rc_timeout(unsigned long arg)
911 struct qib_ibport *ibp; 911 struct qib_ibport *ibp;
912 unsigned long flags; 912 unsigned long flags;
913 913
914 spin_lock_irqsave(&qp->s_lock, flags); 914 spin_lock_irqsave(&qp->r_lock, flags);
915 spin_lock(&qp->s_lock);
915 if (qp->s_flags & QIB_S_TIMER) { 916 if (qp->s_flags & QIB_S_TIMER) {
916 ibp = to_iport(qp->ibqp.device, qp->port_num); 917 ibp = to_iport(qp->ibqp.device, qp->port_num);
917 ibp->n_rc_timeouts++; 918 ibp->n_rc_timeouts++;
@@ -920,7 +921,8 @@ static void rc_timeout(unsigned long arg)
920 qib_restart_rc(qp, qp->s_last_psn + 1, 1); 921 qib_restart_rc(qp, qp->s_last_psn + 1, 1);
921 qib_schedule_send(qp); 922 qib_schedule_send(qp);
922 } 923 }
923 spin_unlock_irqrestore(&qp->s_lock, flags); 924 spin_unlock(&qp->s_lock);
925 spin_unlock_irqrestore(&qp->r_lock, flags);
924} 926}
925 927
926/* 928/*
@@ -1414,10 +1416,6 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp,
1414 1416
1415 spin_lock_irqsave(&qp->s_lock, flags); 1417 spin_lock_irqsave(&qp->s_lock, flags);
1416 1418
1417 /* Double check we can process this now that we hold the s_lock. */
1418 if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK))
1419 goto ack_done;
1420
1421 /* Ignore invalid responses. */ 1419 /* Ignore invalid responses. */
1422 if (qib_cmp24(psn, qp->s_next_psn) >= 0) 1420 if (qib_cmp24(psn, qp->s_next_psn) >= 0)
1423 goto ack_done; 1421 goto ack_done;
@@ -1661,9 +1659,6 @@ static int qib_rc_rcv_error(struct qib_other_headers *ohdr,
1661 ibp->n_rc_dupreq++; 1659 ibp->n_rc_dupreq++;
1662 1660
1663 spin_lock_irqsave(&qp->s_lock, flags); 1661 spin_lock_irqsave(&qp->s_lock, flags);
1664 /* Double check we can process this now that we hold the s_lock. */
1665 if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK))
1666 goto unlock_done;
1667 1662
1668 for (i = qp->r_head_ack_queue; ; i = prev) { 1663 for (i = qp->r_head_ack_queue; ; i = prev) {
1669 if (i == qp->s_tail_ack_queue) 1664 if (i == qp->s_tail_ack_queue)
@@ -1878,9 +1873,6 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr,
1878 psn = be32_to_cpu(ohdr->bth[2]); 1873 psn = be32_to_cpu(ohdr->bth[2]);
1879 opcode >>= 24; 1874 opcode >>= 24;
1880 1875
1881 /* Prevent simultaneous processing after APM on different CPUs */
1882 spin_lock(&qp->r_lock);
1883
1884 /* 1876 /*
1885 * Process responses (ACKs) before anything else. Note that the 1877 * Process responses (ACKs) before anything else. Note that the
1886 * packet sequence number will be for something in the send work 1878 * packet sequence number will be for something in the send work
@@ -1891,14 +1883,14 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr,
1891 opcode <= OP(ATOMIC_ACKNOWLEDGE)) { 1883 opcode <= OP(ATOMIC_ACKNOWLEDGE)) {
1892 qib_rc_rcv_resp(ibp, ohdr, data, tlen, qp, opcode, psn, 1884 qib_rc_rcv_resp(ibp, ohdr, data, tlen, qp, opcode, psn,
1893 hdrsize, pmtu, rcd); 1885 hdrsize, pmtu, rcd);
1894 goto runlock; 1886 return;
1895 } 1887 }
1896 1888
1897 /* Compute 24 bits worth of difference. */ 1889 /* Compute 24 bits worth of difference. */
1898 diff = qib_cmp24(psn, qp->r_psn); 1890 diff = qib_cmp24(psn, qp->r_psn);
1899 if (unlikely(diff)) { 1891 if (unlikely(diff)) {
1900 if (qib_rc_rcv_error(ohdr, data, qp, opcode, psn, diff, rcd)) 1892 if (qib_rc_rcv_error(ohdr, data, qp, opcode, psn, diff, rcd))
1901 goto runlock; 1893 return;
1902 goto send_ack; 1894 goto send_ack;
1903 } 1895 }
1904 1896
@@ -2090,9 +2082,6 @@ send_last:
2090 if (next > QIB_MAX_RDMA_ATOMIC) 2082 if (next > QIB_MAX_RDMA_ATOMIC)
2091 next = 0; 2083 next = 0;
2092 spin_lock_irqsave(&qp->s_lock, flags); 2084 spin_lock_irqsave(&qp->s_lock, flags);
2093 /* Double check we can process this while holding the s_lock. */
2094 if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK))
2095 goto srunlock;
2096 if (unlikely(next == qp->s_tail_ack_queue)) { 2085 if (unlikely(next == qp->s_tail_ack_queue)) {
2097 if (!qp->s_ack_queue[next].sent) 2086 if (!qp->s_ack_queue[next].sent)
2098 goto nack_inv_unlck; 2087 goto nack_inv_unlck;
@@ -2146,7 +2135,7 @@ send_last:
2146 qp->s_flags |= QIB_S_RESP_PENDING; 2135 qp->s_flags |= QIB_S_RESP_PENDING;
2147 qib_schedule_send(qp); 2136 qib_schedule_send(qp);
2148 2137
2149 goto srunlock; 2138 goto sunlock;
2150 } 2139 }
2151 2140
2152 case OP(COMPARE_SWAP): 2141 case OP(COMPARE_SWAP):
@@ -2165,9 +2154,6 @@ send_last:
2165 if (next > QIB_MAX_RDMA_ATOMIC) 2154 if (next > QIB_MAX_RDMA_ATOMIC)
2166 next = 0; 2155 next = 0;
2167 spin_lock_irqsave(&qp->s_lock, flags); 2156 spin_lock_irqsave(&qp->s_lock, flags);
2168 /* Double check we can process this while holding the s_lock. */
2169 if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK))
2170 goto srunlock;
2171 if (unlikely(next == qp->s_tail_ack_queue)) { 2157 if (unlikely(next == qp->s_tail_ack_queue)) {
2172 if (!qp->s_ack_queue[next].sent) 2158 if (!qp->s_ack_queue[next].sent)
2173 goto nack_inv_unlck; 2159 goto nack_inv_unlck;
@@ -2213,7 +2199,7 @@ send_last:
2213 qp->s_flags |= QIB_S_RESP_PENDING; 2199 qp->s_flags |= QIB_S_RESP_PENDING;
2214 qib_schedule_send(qp); 2200 qib_schedule_send(qp);
2215 2201
2216 goto srunlock; 2202 goto sunlock;
2217 } 2203 }
2218 2204
2219 default: 2205 default:
@@ -2227,7 +2213,7 @@ send_last:
2227 /* Send an ACK if requested or required. */ 2213 /* Send an ACK if requested or required. */
2228 if (psn & (1 << 31)) 2214 if (psn & (1 << 31))
2229 goto send_ack; 2215 goto send_ack;
2230 goto runlock; 2216 return;
2231 2217
2232rnr_nak: 2218rnr_nak:
2233 qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; 2219 qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer;
@@ -2238,7 +2224,7 @@ rnr_nak:
2238 atomic_inc(&qp->refcount); 2224 atomic_inc(&qp->refcount);
2239 list_add_tail(&qp->rspwait, &rcd->qp_wait_list); 2225 list_add_tail(&qp->rspwait, &rcd->qp_wait_list);
2240 } 2226 }
2241 goto runlock; 2227 return;
2242 2228
2243nack_op_err: 2229nack_op_err:
2244 qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); 2230 qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
@@ -2250,7 +2236,7 @@ nack_op_err:
2250 atomic_inc(&qp->refcount); 2236 atomic_inc(&qp->refcount);
2251 list_add_tail(&qp->rspwait, &rcd->qp_wait_list); 2237 list_add_tail(&qp->rspwait, &rcd->qp_wait_list);
2252 } 2238 }
2253 goto runlock; 2239 return;
2254 2240
2255nack_inv_unlck: 2241nack_inv_unlck:
2256 spin_unlock_irqrestore(&qp->s_lock, flags); 2242 spin_unlock_irqrestore(&qp->s_lock, flags);
@@ -2264,7 +2250,7 @@ nack_inv:
2264 atomic_inc(&qp->refcount); 2250 atomic_inc(&qp->refcount);
2265 list_add_tail(&qp->rspwait, &rcd->qp_wait_list); 2251 list_add_tail(&qp->rspwait, &rcd->qp_wait_list);
2266 } 2252 }
2267 goto runlock; 2253 return;
2268 2254
2269nack_acc_unlck: 2255nack_acc_unlck:
2270 spin_unlock_irqrestore(&qp->s_lock, flags); 2256 spin_unlock_irqrestore(&qp->s_lock, flags);
@@ -2274,13 +2260,6 @@ nack_acc:
2274 qp->r_ack_psn = qp->r_psn; 2260 qp->r_ack_psn = qp->r_psn;
2275send_ack: 2261send_ack:
2276 qib_send_rc_ack(qp); 2262 qib_send_rc_ack(qp);
2277runlock:
2278 spin_unlock(&qp->r_lock);
2279 return;
2280
2281srunlock:
2282 spin_unlock_irqrestore(&qp->s_lock, flags);
2283 spin_unlock(&qp->r_lock);
2284 return; 2263 return;
2285 2264
2286sunlock: 2265sunlock: