176 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_NET 181 #include <netinet/in.h> 182 #include <arpa/inet.h> 185 #include <sys/epoll.h> 198 #define U32_TO_VPTR(a) ((void*)((uintptr_t)a)) 199 #define VPTR_TO_U32(a) ((uint32_t)((uintptr_t)a)) 204 static const char *providers[FAB_FABRIC_PROV_MAX] = {
205 [FAB_FABRIC_PROV_VERBS] =
"verbs",
206 [FAB_FABRIC_PROV_TCP] =
"tcp",
207 [FAB_FABRIC_PROV_SOCK] =
"sockets" };
210 static,
struct m0_fab__buf, fb_linkage, fb_magic,
215 static,
struct m0_fab__buf, fb_snd_link, fb_sndmagic,
220 static,
struct m0_fab__fab, fab_link, fab_magic,
225 static,
struct m0_fab__bulk_op, fbl_link, fbl_magic,
229 static uint32_t libfab_bht_func(
const struct m0_htable *ht,
const void *
key)
231 const union m0_fab__token *
token =
key;
238 return ((
token->t_Fields.tf_queue_id * FAB_NUM_BUCKETS_PER_QTYPE) +
239 token->t_Fields.tf_queue_num);
242 static bool libfab_bht_key_eq(
const void *key1,
const void *key2)
244 const union m0_fab__token *token1 = key1;
245 const union m0_fab__token *token2 = key2;
247 return token1->t_val == token2->t_val;
253 fb_token, libfab_bht_func, libfab_bht_key_eq);
255 M0_HT_DEFINE(fab_bufhash,
static,
struct m0_fab__buf, uint32_t);
257 static int libfab_ep_txres_init(
struct m0_fab__active_ep *aep,
258 struct m0_fab__tm *tm,
void *
ctx);
259 static int libfab_ep_rxres_init(
struct m0_fab__active_ep *aep,
260 struct m0_fab__tm *tm,
void *
ctx);
261 static int libfab_pep_res_init(
struct m0_fab__passive_ep *pep,
262 struct m0_fab__tm *tm,
void *
ctx);
270 static int libfab_active_ep_create(
struct m0_fab__ep *
ep,
271 struct m0_fab__tm *tm);
272 static int libfab_passive_ep_create(
struct m0_fab__ep *
ep,
273 struct m0_fab__tm *tm);
274 static int libfab_aep_param_free(
struct m0_fab__active_ep *aep,
275 struct m0_fab__tm *tm);
276 static int libfab_pep_param_free(
struct m0_fab__passive_ep *pep,
277 struct m0_fab__tm *tm);
278 static int libfab_ep_param_free(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm);
279 static int libfab_pep_res_free(
struct m0_fab__pep_res *pep_res,
280 struct m0_fab__tm *tm);
281 static int libfab_ep_txres_free(
struct m0_fab__tx_res *tx_res,
282 struct m0_fab__tm *tm);
283 static int libfab_ep_rxres_free(
struct m0_fab__rx_res *rx_res,
284 struct m0_fab__tm *tm);
285 static void libfab_poller(
struct m0_fab__tm *
ma);
286 static int libfab_waitfd_init(
struct m0_fab__tm *tm);
287 static void libfab_tm_event_post(
struct m0_fab__tm *tm,
289 static inline void libfab_tm_lock(
struct m0_fab__tm *tm);
290 static inline void libfab_tm_unlock(
struct m0_fab__tm *tm);
291 static inline void libfab_tm_evpost_lock(
struct m0_fab__tm *tm);
292 static inline void libfab_tm_evpost_unlock(
struct m0_fab__tm *tm);
293 static inline bool libfab_tm_is_locked(
const struct m0_fab__tm *tm);
294 static void libfab_buf_complete(
struct m0_fab__buf *
buf);
295 static void libfab_buf_done(
struct m0_fab__buf *
buf,
int rc,
bool add_to_list);
296 static inline struct m0_fab__tm *libfab_buf_tm(
struct m0_fab__buf *
buf);
298 static bool libfab_tm_invariant(
const struct m0_fab__tm *tm);
300 static inline void libfab_ep_get(
struct m0_fab__ep *
ep);
301 static void libfab_ep_release(
struct m0_ref *ref);
302 static uint64_t libfab_mr_keygen(
struct m0_fab__tm *tm);
303 static int libfab_check_for_event(
struct fid_eq *eq, uint32_t *ev);
304 static int libfab_check_for_comp(
struct fid_cq *cq, uint32_t *
ctx,
307 static int libfab_buf_dom_reg(
struct m0_net_buffer *nb,
struct m0_fab__tm *tm);
308 static int libfab_buf_dom_dereg(
struct m0_fab__buf *fbp);
309 static void libfab_pending_bufs_send(
struct m0_fab__ep *
ep);
310 static int libfab_target_notify(
struct m0_fab__buf *
buf);
311 static int libfab_conn_init(
struct m0_fab__ep *
ep,
struct m0_fab__tm *
ma,
312 struct m0_fab__buf *fbp);
313 static int libfab_conn_accept(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm,
314 struct fi_info *info);
315 static int libfab_fab_ep_find(
struct m0_fab__tm *tm,
const char *
name,
317 struct m0_fab__ep **
ep);
319 static void libfab_txep_event_check(
struct m0_fab__ep *txep,
320 struct m0_fab__active_ep *aep,
321 struct m0_fab__tm *tm);
322 static int libfab_txep_init(
struct m0_fab__active_ep *aep,
323 struct m0_fab__tm *tm,
void *
ctx);
324 static int libfab_waitfd_bind(
struct fid*
fid,
struct m0_fab__tm *tm,
326 static int libfab_waitfd_unbind(
struct fid*
fid,
struct m0_fab__tm *tm,
328 static inline struct m0_fab__active_ep *libfab_aep_get(
struct m0_fab__ep *
ep);
329 static int libfab_ping_op(
struct m0_fab__active_ep *
ep,
struct m0_fab__buf *fb);
330 static int libfab_bulk_op(
struct m0_fab__active_ep *
ep,
struct m0_fab__buf *fb);
331 static inline bool libfab_is_verbs(
struct m0_fab__tm *tm);
332 static int libfab_txbuf_list_add(
struct m0_fab__tm *tm,
struct m0_fab__buf *fb,
333 struct m0_fab__active_ep *aep);
334 static void libfab_bufq_process(
struct m0_fab__tm *tm);
335 static uint32_t libfab_buf_token_get(
struct m0_fab__tm *tm,
336 struct m0_fab__buf *fb);
337 static bool libfab_buf_invariant(
const struct m0_fab__buf *
buf);
361 inet_ntop(AF_INET, &
addr->nip_ip_n.sn[0], ip,
362 LIBFAB_ADDR_LEN_MAX);
364 inet_ntop(AF_INET6, &
addr->nip_ip_n.ln[0], ip,
365 LIBFAB_ADDR_LEN_MAX);
388 static int libfab_ep_addr_decode(
struct m0_fab__ep *
ep,
const char *
name)
402 static inline void libfab_tm_lock(
struct m0_fab__tm *tm)
410 static inline void libfab_tm_unlock(
struct m0_fab__tm *tm)
415 static inline int libfab_tm_trylock(
struct m0_fab__tm *tm)
423 static inline void libfab_tm_evpost_lock(
struct m0_fab__tm *tm)
431 static inline void libfab_tm_evpost_unlock(
struct m0_fab__tm *tm)
440 static inline bool libfab_tm_is_locked(
const struct m0_fab__tm *tm)
448 static void libfab_tm_event_post(
struct m0_fab__tm *tm,
455 listen = &tm->ftm_pep->fep_nep;
461 .nte_next_state = state,
464 .nte_tm = tm->ftm_ntm,
472 static void libfab_tm_buf_timeout(
struct m0_fab__tm *ftm)
476 struct m0_fab__buf *fb;
480 M0_PRE(libfab_tm_is_locked(ftm));
481 M0_PRE(libfab_tm_invariant(ftm));
489 libfab_buf_dom_dereg(fb);
490 fb->fb_state = FAB_BUF_TIMEDOUT;
491 libfab_buf_done(fb, -ETIMEDOUT,
false);
495 M0_POST(libfab_tm_invariant(ftm));
505 static void libfab_tm_buf_done(
struct m0_fab__tm *ftm)
507 struct m0_fab__buf *
buffer;
510 M0_PRE(libfab_tm_is_locked(ftm) && libfab_tm_invariant(ftm));
512 libfab_buf_complete(
buffer);
516 if (
nr > 0 && ftm->ftm_ntm->ntm_callback_counter == 0)
518 M0_POST(libfab_tm_invariant(ftm));
530 static uint32_t libfab_handle_connect_request_events(
struct m0_fab__tm *tm)
532 struct m0_fab__ep *
ep =
NULL;
534 struct fi_eq_err_entry eq_err = {};
535 struct fi_eq_cm_entry *cm_entry;
536 char entry[(
sizeof(
struct fi_eq_cm_entry) +
537 sizeof(struct m0_fab__conn_data))];
543 eq = tm->ftm_pep->fep_listen->pep_res.fpr_eq;
545 rc = fi_eq_read(eq, &event, &entry,
sizeof(entry), 0);
547 if (
rc >= (
int)
sizeof(
struct fi_eq_cm_entry) &&
548 event == FI_CONNREQ) {
549 cm_entry = (
struct fi_eq_cm_entry *)entry;
554 rc = libfab_conn_accept(
ep, tm, cm_entry->info);
560 fi_freeinfo(cm_entry->info);
561 }
else if (
rc == -FI_EAVAIL) {
562 rc = fi_eq_readerr(eq, &eq_err, 0);
563 if (
rc !=
sizeof(eq_err))
565 fi_strerror((
int) -
rc));
569 fi_eq_strerror(eq, eq_err.prov_errno,
570 eq_err.err_data,
NULL,
572 }
else if (
rc != -EAGAIN)
578 }
while (ret != -EAGAIN);
586 static void libfab_txep_event_check(
struct m0_fab__ep *txep,
587 struct m0_fab__active_ep *aep,
588 struct m0_fab__tm *tm)
590 struct m0_fab__buf *fbp;
594 if (aep->aep_rx_state == FAB_CONNECTING) {
596 rc = libfab_check_for_event(aep->aep_rx_res.frr_eq,
598 if (
rc >= 0 && event == FI_CONNECTED) {
599 aep->aep_rx_state = FAB_CONNECTED;
600 if (txep == tm->ftm_pep)
601 txep->fep_connlink |=
602 FAB_CONNLINK_RXEP_RDY;
604 }
while (
rc != -EAGAIN);
608 rc = libfab_check_for_event(aep->aep_tx_res.ftr_eq, &event);
610 if (event == FI_CONNECTED) {
611 aep->aep_tx_state = FAB_CONNECTED;
612 if (txep == tm->ftm_pep)
613 txep->fep_connlink |=
614 FAB_CONNLINK_TXEP_RDY;
616 txep->fep_connlink |=
617 FAB_CONNLINK_TXEP_RDY |
618 FAB_CONNLINK_RXEP_RDY;
619 }
else if (event == FI_SHUTDOWN) {
621 if (aep->aep_rx_res.frr_eq !=
NULL) {
622 while (libfab_check_for_event(
623 aep->aep_rx_res.frr_eq,
627 libfab_txep_init(aep, tm, txep);
629 }
else if (
rc == -ECONNREFUSED &&
630 aep->aep_tx_state == FAB_CONNECTING) {
631 libfab_txep_init(aep, tm, txep);
633 libfab_buf_done(fbp,
rc,
false);
636 }
while (
rc != -EAGAIN);
639 if (txep->fep_connlink == FAB_CONNLINK_RDY_TO_SEND) {
640 libfab_pending_bufs_send(txep);
641 txep->fep_connlink = FAB_CONNLINK_PENDING_SEND_DONE;
653 if (aep->aep_tx_state == FAB_CONNECTING &&
656 (
char*)tm->ftm_pep->fep_name.nia_p,
657 (
char*)txep->fep_name.nia_p);
658 libfab_txep_init(aep, tm, txep);
660 libfab_buf_done(fbp, -ECONNREFUSED,
false);
668 static void libfab_rxep_comp_read(
struct fid_cq *cq,
struct m0_fab__ep *
ep,
669 struct m0_fab__tm *tm)
671 struct m0_fab__buf *fb =
NULL;
672 uint32_t
token[FAB_MAX_COMP_READ];
674 uint64_t
data[FAB_MAX_COMP_READ];
681 for (
i = 0;
i <
cnt;
i++) {
682 fb = fab_bufhash_htable_lookup(
683 &tm->ftm_bufhash.bht_hash,
686 if (fb->fb_length == 0)
687 fb->fb_length = len[
i];
689 libfab_buf_done(fb, 0,
false);
692 rem_token = (uint32_t)
data[
i];
693 fb = fab_bufhash_htable_lookup(
694 &tm->ftm_bufhash.bht_hash,
697 libfab_buf_done(fb, 0,
false);
706 static void libfab_txep_comp_read(
struct fid_cq *cq,
struct m0_fab__tm *tm)
708 struct m0_fab__active_ep *aep;
709 struct m0_fab__buf *fb =
NULL;
710 uint32_t
token[FAB_MAX_COMP_READ];
715 for (
i = 0;
i <
cnt;
i++) {
717 fb = fab_bufhash_htable_lookup(
718 &tm->ftm_bufhash.bht_hash,
723 aep = libfab_aep_get(fb->fb_txctx);
725 fab_bufhash_htable_del(
726 &tm->ftm_bufhash.bht_hash, fb);
729 aep->aep_txq_full =
false;
732 if (M0_IN(fb->fb_nb->nb_qtype,
738 aep->aep_bulk_cnt -= fb->fb_wr_cnt;
739 aep->aep_txq_full =
false;
741 libfab_target_notify(fb);
742 libfab_buf_done(fb, 0,
false);
752 static void libfab_poller(
struct m0_fab__tm *tm)
755 struct m0_fab__ev_ctx *
ctx;
756 struct m0_fab__ep *xep;
757 struct m0_fab__active_ep *aep;
759 struct epoll_event ev;
765 while (tm->ftm_state != FAB_TM_SHUTDOWN) {
767 ret = fi_trywait(tm->ftm_fab->fab_fab,
768 tm->ftm_fids.ftf_head,
769 tm->ftm_fids.ftf_cnt);
778 if (!M0_IN(ret, (0, -EAGAIN, -EINVAL)))
783 ret = epoll_wait(tm->ftm_epfd, &ev, 1,
790 err = ret < 0 ? -errno : 0;
791 if (!M0_IN(ret, (-1, 0, 1)))
793 "Unexpected epoll_wait rc=%d",
795 if (ret == -1 && err != -EINTR)
797 "Unexpected epoll_wait err=%d",
799 ev_cnt = ret > 0 ? ret : 0;
804 }
while (err == -EINTR);
808 if (tm->ftm_state == FAB_TM_SHUTDOWN) {
813 ret = libfab_tm_trylock(tm);
824 M0_ASSERT(libfab_tm_is_locked(tm) && libfab_tm_invariant(tm));
827 libfab_handle_connect_request_events(tm);
828 libfab_txep_comp_read(tm->ftm_tx_cq, tm);
832 if (
ctx->evctx_type != FAB_COMMON_Q_EVENT) {
838 aep = libfab_aep_get(xep);
839 libfab_txep_event_check(xep, aep, tm);
840 cq = aep->aep_rx_res.frr_cq;
841 libfab_rxep_comp_read(cq, xep, tm);
849 net = m0_nep_tlist_pop(&tm->ftm_ntm->ntm_end_points);
856 m0_nep_tlist_add_tail(&tm->ftm_ntm->ntm_end_points,
net);
857 xep = libfab_ep(
net);
858 aep = libfab_aep_get(xep);
859 libfab_txep_event_check(xep, aep, tm);
860 cq = aep->aep_rx_res.frr_cq;
861 libfab_rxep_comp_read(cq, xep, tm);
865 libfab_bufq_process(tm);
867 libfab_tm_buf_timeout(tm);
868 libfab_tm_buf_done(tm);
871 libfab_tm_unlock(tm);
889 struct m0_fab__ep **
ep)
906 static bool libfab_ep_find_by_str(
const char *
name,
908 struct m0_fab__ep **
ep)
913 strcmp((libfab_ep(
net))->fep_name.nia_p,
name) == 0);
933 struct m0_fab__ep *
ep;
934 struct m0_fab__active_ep *aep;
936 struct m0_fab__tm *
ma;
946 found = libfab_ep_find_by_num(&net_ip, tm, &
ep);
956 rc = libfab_ep_create(tm, net_ip.
nia_p,
addr, epp);
961 wc = strchr(
name,
'*');
967 ep->fep_name.nia_n.nip_port !=
969 ep->fep_name.nia_n.nip_ip_n.sn[0] =
971 ep->fep_name.nia_n.nip_port =
973 ep->fep_name.nia_n.nip_fmt_pvt.la.nla_tmid =
975 libfab_ep_pton(&
ep->fep_name,
977 aep = libfab_aep_get(
ep);
979 if (aep->aep_tx_state == FAB_CONNECTED)
980 rc = libfab_txep_init(aep,
ma,
ep);
1000 struct m0_fab__ep *
ep =
NULL;
1011 if (
ep->fep_aep ==
NULL) {
1018 rc = libfab_ep_addr_decode(
ep,
name);
1020 libfab_aep_param_free(
ep->fep_aep,
ma);
1030 addr->nip_fmt_pvt.la.nla_autotm) {
1031 ep->fep_name.nia_n.nip_port =
addr->nip_port;
1032 ep->fep_name.nia_n.nip_fmt_pvt.la.nla_tmid =
1033 addr->nip_fmt_pvt.la.nla_tmid;
1036 rc = libfab_active_ep_create(
ep,
ma);
1038 libfab_aep_param_free(
ep->fep_aep,
ma);
1043 fab_sndbuf_tlist_init(&
ep->fep_sndbuf);
1044 *epp = &
ep->fep_nep;
1051 static int libfab_tm_res_init(
struct m0_fab__tm *tm)
1053 struct m0_fab__fab *fab;
1054 struct m0_fab__passive_ep *pep;
1055 struct fi_cq_attr cq_attr = {};
1060 pep = tm->ftm_pep->fep_listen;
1063 cq_attr.wait_obj = FI_WAIT_FD;
1064 cq_attr.wait_cond = FI_CQ_COND_NONE;
1065 cq_attr.format = FI_CQ_FORMAT_DATA;
1066 cq_attr.size = FAB_MAX_TX_CQ_EV;
1067 rc = fi_cq_open(fab->fab_dom, &cq_attr, &tm->ftm_tx_cq,
NULL);
1072 tm->ftm_txcq_ctx.evctx_type = FAB_COMMON_Q_EVENT;
1073 tm->ftm_txcq_ctx.evctx_ep =
NULL;
1074 tm->ftm_txcq_ctx.evctx_dbg =
"txep cq";
1075 rc = libfab_waitfd_bind(&tm->ftm_tx_cq->fid, tm, &tm->ftm_txcq_ctx);
1079 return M0_RC(libfab_txep_init(pep->pep_aep, tm, tm->ftm_pep));
1086 static int libfab_ep_txres_init(
struct m0_fab__active_ep *aep,
1087 struct m0_fab__tm *tm,
void *
ctx)
1089 struct fi_eq_attr eq_attr = {};
1090 struct m0_fab__fab *fab;
1096 rc = fi_ep_bind(aep->aep_txep, &tm->ftm_tx_cq->fid,
1097 FI_TRANSMIT | FI_RECV | FI_SELECTIVE_COMPLETION);
1102 eq_attr.wait_obj = FI_WAIT_FD;
1103 eq_attr.size = FAB_MAX_AEP_EQ_EV;
1104 rc = fi_eq_open(fab->fab_fab, &eq_attr, &aep->aep_tx_res.ftr_eq,
NULL);
1108 aep->aep_tx_res.ftr_ctx.evctx_type = FAB_PRIVATE_Q_EVENT;
1109 aep->aep_tx_res.ftr_ctx.evctx_ep =
ctx;
1110 aep->aep_tx_res.ftr_ctx.evctx_dbg =
"txep eq";
1111 rc = libfab_waitfd_bind(&aep->aep_tx_res.ftr_eq->fid, tm,
1112 &aep->aep_tx_res.ftr_ctx);
1116 rc = fi_ep_bind(aep->aep_txep, &aep->aep_tx_res.ftr_eq->fid, 0);
1125 static int libfab_ep_rxres_init(
struct m0_fab__active_ep *aep,
1126 struct m0_fab__tm *tm,
void *
ctx)
1128 struct fi_cq_attr cq_attr = {};
1129 struct fi_eq_attr eq_attr = {};
1130 struct m0_fab__fab *fab;
1136 cq_attr.wait_obj = FI_WAIT_FD;
1137 cq_attr.wait_cond = FI_CQ_COND_NONE;
1138 cq_attr.format = FI_CQ_FORMAT_DATA;
1139 cq_attr.size = FAB_MAX_RX_CQ_EV;
1140 rc = fi_cq_open(fab->fab_dom, &cq_attr, &aep->aep_rx_res.frr_cq,
NULL);
1144 aep->aep_rx_res.frr_cq_ctx.evctx_type = FAB_PRIVATE_Q_EVENT;
1145 aep->aep_rx_res.frr_cq_ctx.evctx_ep =
ctx;
1146 aep->aep_rx_res.frr_cq_ctx.evctx_dbg =
"rxep cq";
1147 rc = libfab_waitfd_bind(&aep->aep_rx_res.frr_cq->fid, tm,
1148 &aep->aep_rx_res.frr_cq_ctx);
1152 rc = fi_ep_bind(aep->aep_rxep, &tm->ftm_tx_cq->fid,
1153 FI_TRANSMIT | FI_SELECTIVE_COMPLETION) ? :
1154 fi_ep_bind(aep->aep_rxep, &aep->aep_rx_res.frr_cq->fid, FI_RECV);
1159 eq_attr.wait_obj = FI_WAIT_FD;
1160 eq_attr.size = FAB_MAX_AEP_EQ_EV;
1161 aep->aep_rx_res.frr_eq_ctx.evctx_type = FAB_PRIVATE_Q_EVENT;
1162 aep->aep_rx_res.frr_eq_ctx.evctx_ep =
ctx;
1163 aep->aep_rx_res.frr_eq_ctx.evctx_dbg =
"rxep eq";
1164 rc = fi_eq_open(fab->fab_fab, &eq_attr, &aep->aep_rx_res.frr_eq,
1166 libfab_waitfd_bind(&aep->aep_rx_res.frr_eq->fid, tm,
1167 &aep->aep_rx_res.frr_eq_ctx) ? :
1168 fi_ep_bind(aep->aep_rxep, &aep->aep_rx_res.frr_eq->fid, 0) ? :
1169 fi_ep_bind(aep->aep_rxep, &tm->ftm_rctx->fid, 0);
1178 static int libfab_pep_res_init(
struct m0_fab__passive_ep *pep,
1179 struct m0_fab__tm *tm,
void *
ctx)
1181 struct fi_eq_attr eq_attr = {};
1185 eq_attr.wait_obj = FI_WAIT_FD;
1186 eq_attr.size = FAB_MAX_PEP_EQ_EV;
1187 rc = fi_eq_open(tm->ftm_fab->fab_fab, &eq_attr, &pep->pep_res.fpr_eq,
1192 pep->pep_res.fpr_ctx.evctx_type = FAB_COMMON_Q_EVENT;
1193 pep->pep_res.fpr_ctx.evctx_ep =
ctx;
1194 pep->pep_res.fpr_ctx.evctx_dbg =
"pep eq";
1195 rc = libfab_waitfd_bind(&pep->pep_res.fpr_eq->fid, tm,
1196 &pep->pep_res.fpr_ctx) ? :
1197 fi_pep_bind(pep->pep_pep, &pep->pep_res.fpr_eq->fid, 0);
1205 static int libfab_conn_accept(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm,
1206 struct fi_info *info)
1208 struct m0_fab__active_ep *aep;
1209 struct fid_domain *dp;
1212 M0_ENTRY(
"from ep=%s -> tm=%s", (
char*)
ep->fep_name.nia_p,
1213 (
char*)tm->ftm_pep->fep_name.nia_p);
1215 aep = libfab_aep_get(
ep);
1216 dp = tm->ftm_fab->fab_dom;
1218 if (aep->aep_rxep !=
NULL) {
1219 rc = fi_close(&aep->aep_rxep->fid);
1222 libfab_ep_rxres_free(&aep->aep_rx_res, tm);
1224 aep->aep_rx_state = FAB_NOT_CONNECTED;
1225 ep->fep_connlink = FAB_CONNLINK_DOWN;
1227 rc = fi_endpoint(dp, info, &aep->aep_rxep,
NULL) ? :
1228 libfab_ep_rxres_init(aep, tm,
ep) ? :
1229 fi_enable(aep->aep_rxep) ? :
1230 fi_accept(aep->aep_rxep,
NULL, 0);
1233 libfab_aep_param_free(aep, tm);
1237 aep->aep_rx_state = FAB_CONNECTING;
1245 static int libfab_active_ep_create(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm)
1248 struct m0_fab__active_ep *aep;
1253 rc = libfab_txep_init(aep, tm,
ep);
1255 libfab_aep_param_free(aep, tm);
1260 net->nep_xprt_pvt =
ep;
1261 net->nep_tm = tm->ftm_ntm;
1262 libfab_ep_pton(&
ep->fep_name, &
ep->fep_name_n);
1263 m0_nep_tlink_init_at_tail(
net, &tm->ftm_ntm->ntm_end_points);
1264 net->nep_addr = (
const char *)(&
ep->fep_name.nia_p);
1274 static int libfab_passive_ep_create(
struct m0_fab__ep *
ep,
1275 struct m0_fab__tm *tm)
1277 struct m0_fab__passive_ep *pep;
1278 struct fi_info *hints;
1280 enum m0_fab__prov_type idx;
1283 char addr[LIBFAB_ADDR_LEN_MAX] = {};
1284 char port[LIBFAB_PORT_LEN_MAX] = {};
1287 (
char*)
ep->fep_name.nia_p,
1288 ep->fep_name.nia_n.nip_ip_n.ln[0],
1289 ep->fep_name.nia_n.nip_ip_n.ln[1],
1290 (
int)
ep->fep_name.nia_n.nip_port);
1293 if (
ep->fep_listen ==
NULL)
1296 if (
ep->fep_listen->pep_aep ==
NULL) {
1301 pep =
ep->fep_listen;
1302 ep->fep_listen->pep_aep->aep_rxep =
NULL;
1303 ep->fep_listen->pep_aep->aep_txep =
NULL;
1305 libfab_straddr_gen(&
ep->fep_name.nia_n,
addr);
1308 hints = fi_allocinfo();
1309 if (hints ==
NULL) {
1315 hints->ep_attr->type = FI_EP_MSG;
1316 hints->caps = FI_MSG | FI_RMA;
1317 hints->mode |= FI_RX_CQ_DATA;
1318 hints->domain_attr->mr_mode = FI_MR_LOCAL | FI_MR_ALLOCATED |
1319 FI_MR_PROV_KEY | FI_MR_VIRT_ADDR;
1320 hints->domain_attr->cq_data_size = 4;
1322 for (idx = 0; idx < FAB_FABRIC_PROV_MAX; idx++) {
1323 hints->fabric_attr->prov_name = (
char *)providers[idx];
1324 rc = fi_getinfo(LIBFAB_VERSION,
addr,
port, FI_SOURCE, hints,
1336 (
char*)
ep->fep_name.nia_p,
fi->fabric_attr->prov_name);
1337 hints->fabric_attr->prov_name =
NULL;
1338 tm->ftm_fab->fab_fi =
fi;
1339 tm->ftm_fab->fab_prov = idx;
1340 tm->ftm_fab->fab_max_iov =
min32u(
fi->tx_attr->iov_limit,
1341 fi->tx_attr->rma_iov_limit);
1344 M0_ALLOC_ARR(tm->ftm_rem_iov, tm->ftm_fab->fab_max_iov);
1345 M0_ALLOC_ARR(tm->ftm_loc_iov, tm->ftm_fab->fab_max_iov);
1346 if (tm->ftm_rem_iov ==
NULL || tm->ftm_loc_iov ==
NULL) {
1352 rc = fi_fabric(tm->ftm_fab->fab_fi->fabric_attr, &tm->ftm_fab->fab_fab,
1354 libfab_waitfd_init(tm) ? :
1355 fi_passive_ep(tm->ftm_fab->fab_fab, tm->ftm_fab->fab_fi,
1356 &pep->pep_pep,
NULL) ? :
1357 libfab_pep_res_init(pep, tm,
ep) ? :
1358 fi_listen(pep->pep_pep) ? :
1359 fi_domain(tm->ftm_fab->fab_fab, tm->ftm_fab->fab_fi,
1360 &tm->ftm_fab->fab_dom,
NULL);
1363 libfab_pep_param_free(pep, tm);
1367 rx_size = tm->ftm_fab->fab_fi->rx_attr->size;
1368 tm->ftm_fab->fab_fi->rx_attr->size = FAB_MAX_SRX_SIZE;
1369 rc = fi_srx_context(tm->ftm_fab->fab_dom, tm->ftm_fab->fab_fi->rx_attr,
1370 &tm->ftm_rctx,
NULL);
1371 tm->ftm_fab->fab_fi->rx_attr->size = rx_size;
1374 libfab_pep_param_free(pep, tm);
1378 rc = libfab_tm_res_init(tm);
1381 libfab_pep_param_free(pep, tm);
1385 fab_sndbuf_tlist_init(&
ep->fep_sndbuf);
1386 m0_ref_init(&tm->ftm_pep->fep_nep.nep_ref, 1, &libfab_ep_release);
1387 libfab_ep_get(tm->ftm_pep);
1395 static int libfab_pep_res_free(
struct m0_fab__pep_res *pep_res,
1396 struct m0_fab__tm *tm)
1400 if (pep_res->fpr_eq !=
NULL) {
1401 rc = libfab_waitfd_unbind(&pep_res->fpr_eq->fid, tm,
1405 rc = fi_close(&pep_res->fpr_eq->fid);
1408 rc, (
int)pep_res->fpr_eq->fid.fclass);
1409 pep_res->fpr_eq =
NULL;
1418 static int libfab_ep_txres_free(
struct m0_fab__tx_res *tx_res,
1419 struct m0_fab__tm *tm)
1423 if (tx_res->ftr_eq !=
NULL) {
1424 rc = libfab_waitfd_unbind(&tx_res->ftr_eq->fid, tm,
1428 rc = fi_close(&tx_res->ftr_eq->fid);
1431 rc, (
int)tx_res->ftr_eq->fid.fclass);
1432 tx_res->ftr_eq =
NULL;
1441 static int libfab_ep_rxres_free(
struct m0_fab__rx_res *rx_res,
1442 struct m0_fab__tm *tm)
1446 if (rx_res->frr_eq !=
NULL) {
1447 rc = libfab_waitfd_unbind(&rx_res->frr_eq->fid, tm,
1448 &rx_res->frr_eq_ctx);
1451 rc = fi_close(&rx_res->frr_eq->fid);
1454 rc, (
int)rx_res->frr_eq->fid.fclass);
1455 rx_res->frr_eq =
NULL;
1458 if (rx_res->frr_cq !=
NULL) {
1459 rc = libfab_waitfd_unbind(&rx_res->frr_cq->fid, tm,
1460 &rx_res->frr_cq_ctx);
1463 rc = fi_close(&rx_res->frr_cq->fid);
1466 rc, (
int)rx_res->frr_cq->fid.fclass);
1467 rx_res->frr_cq =
NULL;
1476 static int libfab_aep_param_free(
struct m0_fab__active_ep *aep,
1477 struct m0_fab__tm *tm)
1483 if (aep->aep_txep !=
NULL) {
1484 rc = fi_close(&aep->aep_txep->fid);
1487 rc, (
int)aep->aep_txep->fid.fclass);
1488 aep->aep_txep =
NULL;
1491 if (aep->aep_rxep !=
NULL) {
1492 rc = fi_close(&aep->aep_rxep->fid);
1495 rc, (
int)aep->aep_rxep->fid.fclass);
1496 aep->aep_rxep =
NULL;
1499 rc = libfab_ep_txres_free(&aep->aep_tx_res, tm);
1503 rc = libfab_ep_rxres_free(&aep->aep_rx_res, tm);
1515 static int libfab_pep_param_free(
struct m0_fab__passive_ep *pep,
1516 struct m0_fab__tm *tm)
1523 if (pep->pep_pep !=
NULL) {
1524 rc = fi_close(&pep->pep_pep->fid);
1527 rc, (
int)pep->pep_pep->fid.fclass);
1528 pep->pep_pep =
NULL;
1531 rc = libfab_aep_param_free(pep->pep_aep, tm);
1535 rc = libfab_pep_res_free(&pep->pep_res, tm);
1547 static int libfab_ep_param_free(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm)
1554 rc = libfab_pep_param_free(
ep->fep_listen, tm) ? :
1555 libfab_aep_param_free(
ep->fep_aep, tm);
1566 static int libfab_tm_param_free(
struct m0_fab__tm *tm)
1568 struct m0_fab__bulk_op *
op;
1570 struct m0_fab__ep *xep;
1571 struct m0_fab__buf *fbp;
1577 if (tm->ftm_poller.t_func !=
NULL) {
1584 xep = libfab_ep(
net);
1585 rc = libfab_ep_param_free(xep, tm);
1587 M0_ASSERT(m0_nep_tlist_is_empty(&tm->ftm_ntm->ntm_end_points));
1588 tm->ftm_ntm->ntm_ep =
NULL;
1590 if (tm->ftm_rctx !=
NULL) {
1591 rc = fi_close(&tm->ftm_rctx->fid);
1594 rc, (
int)tm->ftm_rctx->fid.fclass);
1595 tm->ftm_rctx =
NULL;
1598 if (tm->ftm_tx_cq !=
NULL) {
1599 rc = libfab_waitfd_unbind(&tm->ftm_tx_cq->fid, tm,
1603 rc = fi_close(&tm->ftm_tx_cq->fid);
1606 rc, (
int)tm->ftm_tx_cq->fid.fclass);
1607 tm->ftm_tx_cq =
NULL;
1610 close(tm->ftm_epfd);
1611 m0_free(tm->ftm_fids.ftf_head);
1612 m0_free(tm->ftm_fids.ftf_ctx);
1616 m0_htable_for(fab_bufhash, fbp, &tm->ftm_bufhash.bht_hash) {
1617 fab_bufhash_htable_del(&tm->ftm_bufhash.bht_hash, fbp);
1619 fab_bufhash_htable_fini(&tm->ftm_bufhash.bht_hash);
1624 fab_bulk_tlist_fini(&tm->ftm_bulk);
1633 static int libfab_waitfd_init(
struct m0_fab__tm *tm)
1635 M0_PRE(tm->ftm_epfd == -1);
1637 tm->ftm_epfd = epoll_create(1);
1638 if (tm->ftm_epfd < 0)
1647 static inline struct m0_fab__tm *libfab_buf_tm(
struct m0_fab__buf *
buf)
1649 return buf->fb_nb->nb_tm->ntm_xprt_private;
1663 static void libfab_buf_fini(
struct m0_fab__buf *
buf)
1665 struct m0_fab__buf *fbp;
1669 libfab_buf_invariant(
buf);
1671 fab_buf_tlink_fini(
buf);
1674 if (
buf->fb_bulk_op !=
NULL && fab_bulk_tlink_is_in(
buf->fb_bulk_op)) {
1675 fab_bulk_tlist_del(
buf->fb_bulk_op);
1681 fbp =
m0_tl_find(fab_sndbuf, fbp, &
buf->fb_txctx->fep_sndbuf,
1684 fab_sndbuf_tlist_del(fbp);
1699 buf->fb_state = (
buf->fb_state == FAB_BUF_CANCELED ||
1700 buf->fb_state == FAB_BUF_TIMEDOUT) ?
1701 FAB_BUF_INITIALIZED : FAB_BUF_REGISTERED;
1711 struct m0_fab__ndom *fnd =
dom->nd_xprt_private;
1712 return _0C(!fab_fabs_tlist_is_empty(&fnd->fnd_fabrics)) &&
1713 _0C(
dom->nd_xprt == &m0_net_libfab_xprt);
1719 static bool libfab_tm_invariant(
const struct m0_fab__tm *fab_tm)
1721 return fab_tm !=
NULL &&
1722 fab_tm->ftm_ntm->ntm_xprt_private == fab_tm &&
1723 libfab_dom_invariant(fab_tm->ftm_ntm->ntm_dom);
1729 static bool libfab_buf_invariant(
const struct m0_fab__buf *
buf)
1744 static void libfab_buf_complete(
struct m0_fab__buf *
buf)
1746 struct m0_fab__tm *
ma = libfab_buf_tm(
buf);
1750 .nbe_status =
buf->fb_status,
1754 M0_ENTRY(
"fb=%p nb=%p q=%d rc=%d",
buf, nb,
buf->fb_nb->nb_qtype,
1765 libfab_ep_get(
buf->fb_ev_ep);
1768 ma->ftm_ntm->ntm_callback_counter++;
1770 fab_bufhash_htable_del(&
ma->ftm_bufhash.bht_hash,
buf);
1771 libfab_buf_fini(
buf);
1773 libfab_tm_evpost_lock(
ma);
1774 libfab_tm_unlock(
ma);
1777 libfab_tm_evpost_unlock(
ma);
1781 ma->ftm_ntm->ntm_callback_counter--;
1789 static int libfab_dummy_msg_rcv_chk(
struct m0_fab__buf *fbp)
1791 struct m0_fab__tm *
ma = libfab_buf_tm(fbp);
1793 struct m0_fab__buf *pas_buf;
1799 if (fbp->fb_length == (
sizeof(uint32_t) * 2)) {
1801 if (*
ptr == FAB_DUMMY_DATA) {
1804 pas_buf = fab_bufhash_htable_lookup(
1805 &
ma->ftm_bufhash.bht_hash,
1807 if (pas_buf !=
NULL)
1808 libfab_buf_complete(pas_buf);
1819 fbp->fb_mr.bm_desc, 1, 0,
1820 U32_TO_VPTR(fbp->fb_token)) == 0);
1831 static void libfab_buf_done(
struct m0_fab__buf *
buf,
int rc,
bool add_to_list)
1833 struct m0_fab__tm *
ma = libfab_buf_tm(
buf);
1837 (
int)
buf->fb_length,
rc);
1843 if (!fab_buf_tlink_is_in(
buf)) {
1844 buf->fb_status =
buf->fb_status == 0 ?
rc :
buf->fb_status;
1847 if (libfab_dummy_msg_rcv_chk(
buf) != 0)
1848 libfab_buf_complete(
buf);
1854 buf->fb_status =
rc;
1855 fab_buf_tlist_add_tail(&
ma->ftm_done,
buf);
1863 static inline void libfab_ep_get(
struct m0_fab__ep *
ep)
1874 static void libfab_ep_release(
struct m0_ref *ref)
1877 struct m0_fab__ep *
ep;
1878 struct m0_fab__tm *tm;
1881 ep = libfab_ep(nep);
1885 m0_nep_tlist_del(nep);
1886 libfab_ep_param_free(
ep, tm);
1892 static uint64_t libfab_mr_keygen(
struct m0_fab__tm *tm)
1894 uint64_t
key = FAB_MR_KEY + tm->ftm_mr_key_idx;
1895 tm->ftm_mr_key_idx++;
1902 static int libfab_check_for_event(
struct fid_eq *eq, uint32_t *ev)
1904 struct fi_eq_cm_entry entry;
1909 rc = fi_eq_read(eq, &event, &entry,
sizeof(entry), 0);
1910 if (
rc == -FI_EAVAIL) {
1916 fi_eq_strerror(eq,
err_entry.prov_errno,
1920 *ev =
rc < 0 ? 0xFF : event;
1929 static int libfab_check_for_comp(
struct fid_cq *cq, uint32_t *
ctx,
1932 struct fi_cq_data_entry entry[FAB_MAX_COMP_READ];
1934 uint64_t wr_cqdata = FI_REMOTE_WRITE | FI_REMOTE_CQ_DATA;
1938 ret = fi_cq_read(cq, entry, FAB_MAX_COMP_READ);
1940 for (
i = 0;
i < ret;
i++) {
1941 ctx[
i] = entry[
i].op_context ==
NULL ? 0 :
1942 VPTR_TO_U32(entry[
i].op_context);
1944 len[
i] = entry[
i].len;
1946 data[
i] = ((entry[
i].flags & wr_cqdata)) ?
1949 }
else if (ret != -FI_EAGAIN) {
1954 fi_cq_strerror(cq,
err_entry.prov_errno,
1972 if (
ma->ftm_state != FAB_TM_SHUTDOWN) {
1976 libfab_tm_unlock(
ma);
1982 ma->ftm_state = FAB_TM_SHUTDOWN;
1985 libfab_tm_buf_done(
ma);
1987 rc = libfab_tm_param_free(
ma);
1993 libfab_tm_unlock(
ma);
2002 static int libfab_bdesc_encode(
struct m0_fab__buf *
buf)
2004 struct m0_fab__bdesc *fbd;
2005 struct fi_rma_iov *iov;
2008 struct m0_fab__tm *tm = libfab_buf_ma(nb);
2012 bool is_verbs = libfab_is_verbs(tm);
2014 M0_PRE(seg_nr <= nd->fnd_seg_nr);
2016 nbd->
nbd_len = (
sizeof(
struct m0_fab__bdesc) +
2017 (sizeof(struct fi_rma_iov) *
seg_nr));
2020 return M0_RC(-ENOMEM);
2022 fbd = (
struct m0_fab__bdesc *)nbd->
nbd_data;
2023 fbd->fbd_netaddr = tm->ftm_pep->fep_name.nia_n;
2024 fbd->fbd_buftoken =
buf->fb_token;
2026 fbd->fbd_iov_cnt = (uint32_t)
seg_nr;
2027 iov = (
struct fi_rma_iov *)(nbd->
nbd_data +
2028 sizeof(
struct m0_fab__bdesc));
2032 iov[
i].key = fi_mr_key(
buf->fb_mr.bm_mr[
i]);
2042 static void libfab_bdesc_decode(
struct m0_fab__buf *fb,
2050 sizeof(
struct m0_fab__bdesc));
2051 *
addr = fb->fb_rbd->fbd_netaddr;
2052 M0_ASSERT(fb->fb_rbd->fbd_iov_cnt <= ndom->fnd_seg_nr);
2058 static int libfab_buf_dom_reg(
struct m0_net_buffer *nb,
struct m0_fab__tm *tm)
2060 struct m0_fab__buf *fbp;
2061 struct m0_fab__buf_mr *mr;
2062 struct m0_fab__ndom *ndom;
2063 struct fid_domain *dp;
2074 dp = tm->ftm_fab->fab_dom;
2080 if (fbp->fb_dp == dp)
2083 if (fbp->fb_state == FAB_BUF_REGISTERED)
2094 while (ret != 0 && retry_cnt > 0) {
2095 key = libfab_mr_keygen(tm);
2098 FAB_MR_ACCESS, FAB_MR_OFFSET,
key,
2099 FAB_MR_FLAG, &mr->bm_mr[
i],
NULL);
2109 mr->bm_desc[
i] = fi_mr_desc(mr->bm_mr[
i]);
2114 fbp->fb_state = FAB_BUF_REGISTERED;
2124 static void libfab_pending_bufs_send(
struct m0_fab__ep *
ep)
2126 struct m0_fab__active_ep *aep;
2127 struct m0_fab__buf *fbp;
2131 aep = libfab_aep_get(
ep);
2139 ret = libfab_txbuf_list_add(libfab_buf_ma(nb),
2147 libfab_buf_done(fbp, ret,
false);
2151 libfab_bufq_process(libfab_buf_ma(nb));
2158 static int libfab_target_notify(
struct m0_fab__buf *
buf)
2160 struct m0_fab__active_ep *aep;
2161 struct m0_fab__buf *fbp;
2162 struct m0_fab__tm *tm;
2164 struct fi_msg op_msg;
2168 aep = libfab_aep_get(
buf->fb_txctx);
2172 aep->aep_tx_state == FAB_CONNECTED) {
2178 fbp->fb_dummy[0] = FAB_DUMMY_DATA;
2179 fbp->fb_dummy[1] =
buf->fb_rbd->fbd_buftoken;
2180 fbp->fb_txctx =
buf->fb_txctx;
2181 tm = libfab_buf_tm(
buf);
2182 fbp->fb_token = libfab_buf_token_get(tm, fbp);
2183 aep->aep_bulk_cnt++;
2185 fab_bufhash_htable_add(&tm->ftm_bufhash.bht_hash, fbp);
2187 iv.iov_base = fbp->fb_dummy;
2188 iv.iov_len =
sizeof(fbp->fb_dummy);
2189 op_msg.msg_iov = &iv;
2191 op_msg.iov_count = 1;
2193 op_msg.context = U32_TO_VPTR(fbp->fb_token);
2196 ret = fi_sendmsg(aep->aep_txep, &op_msg, FI_COMPLETION);
2200 fab_bufhash_htable_del(&tm->ftm_bufhash.bht_hash, fbp);
2201 --aep->aep_bulk_cnt;
2212 static struct m0_fab__fab *libfab_newfab_init(
struct m0_fab__ndom *fnd)
2214 struct m0_fab__fab *fab =
NULL;
2218 fab_fabs_tlink_init_at_tail(fab, &fnd->fnd_fabrics);
2226 static int libfab_dns_resolve_retry(
struct m0_fab__ep *
ep)
2231 char *fqdn = en->
nia_p;
2232 char ip[LIBFAB_ADDR_LEN_MAX] = {};
2236 fqdn = strchr(fqdn,
':');
2237 fqdn = strchr(fqdn + 1,
':');
2245 libfab_ep_pton(en, &
ep->fep_name_n);
2250 rc > 0 ?
"gethostbyname()" :
"hostname_to_ip()",
2261 static int libfab_conn_init(
struct m0_fab__ep *
ep,
struct m0_fab__tm *
ma,
2262 struct m0_fab__buf *fbp)
2264 struct m0_fab__active_ep *aep;
2266 size_t cm_max_size = 0;
2267 size_t opt_size =
sizeof(size_t);
2268 struct m0_fab__conn_data cd;
2271 aep = libfab_aep_get(
ep);
2272 if (aep->aep_tx_state == FAB_NOT_CONNECTED) {
2277 libfab_dns_resolve_retry(
ep);
2278 dst =
ep->fep_name_n | 0x02;
2279 cd.fcd_addr =
ma->ftm_pep->fep_name.nia_n;
2281 ret = fi_getopt(&aep->aep_txep->fid, FI_OPT_ENDPOINT,
2282 FI_OPT_CM_DATA_SIZE,
2283 &cm_max_size, &opt_size);
2284 M0_ASSERT(ret == 0 &&
sizeof(cd) < cm_max_size);
2286 ret = fi_connect(aep->aep_txep, &
dst, &cd,
sizeof(cd));
2288 aep->aep_tx_state = FAB_CONNECTING;
2290 FAB_CONNECTING_TMOUT, 0);
2297 fab_sndbuf_tlink_init_at_tail(fbp, &
ep->fep_sndbuf);
2307 if (ret == -ECONNREFUSED) {
2308 libfab_buf_done(fbp, -ECONNREFUSED,
true);
2320 static int libfab_fab_ep_find(
struct m0_fab__tm *tm,
const char *
name,
2322 struct m0_fab__ep **
ep)
2330 *
ep = libfab_ep(
net);
2340 uint32_t
addr =
name->nia_n.nip_ip_n.sn[0];
2341 uint32_t
port =
name->nia_n.nip_port;
2356 static int libfab_txep_init(
struct m0_fab__active_ep *aep,
2357 struct m0_fab__tm *tm,
void *
ctx)
2359 struct m0_fab__ep *
ep = (
struct m0_fab__ep *)
ctx;
2361 struct m0_fab__fab *fab = tm->ftm_fab;
2362 struct fi_info *info;
2363 struct fi_info *hints =
NULL;
2365 char ip[LIBFAB_ADDR_LEN_MAX] = {};
2366 char port[LIBFAB_PORT_LEN_MAX] = {};
2368 if (aep->aep_txep !=
NULL) {
2369 rc = fi_close(&aep->aep_txep->fid);
2373 rc = libfab_ep_txres_free(&aep->aep_tx_res, tm);
2377 aep->aep_tx_state = FAB_NOT_CONNECTED;
2378 aep->aep_txq_full =
false;
2379 ep->fep_connlink = FAB_CONNLINK_DOWN;
2381 hints = fi_allocinfo();
2384 hints->ep_attr->type = FI_EP_MSG;
2385 hints->caps = FI_MSG | FI_RMA;
2387 hints->mode |= FI_RX_CQ_DATA;
2388 hints->domain_attr->cq_data_size = 4;
2389 hints->domain_attr->mr_mode = FI_MR_LOCAL | FI_MR_ALLOCATED |
2390 FI_MR_PROV_KEY | FI_MR_VIRT_ADDR;
2391 hints->fabric_attr->prov_name = fab->fab_fi->fabric_attr->prov_name;
2393 libfab_straddr_gen(&en->
nia_n, ip);
2395 rc = fi_getinfo(LIBFAB_VERSION, ip,
port, 0, hints, &info);
2397 hints->fabric_attr->prov_name =
NULL;
2402 rc = fi_endpoint(fab->fab_dom, info, &aep->aep_txep,
NULL) ? :
2403 libfab_ep_txres_init(aep, tm,
ctx) ? :
2404 fi_enable(aep->aep_txep);
2406 hints->fabric_attr->prov_name =
NULL;
2418 static int libfab_fid_array_grow(
struct m0_fab__tm_fids *tmfid, uint32_t incr)
2420 struct m0_fab__ev_ctx **old_ctx = tmfid->ftf_ctx;
2421 struct m0_fab__ev_ctx **new_ctx =
NULL;
2422 struct fid **old_fid = tmfid->ftf_head;
2424 uint32_t old_size = tmfid->ftf_arr_size;
2425 uint32_t new_size = old_size + incr;
2428 M0_PRE(old_ctx !=
NULL && old_fid !=
NULL && old_size < new_size);
2439 for (
i = 0;
i < old_size;
i++) {
2440 new_ctx[
i] = old_ctx[
i];
2443 tmfid->ftf_ctx = new_ctx;
2445 tmfid->ftf_arr_size = new_size;
2447 M0_LOG(
M0_DEBUG,
"old={fid=%p ctx=%p size=%d} new={fid=%p ctx=%p size=%d}",
2448 old_fid, old_ctx, old_size,
new_fid, new_ctx, new_size);
2460 static int libfab_waitfd_bind(
struct fid*
fid,
struct m0_fab__tm *tm,
void *
ctx)
2462 struct m0_fab__tm_fids *tmfid = &tm->ftm_fids;
2463 struct m0_fab__ev_ctx *
ptr =
ctx;
2464 struct epoll_event ev;
2468 rc = fi_control(
fid, FI_GETWAIT, &
fd);
2472 ev.events = EPOLLIN;
2475 ptr->evctx_dbg,
fid,
fd,
ctx, tm, (
int)tmfid->ftf_cnt);
2476 rc = epoll_ctl(tm->ftm_epfd, EPOLL_CTL_ADD,
fd, &ev);
2479 if (tmfid->ftf_cnt >= (tmfid->ftf_arr_size - 1)) {
2480 rc = libfab_fid_array_grow(tmfid,
2481 FAB_TM_FID_MALLOC_STEP);
2485 tmfid->ftf_head[tmfid->ftf_cnt] =
fid;
2486 tmfid->ftf_ctx[tmfid->ftf_cnt] =
ptr;
2487 ptr->evctx_pos = tmfid->ftf_cnt;
2489 M0_ASSERT(tmfid->ftf_cnt < tmfid->ftf_arr_size);
2499 static int libfab_waitfd_unbind(
struct fid*
fid,
struct m0_fab__tm *tm,
2502 struct m0_fab__tm_fids *tmfid = &tm->ftm_fids;
2503 struct m0_fab__ev_ctx *
ptr =
ctx;
2504 struct epoll_event ev = {};
2509 rc = fi_control(
fid, FI_GETWAIT, &
fd);
2513 rc = epoll_ctl(tm->ftm_epfd, EPOLL_CTL_DEL,
fd, &ev);
2517 for (
i =
ptr->evctx_pos; i < tmfid->ftf_cnt - 1;
i++) {
2518 tmfid->ftf_head[
i] = tmfid->ftf_head[
i + 1];
2519 tmfid->ftf_ctx[
i] = tmfid->ftf_ctx[
i + 1];
2520 tmfid->ftf_ctx[
i]->evctx_pos--;
2523 tmfid->ftf_head[tmfid->ftf_cnt] = 0;
2524 tmfid->ftf_ctx[tmfid->ftf_cnt] = 0;
2534 static inline struct m0_fab__active_ep *libfab_aep_get(
struct m0_fab__ep *
ep)
2536 return ep->fep_listen ==
NULL ?
ep->fep_aep :
ep->fep_listen->pep_aep;
2542 static inline bool libfab_is_verbs(
struct m0_fab__tm *tm)
2544 return tm->ftm_fab->fab_prov == FAB_FABRIC_PROV_VERBS;
2550 static int libfab_txbuf_list_add(
struct m0_fab__tm *tm,
struct m0_fab__buf *fb,
2551 struct m0_fab__active_ep *aep)
2553 struct m0_fab__bulk_op *
op;
2560 fb->fb_bulk_op =
op;
2563 fab_bulk_tlink_init_at_tail(
op, &tm->ftm_bulk);
2571 static void libfab_bufq_process(
struct m0_fab__tm *tm)
2573 struct m0_fab__bulk_op *
op;
2581 if (
op->fbl_aep->aep_tx_state == FAB_CONNECTED &&
2582 !
op->fbl_aep->aep_txq_full) {
2584 ret = libfab_ping_op(
op->fbl_aep,
op->fbl_buf);
2586 ret = libfab_bulk_op(
op->fbl_aep,
op->fbl_buf);
2589 fab_bulk_tlist_del(
op);
2590 op->fbl_buf->fb_bulk_op =
NULL;
2593 op->fbl_aep->aep_txq_full =
true;
2604 static int libfab_ping_op(
struct m0_fab__active_ep *aep,
struct m0_fab__buf *fb)
2606 struct fi_msg op_msg;
2610 iv.iov_base = fb->fb_nb->nb_buffer.ov_buf[0];
2611 iv.iov_len = fb->fb_nb->nb_buffer.ov_vec.v_count[0];
2612 op_msg.msg_iov = &iv;
2613 op_msg.desc = fb->fb_mr.bm_desc;
2614 op_msg.iov_count = 1;
2616 op_msg.context = U32_TO_VPTR(fb->fb_token);
2619 ret = fi_sendmsg(aep->aep_txep, &op_msg, FI_COMPLETION);
2621 aep->aep_bulk_cnt += fb->fb_wr_cnt;
2630 static int libfab_bulk_op(
struct m0_fab__active_ep *aep,
struct m0_fab__buf *fb)
2632 struct m0_fab__buf_xfer_params xp;
2633 struct m0_fab__tm *tm = libfab_buf_tm(fb);
2634 struct fi_msg_rma op_msg;
2635 struct fi_rma_iov *r_iov;
2636 struct fi_rma_iov *
remote = tm->ftm_rem_iov;
2637 struct iovec *loc_iv = tm->ftm_loc_iov;
2642 uint32_t wr_cnt = 0;
2643 uint32_t max_iov = tm->ftm_fab->fab_max_iov;
2647 bool last_seg =
false;
2649 M0_ENTRY(
"loc_buf=%p q=%d loc_seg=%d rem_buf=%d rem_seg=%d iov_max=%d",
2650 fb, fb->fb_nb->nb_qtype, fb->fb_nb->nb_buffer.ov_vec.v_nr,
2651 (
int)fb->fb_rbd->fbd_buftoken, (
int)fb->fb_rbd->fbd_iov_cnt,
2656 v_cnt = fb->fb_nb->nb_buffer.ov_vec.v_count;
2658 xp = fb->fb_xfer_params;
2659 r_iov = fb->fb_riov;
2662 while (xp.bxp_xfer_len < fb->fb_nb->nb_length) {
2663 for (idx = 0; idx < max_iov && !last_seg; idx++) {
2664 M0_ASSERT(xp.bxp_rem_sidx <= fb->fb_rbd->fbd_iov_cnt);
2665 loc_slen = v_cnt[xp.bxp_loc_sidx] - xp.bxp_loc_soff;
2666 rem_slen = r_iov[xp.bxp_rem_sidx].len - xp.bxp_rem_soff;
2668 loc_iv[idx].iov_base = fb->fb_nb->nb_buffer.ov_buf[
2671 loc_iv[idx].iov_len =
min64u(loc_slen, rem_slen);
2672 remote[idx] = r_iov[xp.bxp_rem_sidx];
2673 remote[idx].addr += xp.bxp_rem_soff;
2674 remote[idx].len -= xp.bxp_rem_soff;
2676 if (loc_slen > rem_slen) {
2678 xp.bxp_rem_soff = 0;
2679 xp.bxp_loc_soff += loc_iv[idx].iov_len;
2682 xp.bxp_loc_soff = 0;
2683 xp.bxp_rem_soff += loc_iv[idx].iov_len;
2684 if (xp.bxp_rem_soff >=
2685 r_iov[xp.bxp_rem_sidx].len) {
2687 xp.bxp_rem_soff = 0;
2691 xp.bxp_xfer_len += loc_iv[idx].iov_len;
2692 if (xp.bxp_xfer_len >= fb->fb_nb->nb_length)
2696 op_msg.msg_iov = &loc_iv[0];
2697 op_msg.desc = &fb->fb_mr.bm_desc[xp.bxp_loc_sidx];
2698 op_msg.iov_count = idx;
2699 op_msg.addr = xp.bxp_rem_soff;
2700 op_msg.rma_iov = &
remote[0];
2701 op_msg.rma_iov_count = idx;
2702 op_msg.context = U32_TO_VPTR(fb->fb_token);
2704 op_msg.data = (isread || (!last_seg)) ? 0 :
2705 fb->fb_rbd->fbd_buftoken;
2706 op_flag = (isread || (!last_seg)) ? 0 : FI_REMOTE_CQ_DATA;
2707 op_flag |= last_seg ? FI_COMPLETION : 0;
2709 ret = isread ? fi_readmsg(aep->aep_txep, &op_msg, op_flag) :
2710 fi_writemsg(aep->aep_txep, &op_msg, op_flag);
2714 opcnt=%d", ret, fb, fb->fb_nb->nb_qtype,
2715 xp.bxp_loc_sidx, aep->aep_bulk_cnt);
2719 aep->aep_bulk_cnt++;
2721 fb->fb_xfer_params = xp;
2724 fb->fb_wr_cnt += wr_cnt;
2731 static uint32_t libfab_buf_token_get(
struct m0_fab__tm *tm,
2732 struct m0_fab__buf *fb)
2734 union m0_fab__token
token;
2738 fb->fb_nb->nb_qtype;
2740 if (tm->ftm_op_id == 0)
2743 ++tm->ftm_rr_qt[
token.t_Fields.tf_queue_id];
2745 token.t_Fields.tf_queue_num = (tm->ftm_rr_qt[
token.t_Fields.tf_queue_id]
2746 % FAB_NUM_BUCKETS_PER_QTYPE);
2747 token.t_Fields.tf_tag = tm->ftm_op_id;
2752 static int libfab_domain_params_get(
struct m0_fab__ndom *fab_ndom)
2754 struct fi_info *hints;
2756 struct sockaddr_in *v_src;
2757 struct sockaddr_in t_src;
2760 hints = fi_allocinfo();
2763 hints->fabric_attr->prov_name = (
char *)providers[FAB_FABRIC_PROV_VERBS];
2764 result = fi_getinfo(FI_VERSION(1,11),
NULL,
NULL, 0, hints, &
fi);
2767 v_src =
fi->src_addr;
2768 inet_ntop(AF_INET, &v_src->sin_addr, fab_ndom->fnd_loc_ip,
2770 fab_ndom->fnd_seg_nr = FAB_VERBS_IOV_MAX;
2771 fab_ndom->fnd_seg_size = FAB_VERBS_MAX_BULK_SEG_SIZE;
2775 t_src.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2776 inet_ntop(AF_INET, &t_src.sin_addr, fab_ndom->fnd_loc_ip,
2778 fab_ndom->fnd_seg_nr = FAB_TCP_SOCK_IOV_MAX;
2779 fab_ndom->fnd_seg_size = FAB_TCP_SOCK_MAX_BULK_SEG_SIZE;
2781 hints->fabric_attr->prov_name =
NULL;
2786 static int libfab_buf_dom_dereg(
struct m0_fab__buf *fbp)
2794 seg_nr = fbp->fb_nb->nb_buffer.ov_vec.v_nr;
2797 if (fbp->fb_mr.bm_mr[
i] !=
NULL) {
2807 ret = fi_close(&fbp->fb_mr.bm_mr[
i]->fid);
2814 fbp->fb_mr.bm_mr[
i] =
NULL;
2820 fbp->fb_state = FAB_BUF_DEREGISTERED;
2834 struct m0_fab__ndom *fab_ndom;
2840 if (fab_ndom ==
NULL)
2843 ret = libfab_domain_params_get(fab_ndom);
2847 dom->nd_xprt_private = fab_ndom;
2848 fab_ndom->fnd_ndom =
dom;
2850 fab_fabs_tlist_init(&fab_ndom->fnd_fabrics);
2860 struct m0_fab__ndom *fnd;
2861 struct m0_fab__fab *fab;
2865 libfab_dom_invariant(
dom);
2866 fnd =
dom->nd_xprt_private;
2868 if (fab->fab_dom !=
NULL) {
2869 rc = fi_close(&fab->fab_dom->fid);
2872 fab->fab_dom =
NULL;
2875 if (fab->fab_fab !=
NULL) {
2876 rc = fi_close(&fab->fab_fab->fid);
2880 fab->fab_fab =
NULL;
2883 if (fab->fab_fi !=
NULL) {
2884 fi_freeinfo(fab->fab_fi);
2890 fab_fabs_tlist_fini(&fnd->fnd_fabrics);
2893 fnd->fnd_ndom =
NULL;
2911 fab_buf_tlist_fini(&
ma->ftm_done);
2924 struct m0_fab__tm *ftm;
2931 ftm->ftm_state = FAB_TM_INIT;
2934 ftm->ftm_fids.ftf_cnt = 0;
2935 M0_ALLOC_ARR(ftm->ftm_fids.ftf_head, FAB_TM_FID_MALLOC_STEP);
2936 M0_ALLOC_ARR(ftm->ftm_fids.ftf_ctx, FAB_TM_FID_MALLOC_STEP);
2937 if (ftm->ftm_fids.ftf_head ==
NULL ||
2938 ftm->ftm_fids.ftf_ctx ==
NULL) {
2939 m0_free(ftm->ftm_fids.ftf_head);
2940 m0_free(ftm->ftm_fids.ftf_ctx);
2943 ftm->ftm_fids.ftf_arr_size = FAB_TM_FID_MALLOC_STEP;
2944 fab_buf_tlist_init(&ftm->ftm_done);
2945 fab_bulk_tlist_init(&ftm->ftm_bulk);
2947 rc = fab_bufhash_htable_init(&ftm->ftm_bufhash.bht_hash,
2949 FAB_NUM_BUCKETS_PER_QTYPE));
2953 if (
rc != 0 && ftm !=
NULL)
2954 libfab_ma_fini(ntm);
2965 struct m0_fab__ndom *fnd;
2971 if (ftm->ftm_pep !=
NULL) {
2973 rc = libfab_ep_addr_decode(ftm->ftm_pep,
name);
2977 ftm->ftm_fab = libfab_newfab_init(fnd);
2978 ftm->ftm_fab->fab_prov = FAB_FABRIC_PROV_MAX;
2979 rc = libfab_passive_ep_create(ftm->ftm_pep, ftm);
2983 nep = &ftm->ftm_pep->fep_nep;
2986 libfab_ep_pton(&ftm->ftm_pep->fep_name,
2987 &ftm->ftm_pep->fep_name_n);
2989 ftm->ftm_pep->fep_nep.nep_addr = ftm->ftm_pep->fep_name.nia_p;
2995 &libfab_poller, ftm,
"libfab_tm");
2999 ftm->ftm_state = FAB_TM_STARTED;
3012 struct m0_fab__tm *tm =
net->ntm_xprt_private;
3019 libfab_tm_unlock(tm);
3020 libfab_tm_fini(
net);
3048 return (libfab_ep_find(tm,
name,
NULL, epp));
3064 libfab_buf_invariant(fb));
3066 libfab_buf_dom_dereg(fb);
3067 libfab_buf_fini(fb);
3083 struct m0_fab__buf *fb;
3098 if (fb->fb_mr.bm_desc ==
NULL || fb->fb_mr.bm_mr ==
NULL) {
3105 fab_buf_tlink_init(fb);
3108 fb->fb_state = FAB_BUF_INITIALIZED;
3123 struct m0_fab__tm *
ma = libfab_buf_ma(nb);
3124 struct m0_fab__ep *
ep =
NULL;
3125 struct m0_fab__active_ep *aep;
3133 M0_PRE(libfab_tm_is_locked(
ma) && libfab_tm_invariant(
ma) &&
3134 libfab_buf_invariant(fbp));
3138 fab_buf_tlink_init(fbp);
3139 fbp->fb_token = libfab_buf_token_get(
ma, fbp);
3140 libfab_buf_dom_reg(nb,
ma);
3149 ret = fi_recvv(
ma->ftm_rctx, &iv, fbp->fb_mr.bm_desc, 1, 0,
3150 U32_TO_VPTR(fbp->fb_token));
3165 aep = libfab_aep_get(
ep);
3168 if (aep->aep_tx_state != FAB_CONNECTED)
3169 ret = libfab_conn_init(
ep,
ma, fbp);
3171 ret = libfab_txbuf_list_add(
ma, fbp, aep);
3172 libfab_bufq_process(
ma);
3180 if (!libfab_is_verbs(
ma)) {
3181 ret = libfab_bdesc_encode(fbp);
3189 if (m0_net_tm_tlist_is_empty(
3191 ret = fi_recv(
ma->ftm_rctx, fbp->fb_dummy,
3192 sizeof(fbp->fb_dummy),
NULL, 0,
3193 U32_TO_VPTR(fbp->fb_token));
3196 ret = libfab_bdesc_encode(fbp);
3206 libfab_bdesc_decode(fbp, &
addr.nia_n);
3211 aep = libfab_aep_get(
ep);
3212 if (aep->aep_tx_state != FAB_CONNECTED)
3213 ret = libfab_conn_init(
ep,
ma, fbp);
3215 ret = libfab_txbuf_list_add(
ma, fbp, aep);
3216 libfab_bufq_process(
ma);
3227 fbp->fb_state = FAB_BUF_QUEUED;
3229 fab_bufhash_htable_add(&
ma->ftm_bufhash.bht_hash, fbp);
3245 struct m0_fab__tm *
ma = libfab_buf_ma(nb);
3247 M0_PRE(libfab_tm_is_locked(
ma) && libfab_tm_invariant(
ma) &&
3248 libfab_buf_invariant(
buf));
3251 libfab_buf_dom_dereg(
buf);
3252 buf->fb_state = FAB_BUF_CANCELED;
3253 libfab_buf_done(
buf, -ECANCELED,
false);
3306 struct m0_fab__ndom *
nd =
dom->nd_xprt_private;
3320 return ((
struct m0_fab__ndom *)
dom->nd_xprt_private)->fnd_seg_size;
3330 static int32_t libfab_get_max_buf_segments(
const struct m0_net_domain *
dom)
3332 return ((
struct m0_fab__ndom *)
dom->nd_xprt_private)->fnd_seg_nr;
3343 struct m0_fab__ndom *
nd =
dom->nd_xprt_private;
3344 m0_bcount_t max_bd_size =
sizeof(
struct fi_rma_iov);
3346 max_bd_size = (max_bd_size *
nd->fnd_seg_nr) +
3347 sizeof(
struct m0_fab__bdesc);
3362 return FAB_MAX_RPC_SEG_SIZE;
3372 static uint32_t libfab_rpc_max_segs_nr(
struct m0_net_domain *ndom)
3375 return FAB_MAX_RPC_SEG_NR;
3391 mbs = libfab_rpc_max_seg_size(ndom) * libfab_rpc_max_segs_nr(ndom);
3392 return rpc_size != 0 ?
m0_clip64u(M0_SEG_SIZE, mbs, rpc_size) : mbs;
3402 static uint32_t libfab_rpc_max_recv_msgs(
struct m0_net_domain *ndom,
3406 return FAB_MAX_RPC_RECV_MSG_NR;
3411 .xo_dom_fini = &libfab_dom_fini,
3412 .xo_tm_init = &libfab_ma_init,
3413 .xo_tm_confine = &libfab_ma_confine,
3414 .xo_tm_start = &libfab_ma_start,
3415 .xo_tm_stop = &libfab_ma_stop,
3416 .xo_tm_fini = &libfab_ma_fini,
3417 .xo_end_point_create = &libfab_end_point_create,
3418 .xo_buf_register = &libfab_buf_register,
3419 .xo_buf_deregister = &libfab_buf_deregister,
3420 .xo_buf_add = &libfab_buf_add,
3421 .xo_buf_del = &libfab_buf_del,
3422 .xo_bev_deliver_sync = &libfab_bev_deliver_sync,
3423 .xo_bev_deliver_all = &libfab_bev_deliver_all,
3424 .xo_bev_pending = &libfab_bev_pending,
3425 .xo_bev_notify = &libfab_bev_notify,
3426 .xo_get_max_buffer_size = &libfab_get_max_buf_size,
3427 .xo_get_max_buffer_segment_size = &libfab_get_max_buf_seg_size,
3428 .xo_get_max_buffer_segments = &libfab_get_max_buf_segments,
3429 .xo_get_max_buffer_desc_size = &libfab_get_max_buf_desc_size,
3430 .xo_rpc_max_seg_size = &libfab_rpc_max_seg_size,
3431 .xo_rpc_max_segs_nr = &libfab_rpc_max_segs_nr,
3432 .xo_rpc_max_msg_size = &libfab_rpc_max_msg_size,
3433 .xo_rpc_max_recv_msgs = &libfab_rpc_max_recv_msgs,
3438 .nx_ops = &libfab_xprt_ops
3440 M0_EXPORTED(m0_net_libfab_xprt);
3457 #undef M0_TRACE_SUBSYSTEM union m0_net_ip_params::@378 nip_fmt_pvt
M0_INTERNAL int m0_mutex_trylock(struct m0_mutex *mutex)
static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
struct m0_net_ip_lnet_addr la
struct m0_net_transfer_mc * nb_tm
#define M0_ALLOC_ARR(arr, nr)
struct m0t1fs_fsync_interactions fi
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
enum m0_net_ip_format nip_format
#define m0_htable_for(name, var, htable)
#define M0_HT_DESCR_DEFINE(name, htname, scope, amb_type, amb_link_field, amb_magic_field, amb_magic, head_magic, key_field, hash_func, key_eq)
M0_INTERNAL void m0_net_libfab_fini(void)
struct m0_bufvec nb_buffer
M0_INTERNAL int m0_net_hostname_to_ip(const char *hostname, char *ip, enum m0_net_ip_format *fmt)
M0_INTERNAL void m0_net__tm_cancel(struct m0_net_transfer_mc *tm)
int m0_thread_join(struct m0_thread *q)
union m0_net_ip_params::@377 nip_ip_n
#define M0_LOG(level,...)
struct m0_net_domain * ntm_dom
M0_INTERNAL void m0_net_xprt_default_set(const struct m0_net_xprt *xprt)
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
#define container_of(ptr, type, member)
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
struct m0_net_buffer * nbe_buffer
M0_INTERNAL void m0_net_buffer_event_post(const struct m0_net_buffer_event *ev)
struct m0_net_ip_params nia_n
struct m0_net_end_point * nbe_ep
static int struct dentry int struct nameidata * nd
struct m0_tl ntm_end_points
char nia_p[M0_NET_IP_STRLEN_MAX]
M0_INTERNAL int m0_net_ip_print(const struct m0_net_ip_addr *nia)
static uint64_t m0_clip64u(uint64_t lo, uint64_t hi, uint64_t x)
M0_INTERNAL void m0_net_xprt_register(const struct m0_net_xprt *xprt)
bool m0_time_is_in_past(m0_time_t t)
M0_INTERNAL void m0_ref_put(struct m0_ref *ref)
void m0_ref_init(struct m0_ref *ref, int init_num, void(*release)(struct m0_ref *ref))
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_ref_get(struct m0_ref *ref)
struct m0_net_ip_inet_addr ia
#define m0_tl_teardown(name, head, obj)
enum m0_net_queue_type nb_qtype
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
m0_time_t m0_time_now(void)
#define M0_DEFAULT_NETWORK
void m0_thread_fini(struct m0_thread *q)
static struct m0_stob_domain * dom
struct m0_net_domain * nb_dom
void * m0_alloc(size_t size)
M0_INTERNAL void m0_net_tm_event_post(const struct m0_net_tm_event *ev)
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
static void token(struct ff2c_context *ctx, struct ff2c_term *term, struct ff2c_token *tok)
M0_INTERNAL void m0_net_end_point_get(struct m0_net_end_point *ep)
struct m0_net_transfer_mc * nep_tm
static uint64_t min64u(uint64_t a, uint64_t b)
M0_INTERNAL void m0_tlink_init(const struct m0_tl_descr *d, void *obj)
#define M0_TL_DEFINE(name, scope, amb_type)
static struct fdmi_ctx ctx
M0_INTERNAL m0_bcount_t m0_vec_count(const struct m0_vec *vec)
static uint32_t min32u(uint32_t a, uint32_t b)
M0_INTERNAL bool m0_net__buffer_invariant(const struct m0_net_buffer *buf)
static struct m0_chan chan[RDWR_REQUEST_MAX]
#define M0_ALLOC_PTR(ptr)
m0_time_t m0_time_from_now(uint64_t secs, long ns)
M0_INTERNAL int m0_net_libfab_init(void)
M0_INTERNAL struct m0_thread * m0_thread_self(void)
static struct m0_rm_remote * remote
M0_INTERNAL int m0_net_ip_parse(const char *name, struct m0_net_ip_addr *addr)
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
#define M0_TL_DESCR_DEFINE(name, hname, scope, amb_type, amb_link_field, amb_magic_field, amb_magic, head_magic)
struct m0t1fs_filedata * fd
M0_INTERNAL void m0_net_xprt_deregister(const struct m0_net_xprt *xprt)
int(* xo_dom_init)(const struct m0_net_xprt *xprt, struct m0_net_domain *dom)
static struct m0_addb2_net * net
struct m0_net_buf_desc nb_desc
struct m0_net_xprt * xprt
#define m0_tl_find(name, var, head,...)
#define m0_tl_for(name, head, obj)
M0_INTERNAL bool m0_processor_is_vm(void)
M0_INTERNAL void m0_chan_broadcast(struct m0_chan *chan)
int const char void * buffer
struct m0_net_end_point * nb_ep
#define M0_HT_DEFINE(name, scope, amb_type, key_type)
#define M0_IMPOSSIBLE(fmt,...)
M0_INTERNAL bool m0_net_ip_addr_eq(const struct m0_net_ip_addr *addr1, const struct m0_net_ip_addr *addr2, bool is_ncmp)