85 if (tr==0)
return false;
87 if (multi_gid == 0)
return false;
89 if (!QP()->InitUD())
return false;
91 memcpy(f_multi_gid.raw, multi_gid->raw,
sizeof(f_multi_gid.raw));
97 if (!f_multi)
return false;
99 f_ud_ah = fContext.CreateMAH(f_multi_gid, f_multi_lid);
100 if (f_ud_ah==0)
return false;
108 if (!QP()->AttachMcast(&f_multi_gid, f_multi_lid))
return false;
121 DOUT3(
"++++ verbs::VerbsNetworkInetrface::AllocateNet tr = %p poolname %s", tr, tr->
TransportPoolName().c_str());
126 fPoolReg = fContext.RegisterPool(pool());
129 EOUT(
"Cannot make verbs transport without memory pool");
134 fHeadersPool =
new MemoryPool(fContext,
"HeadersPool", tr->
NumRecs(),
138 fSegmPerOper = fQP->NumSendSegs();
139 if (fSegmPerOper<2) fSegmPerOper = 2;
142 f_swr =
new ibv_send_wr [tr->
NumRecs()];
143 f_sge =
new ibv_sge [tr->
NumRecs()*fSegmPerOper];
145 for (uint32_t n=0;n<tr->
NumRecs();n++) {
147 tr->
SetRecHeader(n, fHeadersPool->GetSendBufferLocation(n));
149 for (
unsigned seg_cnt=0; seg_cnt<fSegmPerOper; seg_cnt++) {
150 unsigned nseg = n*fSegmPerOper + seg_cnt;
151 f_sge[nseg].addr = (uintptr_t) 0;
152 f_sge[nseg].length = 0;
153 f_sge[nseg].lkey = 0;
157 f_swr[n].sg_list = 0;
158 f_swr[n].num_sge = 1;
159 f_swr[n].opcode = IBV_WR_SEND;
160 f_swr[n].next = NULL;
161 f_swr[n].send_flags = IBV_SEND_SIGNALED;
164 f_rwr[n].sg_list = 0;
165 f_rwr[n].num_sge = 1;
166 f_rwr[n].next = NULL;
178 uint32_t segid = recid*fSegmPerOper;
183 if ((rec==0) || (f_sge==0)) {
184 EOUT(
"Did not found rec %p or f_sge %p - abort", rec, f_sge);
188 f_sge[segid].addr = (uintptr_t) rec->
header;
190 f_sge[segid].lkey = fHeadersPool->GetLkey(recid);
192 f_swr[recid].wr_id = recid;
193 f_swr[recid].sg_list = &(f_sge[segid]);
194 f_swr[recid].num_sge = 1;
195 f_swr[recid].opcode = IBV_WR_SEND;
196 f_swr[recid].next = NULL;
197 f_swr[recid].send_flags = IBV_SEND_SIGNALED;
200 f_swr[recid].wr.ud.ah = f_ud_ah;
201 f_swr[recid].wr.ud.remote_qpn = f_ud_qpn;
202 f_swr[recid].wr.ud.remote_qkey = f_ud_qkey;
205 if ((senddtyp==2) && !fPoolReg.null()) {
208 EOUT(
"Too many segments");
213 fPoolReg()->CheckMRStructure();
216 f_sge[segid+1+seg].addr = (uintptr_t) rec->
buf.
SegmentPtr(seg);
218 f_sge[segid+1+seg].lkey = fPoolReg()->GetLkey(rec->
buf.
SegmentId(seg));
224 if ((f_swr[recid].num_sge==1) && (f_sge[segid].length<=256))
226 f_swr[recid].send_flags = (ibv_send_flags) (IBV_SEND_SIGNALED | IBV_SEND_INLINE);
228 fQP->Post_Send(&(f_swr[recid]));
236 uint32_t segid = recid*fSegmPerOper;
240 f_rwr[recid].wr_id = recid;
241 f_rwr[recid].sg_list = &(f_sge[segid]);
242 f_rwr[recid].num_sge = 1;
243 f_rwr[recid].next = NULL;
246 f_sge[segid].addr = (uintptr_t) fHeadersPool->GetBufferLocation(recid);
249 f_sge[segid].addr = (uintptr_t) rec->
header;
252 f_sge[segid].lkey = fHeadersPool->GetLkey(recid);
254 if (!rec->
buf.
null() && !fPoolReg.null()) {
257 EOUT(
"Too many segments");
261 fPoolReg()->CheckMRStructure();
264 f_sge[segid+1+seg].addr = (uintptr_t) rec->
buf.
SegmentPtr(seg);
266 f_sge[segid+1+seg].lkey = fPoolReg()->GetLkey(rec->
buf.
SegmentId(seg));
272 fQP->Post_Recv(&(f_rwr[recid]));
#define VERBS_DEFAULT_QKEY
#define VERBS_UD_MEMADDON
unsigned NumSegments() const
Returns number of segment in buffer.
unsigned SegmentSize(unsigned n=0) const
Returns size on the segment, no any boundary checks.
unsigned SegmentId(unsigned n=0) const
Returns id of the segment, no any boundary checks.
void * SegmentPtr(unsigned n=0) const
Returns pointer on the segment, no any boundary checks.
Reference FindPool(const std::string &name)
Reference on dabc::MemoryPool class
std::string TransportPoolName() const
Provides name of memory pool, used by transport.
void SetRecHeader(uint32_t recid, void *header)
NetIORec * GetRec(unsigned id) const
unsigned GetFullHeaderSize() const
void ProcessRecvCompl(uint32_t recid)
void ProcessSendCompl(uint32_t recid)
int PackHeader(uint32_t recid)
static void Destroy(Object *obj)
User method for object destroyment.
bool null() const
Returns true if reference contains nullptr.
bool IsInputTransport() const
virtual long Notify(const std::string &, int)
Light-weight command interface, which can be used from worker.
Reference to verbs::Context
int ManageMulticast(int action, ibv_gid &mgid, uint16_t &mlid)
Represent VERBS queue pair functionality.
bool DetachMcast(ibv_gid *mgid, uint16_t mlid)
struct ibv_send_wr * f_swr
virtual void VerbsProcessSendCompl(uint32_t)
virtual void AllocateNet(unsigned fulloutputqueue, unsigned fullinputqueue)
void SetUdAddr(struct ibv_ah *ud_ah, uint32_t ud_qpn, uint32_t ud_qkey)
virtual ~VerbsNetworkInetrface()
virtual void SubmitSend(uint32_t recid)
virtual void VerbsProcessOperError(uint32_t)
virtual void VerbsProcessRecvCompl(uint32_t)
MemoryPool * fHeadersPool
virtual void SubmitRecv(uint32_t recid)
VerbsNetworkInetrface(verbs::ContextRef ctx, QueuePair *qp)
verbs::ContextRef fContext
struct ibv_recv_wr * f_rwr
virtual long Notify(const std::string &, int)
Light-weight command interface, which can be used from worker.
bool AssignMultiGid(ibv_gid *multi_gid)
Support of InfiniBand verbs.
std::string ConvertGidToStr(ibv_gid &gid)