.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ |
---|
| 2 | +/* |
---|
| 3 | + * Copyright(c) 2016 - 2020 Intel Corporation. |
---|
| 4 | + */ |
---|
| 5 | + |
---|
1 | 6 | #ifndef DEF_RDMAVT_INCQP_H |
---|
2 | 7 | #define DEF_RDMAVT_INCQP_H |
---|
3 | | - |
---|
4 | | -/* |
---|
5 | | - * Copyright(c) 2016 - 2018 Intel Corporation. |
---|
6 | | - * |
---|
7 | | - * This file is provided under a dual BSD/GPLv2 license. When using or |
---|
8 | | - * redistributing this file, you may do so under either license. |
---|
9 | | - * |
---|
10 | | - * GPL LICENSE SUMMARY |
---|
11 | | - * |
---|
12 | | - * This program is free software; you can redistribute it and/or modify |
---|
13 | | - * it under the terms of version 2 of the GNU General Public License as |
---|
14 | | - * published by the Free Software Foundation. |
---|
15 | | - * |
---|
16 | | - * This program is distributed in the hope that it will be useful, but |
---|
17 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
18 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
19 | | - * General Public License for more details. |
---|
20 | | - * |
---|
21 | | - * BSD LICENSE |
---|
22 | | - * |
---|
23 | | - * Redistribution and use in source and binary forms, with or without |
---|
24 | | - * modification, are permitted provided that the following conditions |
---|
25 | | - * are met: |
---|
26 | | - * |
---|
27 | | - * - Redistributions of source code must retain the above copyright |
---|
28 | | - * notice, this list of conditions and the following disclaimer. |
---|
29 | | - * - Redistributions in binary form must reproduce the above copyright |
---|
30 | | - * notice, this list of conditions and the following disclaimer in |
---|
31 | | - * the documentation and/or other materials provided with the |
---|
32 | | - * distribution. |
---|
33 | | - * - Neither the name of Intel Corporation nor the names of its |
---|
34 | | - * contributors may be used to endorse or promote products derived |
---|
35 | | - * from this software without specific prior written permission. |
---|
36 | | - * |
---|
37 | | - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
---|
38 | | - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
---|
39 | | - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
---|
40 | | - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
---|
41 | | - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
---|
42 | | - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
---|
43 | | - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
---|
44 | | - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
---|
45 | | - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
---|
46 | | - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
---|
47 | | - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
48 | | - * |
---|
49 | | - */ |
---|
50 | 8 | |
---|
51 | 9 | #include <rdma/rdma_vt.h> |
---|
52 | 10 | #include <rdma/ib_pack.h> |
---|
53 | 11 | #include <rdma/ib_verbs.h> |
---|
54 | 12 | #include <rdma/rdmavt_cq.h> |
---|
| 13 | +#include <rdma/rvt-abi.h> |
---|
55 | 14 | /* |
---|
56 | 15 | * Atomic bit definitions for r_aflags. |
---|
57 | 16 | */ |
---|
.. | .. |
---|
66 | 25 | #define RVT_R_RSP_NAK 0x04 |
---|
67 | 26 | #define RVT_R_RSP_SEND 0x08 |
---|
68 | 27 | #define RVT_R_COMM_EST 0x10 |
---|
| 28 | + |
---|
| 29 | +/* |
---|
| 30 | + * If a packet's QP[23:16] bits match this value, then it is |
---|
| 31 | + * a PSM packet and the hardware will expect a KDETH header |
---|
| 32 | + * following the BTH. |
---|
| 33 | + */ |
---|
| 34 | +#define RVT_KDETH_QP_PREFIX 0x80 |
---|
| 35 | +#define RVT_KDETH_QP_SUFFIX 0xffff |
---|
| 36 | +#define RVT_KDETH_QP_PREFIX_MASK 0x00ff0000 |
---|
| 37 | +#define RVT_KDETH_QP_PREFIX_SHIFT 16 |
---|
| 38 | +#define RVT_KDETH_QP_BASE (u32)(RVT_KDETH_QP_PREFIX << \ |
---|
| 39 | + RVT_KDETH_QP_PREFIX_SHIFT) |
---|
| 40 | +#define RVT_KDETH_QP_MAX (u32)(RVT_KDETH_QP_BASE + RVT_KDETH_QP_SUFFIX) |
---|
| 41 | + |
---|
| 42 | +/* |
---|
| 43 | + * If a packet's LNH == BTH and DEST QPN[23:16] in the BTH match this |
---|
| 44 | + * prefix value, then it is an AIP packet with a DETH containing the entropy |
---|
| 45 | + * value in byte 4 following the BTH. |
---|
| 46 | + */ |
---|
| 47 | +#define RVT_AIP_QP_PREFIX 0x81 |
---|
| 48 | +#define RVT_AIP_QP_SUFFIX 0xffff |
---|
| 49 | +#define RVT_AIP_QP_PREFIX_MASK 0x00ff0000 |
---|
| 50 | +#define RVT_AIP_QP_PREFIX_SHIFT 16 |
---|
| 51 | +#define RVT_AIP_QP_BASE (u32)(RVT_AIP_QP_PREFIX << \ |
---|
| 52 | + RVT_AIP_QP_PREFIX_SHIFT) |
---|
| 53 | +#define RVT_AIP_QPN_MAX BIT(RVT_AIP_QP_PREFIX_SHIFT) |
---|
| 54 | +#define RVT_AIP_QP_MAX (u32)(RVT_AIP_QP_BASE + RVT_AIP_QPN_MAX - 1) |
---|
69 | 55 | |
---|
70 | 56 | /* |
---|
71 | 57 | * Bit definitions for s_flags. |
---|
.. | .. |
---|
83 | 69 | * RVT_S_WAIT_DMA - waiting for send DMA queue to drain before generating |
---|
84 | 70 | * next send completion entry not via send DMA |
---|
85 | 71 | * RVT_S_WAIT_PIO - waiting for a send buffer to be available |
---|
86 | | - * RVT_S_WAIT_PIO_DRAIN - waiting for a qp to drain pio packets |
---|
87 | 72 | * RVT_S_WAIT_TX - waiting for a struct verbs_txreq to be available |
---|
88 | 73 | * RVT_S_WAIT_DMA_DESC - waiting for DMA descriptors to be available |
---|
89 | 74 | * RVT_S_WAIT_KMEM - waiting for kernel memory to be available |
---|
.. | .. |
---|
157 | 142 | #define RVT_SEND_RESERVE_USED IB_SEND_RESERVED_START |
---|
158 | 143 | #define RVT_SEND_COMPLETION_ONLY (IB_SEND_RESERVED_START << 1) |
---|
159 | 144 | |
---|
| 145 | +/** |
---|
| 146 | + * rvt_ud_wr - IB UD work plus AH cache |
---|
| 147 | + * @wr: valid IB work request |
---|
| 148 | + * @attr: pointer to an allocated AH attribute |
---|
| 149 | + * |
---|
| 150 | + * Special case the UD WR so we can keep track of the AH attributes. |
---|
| 151 | + * |
---|
| 152 | + * NOTE: This data structure is stricly ordered wr then attr. I.e the attr |
---|
| 153 | + * MUST come after wr. The ib_ud_wr is sized and copied in rvt_post_one_wr. |
---|
| 154 | + * The copy assumes that wr is first. |
---|
| 155 | + */ |
---|
| 156 | +struct rvt_ud_wr { |
---|
| 157 | + struct ib_ud_wr wr; |
---|
| 158 | + struct rdma_ah_attr *attr; |
---|
| 159 | +}; |
---|
| 160 | + |
---|
160 | 161 | /* |
---|
161 | 162 | * Send work request queue entry. |
---|
162 | 163 | * The size of the sg_list is determined when the QP is created and stored |
---|
.. | .. |
---|
165 | 166 | struct rvt_swqe { |
---|
166 | 167 | union { |
---|
167 | 168 | struct ib_send_wr wr; /* don't use wr.sg_list */ |
---|
168 | | - struct ib_ud_wr ud_wr; |
---|
| 169 | + struct rvt_ud_wr ud_wr; |
---|
169 | 170 | struct ib_reg_wr reg_wr; |
---|
170 | 171 | struct ib_rdma_wr rdma_wr; |
---|
171 | 172 | struct ib_atomic_wr atomic_wr; |
---|
.. | .. |
---|
174 | 175 | u32 lpsn; /* last packet sequence number */ |
---|
175 | 176 | u32 ssn; /* send sequence number */ |
---|
176 | 177 | u32 length; /* total length of data in sg_list */ |
---|
177 | | - struct rvt_sge sg_list[0]; |
---|
| 178 | + void *priv; /* driver dependent field */ |
---|
| 179 | + struct rvt_sge sg_list[]; |
---|
178 | 180 | }; |
---|
179 | 181 | |
---|
180 | | -/* |
---|
181 | | - * Receive work request queue entry. |
---|
182 | | - * The size of the sg_list is determined when the QP (or SRQ) is created |
---|
183 | | - * and stored in qp->r_rq.max_sge (or srq->rq.max_sge). |
---|
| 182 | +/** |
---|
| 183 | + * struct rvt_krwq - kernel struct receive work request |
---|
| 184 | + * @p_lock: lock to protect producer of the kernel buffer |
---|
| 185 | + * @head: index of next entry to fill |
---|
| 186 | + * @c_lock:lock to protect consumer of the kernel buffer |
---|
| 187 | + * @tail: index of next entry to pull |
---|
| 188 | + * @count: count is aproximate of total receive enteries posted |
---|
| 189 | + * @rvt_rwqe: struct of receive work request queue entry |
---|
| 190 | + * |
---|
| 191 | + * This structure is used to contain the head pointer, |
---|
| 192 | + * tail pointer and receive work queue entries for kernel |
---|
| 193 | + * mode user. |
---|
184 | 194 | */ |
---|
185 | | -struct rvt_rwqe { |
---|
186 | | - u64 wr_id; |
---|
187 | | - u8 num_sge; |
---|
188 | | - struct ib_sge sg_list[0]; |
---|
189 | | -}; |
---|
190 | | - |
---|
191 | | -/* |
---|
192 | | - * This structure is used to contain the head pointer, tail pointer, |
---|
193 | | - * and receive work queue entries as a single memory allocation so |
---|
194 | | - * it can be mmap'ed into user space. |
---|
195 | | - * Note that the wq array elements are variable size so you can't |
---|
196 | | - * just index into the array to get the N'th element; |
---|
197 | | - * use get_rwqe_ptr() instead. |
---|
198 | | - */ |
---|
199 | | -struct rvt_rwq { |
---|
| 195 | +struct rvt_krwq { |
---|
| 196 | + spinlock_t p_lock; /* protect producer */ |
---|
200 | 197 | u32 head; /* new work requests posted to the head */ |
---|
| 198 | + |
---|
| 199 | + /* protect consumer */ |
---|
| 200 | + spinlock_t c_lock ____cacheline_aligned_in_smp; |
---|
201 | 201 | u32 tail; /* receives pull requests from here. */ |
---|
202 | | - struct rvt_rwqe wq[0]; |
---|
| 202 | + u32 count; /* approx count of receive entries posted */ |
---|
| 203 | + struct rvt_rwqe *curr_wq; |
---|
| 204 | + struct rvt_rwqe wq[]; |
---|
203 | 205 | }; |
---|
| 206 | + |
---|
| 207 | +/* |
---|
| 208 | + * rvt_get_swqe_ah - Return the pointer to the struct rvt_ah |
---|
| 209 | + * @swqe: valid Send WQE |
---|
| 210 | + * |
---|
| 211 | + */ |
---|
| 212 | +static inline struct rvt_ah *rvt_get_swqe_ah(struct rvt_swqe *swqe) |
---|
| 213 | +{ |
---|
| 214 | + return ibah_to_rvtah(swqe->ud_wr.wr.ah); |
---|
| 215 | +} |
---|
| 216 | + |
---|
| 217 | +/** |
---|
| 218 | + * rvt_get_swqe_ah_attr - Return the cached ah attribute information |
---|
| 219 | + * @swqe: valid Send WQE |
---|
| 220 | + * |
---|
| 221 | + */ |
---|
| 222 | +static inline struct rdma_ah_attr *rvt_get_swqe_ah_attr(struct rvt_swqe *swqe) |
---|
| 223 | +{ |
---|
| 224 | + return swqe->ud_wr.attr; |
---|
| 225 | +} |
---|
| 226 | + |
---|
| 227 | +/** |
---|
| 228 | + * rvt_get_swqe_remote_qpn - Access the remote QPN value |
---|
| 229 | + * @swqe: valid Send WQE |
---|
| 230 | + * |
---|
| 231 | + */ |
---|
| 232 | +static inline u32 rvt_get_swqe_remote_qpn(struct rvt_swqe *swqe) |
---|
| 233 | +{ |
---|
| 234 | + return swqe->ud_wr.wr.remote_qpn; |
---|
| 235 | +} |
---|
| 236 | + |
---|
| 237 | +/** |
---|
| 238 | + * rvt_get_swqe_remote_qkey - Acces the remote qkey value |
---|
| 239 | + * @swqe: valid Send WQE |
---|
| 240 | + * |
---|
| 241 | + */ |
---|
| 242 | +static inline u32 rvt_get_swqe_remote_qkey(struct rvt_swqe *swqe) |
---|
| 243 | +{ |
---|
| 244 | + return swqe->ud_wr.wr.remote_qkey; |
---|
| 245 | +} |
---|
| 246 | + |
---|
| 247 | +/** |
---|
| 248 | + * rvt_get_swqe_pkey_index - Access the pkey index |
---|
| 249 | + * @swqe: valid Send WQE |
---|
| 250 | + * |
---|
| 251 | + */ |
---|
| 252 | +static inline u16 rvt_get_swqe_pkey_index(struct rvt_swqe *swqe) |
---|
| 253 | +{ |
---|
| 254 | + return swqe->ud_wr.wr.pkey_index; |
---|
| 255 | +} |
---|
204 | 256 | |
---|
205 | 257 | struct rvt_rq { |
---|
206 | 258 | struct rvt_rwq *wq; |
---|
| 259 | + struct rvt_krwq *kwq; |
---|
207 | 260 | u32 size; /* size of RWQE array */ |
---|
208 | 261 | u8 max_sge; |
---|
209 | 262 | /* protect changes in this struct */ |
---|
210 | 263 | spinlock_t lock ____cacheline_aligned_in_smp; |
---|
211 | 264 | }; |
---|
212 | 265 | |
---|
213 | | -/* |
---|
214 | | - * This structure is used by rvt_mmap() to validate an offset |
---|
215 | | - * when an mmap() request is made. The vm_area_struct then uses |
---|
216 | | - * this as its vm_private_data. |
---|
| 266 | +/** |
---|
| 267 | + * rvt_get_rq_count - count numbers of request work queue entries |
---|
| 268 | + * in circular buffer |
---|
| 269 | + * @rq: data structure for request queue entry |
---|
| 270 | + * @head: head indices of the circular buffer |
---|
| 271 | + * @tail: tail indices of the circular buffer |
---|
| 272 | + * |
---|
| 273 | + * Return - total number of entries in the Receive Queue |
---|
217 | 274 | */ |
---|
218 | | -struct rvt_mmap_info { |
---|
219 | | - struct list_head pending_mmaps; |
---|
220 | | - struct ib_ucontext *context; |
---|
221 | | - void *obj; |
---|
222 | | - __u64 offset; |
---|
223 | | - struct kref ref; |
---|
224 | | - unsigned size; |
---|
225 | | -}; |
---|
| 275 | + |
---|
| 276 | +static inline u32 rvt_get_rq_count(struct rvt_rq *rq, u32 head, u32 tail) |
---|
| 277 | +{ |
---|
| 278 | + u32 count = head - tail; |
---|
| 279 | + |
---|
| 280 | + if ((s32)count < 0) |
---|
| 281 | + count += rq->size; |
---|
| 282 | + return count; |
---|
| 283 | +} |
---|
226 | 284 | |
---|
227 | 285 | /* |
---|
228 | 286 | * This structure holds the information that the send tasklet needs |
---|
.. | .. |
---|
235 | 293 | u32 lpsn; |
---|
236 | 294 | u8 opcode; |
---|
237 | 295 | u8 sent; |
---|
| 296 | + void *priv; |
---|
238 | 297 | }; |
---|
239 | 298 | |
---|
240 | 299 | #define RC_QP_SCALING_INTERVAL 5 |
---|
.. | .. |
---|
244 | 303 | #define RVT_OPERATION_ATOMIC_SGE 0x00000004 |
---|
245 | 304 | #define RVT_OPERATION_LOCAL 0x00000008 |
---|
246 | 305 | #define RVT_OPERATION_USE_RESERVE 0x00000010 |
---|
| 306 | +#define RVT_OPERATION_IGN_RNR_CNT 0x00000020 |
---|
247 | 307 | |
---|
248 | 308 | #define RVT_OPERATION_MAX (IB_WR_RESERVED10 + 1) |
---|
249 | 309 | |
---|
.. | .. |
---|
373 | 433 | u8 s_rnr_retry; /* requester RNR retry counter */ |
---|
374 | 434 | u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ |
---|
375 | 435 | u8 s_tail_ack_queue; /* index into s_ack_queue[] */ |
---|
| 436 | + u8 s_acked_ack_queue; /* index into s_ack_queue[] */ |
---|
376 | 437 | |
---|
377 | 438 | struct rvt_sge_state s_ack_rdma_sge; |
---|
378 | 439 | struct timer_list s_timer; |
---|
.. | .. |
---|
383 | 444 | /* |
---|
384 | 445 | * This sge list MUST be last. Do not add anything below here. |
---|
385 | 446 | */ |
---|
386 | | - struct rvt_sge r_sg_list[0] /* verified SGEs */ |
---|
| 447 | + struct rvt_sge r_sg_list[] /* verified SGEs */ |
---|
387 | 448 | ____cacheline_aligned_in_smp; |
---|
388 | 449 | }; |
---|
389 | 450 | |
---|
.. | .. |
---|
394 | 455 | /* send signal when number of RWQEs < limit */ |
---|
395 | 456 | u32 limit; |
---|
396 | 457 | }; |
---|
| 458 | + |
---|
| 459 | +static inline struct rvt_srq *ibsrq_to_rvtsrq(struct ib_srq *ibsrq) |
---|
| 460 | +{ |
---|
| 461 | + return container_of(ibsrq, struct rvt_srq, ibsrq); |
---|
| 462 | +} |
---|
| 463 | + |
---|
| 464 | +static inline struct rvt_qp *ibqp_to_rvtqp(struct ib_qp *ibqp) |
---|
| 465 | +{ |
---|
| 466 | + return container_of(ibqp, struct rvt_qp, ibqp); |
---|
| 467 | +} |
---|
397 | 468 | |
---|
398 | 469 | #define RVT_QPN_MAX BIT(24) |
---|
399 | 470 | #define RVT_QPNMAP_ENTRIES (RVT_QPN_MAX / PAGE_SIZE / BITS_PER_BYTE) |
---|
.. | .. |
---|
473 | 544 | static inline struct rvt_rwqe *rvt_get_rwqe_ptr(struct rvt_rq *rq, unsigned n) |
---|
474 | 545 | { |
---|
475 | 546 | return (struct rvt_rwqe *) |
---|
476 | | - ((char *)rq->wq->wq + |
---|
| 547 | + ((char *)rq->kwq->curr_wq + |
---|
477 | 548 | (sizeof(struct rvt_rwqe) + |
---|
478 | 549 | rq->max_sge * sizeof(struct ib_sge)) * n); |
---|
479 | 550 | } |
---|
.. | .. |
---|
541 | 612 | /** |
---|
542 | 613 | * rvt_qp_wqe_unreserve - clean reserved operation |
---|
543 | 614 | * @qp - the rvt qp |
---|
544 | | - * @wqe - the send wqe |
---|
| 615 | + * @flags - send wqe flags |
---|
545 | 616 | * |
---|
546 | 617 | * This decrements the reserve use count. |
---|
547 | 618 | * |
---|
.. | .. |
---|
553 | 624 | * the compiler does not juggle the order of the s_last |
---|
554 | 625 | * ring index and the decrementing of s_reserved_used. |
---|
555 | 626 | */ |
---|
556 | | -static inline void rvt_qp_wqe_unreserve( |
---|
557 | | - struct rvt_qp *qp, |
---|
558 | | - struct rvt_swqe *wqe) |
---|
| 627 | +static inline void rvt_qp_wqe_unreserve(struct rvt_qp *qp, int flags) |
---|
559 | 628 | { |
---|
560 | | - if (unlikely(wqe->wr.send_flags & RVT_SEND_RESERVE_USED)) { |
---|
| 629 | + if (unlikely(flags & RVT_SEND_RESERVE_USED)) { |
---|
561 | 630 | atomic_dec(&qp->s_reserved_used); |
---|
562 | 631 | /* insure no compiler re-order up to s_last change */ |
---|
563 | 632 | smp_mb__after_atomic(); |
---|
.. | .. |
---|
565 | 634 | } |
---|
566 | 635 | |
---|
567 | 636 | extern const enum ib_wc_opcode ib_rvt_wc_opcode[]; |
---|
568 | | - |
---|
569 | | -/** |
---|
570 | | - * rvt_qp_swqe_complete() - insert send completion |
---|
571 | | - * @qp - the qp |
---|
572 | | - * @wqe - the send wqe |
---|
573 | | - * @status - completion status |
---|
574 | | - * |
---|
575 | | - * Insert a send completion into the completion |
---|
576 | | - * queue if the qp indicates it should be done. |
---|
577 | | - * |
---|
578 | | - * See IBTA 10.7.3.1 for info on completion |
---|
579 | | - * control. |
---|
580 | | - */ |
---|
581 | | -static inline void rvt_qp_swqe_complete( |
---|
582 | | - struct rvt_qp *qp, |
---|
583 | | - struct rvt_swqe *wqe, |
---|
584 | | - enum ib_wc_opcode opcode, |
---|
585 | | - enum ib_wc_status status) |
---|
586 | | -{ |
---|
587 | | - if (unlikely(wqe->wr.send_flags & RVT_SEND_RESERVE_USED)) |
---|
588 | | - return; |
---|
589 | | - if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) || |
---|
590 | | - (wqe->wr.send_flags & IB_SEND_SIGNALED) || |
---|
591 | | - status != IB_WC_SUCCESS) { |
---|
592 | | - struct ib_wc wc; |
---|
593 | | - |
---|
594 | | - memset(&wc, 0, sizeof(wc)); |
---|
595 | | - wc.wr_id = wqe->wr.wr_id; |
---|
596 | | - wc.status = status; |
---|
597 | | - wc.opcode = opcode; |
---|
598 | | - wc.qp = &qp->ibqp; |
---|
599 | | - wc.byte_len = wqe->length; |
---|
600 | | - rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, |
---|
601 | | - status != IB_WC_SUCCESS); |
---|
602 | | - } |
---|
603 | | -} |
---|
604 | 637 | |
---|
605 | 638 | /* |
---|
606 | 639 | * Compare the lower 24 bits of the msn values. |
---|
.. | .. |
---|
611 | 644 | return (((int)a) - ((int)b)) << 8; |
---|
612 | 645 | } |
---|
613 | 646 | |
---|
614 | | -/** |
---|
615 | | - * rvt_compute_aeth - compute the AETH (syndrome + MSN) |
---|
616 | | - * @qp: the queue pair to compute the AETH for |
---|
617 | | - * |
---|
618 | | - * Returns the AETH. |
---|
619 | | - */ |
---|
620 | 647 | __be32 rvt_compute_aeth(struct rvt_qp *qp); |
---|
621 | 648 | |
---|
622 | | -/** |
---|
623 | | - * rvt_get_credit - flush the send work queue of a QP |
---|
624 | | - * @qp: the qp who's send work queue to flush |
---|
625 | | - * @aeth: the Acknowledge Extended Transport Header |
---|
626 | | - * |
---|
627 | | - * The QP s_lock should be held. |
---|
628 | | - */ |
---|
629 | 649 | void rvt_get_credit(struct rvt_qp *qp, u32 aeth); |
---|
630 | 650 | |
---|
| 651 | +u32 rvt_restart_sge(struct rvt_sge_state *ss, struct rvt_swqe *wqe, u32 len); |
---|
| 652 | + |
---|
631 | 653 | /** |
---|
| 654 | + * rvt_div_round_up_mtu - round up divide |
---|
632 | 655 | * @qp - the qp pair |
---|
633 | 656 | * @len - the length |
---|
634 | 657 | * |
---|
.. | .. |
---|
664 | 687 | return usecs_to_jiffies(1U << timeout) * 4096UL / 1000UL; |
---|
665 | 688 | } |
---|
666 | 689 | |
---|
| 690 | +/** |
---|
| 691 | + * rvt_lookup_qpn - return the QP with the given QPN |
---|
| 692 | + * @ibp: the ibport |
---|
| 693 | + * @qpn: the QP number to look up |
---|
| 694 | + * |
---|
| 695 | + * The caller must hold the rcu_read_lock(), and keep the lock until |
---|
| 696 | + * the returned qp is no longer in use. |
---|
| 697 | + */ |
---|
| 698 | +static inline struct rvt_qp *rvt_lookup_qpn(struct rvt_dev_info *rdi, |
---|
| 699 | + struct rvt_ibport *rvp, |
---|
| 700 | + u32 qpn) __must_hold(RCU) |
---|
| 701 | +{ |
---|
| 702 | + struct rvt_qp *qp = NULL; |
---|
| 703 | + |
---|
| 704 | + if (unlikely(qpn <= 1)) { |
---|
| 705 | + qp = rcu_dereference(rvp->qp[qpn]); |
---|
| 706 | + } else { |
---|
| 707 | + u32 n = hash_32(qpn, rdi->qp_dev->qp_table_bits); |
---|
| 708 | + |
---|
| 709 | + for (qp = rcu_dereference(rdi->qp_dev->qp_table[n]); qp; |
---|
| 710 | + qp = rcu_dereference(qp->next)) |
---|
| 711 | + if (qp->ibqp.qp_num == qpn) |
---|
| 712 | + break; |
---|
| 713 | + } |
---|
| 714 | + return qp; |
---|
| 715 | +} |
---|
| 716 | + |
---|
| 717 | +/** |
---|
| 718 | + * rvt_mod_retry_timer - mod a retry timer |
---|
| 719 | + * @qp - the QP |
---|
| 720 | + * @shift - timeout shift to wait for multiple packets |
---|
| 721 | + * Modify a potentially already running retry timer |
---|
| 722 | + */ |
---|
| 723 | +static inline void rvt_mod_retry_timer_ext(struct rvt_qp *qp, u8 shift) |
---|
| 724 | +{ |
---|
| 725 | + struct ib_qp *ibqp = &qp->ibqp; |
---|
| 726 | + struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); |
---|
| 727 | + |
---|
| 728 | + lockdep_assert_held(&qp->s_lock); |
---|
| 729 | + qp->s_flags |= RVT_S_TIMER; |
---|
| 730 | + /* 4.096 usec. * (1 << qp->timeout) */ |
---|
| 731 | + mod_timer(&qp->s_timer, jiffies + rdi->busy_jiffies + |
---|
| 732 | + (qp->timeout_jiffies << shift)); |
---|
| 733 | +} |
---|
| 734 | + |
---|
| 735 | +static inline void rvt_mod_retry_timer(struct rvt_qp *qp) |
---|
| 736 | +{ |
---|
| 737 | + return rvt_mod_retry_timer_ext(qp, 0); |
---|
| 738 | +} |
---|
| 739 | + |
---|
| 740 | +/** |
---|
| 741 | + * rvt_put_qp_swqe - drop refs held by swqe |
---|
| 742 | + * @qp: the send qp |
---|
| 743 | + * @wqe: the send wqe |
---|
| 744 | + * |
---|
| 745 | + * This drops any references held by the swqe |
---|
| 746 | + */ |
---|
| 747 | +static inline void rvt_put_qp_swqe(struct rvt_qp *qp, struct rvt_swqe *wqe) |
---|
| 748 | +{ |
---|
| 749 | + rvt_put_swqe(wqe); |
---|
| 750 | + if (qp->allowed_ops == IB_OPCODE_UD) |
---|
| 751 | + rdma_destroy_ah_attr(wqe->ud_wr.attr); |
---|
| 752 | +} |
---|
| 753 | + |
---|
| 754 | +/** |
---|
| 755 | + * rvt_qp_sqwe_incr - increment ring index |
---|
| 756 | + * @qp: the qp |
---|
| 757 | + * @val: the starting value |
---|
| 758 | + * |
---|
| 759 | + * Return: the new value wrapping as appropriate |
---|
| 760 | + */ |
---|
| 761 | +static inline u32 |
---|
| 762 | +rvt_qp_swqe_incr(struct rvt_qp *qp, u32 val) |
---|
| 763 | +{ |
---|
| 764 | + if (++val >= qp->s_size) |
---|
| 765 | + val = 0; |
---|
| 766 | + return val; |
---|
| 767 | +} |
---|
| 768 | + |
---|
| 769 | +int rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err); |
---|
| 770 | + |
---|
| 771 | +/** |
---|
| 772 | + * rvt_recv_cq - add a new entry to completion queue |
---|
| 773 | + * by receive queue |
---|
| 774 | + * @qp: receive queue |
---|
| 775 | + * @wc: work completion entry to add |
---|
| 776 | + * @solicited: true if @entry is solicited |
---|
| 777 | + * |
---|
| 778 | + * This is wrapper function for rvt_enter_cq function call by |
---|
| 779 | + * receive queue. If rvt_cq_enter return false, it means cq is |
---|
| 780 | + * full and the qp is put into error state. |
---|
| 781 | + */ |
---|
| 782 | +static inline void rvt_recv_cq(struct rvt_qp *qp, struct ib_wc *wc, |
---|
| 783 | + bool solicited) |
---|
| 784 | +{ |
---|
| 785 | + struct rvt_cq *cq = ibcq_to_rvtcq(qp->ibqp.recv_cq); |
---|
| 786 | + |
---|
| 787 | + if (unlikely(!rvt_cq_enter(cq, wc, solicited))) |
---|
| 788 | + rvt_error_qp(qp, IB_WC_LOC_QP_OP_ERR); |
---|
| 789 | +} |
---|
| 790 | + |
---|
| 791 | +/** |
---|
| 792 | + * rvt_send_cq - add a new entry to completion queue |
---|
| 793 | + * by send queue |
---|
| 794 | + * @qp: send queue |
---|
| 795 | + * @wc: work completion entry to add |
---|
| 796 | + * @solicited: true if @entry is solicited |
---|
| 797 | + * |
---|
| 798 | + * This is wrapper function for rvt_enter_cq function call by |
---|
| 799 | + * send queue. If rvt_cq_enter return false, it means cq is |
---|
| 800 | + * full and the qp is put into error state. |
---|
| 801 | + */ |
---|
| 802 | +static inline void rvt_send_cq(struct rvt_qp *qp, struct ib_wc *wc, |
---|
| 803 | + bool solicited) |
---|
| 804 | +{ |
---|
| 805 | + struct rvt_cq *cq = ibcq_to_rvtcq(qp->ibqp.send_cq); |
---|
| 806 | + |
---|
| 807 | + if (unlikely(!rvt_cq_enter(cq, wc, solicited))) |
---|
| 808 | + rvt_error_qp(qp, IB_WC_LOC_QP_OP_ERR); |
---|
| 809 | +} |
---|
| 810 | + |
---|
| 811 | +/** |
---|
| 812 | + * rvt_qp_complete_swqe - insert send completion |
---|
| 813 | + * @qp - the qp |
---|
| 814 | + * @wqe - the send wqe |
---|
| 815 | + * @opcode - wc operation (driver dependent) |
---|
| 816 | + * @status - completion status |
---|
| 817 | + * |
---|
| 818 | + * Update the s_last information, and then insert a send |
---|
| 819 | + * completion into the completion |
---|
| 820 | + * queue if the qp indicates it should be done. |
---|
| 821 | + * |
---|
| 822 | + * See IBTA 10.7.3.1 for info on completion |
---|
| 823 | + * control. |
---|
| 824 | + * |
---|
| 825 | + * Return: new last |
---|
| 826 | + */ |
---|
| 827 | +static inline u32 |
---|
| 828 | +rvt_qp_complete_swqe(struct rvt_qp *qp, |
---|
| 829 | + struct rvt_swqe *wqe, |
---|
| 830 | + enum ib_wc_opcode opcode, |
---|
| 831 | + enum ib_wc_status status) |
---|
| 832 | +{ |
---|
| 833 | + bool need_completion; |
---|
| 834 | + u64 wr_id; |
---|
| 835 | + u32 byte_len, last; |
---|
| 836 | + int flags = wqe->wr.send_flags; |
---|
| 837 | + |
---|
| 838 | + rvt_qp_wqe_unreserve(qp, flags); |
---|
| 839 | + rvt_put_qp_swqe(qp, wqe); |
---|
| 840 | + |
---|
| 841 | + need_completion = |
---|
| 842 | + !(flags & RVT_SEND_RESERVE_USED) && |
---|
| 843 | + (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) || |
---|
| 844 | + (flags & IB_SEND_SIGNALED) || |
---|
| 845 | + status != IB_WC_SUCCESS); |
---|
| 846 | + if (need_completion) { |
---|
| 847 | + wr_id = wqe->wr.wr_id; |
---|
| 848 | + byte_len = wqe->length; |
---|
| 849 | + /* above fields required before writing s_last */ |
---|
| 850 | + } |
---|
| 851 | + last = rvt_qp_swqe_incr(qp, qp->s_last); |
---|
| 852 | + /* see rvt_qp_is_avail() */ |
---|
| 853 | + smp_store_release(&qp->s_last, last); |
---|
| 854 | + if (need_completion) { |
---|
| 855 | + struct ib_wc w = { |
---|
| 856 | + .wr_id = wr_id, |
---|
| 857 | + .status = status, |
---|
| 858 | + .opcode = opcode, |
---|
| 859 | + .qp = &qp->ibqp, |
---|
| 860 | + .byte_len = byte_len, |
---|
| 861 | + }; |
---|
| 862 | + rvt_send_cq(qp, &w, status != IB_WC_SUCCESS); |
---|
| 863 | + } |
---|
| 864 | + return last; |
---|
| 865 | +} |
---|
| 866 | + |
---|
667 | 867 | extern const int ib_rvt_state_ops[]; |
---|
668 | 868 | |
---|
669 | 869 | struct rvt_dev_info; |
---|
670 | 870 | int rvt_get_rwqe(struct rvt_qp *qp, bool wr_id_only); |
---|
671 | 871 | void rvt_comm_est(struct rvt_qp *qp); |
---|
672 | | -int rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err); |
---|
673 | 872 | void rvt_rc_error(struct rvt_qp *qp, enum ib_wc_status err); |
---|
674 | 873 | unsigned long rvt_rnr_tbl_to_usec(u32 index); |
---|
675 | 874 | enum hrtimer_restart rvt_rc_rnr_retry(struct hrtimer *t); |
---|
676 | 875 | void rvt_add_rnr_timer(struct rvt_qp *qp, u32 aeth); |
---|
677 | 876 | void rvt_del_timers_sync(struct rvt_qp *qp); |
---|
678 | 877 | void rvt_stop_rc_timers(struct rvt_qp *qp); |
---|
679 | | -void rvt_add_retry_timer(struct rvt_qp *qp); |
---|
| 878 | +void rvt_add_retry_timer_ext(struct rvt_qp *qp, u8 shift); |
---|
| 879 | +static inline void rvt_add_retry_timer(struct rvt_qp *qp) |
---|
| 880 | +{ |
---|
| 881 | + rvt_add_retry_timer_ext(qp, 0); |
---|
| 882 | +} |
---|
| 883 | + |
---|
| 884 | +void rvt_copy_sge(struct rvt_qp *qp, struct rvt_sge_state *ss, |
---|
| 885 | + void *data, u32 length, |
---|
| 886 | + bool release, bool copy_last); |
---|
| 887 | +void rvt_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe, |
---|
| 888 | + enum ib_wc_status status); |
---|
| 889 | +void rvt_ruc_loopback(struct rvt_qp *qp); |
---|
680 | 890 | |
---|
681 | 891 | /** |
---|
682 | 892 | * struct rvt_qp_iter - the iterator for QPs |
---|
.. | .. |
---|
700 | 910 | int n; |
---|
701 | 911 | }; |
---|
702 | 912 | |
---|
| 913 | +/** |
---|
| 914 | + * ib_cq_tail - Return tail index of cq buffer |
---|
| 915 | + * @send_cq - The cq for send |
---|
| 916 | + * |
---|
| 917 | + * This is called in qp_iter_print to get tail |
---|
| 918 | + * of cq buffer. |
---|
| 919 | + */ |
---|
| 920 | +static inline u32 ib_cq_tail(struct ib_cq *send_cq) |
---|
| 921 | +{ |
---|
| 922 | + struct rvt_cq *cq = ibcq_to_rvtcq(send_cq); |
---|
| 923 | + |
---|
| 924 | + return ibcq_to_rvtcq(send_cq)->ip ? |
---|
| 925 | + RDMA_READ_UAPI_ATOMIC(cq->queue->tail) : |
---|
| 926 | + ibcq_to_rvtcq(send_cq)->kqueue->tail; |
---|
| 927 | +} |
---|
| 928 | + |
---|
| 929 | +/** |
---|
| 930 | + * ib_cq_head - Return head index of cq buffer |
---|
| 931 | + * @send_cq - The cq for send |
---|
| 932 | + * |
---|
| 933 | + * This is called in qp_iter_print to get head |
---|
| 934 | + * of cq buffer. |
---|
| 935 | + */ |
---|
| 936 | +static inline u32 ib_cq_head(struct ib_cq *send_cq) |
---|
| 937 | +{ |
---|
| 938 | + struct rvt_cq *cq = ibcq_to_rvtcq(send_cq); |
---|
| 939 | + |
---|
| 940 | + return ibcq_to_rvtcq(send_cq)->ip ? |
---|
| 941 | + RDMA_READ_UAPI_ATOMIC(cq->queue->head) : |
---|
| 942 | + ibcq_to_rvtcq(send_cq)->kqueue->head; |
---|
| 943 | +} |
---|
| 944 | + |
---|
| 945 | +/** |
---|
| 946 | + * rvt_free_rq - free memory allocated for rvt_rq struct |
---|
| 947 | + * @rvt_rq: request queue data structure |
---|
| 948 | + * |
---|
| 949 | + * This function should only be called if the rvt_mmap_info() |
---|
| 950 | + * has not succeeded. |
---|
| 951 | + */ |
---|
| 952 | +static inline void rvt_free_rq(struct rvt_rq *rq) |
---|
| 953 | +{ |
---|
| 954 | + kvfree(rq->kwq); |
---|
| 955 | + rq->kwq = NULL; |
---|
| 956 | + vfree(rq->wq); |
---|
| 957 | + rq->wq = NULL; |
---|
| 958 | +} |
---|
| 959 | + |
---|
| 960 | +/** |
---|
| 961 | + * rvt_to_iport - Get the ibport pointer |
---|
| 962 | + * @qp: the qp pointer |
---|
| 963 | + * |
---|
| 964 | + * This function returns the ibport pointer from the qp pointer. |
---|
| 965 | + */ |
---|
| 966 | +static inline struct rvt_ibport *rvt_to_iport(struct rvt_qp *qp) |
---|
| 967 | +{ |
---|
| 968 | + struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device); |
---|
| 969 | + |
---|
| 970 | + return rdi->ports[qp->port_num - 1]; |
---|
| 971 | +} |
---|
| 972 | + |
---|
| 973 | +/** |
---|
| 974 | + * rvt_rc_credit_avail - Check if there are enough RC credits for the request |
---|
| 975 | + * @qp: the qp |
---|
| 976 | + * @wqe: the request |
---|
| 977 | + * |
---|
| 978 | + * This function returns false when there are not enough credits for the given |
---|
| 979 | + * request and true otherwise. |
---|
| 980 | + */ |
---|
| 981 | +static inline bool rvt_rc_credit_avail(struct rvt_qp *qp, struct rvt_swqe *wqe) |
---|
| 982 | +{ |
---|
| 983 | + lockdep_assert_held(&qp->s_lock); |
---|
| 984 | + if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) && |
---|
| 985 | + rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) { |
---|
| 986 | + struct rvt_ibport *rvp = rvt_to_iport(qp); |
---|
| 987 | + |
---|
| 988 | + qp->s_flags |= RVT_S_WAIT_SSN_CREDIT; |
---|
| 989 | + rvp->n_rc_crwaits++; |
---|
| 990 | + return false; |
---|
| 991 | + } |
---|
| 992 | + return true; |
---|
| 993 | +} |
---|
| 994 | + |
---|
703 | 995 | struct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi, |
---|
704 | 996 | u64 v, |
---|
705 | 997 | void (*cb)(struct rvt_qp *qp, u64 v)); |
---|