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);
851 m0_nep_tlist_add_tail(&tm->ftm_ntm->ntm_end_points,
net);
852 xep = libfab_ep(
net);
853 aep = libfab_aep_get(xep);
854 libfab_txep_event_check(xep, aep, tm);
855 cq = aep->aep_rx_res.frr_cq;
856 libfab_rxep_comp_read(cq, xep, tm);
858 libfab_bufq_process(tm);
860 libfab_tm_buf_timeout(tm);
861 libfab_tm_buf_done(tm);
864 libfab_tm_unlock(tm);
882 struct m0_fab__ep **
ep)
899 static bool libfab_ep_find_by_str(
const char *
name,
901 struct m0_fab__ep **
ep)
906 strcmp((libfab_ep(
net))->fep_name.nia_p,
name) == 0);
926 struct m0_fab__ep *
ep;
927 struct m0_fab__active_ep *aep;
929 struct m0_fab__tm *
ma;
939 found = libfab_ep_find_by_num(&net_ip, tm, &
ep);
949 rc = libfab_ep_create(tm, net_ip.
nia_p,
addr, epp);
954 wc = strchr(
name,
'*');
960 ep->fep_name.nia_n.nip_port !=
962 ep->fep_name.nia_n.nip_ip_n.sn[0] =
964 ep->fep_name.nia_n.nip_port =
966 ep->fep_name.nia_n.nip_fmt_pvt.la.nla_tmid =
968 libfab_ep_pton(&
ep->fep_name,
970 aep = libfab_aep_get(
ep);
972 if (aep->aep_tx_state == FAB_CONNECTED)
973 rc = libfab_txep_init(aep,
ma,
ep);
993 struct m0_fab__ep *
ep =
NULL;
1004 if (
ep->fep_aep ==
NULL) {
1011 rc = libfab_ep_addr_decode(
ep,
name);
1013 libfab_aep_param_free(
ep->fep_aep,
ma);
1023 addr->nip_fmt_pvt.la.nla_autotm) {
1024 ep->fep_name.nia_n.nip_port =
addr->nip_port;
1025 ep->fep_name.nia_n.nip_fmt_pvt.la.nla_tmid =
1026 addr->nip_fmt_pvt.la.nla_tmid;
1029 rc = libfab_active_ep_create(
ep,
ma);
1031 libfab_aep_param_free(
ep->fep_aep,
ma);
1036 fab_sndbuf_tlist_init(&
ep->fep_sndbuf);
1037 *epp = &
ep->fep_nep;
1044 static int libfab_tm_res_init(
struct m0_fab__tm *tm)
1046 struct m0_fab__fab *fab;
1047 struct m0_fab__passive_ep *pep;
1048 struct fi_cq_attr cq_attr = {};
1053 pep = tm->ftm_pep->fep_listen;
1056 cq_attr.wait_obj = FI_WAIT_FD;
1057 cq_attr.wait_cond = FI_CQ_COND_NONE;
1058 cq_attr.format = FI_CQ_FORMAT_DATA;
1059 cq_attr.size = FAB_MAX_TX_CQ_EV;
1060 rc = fi_cq_open(fab->fab_dom, &cq_attr, &tm->ftm_tx_cq,
NULL);
1065 tm->ftm_txcq_ctx.evctx_type = FAB_COMMON_Q_EVENT;
1066 tm->ftm_txcq_ctx.evctx_ep =
NULL;
1067 tm->ftm_txcq_ctx.evctx_dbg =
"txep cq";
1068 rc = libfab_waitfd_bind(&tm->ftm_tx_cq->fid, tm, &tm->ftm_txcq_ctx);
1072 return M0_RC(libfab_txep_init(pep->pep_aep, tm, tm->ftm_pep));
1079 static int libfab_ep_txres_init(
struct m0_fab__active_ep *aep,
1080 struct m0_fab__tm *tm,
void *
ctx)
1082 struct fi_eq_attr eq_attr = {};
1083 struct m0_fab__fab *fab;
1089 rc = fi_ep_bind(aep->aep_txep, &tm->ftm_tx_cq->fid,
1090 FI_TRANSMIT | FI_RECV | FI_SELECTIVE_COMPLETION);
1095 eq_attr.wait_obj = FI_WAIT_FD;
1096 eq_attr.size = FAB_MAX_AEP_EQ_EV;
1097 rc = fi_eq_open(fab->fab_fab, &eq_attr, &aep->aep_tx_res.ftr_eq,
NULL);
1101 aep->aep_tx_res.ftr_ctx.evctx_type = FAB_PRIVATE_Q_EVENT;
1102 aep->aep_tx_res.ftr_ctx.evctx_ep =
ctx;
1103 aep->aep_tx_res.ftr_ctx.evctx_dbg =
"txep eq";
1104 rc = libfab_waitfd_bind(&aep->aep_tx_res.ftr_eq->fid, tm,
1105 &aep->aep_tx_res.ftr_ctx);
1109 rc = fi_ep_bind(aep->aep_txep, &aep->aep_tx_res.ftr_eq->fid, 0);
1118 static int libfab_ep_rxres_init(
struct m0_fab__active_ep *aep,
1119 struct m0_fab__tm *tm,
void *
ctx)
1121 struct fi_cq_attr cq_attr = {};
1122 struct fi_eq_attr eq_attr = {};
1123 struct m0_fab__fab *fab;
1129 cq_attr.wait_obj = FI_WAIT_FD;
1130 cq_attr.wait_cond = FI_CQ_COND_NONE;
1131 cq_attr.format = FI_CQ_FORMAT_DATA;
1132 cq_attr.size = FAB_MAX_RX_CQ_EV;
1133 rc = fi_cq_open(fab->fab_dom, &cq_attr, &aep->aep_rx_res.frr_cq,
NULL);
1137 aep->aep_rx_res.frr_cq_ctx.evctx_type = FAB_PRIVATE_Q_EVENT;
1138 aep->aep_rx_res.frr_cq_ctx.evctx_ep =
ctx;
1139 aep->aep_rx_res.frr_cq_ctx.evctx_dbg =
"rxep cq";
1140 rc = libfab_waitfd_bind(&aep->aep_rx_res.frr_cq->fid, tm,
1141 &aep->aep_rx_res.frr_cq_ctx);
1145 rc = fi_ep_bind(aep->aep_rxep, &tm->ftm_tx_cq->fid,
1146 FI_TRANSMIT | FI_SELECTIVE_COMPLETION) ? :
1147 fi_ep_bind(aep->aep_rxep, &aep->aep_rx_res.frr_cq->fid, FI_RECV);
1152 eq_attr.wait_obj = FI_WAIT_FD;
1153 eq_attr.size = FAB_MAX_AEP_EQ_EV;
1154 aep->aep_rx_res.frr_eq_ctx.evctx_type = FAB_PRIVATE_Q_EVENT;
1155 aep->aep_rx_res.frr_eq_ctx.evctx_ep =
ctx;
1156 aep->aep_rx_res.frr_eq_ctx.evctx_dbg =
"rxep eq";
1157 rc = fi_eq_open(fab->fab_fab, &eq_attr, &aep->aep_rx_res.frr_eq,
1159 libfab_waitfd_bind(&aep->aep_rx_res.frr_eq->fid, tm,
1160 &aep->aep_rx_res.frr_eq_ctx) ? :
1161 fi_ep_bind(aep->aep_rxep, &aep->aep_rx_res.frr_eq->fid, 0) ? :
1162 fi_ep_bind(aep->aep_rxep, &tm->ftm_rctx->fid, 0);
1171 static int libfab_pep_res_init(
struct m0_fab__passive_ep *pep,
1172 struct m0_fab__tm *tm,
void *
ctx)
1174 struct fi_eq_attr eq_attr = {};
1178 eq_attr.wait_obj = FI_WAIT_FD;
1179 eq_attr.size = FAB_MAX_PEP_EQ_EV;
1180 rc = fi_eq_open(tm->ftm_fab->fab_fab, &eq_attr, &pep->pep_res.fpr_eq,
1185 pep->pep_res.fpr_ctx.evctx_type = FAB_COMMON_Q_EVENT;
1186 pep->pep_res.fpr_ctx.evctx_ep =
ctx;
1187 pep->pep_res.fpr_ctx.evctx_dbg =
"pep eq";
1188 rc = libfab_waitfd_bind(&pep->pep_res.fpr_eq->fid, tm,
1189 &pep->pep_res.fpr_ctx) ? :
1190 fi_pep_bind(pep->pep_pep, &pep->pep_res.fpr_eq->fid, 0);
1198 static int libfab_conn_accept(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm,
1199 struct fi_info *info)
1201 struct m0_fab__active_ep *aep;
1202 struct fid_domain *dp;
1205 M0_ENTRY(
"from ep=%s -> tm=%s", (
char*)
ep->fep_name.nia_p,
1206 (
char*)tm->ftm_pep->fep_name.nia_p);
1208 aep = libfab_aep_get(
ep);
1209 dp = tm->ftm_fab->fab_dom;
1211 if (aep->aep_rxep !=
NULL) {
1212 rc = fi_close(&aep->aep_rxep->fid);
1215 libfab_ep_rxres_free(&aep->aep_rx_res, tm);
1217 aep->aep_rx_state = FAB_NOT_CONNECTED;
1218 ep->fep_connlink = FAB_CONNLINK_DOWN;
1220 rc = fi_endpoint(dp, info, &aep->aep_rxep,
NULL) ? :
1221 libfab_ep_rxres_init(aep, tm,
ep) ? :
1222 fi_enable(aep->aep_rxep) ? :
1223 fi_accept(aep->aep_rxep,
NULL, 0);
1226 libfab_aep_param_free(aep, tm);
1230 aep->aep_rx_state = FAB_CONNECTING;
1238 static int libfab_active_ep_create(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm)
1241 struct m0_fab__active_ep *aep;
1246 rc = libfab_txep_init(aep, tm,
ep);
1248 libfab_aep_param_free(aep, tm);
1253 net->nep_xprt_pvt =
ep;
1254 net->nep_tm = tm->ftm_ntm;
1255 libfab_ep_pton(&
ep->fep_name, &
ep->fep_name_n);
1256 m0_nep_tlink_init_at_tail(
net, &tm->ftm_ntm->ntm_end_points);
1257 net->nep_addr = (
const char *)(&
ep->fep_name.nia_p);
1267 static int libfab_passive_ep_create(
struct m0_fab__ep *
ep,
1268 struct m0_fab__tm *tm)
1270 struct m0_fab__passive_ep *pep;
1271 struct fi_info *hints;
1273 enum m0_fab__prov_type idx;
1276 char addr[LIBFAB_ADDR_LEN_MAX] = {};
1277 char port[LIBFAB_PORT_LEN_MAX] = {};
1280 (
char*)
ep->fep_name.nia_p,
1281 ep->fep_name.nia_n.nip_ip_n.ln[0],
1282 ep->fep_name.nia_n.nip_ip_n.ln[1],
1283 (
int)
ep->fep_name.nia_n.nip_port);
1286 if (
ep->fep_listen ==
NULL)
1289 if (
ep->fep_listen->pep_aep ==
NULL) {
1294 pep =
ep->fep_listen;
1295 ep->fep_listen->pep_aep->aep_rxep =
NULL;
1296 ep->fep_listen->pep_aep->aep_txep =
NULL;
1298 libfab_straddr_gen(&
ep->fep_name.nia_n,
addr);
1301 hints = fi_allocinfo();
1302 if (hints ==
NULL) {
1308 hints->ep_attr->type = FI_EP_MSG;
1309 hints->caps = FI_MSG | FI_RMA;
1310 hints->mode |= FI_RX_CQ_DATA;
1311 hints->domain_attr->mr_mode = FI_MR_LOCAL | FI_MR_ALLOCATED |
1312 FI_MR_PROV_KEY | FI_MR_VIRT_ADDR;
1313 hints->domain_attr->cq_data_size = 4;
1315 for (idx = 0; idx < FAB_FABRIC_PROV_MAX; idx++) {
1316 hints->fabric_attr->prov_name = (
char *)providers[idx];
1317 rc = fi_getinfo(LIBFAB_VERSION,
addr,
port, FI_SOURCE, hints,
1329 (
char*)
ep->fep_name.nia_p,
fi->fabric_attr->prov_name);
1330 hints->fabric_attr->prov_name =
NULL;
1331 tm->ftm_fab->fab_fi =
fi;
1332 tm->ftm_fab->fab_prov = idx;
1333 tm->ftm_fab->fab_max_iov =
min32u(
fi->tx_attr->iov_limit,
1334 fi->tx_attr->rma_iov_limit);
1337 M0_ALLOC_ARR(tm->ftm_rem_iov, tm->ftm_fab->fab_max_iov);
1338 M0_ALLOC_ARR(tm->ftm_loc_iov, tm->ftm_fab->fab_max_iov);
1339 if (tm->ftm_rem_iov ==
NULL || tm->ftm_loc_iov ==
NULL) {
1345 rc = fi_fabric(tm->ftm_fab->fab_fi->fabric_attr, &tm->ftm_fab->fab_fab,
1347 libfab_waitfd_init(tm) ? :
1348 fi_passive_ep(tm->ftm_fab->fab_fab, tm->ftm_fab->fab_fi,
1349 &pep->pep_pep,
NULL) ? :
1350 libfab_pep_res_init(pep, tm,
ep) ? :
1351 fi_listen(pep->pep_pep) ? :
1352 fi_domain(tm->ftm_fab->fab_fab, tm->ftm_fab->fab_fi,
1353 &tm->ftm_fab->fab_dom,
NULL);
1356 libfab_pep_param_free(pep, tm);
1360 rx_size = tm->ftm_fab->fab_fi->rx_attr->size;
1361 tm->ftm_fab->fab_fi->rx_attr->size = FAB_MAX_SRX_SIZE;
1362 rc = fi_srx_context(tm->ftm_fab->fab_dom, tm->ftm_fab->fab_fi->rx_attr,
1363 &tm->ftm_rctx,
NULL);
1364 tm->ftm_fab->fab_fi->rx_attr->size = rx_size;
1367 libfab_pep_param_free(pep, tm);
1371 rc = libfab_tm_res_init(tm);
1374 libfab_pep_param_free(pep, tm);
1378 fab_sndbuf_tlist_init(&
ep->fep_sndbuf);
1379 m0_ref_init(&tm->ftm_pep->fep_nep.nep_ref, 1, &libfab_ep_release);
1380 libfab_ep_get(tm->ftm_pep);
1388 static int libfab_pep_res_free(
struct m0_fab__pep_res *pep_res,
1389 struct m0_fab__tm *tm)
1393 if (pep_res->fpr_eq !=
NULL) {
1394 rc = libfab_waitfd_unbind(&pep_res->fpr_eq->fid, tm,
1398 rc = fi_close(&pep_res->fpr_eq->fid);
1401 rc, (
int)pep_res->fpr_eq->fid.fclass);
1402 pep_res->fpr_eq =
NULL;
1411 static int libfab_ep_txres_free(
struct m0_fab__tx_res *tx_res,
1412 struct m0_fab__tm *tm)
1416 if (tx_res->ftr_eq !=
NULL) {
1417 rc = libfab_waitfd_unbind(&tx_res->ftr_eq->fid, tm,
1421 rc = fi_close(&tx_res->ftr_eq->fid);
1424 rc, (
int)tx_res->ftr_eq->fid.fclass);
1425 tx_res->ftr_eq =
NULL;
1434 static int libfab_ep_rxres_free(
struct m0_fab__rx_res *rx_res,
1435 struct m0_fab__tm *tm)
1439 if (rx_res->frr_eq !=
NULL) {
1440 rc = libfab_waitfd_unbind(&rx_res->frr_eq->fid, tm,
1441 &rx_res->frr_eq_ctx);
1444 rc = fi_close(&rx_res->frr_eq->fid);
1447 rc, (
int)rx_res->frr_eq->fid.fclass);
1448 rx_res->frr_eq =
NULL;
1451 if (rx_res->frr_cq !=
NULL) {
1452 rc = libfab_waitfd_unbind(&rx_res->frr_cq->fid, tm,
1453 &rx_res->frr_cq_ctx);
1456 rc = fi_close(&rx_res->frr_cq->fid);
1459 rc, (
int)rx_res->frr_cq->fid.fclass);
1460 rx_res->frr_cq =
NULL;
1469 static int libfab_aep_param_free(
struct m0_fab__active_ep *aep,
1470 struct m0_fab__tm *tm)
1476 if (aep->aep_txep !=
NULL) {
1477 rc = fi_close(&aep->aep_txep->fid);
1480 rc, (
int)aep->aep_txep->fid.fclass);
1481 aep->aep_txep =
NULL;
1484 if (aep->aep_rxep !=
NULL) {
1485 rc = fi_close(&aep->aep_rxep->fid);
1488 rc, (
int)aep->aep_rxep->fid.fclass);
1489 aep->aep_rxep =
NULL;
1492 rc = libfab_ep_txres_free(&aep->aep_tx_res, tm);
1496 rc = libfab_ep_rxres_free(&aep->aep_rx_res, tm);
1508 static int libfab_pep_param_free(
struct m0_fab__passive_ep *pep,
1509 struct m0_fab__tm *tm)
1516 if (pep->pep_pep !=
NULL) {
1517 rc = fi_close(&pep->pep_pep->fid);
1520 rc, (
int)pep->pep_pep->fid.fclass);
1521 pep->pep_pep =
NULL;
1524 rc = libfab_aep_param_free(pep->pep_aep, tm);
1528 rc = libfab_pep_res_free(&pep->pep_res, tm);
1540 static int libfab_ep_param_free(
struct m0_fab__ep *
ep,
struct m0_fab__tm *tm)
1547 rc = libfab_pep_param_free(
ep->fep_listen, tm) ? :
1548 libfab_aep_param_free(
ep->fep_aep, tm);
1562 static int libfab_tm_param_free(
struct m0_fab__tm *tm)
1564 struct m0_fab__bulk_op *
op;
1566 struct m0_fab__ep *xep;
1567 struct m0_fab__buf *fbp;
1573 if (tm->ftm_poller.t_func !=
NULL) {
1580 xep = libfab_ep(
net);
1581 rc = libfab_ep_param_free(xep, tm);
1583 M0_ASSERT(m0_nep_tlist_is_empty(&tm->ftm_ntm->ntm_end_points));
1584 tm->ftm_ntm->ntm_ep =
NULL;
1586 if (tm->ftm_rctx !=
NULL) {
1587 rc = fi_close(&tm->ftm_rctx->fid);
1590 rc, (
int)tm->ftm_rctx->fid.fclass);
1591 tm->ftm_rctx =
NULL;
1594 if (tm->ftm_tx_cq !=
NULL) {
1595 rc = libfab_waitfd_unbind(&tm->ftm_tx_cq->fid, tm,
1599 rc = fi_close(&tm->ftm_tx_cq->fid);
1602 rc, (
int)tm->ftm_tx_cq->fid.fclass);
1603 tm->ftm_tx_cq =
NULL;
1606 close(tm->ftm_epfd);
1607 m0_free(tm->ftm_fids.ftf_head);
1608 m0_free(tm->ftm_fids.ftf_ctx);
1612 m0_htable_for(fab_bufhash, fbp, &tm->ftm_bufhash.bht_hash) {
1613 fab_bufhash_htable_del(&tm->ftm_bufhash.bht_hash, fbp);
1615 fab_bufhash_htable_fini(&tm->ftm_bufhash.bht_hash);
1620 fab_bulk_tlist_fini(&tm->ftm_bulk);
1629 static int libfab_waitfd_init(
struct m0_fab__tm *tm)
1631 M0_PRE(tm->ftm_epfd == -1);
1633 tm->ftm_epfd = epoll_create(1);
1634 if (tm->ftm_epfd < 0)
1643 static inline struct m0_fab__tm *libfab_buf_tm(
struct m0_fab__buf *
buf)
1645 return buf->fb_nb->nb_tm->ntm_xprt_private;
1659 static void libfab_buf_fini(
struct m0_fab__buf *
buf)
1661 struct m0_fab__buf *fbp;
1665 libfab_buf_invariant(
buf);
1667 fab_buf_tlink_fini(
buf);
1670 if (
buf->fb_bulk_op !=
NULL && fab_bulk_tlink_is_in(
buf->fb_bulk_op)) {
1671 fab_bulk_tlist_del(
buf->fb_bulk_op);
1677 fbp =
m0_tl_find(fab_sndbuf, fbp, &
buf->fb_txctx->fep_sndbuf,
1680 fab_sndbuf_tlist_del(fbp);
1695 buf->fb_state = (
buf->fb_state == FAB_BUF_CANCELED ||
1696 buf->fb_state == FAB_BUF_TIMEDOUT) ?
1697 FAB_BUF_INITIALIZED : FAB_BUF_REGISTERED;
1707 struct m0_fab__ndom *fnd =
dom->nd_xprt_private;
1708 return _0C(!fab_fabs_tlist_is_empty(&fnd->fnd_fabrics)) &&
1709 _0C(
dom->nd_xprt == &m0_net_libfab_xprt);
1715 static bool libfab_tm_invariant(
const struct m0_fab__tm *fab_tm)
1717 return fab_tm !=
NULL &&
1718 fab_tm->ftm_ntm->ntm_xprt_private == fab_tm &&
1719 libfab_dom_invariant(fab_tm->ftm_ntm->ntm_dom);
1725 static bool libfab_buf_invariant(
const struct m0_fab__buf *
buf)
1740 static void libfab_buf_complete(
struct m0_fab__buf *
buf)
1742 struct m0_fab__tm *
ma = libfab_buf_tm(
buf);
1746 .nbe_status =
buf->fb_status,
1750 M0_ENTRY(
"fb=%p nb=%p q=%d rc=%d",
buf, nb,
buf->fb_nb->nb_qtype,
1761 libfab_ep_get(
buf->fb_ev_ep);
1764 ma->ftm_ntm->ntm_callback_counter++;
1766 fab_bufhash_htable_del(&
ma->ftm_bufhash.bht_hash,
buf);
1767 libfab_buf_fini(
buf);
1769 libfab_tm_evpost_lock(
ma);
1770 libfab_tm_unlock(
ma);
1773 libfab_tm_evpost_unlock(
ma);
1777 ma->ftm_ntm->ntm_callback_counter--;
1785 static int libfab_dummy_msg_rcv_chk(
struct m0_fab__buf *fbp)
1787 struct m0_fab__tm *
ma = libfab_buf_tm(fbp);
1789 struct m0_fab__buf *pas_buf;
1795 if (fbp->fb_length == (
sizeof(uint32_t) * 2)) {
1797 if (*
ptr == FAB_DUMMY_DATA) {
1800 pas_buf = fab_bufhash_htable_lookup(
1801 &
ma->ftm_bufhash.bht_hash,
1803 if (pas_buf !=
NULL)
1804 libfab_buf_complete(pas_buf);
1815 fbp->fb_mr.bm_desc, 1, 0,
1816 U32_TO_VPTR(fbp->fb_token)) == 0);
1827 static void libfab_buf_done(
struct m0_fab__buf *
buf,
int rc,
bool add_to_list)
1829 struct m0_fab__tm *
ma = libfab_buf_tm(
buf);
1833 (
int)
buf->fb_length,
rc);
1839 if (!fab_buf_tlink_is_in(
buf)) {
1840 buf->fb_status =
buf->fb_status == 0 ?
rc :
buf->fb_status;
1843 if (libfab_dummy_msg_rcv_chk(
buf) != 0)
1844 libfab_buf_complete(
buf);
1850 buf->fb_status =
rc;
1851 fab_buf_tlist_add_tail(&
ma->ftm_done,
buf);
1859 static inline void libfab_ep_get(
struct m0_fab__ep *
ep)
1870 static void libfab_ep_release(
struct m0_ref *ref)
1873 struct m0_fab__ep *
ep;
1874 struct m0_fab__tm *tm;
1877 ep = libfab_ep(nep);
1881 m0_nep_tlist_del(nep);
1882 libfab_ep_param_free(
ep, tm);
1888 static uint64_t libfab_mr_keygen(
struct m0_fab__tm *tm)
1890 uint64_t
key = FAB_MR_KEY + tm->ftm_mr_key_idx;
1891 tm->ftm_mr_key_idx++;
1898 static int libfab_check_for_event(
struct fid_eq *eq, uint32_t *ev)
1900 struct fi_eq_cm_entry entry;
1905 rc = fi_eq_read(eq, &event, &entry,
sizeof(entry), 0);
1906 if (
rc == -FI_EAVAIL) {
1912 fi_eq_strerror(eq,
err_entry.prov_errno,
1916 *ev =
rc < 0 ? 0xFF : event;
1925 static int libfab_check_for_comp(
struct fid_cq *cq, uint32_t *
ctx,
1928 struct fi_cq_data_entry entry[FAB_MAX_COMP_READ];
1930 uint64_t wr_cqdata = FI_REMOTE_WRITE | FI_REMOTE_CQ_DATA;
1934 ret = fi_cq_read(cq, entry, FAB_MAX_COMP_READ);
1936 for (
i = 0;
i < ret;
i++) {
1937 ctx[
i] = entry[
i].op_context ==
NULL ? 0 :
1938 VPTR_TO_U32(entry[
i].op_context);
1940 len[
i] = entry[
i].len;
1942 data[
i] = ((entry[
i].flags & wr_cqdata)) ?
1945 }
else if (ret != -FI_EAGAIN) {
1950 fi_cq_strerror(cq,
err_entry.prov_errno,
1968 if (
ma->ftm_state != FAB_TM_SHUTDOWN) {
1972 libfab_tm_unlock(
ma);
1978 ma->ftm_state = FAB_TM_SHUTDOWN;
1981 libfab_tm_buf_done(
ma);
1983 rc = libfab_tm_param_free(
ma);
1989 libfab_tm_unlock(
ma);
1998 static int libfab_bdesc_encode(
struct m0_fab__buf *
buf)
2000 struct m0_fab__bdesc *fbd;
2001 struct fi_rma_iov *iov;
2004 struct m0_fab__tm *tm = libfab_buf_ma(nb);
2008 bool is_verbs = libfab_is_verbs(tm);
2010 M0_PRE(seg_nr <= nd->fnd_seg_nr);
2012 nbd->
nbd_len = (
sizeof(
struct m0_fab__bdesc) +
2013 (sizeof(struct fi_rma_iov) *
seg_nr));
2016 return M0_RC(-ENOMEM);
2018 fbd = (
struct m0_fab__bdesc *)nbd->
nbd_data;
2019 fbd->fbd_netaddr = tm->ftm_pep->fep_name.nia_n;
2020 fbd->fbd_buftoken =
buf->fb_token;
2022 fbd->fbd_iov_cnt = (uint32_t)
seg_nr;
2023 iov = (
struct fi_rma_iov *)(nbd->
nbd_data +
2024 sizeof(
struct m0_fab__bdesc));
2028 iov[
i].key = fi_mr_key(
buf->fb_mr.bm_mr[
i]);
2038 static void libfab_bdesc_decode(
struct m0_fab__buf *fb,
2046 sizeof(
struct m0_fab__bdesc));
2047 *
addr = fb->fb_rbd->fbd_netaddr;
2048 M0_ASSERT(fb->fb_rbd->fbd_iov_cnt <= ndom->fnd_seg_nr);
2054 static int libfab_buf_dom_reg(
struct m0_net_buffer *nb,
struct m0_fab__tm *tm)
2056 struct m0_fab__buf *fbp;
2057 struct m0_fab__buf_mr *mr;
2058 struct m0_fab__ndom *ndom;
2059 struct fid_domain *dp;
2070 dp = tm->ftm_fab->fab_dom;
2076 if (fbp->fb_dp == dp)
2079 if (fbp->fb_state == FAB_BUF_REGISTERED)
2090 while (ret != 0 && retry_cnt > 0) {
2091 key = libfab_mr_keygen(tm);
2094 FAB_MR_ACCESS, FAB_MR_OFFSET,
key,
2095 FAB_MR_FLAG, &mr->bm_mr[
i],
NULL);
2105 mr->bm_desc[
i] = fi_mr_desc(mr->bm_mr[
i]);
2110 fbp->fb_state = FAB_BUF_REGISTERED;
2120 static void libfab_pending_bufs_send(
struct m0_fab__ep *
ep)
2122 struct m0_fab__active_ep *aep;
2123 struct m0_fab__buf *fbp;
2127 aep = libfab_aep_get(
ep);
2135 ret = libfab_txbuf_list_add(libfab_buf_ma(nb),
2143 libfab_buf_done(fbp, ret,
false);
2147 libfab_bufq_process(libfab_buf_ma(nb));
2154 static int libfab_target_notify(
struct m0_fab__buf *
buf)
2156 struct m0_fab__active_ep *aep;
2157 struct m0_fab__buf *fbp;
2158 struct m0_fab__tm *tm;
2160 struct fi_msg op_msg;
2164 aep = libfab_aep_get(
buf->fb_txctx);
2168 aep->aep_tx_state == FAB_CONNECTED) {
2174 fbp->fb_dummy[0] = FAB_DUMMY_DATA;
2175 fbp->fb_dummy[1] =
buf->fb_rbd->fbd_buftoken;
2176 fbp->fb_txctx =
buf->fb_txctx;
2177 tm = libfab_buf_tm(
buf);
2178 fbp->fb_token = libfab_buf_token_get(tm, fbp);
2179 aep->aep_bulk_cnt++;
2181 fab_bufhash_htable_add(&tm->ftm_bufhash.bht_hash, fbp);
2183 iv.iov_base = fbp->fb_dummy;
2184 iv.iov_len =
sizeof(fbp->fb_dummy);
2185 op_msg.msg_iov = &iv;
2187 op_msg.iov_count = 1;
2189 op_msg.context = U32_TO_VPTR(fbp->fb_token);
2192 ret = fi_sendmsg(aep->aep_txep, &op_msg, FI_COMPLETION);
2196 fab_bufhash_htable_del(&tm->ftm_bufhash.bht_hash, fbp);
2197 --aep->aep_bulk_cnt;
2208 static struct m0_fab__fab *libfab_newfab_init(
struct m0_fab__ndom *fnd)
2210 struct m0_fab__fab *fab =
NULL;
2214 fab_fabs_tlink_init_at_tail(fab, &fnd->fnd_fabrics);
2222 static int libfab_dns_resolve_retry(
struct m0_fab__ep *
ep)
2227 char *fqdn = en->
nia_p;
2228 char ip[LIBFAB_ADDR_LEN_MAX] = {};
2232 fqdn = strchr(fqdn,
':');
2233 fqdn = strchr(fqdn + 1,
':');
2241 libfab_ep_pton(en, &
ep->fep_name_n);
2246 rc > 0 ?
"gethostbyname()" :
"hostname_to_ip()",
2257 static int libfab_conn_init(
struct m0_fab__ep *
ep,
struct m0_fab__tm *
ma,
2258 struct m0_fab__buf *fbp)
2260 struct m0_fab__active_ep *aep;
2262 size_t cm_max_size = 0;
2263 size_t opt_size =
sizeof(size_t);
2264 struct m0_fab__conn_data cd;
2267 aep = libfab_aep_get(
ep);
2268 if (aep->aep_tx_state == FAB_NOT_CONNECTED) {
2273 libfab_dns_resolve_retry(
ep);
2274 dst =
ep->fep_name_n | 0x02;
2275 cd.fcd_addr =
ma->ftm_pep->fep_name.nia_n;
2277 ret = fi_getopt(&aep->aep_txep->fid, FI_OPT_ENDPOINT,
2278 FI_OPT_CM_DATA_SIZE,
2279 &cm_max_size, &opt_size);
2280 M0_ASSERT(ret == 0 &&
sizeof(cd) < cm_max_size);
2282 ret = fi_connect(aep->aep_txep, &
dst, &cd,
sizeof(cd));
2284 aep->aep_tx_state = FAB_CONNECTING;
2286 FAB_CONNECTING_TMOUT, 0);
2293 fab_sndbuf_tlink_init_at_tail(fbp, &
ep->fep_sndbuf);
2303 if (ret == -ECONNREFUSED) {
2304 libfab_buf_done(fbp, -ECONNREFUSED,
true);
2316 static int libfab_fab_ep_find(
struct m0_fab__tm *tm,
const char *
name,
2318 struct m0_fab__ep **
ep)
2326 *
ep = libfab_ep(
net);
2336 uint32_t
addr =
name->nia_n.nip_ip_n.sn[0];
2337 uint32_t
port =
name->nia_n.nip_port;
2352 static int libfab_txep_init(
struct m0_fab__active_ep *aep,
2353 struct m0_fab__tm *tm,
void *
ctx)
2355 struct m0_fab__ep *
ep = (
struct m0_fab__ep *)
ctx;
2357 struct m0_fab__fab *fab = tm->ftm_fab;
2358 struct fi_info *info;
2359 struct fi_info *hints =
NULL;
2361 bool is_verbs = libfab_is_verbs(tm);
2362 char ip[LIBFAB_ADDR_LEN_MAX] = {};
2363 char port[LIBFAB_PORT_LEN_MAX] = {};
2365 if (aep->aep_txep !=
NULL) {
2366 rc = fi_close(&aep->aep_txep->fid);
2370 rc = libfab_ep_txres_free(&aep->aep_tx_res, tm);
2374 aep->aep_tx_state = FAB_NOT_CONNECTED;
2375 aep->aep_txq_full =
false;
2376 ep->fep_connlink = FAB_CONNLINK_DOWN;
2379 hints = fi_allocinfo();
2382 hints->ep_attr->type = FI_EP_MSG;
2383 hints->caps = FI_MSG | FI_RMA;
2385 hints->mode |= FI_RX_CQ_DATA;
2386 hints->domain_attr->cq_data_size = 4;
2387 hints->domain_attr->mr_mode = FI_MR_LOCAL | FI_MR_ALLOCATED |
2388 FI_MR_PROV_KEY | FI_MR_VIRT_ADDR;
2389 hints->fabric_attr->prov_name =
2390 fab->fab_fi->fabric_attr->prov_name;
2392 libfab_straddr_gen(&en->
nia_n, ip);
2394 rc = fi_getinfo(LIBFAB_VERSION, ip,
port, 0,
2399 info = tm->ftm_fab->fab_fi;
2401 rc = fi_endpoint(fab->fab_dom, info, &aep->aep_txep,
NULL) ? :
2402 libfab_ep_txres_init(aep, tm,
ctx) ? :
2403 fi_enable(aep->aep_txep);
2406 hints->fabric_attr->prov_name =
NULL;
2419 static int libfab_fid_array_grow(
struct m0_fab__tm_fids *tmfid, uint32_t incr)
2421 struct m0_fab__ev_ctx **old_ctx = tmfid->ftf_ctx;
2422 struct m0_fab__ev_ctx **new_ctx =
NULL;
2423 struct fid **old_fid = tmfid->ftf_head;
2425 uint32_t old_size = tmfid->ftf_arr_size;
2426 uint32_t new_size = old_size + incr;
2429 M0_PRE(old_ctx !=
NULL && old_fid !=
NULL && old_size < new_size);
2440 for (
i = 0;
i < old_size;
i++) {
2441 new_ctx[
i] = old_ctx[
i];
2444 tmfid->ftf_ctx = new_ctx;
2446 tmfid->ftf_arr_size = new_size;
2448 M0_LOG(
M0_DEBUG,
"old={fid=%p ctx=%p size=%d} new={fid=%p ctx=%p size=%d}",
2449 old_fid, old_ctx, old_size,
new_fid, new_ctx, new_size);
2461 static int libfab_waitfd_bind(
struct fid*
fid,
struct m0_fab__tm *tm,
void *
ctx)
2463 struct m0_fab__tm_fids *tmfid = &tm->ftm_fids;
2464 struct m0_fab__ev_ctx *
ptr =
ctx;
2465 struct epoll_event ev;
2469 rc = fi_control(
fid, FI_GETWAIT, &
fd);
2473 ev.events = EPOLLIN;
2476 ptr->evctx_dbg,
fid,
fd,
ctx, tm, (
int)tmfid->ftf_cnt);
2477 rc = epoll_ctl(tm->ftm_epfd, EPOLL_CTL_ADD,
fd, &ev);
2480 if (tmfid->ftf_cnt >= (tmfid->ftf_arr_size - 1)) {
2481 rc = libfab_fid_array_grow(tmfid,
2482 FAB_TM_FID_MALLOC_STEP);
2486 tmfid->ftf_head[tmfid->ftf_cnt] =
fid;
2487 tmfid->ftf_ctx[tmfid->ftf_cnt] =
ptr;
2488 ptr->evctx_pos = tmfid->ftf_cnt;
2490 M0_ASSERT(tmfid->ftf_cnt < tmfid->ftf_arr_size);
2500 static int libfab_waitfd_unbind(
struct fid*
fid,
struct m0_fab__tm *tm,
2503 struct m0_fab__tm_fids *tmfid = &tm->ftm_fids;
2504 struct m0_fab__ev_ctx *
ptr =
ctx;
2505 struct epoll_event ev = {};
2510 rc = fi_control(
fid, FI_GETWAIT, &
fd);
2514 rc = epoll_ctl(tm->ftm_epfd, EPOLL_CTL_DEL,
fd, &ev);
2518 for (
i =
ptr->evctx_pos; i < tmfid->ftf_cnt - 1;
i++) {
2519 tmfid->ftf_head[
i] = tmfid->ftf_head[
i + 1];
2520 tmfid->ftf_ctx[
i] = tmfid->ftf_ctx[
i + 1];
2521 tmfid->ftf_ctx[
i]->evctx_pos--;
2524 tmfid->ftf_head[tmfid->ftf_cnt] = 0;
2525 tmfid->ftf_ctx[tmfid->ftf_cnt] = 0;
2535 static inline struct m0_fab__active_ep *libfab_aep_get(
struct m0_fab__ep *
ep)
2537 return ep->fep_listen ==
NULL ?
ep->fep_aep :
ep->fep_listen->pep_aep;
2543 static inline bool libfab_is_verbs(
struct m0_fab__tm *tm)
2545 return tm->ftm_fab->fab_prov == FAB_FABRIC_PROV_VERBS;
2551 static int libfab_txbuf_list_add(
struct m0_fab__tm *tm,
struct m0_fab__buf *fb,
2552 struct m0_fab__active_ep *aep)
2554 struct m0_fab__bulk_op *
op;
2561 fb->fb_bulk_op =
op;
2564 fab_bulk_tlink_init_at_tail(
op, &tm->ftm_bulk);
2572 static void libfab_bufq_process(
struct m0_fab__tm *tm)
2574 struct m0_fab__bulk_op *
op;
2582 if (
op->fbl_aep->aep_tx_state == FAB_CONNECTED &&
2583 !
op->fbl_aep->aep_txq_full) {
2585 ret = libfab_ping_op(
op->fbl_aep,
op->fbl_buf);
2587 ret = libfab_bulk_op(
op->fbl_aep,
op->fbl_buf);
2590 fab_bulk_tlist_del(
op);
2591 op->fbl_buf->fb_bulk_op =
NULL;
2594 op->fbl_aep->aep_txq_full =
true;
2605 static int libfab_ping_op(
struct m0_fab__active_ep *aep,
struct m0_fab__buf *fb)
2607 struct fi_msg op_msg;
2611 iv.iov_base = fb->fb_nb->nb_buffer.ov_buf[0];
2612 iv.iov_len = fb->fb_nb->nb_buffer.ov_vec.v_count[0];
2613 op_msg.msg_iov = &iv;
2614 op_msg.desc = fb->fb_mr.bm_desc;
2615 op_msg.iov_count = 1;
2617 op_msg.context = U32_TO_VPTR(fb->fb_token);
2620 ret = fi_sendmsg(aep->aep_txep, &op_msg, FI_COMPLETION);
2622 aep->aep_bulk_cnt += fb->fb_wr_cnt;
2631 static int libfab_bulk_op(
struct m0_fab__active_ep *aep,
struct m0_fab__buf *fb)
2633 struct m0_fab__buf_xfer_params xp;
2634 struct m0_fab__tm *tm = libfab_buf_tm(fb);
2635 struct fi_msg_rma op_msg;
2636 struct fi_rma_iov *r_iov;
2637 struct fi_rma_iov *
remote = tm->ftm_rem_iov;
2638 struct iovec *loc_iv = tm->ftm_loc_iov;
2643 uint32_t wr_cnt = 0;
2644 uint32_t max_iov = tm->ftm_fab->fab_max_iov;
2648 bool last_seg =
false;
2650 M0_ENTRY(
"loc_buf=%p q=%d loc_seg=%d rem_buf=%d rem_seg=%d iov_max=%d",
2651 fb, fb->fb_nb->nb_qtype, fb->fb_nb->nb_buffer.ov_vec.v_nr,
2652 (
int)fb->fb_rbd->fbd_buftoken, (
int)fb->fb_rbd->fbd_iov_cnt,
2657 v_cnt = fb->fb_nb->nb_buffer.ov_vec.v_count;
2659 xp = fb->fb_xfer_params;
2660 r_iov = fb->fb_riov;
2663 while (xp.bxp_xfer_len < fb->fb_nb->nb_length) {
2664 for (idx = 0; idx < max_iov && !last_seg; idx++) {
2665 M0_ASSERT(xp.bxp_rem_sidx <= fb->fb_rbd->fbd_iov_cnt);
2666 loc_slen = v_cnt[xp.bxp_loc_sidx] - xp.bxp_loc_soff;
2667 rem_slen = r_iov[xp.bxp_rem_sidx].len - xp.bxp_rem_soff;
2669 loc_iv[idx].iov_base = fb->fb_nb->nb_buffer.ov_buf[
2672 loc_iv[idx].iov_len =
min64u(loc_slen, rem_slen);
2673 remote[idx] = r_iov[xp.bxp_rem_sidx];
2674 remote[idx].addr += xp.bxp_rem_soff;
2675 remote[idx].len -= xp.bxp_rem_soff;
2677 if (loc_slen > rem_slen) {
2679 xp.bxp_rem_soff = 0;
2680 xp.bxp_loc_soff += loc_iv[idx].iov_len;
2683 xp.bxp_loc_soff = 0;
2684 xp.bxp_rem_soff += loc_iv[idx].iov_len;
2685 if (xp.bxp_rem_soff >=
2686 r_iov[xp.bxp_rem_sidx].len) {
2688 xp.bxp_rem_soff = 0;
2692 xp.bxp_xfer_len += loc_iv[idx].iov_len;
2693 if (xp.bxp_xfer_len >= fb->fb_nb->nb_length)
2697 op_msg.msg_iov = &loc_iv[0];
2698 op_msg.desc = &fb->fb_mr.bm_desc[xp.bxp_loc_sidx];
2699 op_msg.iov_count = idx;
2700 op_msg.addr = xp.bxp_rem_soff;
2701 op_msg.rma_iov = &
remote[0];
2702 op_msg.rma_iov_count = idx;
2703 op_msg.context = U32_TO_VPTR(fb->fb_token);
2705 op_msg.data = (isread || (!last_seg)) ? 0 :
2706 fb->fb_rbd->fbd_buftoken;
2707 op_flag = (isread || (!last_seg)) ? 0 : FI_REMOTE_CQ_DATA;
2708 op_flag |= last_seg ? FI_COMPLETION : 0;
2710 ret = isread ? fi_readmsg(aep->aep_txep, &op_msg, op_flag) :
2711 fi_writemsg(aep->aep_txep, &op_msg, op_flag);
2715 opcnt=%d", ret, fb, fb->fb_nb->nb_qtype,
2716 xp.bxp_loc_sidx, aep->aep_bulk_cnt);
2720 aep->aep_bulk_cnt++;
2722 fb->fb_xfer_params = xp;
2725 fb->fb_wr_cnt += wr_cnt;
2732 static uint32_t libfab_buf_token_get(
struct m0_fab__tm *tm,
2733 struct m0_fab__buf *fb)
2735 union m0_fab__token
token;
2739 fb->fb_nb->nb_qtype;
2741 if (tm->ftm_op_id == 0)
2744 ++tm->ftm_rr_qt[
token.t_Fields.tf_queue_id];
2746 token.t_Fields.tf_queue_num = (tm->ftm_rr_qt[
token.t_Fields.tf_queue_id]
2747 % FAB_NUM_BUCKETS_PER_QTYPE);
2748 token.t_Fields.tf_tag = tm->ftm_op_id;
2753 static int libfab_domain_params_get(
struct m0_fab__ndom *fab_ndom)
2755 struct fi_info *hints;
2757 struct sockaddr_in *v_src;
2758 struct sockaddr_in t_src;
2761 hints = fi_allocinfo();
2764 hints->fabric_attr->prov_name = (
char *)providers[FAB_FABRIC_PROV_VERBS];
2765 result = fi_getinfo(FI_VERSION(1,11),
NULL,
NULL, 0, hints, &
fi);
2768 v_src =
fi->src_addr;
2769 inet_ntop(AF_INET, &v_src->sin_addr, fab_ndom->fnd_loc_ip,
2771 fab_ndom->fnd_seg_nr = FAB_VERBS_IOV_MAX;
2772 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;
2782 hints->fabric_attr->prov_name =
NULL;
2788 static int libfab_buf_dom_dereg(
struct m0_fab__buf *fbp)
2796 seg_nr = fbp->fb_nb->nb_buffer.ov_vec.v_nr;
2799 if (fbp->fb_mr.bm_mr[
i] !=
NULL) {
2809 ret = fi_close(&fbp->fb_mr.bm_mr[
i]->fid);
2816 fbp->fb_mr.bm_mr[
i] =
NULL;
2822 fbp->fb_state = FAB_BUF_DEREGISTERED;
2836 struct m0_fab__ndom *fab_ndom;
2842 if (fab_ndom ==
NULL)
2845 ret = libfab_domain_params_get(fab_ndom);
2849 dom->nd_xprt_private = fab_ndom;
2850 fab_ndom->fnd_ndom =
dom;
2852 fab_fabs_tlist_init(&fab_ndom->fnd_fabrics);
2862 struct m0_fab__ndom *fnd;
2863 struct m0_fab__fab *fab;
2867 libfab_dom_invariant(
dom);
2868 fnd =
dom->nd_xprt_private;
2870 if (fab->fab_dom !=
NULL) {
2871 rc = fi_close(&fab->fab_dom->fid);
2874 fab->fab_dom =
NULL;
2877 if (fab->fab_fab !=
NULL) {
2878 rc = fi_close(&fab->fab_fab->fid);
2882 fab->fab_fab =
NULL;
2885 if (fab->fab_fi !=
NULL) {
2886 fi_freeinfo(fab->fab_fi);
2892 fab_fabs_tlist_fini(&fnd->fnd_fabrics);
2895 fnd->fnd_ndom =
NULL;
2913 fab_buf_tlist_fini(&
ma->ftm_done);
2926 struct m0_fab__tm *ftm;
2933 ftm->ftm_state = FAB_TM_INIT;
2936 ftm->ftm_fids.ftf_cnt = 0;
2937 M0_ALLOC_ARR(ftm->ftm_fids.ftf_head, FAB_TM_FID_MALLOC_STEP);
2938 M0_ALLOC_ARR(ftm->ftm_fids.ftf_ctx, FAB_TM_FID_MALLOC_STEP);
2939 if (ftm->ftm_fids.ftf_head ==
NULL ||
2940 ftm->ftm_fids.ftf_ctx ==
NULL) {
2941 m0_free(ftm->ftm_fids.ftf_head);
2942 m0_free(ftm->ftm_fids.ftf_ctx);
2945 ftm->ftm_fids.ftf_arr_size = FAB_TM_FID_MALLOC_STEP;
2946 fab_buf_tlist_init(&ftm->ftm_done);
2947 fab_bulk_tlist_init(&ftm->ftm_bulk);
2949 rc = fab_bufhash_htable_init(&ftm->ftm_bufhash.bht_hash,
2951 FAB_NUM_BUCKETS_PER_QTYPE));
2955 if (
rc != 0 && ftm !=
NULL)
2956 libfab_ma_fini(ntm);
2967 struct m0_fab__ndom *fnd;
2973 if (ftm->ftm_pep !=
NULL) {
2975 rc = libfab_ep_addr_decode(ftm->ftm_pep,
name);
2979 ftm->ftm_fab = libfab_newfab_init(fnd);
2980 ftm->ftm_fab->fab_prov = FAB_FABRIC_PROV_MAX;
2981 rc = libfab_passive_ep_create(ftm->ftm_pep, ftm);
2985 nep = &ftm->ftm_pep->fep_nep;
2988 libfab_ep_pton(&ftm->ftm_pep->fep_name,
2989 &ftm->ftm_pep->fep_name_n);
2991 ftm->ftm_pep->fep_nep.nep_addr = ftm->ftm_pep->fep_name.nia_p;
2997 &libfab_poller, ftm,
"libfab_tm");
3001 ftm->ftm_state = FAB_TM_STARTED;
3014 struct m0_fab__tm *tm =
net->ntm_xprt_private;
3021 libfab_tm_unlock(tm);
3022 libfab_tm_fini(
net);
3050 return (libfab_ep_find(tm,
name,
NULL, epp));
3066 libfab_buf_invariant(fb));
3068 libfab_buf_dom_dereg(fb);
3069 libfab_buf_fini(fb);
3085 struct m0_fab__buf *fb;
3100 if (fb->fb_mr.bm_desc ==
NULL || fb->fb_mr.bm_mr ==
NULL) {
3107 fab_buf_tlink_init(fb);
3110 fb->fb_state = FAB_BUF_INITIALIZED;
3125 struct m0_fab__tm *
ma = libfab_buf_ma(nb);
3126 struct m0_fab__ep *
ep =
NULL;
3127 struct m0_fab__active_ep *aep;
3135 M0_PRE(libfab_tm_is_locked(
ma) && libfab_tm_invariant(
ma) &&
3136 libfab_buf_invariant(fbp));
3140 fab_buf_tlink_init(fbp);
3141 fbp->fb_token = libfab_buf_token_get(
ma, fbp);
3142 libfab_buf_dom_reg(nb,
ma);
3151 ret = fi_recvv(
ma->ftm_rctx, &iv, fbp->fb_mr.bm_desc, 1, 0,
3152 U32_TO_VPTR(fbp->fb_token));
3167 aep = libfab_aep_get(
ep);
3170 if (aep->aep_tx_state != FAB_CONNECTED)
3171 ret = libfab_conn_init(
ep,
ma, fbp);
3173 ret = libfab_txbuf_list_add(
ma, fbp, aep);
3174 libfab_bufq_process(
ma);
3182 if (!libfab_is_verbs(
ma)) {
3183 ret = libfab_bdesc_encode(fbp);
3191 if (m0_net_tm_tlist_is_empty(
3193 ret = fi_recv(
ma->ftm_rctx, fbp->fb_dummy,
3194 sizeof(fbp->fb_dummy),
NULL, 0,
3195 U32_TO_VPTR(fbp->fb_token));
3198 ret = libfab_bdesc_encode(fbp);
3208 libfab_bdesc_decode(fbp, &
addr.nia_n);
3213 aep = libfab_aep_get(
ep);
3214 if (aep->aep_tx_state != FAB_CONNECTED)
3215 ret = libfab_conn_init(
ep,
ma, fbp);
3217 ret = libfab_txbuf_list_add(
ma, fbp, aep);
3218 libfab_bufq_process(
ma);
3229 fbp->fb_state = FAB_BUF_QUEUED;
3231 fab_bufhash_htable_add(&
ma->ftm_bufhash.bht_hash, fbp);
3247 struct m0_fab__tm *
ma = libfab_buf_ma(nb);
3249 M0_PRE(libfab_tm_is_locked(
ma) && libfab_tm_invariant(
ma) &&
3250 libfab_buf_invariant(
buf));
3253 libfab_buf_dom_dereg(
buf);
3254 buf->fb_state = FAB_BUF_CANCELED;
3255 libfab_buf_done(
buf, -ECANCELED,
false);
3308 struct m0_fab__ndom *
nd =
dom->nd_xprt_private;
3322 return ((
struct m0_fab__ndom *)
dom->nd_xprt_private)->fnd_seg_size;
3332 static int32_t libfab_get_max_buf_segments(
const struct m0_net_domain *
dom)
3334 return ((
struct m0_fab__ndom *)
dom->nd_xprt_private)->fnd_seg_nr;
3345 struct m0_fab__ndom *
nd =
dom->nd_xprt_private;
3346 m0_bcount_t max_bd_size =
sizeof(
struct fi_rma_iov);
3348 max_bd_size = (max_bd_size *
nd->fnd_seg_nr) +
3349 sizeof(
struct m0_fab__bdesc);
3364 return FAB_MAX_RPC_SEG_SIZE;
3374 static uint32_t libfab_rpc_max_segs_nr(
struct m0_net_domain *ndom)
3377 return FAB_MAX_RPC_SEG_NR;
3393 mbs = libfab_rpc_max_seg_size(ndom) * libfab_rpc_max_segs_nr(ndom);
3394 return rpc_size != 0 ?
m0_clip64u(M0_SEG_SIZE, mbs, rpc_size) : mbs;
3404 static uint32_t libfab_rpc_max_recv_msgs(
struct m0_net_domain *ndom,
3408 return FAB_MAX_RPC_RECV_MSG_NR;
3413 .xo_dom_fini = &libfab_dom_fini,
3414 .xo_tm_init = &libfab_ma_init,
3415 .xo_tm_confine = &libfab_ma_confine,
3416 .xo_tm_start = &libfab_ma_start,
3417 .xo_tm_stop = &libfab_ma_stop,
3418 .xo_tm_fini = &libfab_ma_fini,
3419 .xo_end_point_create = &libfab_end_point_create,
3420 .xo_buf_register = &libfab_buf_register,
3421 .xo_buf_deregister = &libfab_buf_deregister,
3422 .xo_buf_add = &libfab_buf_add,
3423 .xo_buf_del = &libfab_buf_del,
3424 .xo_bev_deliver_sync = &libfab_bev_deliver_sync,
3425 .xo_bev_deliver_all = &libfab_bev_deliver_all,
3426 .xo_bev_pending = &libfab_bev_pending,
3427 .xo_bev_notify = &libfab_bev_notify,
3428 .xo_get_max_buffer_size = &libfab_get_max_buf_size,
3429 .xo_get_max_buffer_segment_size = &libfab_get_max_buf_seg_size,
3430 .xo_get_max_buffer_segments = &libfab_get_max_buf_segments,
3431 .xo_get_max_buffer_desc_size = &libfab_get_max_buf_desc_size,
3432 .xo_rpc_max_seg_size = &libfab_rpc_max_seg_size,
3433 .xo_rpc_max_segs_nr = &libfab_rpc_max_segs_nr,
3434 .xo_rpc_max_msg_size = &libfab_rpc_max_msg_size,
3435 .xo_rpc_max_recv_msgs = &libfab_rpc_max_recv_msgs,
3440 .nx_ops = &libfab_xprt_ops
3442 M0_EXPORTED(m0_net_libfab_xprt);
3459 #undef M0_TRACE_SUBSYSTEM union m0_net_ip_params::@377 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)
#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)
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
union m0_net_ip_params::@376 nip_ip_n
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)
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)