diff options
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_rc.c')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_rc.c | 47 |
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 | */ |
873 | static void qib_restart_rc(struct qib_qp *qp, u32 psn, int wait) | 873 | static 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 | ||
2232 | rnr_nak: | 2218 | rnr_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 | ||
2243 | nack_op_err: | 2229 | nack_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 | ||
2255 | nack_inv_unlck: | 2241 | nack_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 | ||
2269 | nack_acc_unlck: | 2255 | nack_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; |
2275 | send_ack: | 2261 | send_ack: |
2276 | qib_send_rc_ack(qp); | 2262 | qib_send_rc_ack(qp); |
2277 | runlock: | ||
2278 | spin_unlock(&qp->r_lock); | ||
2279 | return; | ||
2280 | |||
2281 | srunlock: | ||
2282 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
2283 | spin_unlock(&qp->r_lock); | ||
2284 | return; | 2263 | return; |
2285 | 2264 | ||
2286 | sunlock: | 2265 | sunlock: |