.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ |
---|
| 2 | +/* |
---|
| 3 | + * Copyright(c) 2016 - 2019 Intel Corporation. |
---|
| 4 | + */ |
---|
| 5 | + |
---|
1 | 6 | #ifndef DEF_RDMA_VT_H |
---|
2 | 7 | #define DEF_RDMA_VT_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 | /* |
---|
52 | 10 | * Structure that low level drivers will populate in order to register with the |
---|
.. | .. |
---|
59 | 17 | #include <rdma/ib_verbs.h> |
---|
60 | 18 | #include <rdma/ib_mad.h> |
---|
61 | 19 | #include <rdma/rdmavt_mr.h> |
---|
62 | | -#include <rdma/rdmavt_qp.h> |
---|
63 | 20 | |
---|
64 | 21 | #define RVT_MAX_PKEY_VALUES 16 |
---|
65 | 22 | |
---|
.. | .. |
---|
72 | 29 | struct list_head list; |
---|
73 | 30 | }; |
---|
74 | 31 | |
---|
| 32 | +struct rvt_qp; |
---|
| 33 | +struct rvt_qpn_table; |
---|
75 | 34 | struct rvt_ibport { |
---|
76 | 35 | struct rvt_qp __rcu *qp[2]; |
---|
77 | 36 | struct ib_mad_agent *send_agent; /* agent for SMI (traps) */ |
---|
.. | .. |
---|
115 | 74 | u64 n_unaligned; |
---|
116 | 75 | u64 n_rc_dupreq; |
---|
117 | 76 | u64 n_rc_seqnak; |
---|
| 77 | + u64 n_rc_crwaits; |
---|
118 | 78 | u16 pkey_violations; |
---|
119 | 79 | u16 qkey_violations; |
---|
120 | 80 | u16 mkey_violations; |
---|
.. | .. |
---|
149 | 109 | |
---|
150 | 110 | #define RVT_CQN_MAX 16 /* maximum length of cq name */ |
---|
151 | 111 | |
---|
| 112 | +#define RVT_SGE_COPY_MEMCPY 0 |
---|
| 113 | +#define RVT_SGE_COPY_CACHELESS 1 |
---|
| 114 | +#define RVT_SGE_COPY_ADAPTIVE 2 |
---|
| 115 | + |
---|
152 | 116 | /* |
---|
153 | 117 | * Things that are driver specific, module parameters in hfi1 and qib |
---|
154 | 118 | */ |
---|
.. | .. |
---|
161 | 125 | */ |
---|
162 | 126 | unsigned int lkey_table_size; |
---|
163 | 127 | unsigned int qp_table_size; |
---|
| 128 | + unsigned int sge_copy_mode; |
---|
| 129 | + unsigned int wss_threshold; |
---|
| 130 | + unsigned int wss_clean_period; |
---|
164 | 131 | int qpn_start; |
---|
165 | 132 | int qpn_inc; |
---|
166 | 133 | int qpn_res_start; |
---|
.. | .. |
---|
175 | 142 | u32 max_mad_size; |
---|
176 | 143 | u8 qos_shift; |
---|
177 | 144 | u8 max_rdma_atomic; |
---|
| 145 | + u8 extra_rdma_atomic; |
---|
178 | 146 | u8 reserved_operations; |
---|
| 147 | +}; |
---|
| 148 | + |
---|
| 149 | +/* User context */ |
---|
| 150 | +struct rvt_ucontext { |
---|
| 151 | + struct ib_ucontext ibucontext; |
---|
179 | 152 | }; |
---|
180 | 153 | |
---|
181 | 154 | /* Protection domain */ |
---|
.. | .. |
---|
188 | 161 | struct rvt_ah { |
---|
189 | 162 | struct ib_ah ibah; |
---|
190 | 163 | struct rdma_ah_attr attr; |
---|
191 | | - atomic_t refcount; |
---|
192 | 164 | u8 vl; |
---|
193 | 165 | u8 log_pmtu; |
---|
| 166 | +}; |
---|
| 167 | + |
---|
| 168 | +/* |
---|
| 169 | + * This structure is used by rvt_mmap() to validate an offset |
---|
| 170 | + * when an mmap() request is made. The vm_area_struct then uses |
---|
| 171 | + * this as its vm_private_data. |
---|
| 172 | + */ |
---|
| 173 | +struct rvt_mmap_info { |
---|
| 174 | + struct list_head pending_mmaps; |
---|
| 175 | + struct ib_ucontext *context; |
---|
| 176 | + void *obj; |
---|
| 177 | + __u64 offset; |
---|
| 178 | + struct kref ref; |
---|
| 179 | + u32 size; |
---|
| 180 | +}; |
---|
| 181 | + |
---|
| 182 | +/* memory working set size */ |
---|
| 183 | +struct rvt_wss { |
---|
| 184 | + unsigned long *entries; |
---|
| 185 | + atomic_t total_count; |
---|
| 186 | + atomic_t clean_counter; |
---|
| 187 | + atomic_t clean_entry; |
---|
| 188 | + |
---|
| 189 | + int threshold; |
---|
| 190 | + int num_entries; |
---|
| 191 | + long pages_mask; |
---|
| 192 | + unsigned int clean_period; |
---|
194 | 193 | }; |
---|
195 | 194 | |
---|
196 | 195 | struct rvt_dev_info; |
---|
.. | .. |
---|
211 | 210 | * version requires the s_lock not to be held. The other assumes the |
---|
212 | 211 | * s_lock is held. |
---|
213 | 212 | */ |
---|
214 | | - void (*schedule_send)(struct rvt_qp *qp); |
---|
215 | | - void (*schedule_send_no_lock)(struct rvt_qp *qp); |
---|
| 213 | + bool (*schedule_send)(struct rvt_qp *qp); |
---|
| 214 | + bool (*schedule_send_no_lock)(struct rvt_qp *qp); |
---|
216 | 215 | |
---|
217 | | - /* Driver specific work request checking */ |
---|
218 | | - int (*check_send_wqe)(struct rvt_qp *qp, struct rvt_swqe *wqe); |
---|
| 216 | + /* |
---|
| 217 | + * Driver specific work request setup and checking. |
---|
| 218 | + * This function is allowed to perform any setup, checks, or |
---|
| 219 | + * adjustments required to the SWQE in order to be usable by |
---|
| 220 | + * underlying protocols. This includes private data structure |
---|
| 221 | + * allocations. |
---|
| 222 | + */ |
---|
| 223 | + int (*setup_wqe)(struct rvt_qp *qp, struct rvt_swqe *wqe, |
---|
| 224 | + bool *call_send); |
---|
219 | 225 | |
---|
220 | 226 | /* |
---|
221 | 227 | * Sometimes rdmavt needs to kick the driver's send progress. That is |
---|
222 | 228 | * done by this call back. |
---|
223 | 229 | */ |
---|
224 | 230 | void (*do_send)(struct rvt_qp *qp); |
---|
225 | | - |
---|
226 | | - /* Passed to ib core registration. Callback to create syfs files */ |
---|
227 | | - int (*port_callback)(struct ib_device *, u8, struct kobject *); |
---|
228 | 231 | |
---|
229 | 232 | /* |
---|
230 | 233 | * Returns a pointer to the undelying hardware's PCI device. This is |
---|
.. | .. |
---|
240 | 243 | * pointer. |
---|
241 | 244 | */ |
---|
242 | 245 | void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp); |
---|
| 246 | + |
---|
| 247 | + /* |
---|
| 248 | + * Init a struture allocated with qp_priv_alloc(). This should be |
---|
| 249 | + * called after all qp fields have been initialized in rdmavt. |
---|
| 250 | + */ |
---|
| 251 | + int (*qp_priv_init)(struct rvt_dev_info *rdi, struct rvt_qp *qp, |
---|
| 252 | + struct ib_qp_init_attr *init_attr); |
---|
243 | 253 | |
---|
244 | 254 | /* |
---|
245 | 255 | * Free the driver's private qp structure. |
---|
.. | .. |
---|
371 | 381 | /* post send table */ |
---|
372 | 382 | const struct rvt_operation_params *post_parms; |
---|
373 | 383 | |
---|
| 384 | + /* opcode translation table */ |
---|
| 385 | + const enum ib_wc_opcode *wc_opcode; |
---|
| 386 | + |
---|
374 | 387 | /* Driver specific helper functions */ |
---|
375 | 388 | struct rvt_driver_provided driver_f; |
---|
376 | 389 | |
---|
.. | .. |
---|
411 | 424 | u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ |
---|
412 | 425 | spinlock_t n_mcast_grps_lock; |
---|
413 | 426 | |
---|
| 427 | + /* Memory Working Set Size */ |
---|
| 428 | + struct rvt_wss *wss; |
---|
414 | 429 | }; |
---|
415 | 430 | |
---|
416 | 431 | /** |
---|
.. | .. |
---|
423 | 438 | const char *fmt, const char *name, |
---|
424 | 439 | const int unit) |
---|
425 | 440 | { |
---|
426 | | - snprintf(rdi->ibdev.name, sizeof(rdi->ibdev.name), fmt, name, unit); |
---|
| 441 | + /* |
---|
| 442 | + * FIXME: rvt and its users want to touch the ibdev before |
---|
| 443 | + * registration and have things like the name work. We don't have the |
---|
| 444 | + * infrastructure in the core to support this directly today, hack it |
---|
| 445 | + * to work by setting the name manually here. |
---|
| 446 | + */ |
---|
| 447 | + dev_set_name(&rdi->ibdev.dev, fmt, name, unit); |
---|
| 448 | + strlcpy(rdi->ibdev.name, dev_name(&rdi->ibdev.dev), IB_DEVICE_NAME_MAX); |
---|
427 | 449 | } |
---|
428 | 450 | |
---|
429 | 451 | /** |
---|
.. | .. |
---|
434 | 456 | */ |
---|
435 | 457 | static inline const char *rvt_get_ibdev_name(const struct rvt_dev_info *rdi) |
---|
436 | 458 | { |
---|
437 | | - return rdi->ibdev.name; |
---|
| 459 | + return dev_name(&rdi->ibdev.dev); |
---|
438 | 460 | } |
---|
439 | 461 | |
---|
440 | 462 | static inline struct rvt_pd *ibpd_to_rvtpd(struct ib_pd *ibpd) |
---|
.. | .. |
---|
452 | 474 | return container_of(ibdev, struct rvt_dev_info, ibdev); |
---|
453 | 475 | } |
---|
454 | 476 | |
---|
455 | | -static inline struct rvt_srq *ibsrq_to_rvtsrq(struct ib_srq *ibsrq) |
---|
456 | | -{ |
---|
457 | | - return container_of(ibsrq, struct rvt_srq, ibsrq); |
---|
458 | | -} |
---|
459 | | - |
---|
460 | | -static inline struct rvt_qp *ibqp_to_rvtqp(struct ib_qp *ibqp) |
---|
461 | | -{ |
---|
462 | | - return container_of(ibqp, struct rvt_qp, ibqp); |
---|
463 | | -} |
---|
464 | | - |
---|
465 | 477 | static inline unsigned rvt_get_npkeys(struct rvt_dev_info *rdi) |
---|
466 | 478 | { |
---|
467 | 479 | /* |
---|
.. | .. |
---|
476 | 488 | */ |
---|
477 | 489 | static inline unsigned int rvt_max_atomic(struct rvt_dev_info *rdi) |
---|
478 | 490 | { |
---|
479 | | - return rdi->dparms.max_rdma_atomic + 1; |
---|
| 491 | + return rdi->dparms.max_rdma_atomic + |
---|
| 492 | + rdi->dparms.extra_rdma_atomic + 1; |
---|
| 493 | +} |
---|
| 494 | + |
---|
| 495 | +static inline unsigned int rvt_size_atomic(struct rvt_dev_info *rdi) |
---|
| 496 | +{ |
---|
| 497 | + return rdi->dparms.max_rdma_atomic + |
---|
| 498 | + rdi->dparms.extra_rdma_atomic; |
---|
480 | 499 | } |
---|
481 | 500 | |
---|
482 | 501 | /* |
---|
.. | .. |
---|
492 | 511 | return rdi->ports[port_index]->pkey_table[index]; |
---|
493 | 512 | } |
---|
494 | 513 | |
---|
495 | | -/** |
---|
496 | | - * rvt_lookup_qpn - return the QP with the given QPN |
---|
497 | | - * @ibp: the ibport |
---|
498 | | - * @qpn: the QP number to look up |
---|
499 | | - * |
---|
500 | | - * The caller must hold the rcu_read_lock(), and keep the lock until |
---|
501 | | - * the returned qp is no longer in use. |
---|
502 | | - */ |
---|
503 | | -/* TODO: Remove this and put in rdmavt/qp.h when no longer needed by drivers */ |
---|
504 | | -static inline struct rvt_qp *rvt_lookup_qpn(struct rvt_dev_info *rdi, |
---|
505 | | - struct rvt_ibport *rvp, |
---|
506 | | - u32 qpn) __must_hold(RCU) |
---|
507 | | -{ |
---|
508 | | - struct rvt_qp *qp = NULL; |
---|
509 | | - |
---|
510 | | - if (unlikely(qpn <= 1)) { |
---|
511 | | - qp = rcu_dereference(rvp->qp[qpn]); |
---|
512 | | - } else { |
---|
513 | | - u32 n = hash_32(qpn, rdi->qp_dev->qp_table_bits); |
---|
514 | | - |
---|
515 | | - for (qp = rcu_dereference(rdi->qp_dev->qp_table[n]); qp; |
---|
516 | | - qp = rcu_dereference(qp->next)) |
---|
517 | | - if (qp->ibqp.qp_num == qpn) |
---|
518 | | - break; |
---|
519 | | - } |
---|
520 | | - return qp; |
---|
521 | | -} |
---|
522 | | - |
---|
523 | | -/** |
---|
524 | | - * rvt_mod_retry_timer - mod a retry timer |
---|
525 | | - * @qp - the QP |
---|
526 | | - * Modify a potentially already running retry timer |
---|
527 | | - */ |
---|
528 | | -static inline void rvt_mod_retry_timer(struct rvt_qp *qp) |
---|
529 | | -{ |
---|
530 | | - struct ib_qp *ibqp = &qp->ibqp; |
---|
531 | | - struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); |
---|
532 | | - |
---|
533 | | - lockdep_assert_held(&qp->s_lock); |
---|
534 | | - qp->s_flags |= RVT_S_TIMER; |
---|
535 | | - /* 4.096 usec. * (1 << qp->timeout) */ |
---|
536 | | - mod_timer(&qp->s_timer, jiffies + qp->timeout_jiffies + |
---|
537 | | - rdi->busy_jiffies); |
---|
538 | | -} |
---|
539 | | - |
---|
540 | 514 | struct rvt_dev_info *rvt_alloc_device(size_t size, int nports); |
---|
541 | 515 | void rvt_dealloc_device(struct rvt_dev_info *rdi); |
---|
542 | | -int rvt_register_device(struct rvt_dev_info *rvd, u32 driver_id); |
---|
| 516 | +int rvt_register_device(struct rvt_dev_info *rvd); |
---|
543 | 517 | void rvt_unregister_device(struct rvt_dev_info *rvd); |
---|
544 | 518 | int rvt_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr); |
---|
545 | 519 | int rvt_init_port(struct rvt_dev_info *rdi, struct rvt_ibport *port, |
---|