Message ID | 20151207204433.8144.93461.stgit@phlsvslse11.ph.intel.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
PiAgZHJpdmVycy9pbmZpbmliYW5kL3N3L3JkbWF2dC9xcC5oIHwgICAgNSAtDQo+ICBpbmNsdWRl L3JkbWEvcmRtYV92dC5oICAgICAgICAgICAgfCAgMjMzDQo+ICsrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysNCj4gIDIgZmlsZXMgY2hhbmdlZCwgMjMzIGluc2VydGlvbnMoKyks IDUgZGVsZXRpb25zKC0pDQo+IA0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9pbmZpbmliYW5kL3N3 L3JkbWF2dC9xcC5oDQo+IGIvZHJpdmVycy9pbmZpbmliYW5kL3N3L3JkbWF2dC9xcC5oDQo+IGlu ZGV4IDRlNDcwOWYuLmM4MGQzMjYgMTAwNjQ0DQo+IC0tLSBhL2RyaXZlcnMvaW5maW5pYmFuZC9z dy9yZG1hdnQvcXAuaA0KPiArKysgYi9kcml2ZXJzL2luZmluaWJhbmQvc3cvcmRtYXZ0L3FwLmgN Cj4gQEAgLTUzLDExICs1Myw2IEBADQo+IA0KPiAgI2luY2x1ZGUgPHJkbWEvcmRtYV92dC5oPg0K PiANCj4gLXN0cnVjdCBydnRfcXAgew0KPiAtCXN0cnVjdCBpYl9xcCAqaWJxcDsNCj4gLQkvKiBP dGhlciBzdHVmZiAqLw0KPiAtfTsNCj4gLQ0KPiAgc3RydWN0IGliX3FwICpydnRfY3JlYXRlX3Fw KHN0cnVjdCBpYl9wZCAqaWJwZCwNCj4gIAkJCSAgICBzdHJ1Y3QgaWJfcXBfaW5pdF9hdHRyICpp bml0X2F0dHIsDQo+ICAJCQkgICAgc3RydWN0IGliX3VkYXRhICp1ZGF0YSk7DQo+IGRpZmYgLS1n aXQgYS9pbmNsdWRlL3JkbWEvcmRtYV92dC5oIGIvaW5jbHVkZS9yZG1hL3JkbWFfdnQuaA0KPiBp bmRleCAzOWEwNzM3Li44ZDNhNDFhIDEwMDY0NA0KPiAtLS0gYS9pbmNsdWRlL3JkbWEvcmRtYV92 dC5oDQo+ICsrKyBiL2luY2x1ZGUvcmRtYS9yZG1hX3Z0LmgNCj4gQEAgLTEwOSw2ICsxMDksMjM5 IEBAIHN0cnVjdCBydnRfbGtleV90YWJsZSB7DQo+ICAvKiBFbmQgTWVtbW9yeSBSZWdpb24gKi8N Cj4gDQo+ICAvKg0KPiArICogVGhpbmdzIG5lZWRlZCBmb3IgdGhlIFF1ZXVlIFBhaXIgZGVmaW5p dGlvbi4gTGlrZSB0aGUgTVIgc3R1ZmYgYWJvdmUNCj4gdGhlDQo+ICsgKiBmb2xsb3dpbmcgc2hv dWxkIHByb2JhYmx5IGdldCBtb3ZlZCB0byBxcC5oIG9uY2UgZHJpdmVycyBzdG9wIHRyeWluZw0K PiB0byBtYWtlDQo+ICsgKiBhbmQgbWFuaXB1bGF0ZSB0aGllciBvd24gUVBzLiBGb3IgdGhlIGZl dyBpbnN0bmFjZXMgd2hlcmUgYSBkcml2ZXIgbWF5DQo+IG5lZWQNCj4gKyAqIHRvIGxvb2sgaW50 byBhIHF1ZXVlIHBhaXIgdGhlcmUgc2hvdWxkIGJlIGEgcG9pbnRlciB0byBhIGRyaXZlcg0KPiBw cmlhdnRlIGRhdGENCj4gKyAqIHN0cnVjdHVyZSB0aGF0IHRoZXkgY2FuIGxvb2sgYXQuDQo+ICsg Ki8NCj4gKw0KPiArLyoNCj4gKyAqIFRoZXNlIGtlZXAgdHJhY2sgb2YgdGhlIGNvcHkgcHJvZ3Jl c3Mgd2l0aGluIGEgbWVtb3J5IHJlZ2lvbi4NCj4gKyAqIFVzZWQgYnkgdGhlIHZlcmJzIGxheWVy Lg0KPiArICovDQo+ICtzdHJ1Y3QgcnZ0X3NnZSB7DQo+ICsJc3RydWN0IHJ2dF9tcmVnaW9uICpt cjsNCj4gKwl2b2lkICp2YWRkcjsgICAgICAgICAgICAvKiBrZXJuZWwgdmlydHVhbCBhZGRyZXNz IG9mIHNlZ21lbnQgKi8NCj4gKwl1MzIgc2dlX2xlbmd0aDsgICAgICAgICAvKiBsZW5ndGggb2Yg dGhlIFNHRSAqLw0KPiArCXUzMiBsZW5ndGg7ICAgICAgICAgICAgIC8qIHJlbWFpbmluZyBsZW5n dGggb2YgdGhlIHNlZ21lbnQgKi8NCj4gKwl1MTYgbTsgICAgICAgICAgICAgICAgICAvKiBjdXJy ZW50IGluZGV4OiBtci0+bWFwW21dICovDQoNClJlbmFtZSB0byBjdXJfbWFwPw0KDQo+ICsJdTE2 IG47ICAgICAgICAgICAgICAgICAgLyogY3VycmVudCBpbmRleDogbXItPm1hcFttXS0+c2Vnc1tu XSAqLw0KDQpjdXJfc2VnPw0KDQo+ICt9Ow0KPiArDQo+ICsvKg0KPiArICogU2VuZCB3b3JrIHJl cXVlc3QgcXVldWUgZW50cnkuDQo+ICsgKiBUaGUgc2l6ZSBvZiB0aGUgc2dfbGlzdCBpcyBkZXRl cm1pbmVkIHdoZW4gdGhlIFFQIGlzIGNyZWF0ZWQgYW5kDQo+IHN0b3JlZA0KPiArICogaW4gcXAt PnNfbWF4X3NnZS4NCj4gKyAqLw0KPiArc3RydWN0IHJ2dF9zd3FlIHsNCj4gKwl1bmlvbiB7DQo+ ICsJCXN0cnVjdCBpYl9zZW5kX3dyIHdyOyAgIC8qIGRvbid0IHVzZSB3ci5zZ19saXN0ICovDQo+ ICsJCXN0cnVjdCBpYl91ZF93ciB1ZF93cjsNCj4gKwkJc3RydWN0IGliX3JlZ193ciByZWdfd3I7 DQo+ICsJCXN0cnVjdCBpYl9yZG1hX3dyIHJkbWFfd3I7DQo+ICsJCXN0cnVjdCBpYl9hdG9taWNf d3IgYXRvbWljX3dyOw0KPiArCX07DQo+ICsJdTMyIHBzbjsgICAgICAgICAgICAgICAgLyogZmly c3QgcGFja2V0IHNlcXVlbmNlIG51bWJlciAqLw0KPiArCXUzMiBscHNuOyAgICAgICAgICAgICAg IC8qIGxhc3QgcGFja2V0IHNlcXVlbmNlIG51bWJlciAqLw0KPiArCXUzMiBzc247ICAgICAgICAg ICAgICAgIC8qIHNlbmQgc2VxdWVuY2UgbnVtYmVyICovDQo+ICsJdTMyIGxlbmd0aDsgICAgICAg ICAgICAgLyogdG90YWwgbGVuZ3RoIG9mIGRhdGEgaW4gc2dfbGlzdCAqLw0KPiArCXN0cnVjdCBy dnRfc2dlIHNnX2xpc3RbMF07DQo+ICt9Ow0KPiArDQo+ICsvKg0KPiArICogUmVjZWl2ZSB3b3Jr IHJlcXVlc3QgcXVldWUgZW50cnkuDQo+ICsgKiBUaGUgc2l6ZSBvZiB0aGUgc2dfbGlzdCBpcyBk ZXRlcm1pbmVkIHdoZW4gdGhlIFFQIChvciBTUlEpIGlzIGNyZWF0ZWQNCj4gKyAqIGFuZCBzdG9y ZWQgaW4gcXAtPnJfcnEubWF4X3NnZSAob3Igc3JxLT5ycS5tYXhfc2dlKS4NCj4gKyAqLw0KPiAr c3RydWN0IHJ2dF9yd3FlIHsNCj4gKwl1NjQgd3JfaWQ7DQo+ICsJdTggbnVtX3NnZTsNCj4gKwlz dHJ1Y3QgaWJfc2dlIHNnX2xpc3RbMF07DQo+ICt9Ow0KPiArDQo+ICsvKg0KPiArICogVGhpcyBz dHJ1Y3R1cmUgaXMgdXNlZCB0byBjb250YWluIHRoZSBoZWFkIHBvaW50ZXIsIHRhaWwgcG9pbnRl ciwNCj4gKyAqIGFuZCByZWNlaXZlIHdvcmsgcXVldWUgZW50cmllcyBhcyBhIHNpbmdsZSBtZW1v cnkgYWxsb2NhdGlvbiBzbw0KPiArICogaXQgY2FuIGJlIG1tYXAnZWQgaW50byB1c2VyIHNwYWNl Lg0KPiArICogTm90ZSB0aGF0IHRoZSB3cSBhcnJheSBlbGVtZW50cyBhcmUgdmFyaWFibGUgc2l6 ZSBzbyB5b3UgY2FuJ3QNCj4gKyAqIGp1c3QgaW5kZXggaW50byB0aGUgYXJyYXkgdG8gZ2V0IHRo ZSBOJ3RoIGVsZW1lbnQ7DQo+ICsgKiB1c2UgZ2V0X3J3cWVfcHRyKCkgaW5zdGVhZC4NCg0KQ2Fu IHlvdSBhZGQvdXNlIGFuIGVudHJ5X3NpemUgZmllbGQ/DQoNCg0KPiArICovDQo+ICtzdHJ1Y3Qg cnZ0X3J3cSB7DQo+ICsJdTMyIGhlYWQ7ICAgICAgICAgICAgICAgLyogbmV3IHdvcmsgcmVxdWVz dHMgcG9zdGVkIHRvIHRoZSBoZWFkICovDQo+ICsJdTMyIHRhaWw7ICAgICAgICAgICAgICAgLyog cmVjZWl2ZXMgcHVsbCByZXF1ZXN0cyBmcm9tIGhlcmUuICovDQo+ICsJc3RydWN0IHJ2dF9yd3Fl IHdxWzBdOw0KPiArfTsNCj4gKw0KPiArc3RydWN0IHJ2dF9ycSB7DQo+ICsJc3RydWN0IHJ2dF9y d3EgKndxOw0KPiArCXUzMiBzaXplOyAgICAgICAgICAgICAgIC8qIHNpemUgb2YgUldRRSBhcnJh eSAqLw0KPiArCXU4IG1heF9zZ2U7DQo+ICsJLyogcHJvdGVjdCBjaGFuZ2VzIGluIHRoaXMgc3Ry dWN0ICovDQo+ICsJc3BpbmxvY2tfdCBsb2NrIF9fX19jYWNoZWxpbmVfYWxpZ25lZF9pbl9zbXA7 DQo+ICt9Ow0K -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Dec 07, 2015 at 03:48:17PM -0600, Hefty, Sean wrote: >> +struct rvt_rwqe { >> + u64 wr_id; >> + u8 num_sge; >> + struct ib_sge sg_list[0]; >> +}; >> + >> +/* >> + * This structure is used to contain the head pointer, tail pointer, >> + * and receive work queue entries as a single memory allocation so >> + * it can be mmap'ed into user space. >> + * Note that the wq array elements are variable size so you can't >> + * just index into the array to get the N'th element; >> + * use get_rwqe_ptr() instead. > >Can you add/use an entry_size field? I think we could work something like that, however what we have in qib/hfi1 also works. Any reason we really should change this? >> + */ >> +struct rvt_rwq { >> + u32 head; /* new work requests posted to the head */ >> + u32 tail; /* receives pull requests from here. */ >> + struct rvt_rwqe wq[0]; >> +}; >> + >> +struct rvt_rq { >> + struct rvt_rwq *wq; >> + u32 size; /* size of RWQE array */ >> + u8 max_sge; >> + /* protect changes in this struct */ >> + spinlock_t lock ____cacheline_aligned_in_smp; >> +}; -Denny -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> >> +struct rvt_rwqe { > >> + u64 wr_id; > >> + u8 num_sge; > >> + struct ib_sge sg_list[0]; > >> +}; > >> + > >> +/* > >> + * This structure is used to contain the head pointer, tail pointer, > >> + * and receive work queue entries as a single memory allocation so > >> + * it can be mmap'ed into user space. > >> + * Note that the wq array elements are variable size so you can't > >> + * just index into the array to get the N'th element; > >> + * use get_rwqe_ptr() instead. > > > >Can you add/use an entry_size field? > > I think we could work something like that, however what we have in > qib/hfi1 > also works. Any reason we really should change this? I did not check to see what the drivers do. Using entry_size is straightforward, may provide the best performance, and can be done in common code, versus adding callbacks to all users. -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Dec 10, 2015 at 01:12:51PM -0600, Hefty, Sean wrote: >> >> +struct rvt_rwqe { >> >> + u64 wr_id; >> >> + u8 num_sge; >> >> + struct ib_sge sg_list[0]; >> >> +}; >> >> + >> >> +/* >> >> + * This structure is used to contain the head pointer, tail pointer, >> >> + * and receive work queue entries as a single memory allocation so >> >> + * it can be mmap'ed into user space. >> >> + * Note that the wq array elements are variable size so you can't >> >> + * just index into the array to get the N'th element; >> >> + * use get_rwqe_ptr() instead. >> > >> >Can you add/use an entry_size field? >> >> I think we could work something like that, however what we have in >> qib/hfi1 >> also works. Any reason we really should change this? > >I did not check to see what the drivers do. Using entry_size is >straightforward, may provide the best performance, and can be done in >common code, versus adding callbacks to all users. Are you concerned that we have to do something different in each driver? If so, I do plan to move get_rwqe_ptr to rdmavt in a later patch. It won't be part of the drivers any more. I kind of like what we have for get_rwqe_ptr, it illustrates how we are fishing out the pointer. I'll take another look at it though for the coming patch, it could save us from doing a bit of math on the fly. -Denny -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/infiniband/sw/rdmavt/qp.h b/drivers/infiniband/sw/rdmavt/qp.h index 4e4709f..c80d326 100644 --- a/drivers/infiniband/sw/rdmavt/qp.h +++ b/drivers/infiniband/sw/rdmavt/qp.h @@ -53,11 +53,6 @@ #include <rdma/rdma_vt.h> -struct rvt_qp { - struct ib_qp *ibqp; - /* Other stuff */ -}; - struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, struct ib_qp_init_attr *init_attr, struct ib_udata *udata); diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h index 39a0737..8d3a41a 100644 --- a/include/rdma/rdma_vt.h +++ b/include/rdma/rdma_vt.h @@ -109,6 +109,239 @@ struct rvt_lkey_table { /* End Memmory Region */ /* + * Things needed for the Queue Pair definition. Like the MR stuff above the + * following should probably get moved to qp.h once drivers stop trying to make + * and manipulate thier own QPs. For the few instnaces where a driver may need + * to look into a queue pair there should be a pointer to a driver priavte data + * structure that they can look at. + */ + +/* + * These keep track of the copy progress within a memory region. + * Used by the verbs layer. + */ +struct rvt_sge { + struct rvt_mregion *mr; + void *vaddr; /* kernel virtual address of segment */ + u32 sge_length; /* length of the SGE */ + u32 length; /* remaining length of the segment */ + u16 m; /* current index: mr->map[m] */ + u16 n; /* current index: mr->map[m]->segs[n] */ +}; + +/* + * Send work request queue entry. + * The size of the sg_list is determined when the QP is created and stored + * in qp->s_max_sge. + */ +struct rvt_swqe { + union { + struct ib_send_wr wr; /* don't use wr.sg_list */ + struct ib_ud_wr ud_wr; + struct ib_reg_wr reg_wr; + struct ib_rdma_wr rdma_wr; + struct ib_atomic_wr atomic_wr; + }; + u32 psn; /* first packet sequence number */ + u32 lpsn; /* last packet sequence number */ + u32 ssn; /* send sequence number */ + u32 length; /* total length of data in sg_list */ + struct rvt_sge sg_list[0]; +}; + +/* + * Receive work request queue entry. + * The size of the sg_list is determined when the QP (or SRQ) is created + * and stored in qp->r_rq.max_sge (or srq->rq.max_sge). + */ +struct rvt_rwqe { + u64 wr_id; + u8 num_sge; + struct ib_sge sg_list[0]; +}; + +/* + * This structure is used to contain the head pointer, tail pointer, + * and receive work queue entries as a single memory allocation so + * it can be mmap'ed into user space. + * Note that the wq array elements are variable size so you can't + * just index into the array to get the N'th element; + * use get_rwqe_ptr() instead. + */ +struct rvt_rwq { + u32 head; /* new work requests posted to the head */ + u32 tail; /* receives pull requests from here. */ + struct rvt_rwqe wq[0]; +}; + +struct rvt_rq { + struct rvt_rwq *wq; + u32 size; /* size of RWQE array */ + u8 max_sge; + /* protect changes in this struct */ + spinlock_t lock ____cacheline_aligned_in_smp; +}; + +/* + * This structure is used by rvt_mmap() to validate an offset + * when an mmap() request is made. The vm_area_struct then uses + * this as its vm_private_data. + */ +struct rvt_mmap_info { + struct list_head pending_mmaps; + struct ib_ucontext *context; + void *obj; + __u64 offset; + struct kref ref; + unsigned size; +}; + +#define RVT_MAX_RDMA_ATOMIC 16 + +/* + * This structure holds the information that the send tasklet needs + * to send a RDMA read response or atomic operation. + */ +struct rvt_ack_entry { + u8 opcode; + u8 sent; + u32 psn; + u32 lpsn; + union { + struct rvt_sge rdma_sge; + u64 atomic_data; + }; +}; + +struct rvt_sge_state { + struct rvt_sge *sg_list; /* next SGE to be used if any */ + struct rvt_sge sge; /* progress state for the current SGE */ + u32 total_len; + u8 num_sge; +}; + +/* + * Variables prefixed with s_ are for the requester (sender). + * Variables prefixed with r_ are for the responder (receiver). + * Variables prefixed with ack_ are for responder replies. + * + * Common variables are protected by both r_rq.lock and s_lock in that order + * which only happens in modify_qp() or changing the QP 'state'. + */ +struct rvt_qp { + struct ib_qp ibqp; + void *priv; /* Driver private data */ + /* read mostly fields above and below */ + struct ib_ah_attr remote_ah_attr; + struct ib_ah_attr alt_ah_attr; + struct rvt_qp __rcu *next; /* link list for QPN hash table */ + struct rvt_swqe *s_wq; /* send work queue */ + struct rvt_mmap_info *ip; + + unsigned long timeout_jiffies; /* computed from timeout */ + + enum ib_mtu path_mtu; + int srate_mbps; /* s_srate (below) converted to Mbit/s */ + u32 remote_qpn; + u32 pmtu; /* decoded from path_mtu */ + u32 qkey; /* QKEY for this QP (for UD or RD) */ + u32 s_size; /* send work queue size */ + u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ + u32 s_ahgpsn; /* set to the psn in the copy of the header */ + + u8 state; /* QP state */ + u8 allowed_ops; /* high order bits of allowed opcodes */ + u8 qp_access_flags; + u8 alt_timeout; /* Alternate path timeout for this QP */ + u8 timeout; /* Timeout for this QP */ + u8 s_srate; + u8 s_mig_state; + u8 port_num; + u8 s_pkey_index; /* PKEY index to use */ + u8 s_alt_pkey_index; /* Alternate path PKEY index to use */ + u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ + u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ + u8 s_retry_cnt; /* number of times to retry */ + u8 s_rnr_retry_cnt; + u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ + u8 s_max_sge; /* size of s_wq->sg_list */ + u8 s_draining; + + /* start of read/write fields */ + atomic_t refcount ____cacheline_aligned_in_smp; + wait_queue_head_t wait; + + struct rvt_ack_entry s_ack_queue[RVT_MAX_RDMA_ATOMIC + 1] + ____cacheline_aligned_in_smp; + struct rvt_sge_state s_rdma_read_sge; + + spinlock_t r_lock ____cacheline_aligned_in_smp; /* used for APM */ + unsigned long r_aflags; + u64 r_wr_id; /* ID for current receive WQE */ + u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ + u32 r_len; /* total length of r_sge */ + u32 r_rcv_len; /* receive data len processed */ + u32 r_psn; /* expected rcv packet sequence number */ + u32 r_msn; /* message sequence number */ + + u8 r_state; /* opcode of last packet received */ + u8 r_flags; + u8 r_head_ack_queue; /* index into s_ack_queue[] */ + + struct list_head rspwait; /* link for waiting to respond */ + + struct rvt_sge_state r_sge; /* current receive data */ + struct rvt_rq r_rq; /* receive work queue */ + + spinlock_t s_lock ____cacheline_aligned_in_smp; + struct rvt_sge_state *s_cur_sge; + u32 s_flags; + struct rvt_swqe *s_wqe; + struct rvt_sge_state s_sge; /* current send request data */ + struct rvt_mregion *s_rdma_mr; + struct sdma_engine *s_sde; /* current sde */ + u32 s_cur_size; /* size of send packet in bytes */ + u32 s_len; /* total length of s_sge */ + u32 s_rdma_read_len; /* total length of s_rdma_read_sge */ + u32 s_next_psn; /* PSN for next request */ + u32 s_last_psn; /* last response PSN processed */ + u32 s_sending_psn; /* lowest PSN that is being sent */ + u32 s_sending_hpsn; /* highest PSN that is being sent */ + u32 s_psn; /* current packet sequence number */ + u32 s_ack_rdma_psn; /* PSN for sending RDMA read responses */ + u32 s_ack_psn; /* PSN for acking sends and RDMA writes */ + u32 s_head; /* new entries added here */ + u32 s_tail; /* next entry to process */ + u32 s_cur; /* current work queue entry */ + u32 s_acked; /* last un-ACK'ed entry */ + u32 s_last; /* last completed entry */ + u32 s_ssn; /* SSN of tail entry */ + u32 s_lsn; /* limit sequence number (credit) */ + u16 s_hdrwords; /* size of s_hdr in 32 bit words */ + u16 s_rdma_ack_cnt; + s8 s_ahgidx; + u8 s_state; /* opcode of last packet sent */ + u8 s_ack_state; /* opcode of packet to ACK */ + u8 s_nak_state; /* non-zero if NAK is pending */ + u8 r_nak_state; /* non-zero if NAK is pending */ + u8 s_retry; /* requester retry counter */ + u8 s_rnr_retry; /* requester RNR retry counter */ + u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ + u8 s_tail_ack_queue; /* index into s_ack_queue[] */ + + struct rvt_sge_state s_ack_rdma_sge; + struct timer_list s_timer; + + /* + * This sge list MUST be last. Do not add anything below here. + */ + struct rvt_sge r_sg_list[0] /* verified SGEs */ + ____cacheline_aligned_in_smp; +}; + +/* End QP section */ + +/* * Things that are driver specific, module parameters in hfi1 and qib */ struct rvt_driver_params {