corosync  2.3.2
totemiba.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2012 Red Hat, Inc.
3  *
4  * All rights reserved.
5  *
6  * Author: Steven Dake (sdake@redhat.com)
7 
8  * This software licensed under BSD license, the text of which follows:
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  * - Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * - Neither the name of the MontaVista Software, Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <config.h>
36 
37 #include <assert.h>
38 #include <pthread.h>
39 #include <sys/mman.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/socket.h>
43 #include <netdb.h>
44 #include <sys/un.h>
45 #include <sys/ioctl.h>
46 #include <sys/param.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49 #include <unistd.h>
50 #include <fcntl.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <errno.h>
54 #include <sched.h>
55 #include <time.h>
56 #include <sys/time.h>
57 #include <sys/poll.h>
58 #include <limits.h>
59 #include <stdio.h>
60 #include <string.h>
61 #include <stdlib.h>
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <netdb.h>
65 #include <rdma/rdma_cma.h>
66 #include <assert.h>
67 #include <errno.h>
68 
69 #include <corosync/sq.h>
70 #include <corosync/list.h>
71 #include <corosync/hdb.h>
72 #include <corosync/swab.h>
73 
74 #include <qb/qbdefs.h>
75 #include <qb/qbloop.h>
76 #define LOGSYS_UTILS_ONLY 1
77 #include <corosync/logsys.h>
78 #include "totemiba.h"
79 
80 #define COMPLETION_QUEUE_ENTRIES 100
81 
82 #define TOTAL_READ_POSTS 100
83 
84 #define MAX_MTU_SIZE 4096
85 
87  struct sockaddr bind_addr;
88 
89  struct sockaddr send_token_bind_addr;
90 
91  struct sockaddr mcast_addr;
92 
93  struct sockaddr token_addr;
94 
95  struct sockaddr local_mcast_bind_addr;
96 
98 
100 
102 
104  void *context,
105  const struct totem_ip_address *iface_address);
106 
108  void *context,
109  const void *msg,
110  unsigned int msg_len);
111 
113  void *context);
114 
115  void *rrp_context;
116 
117  qb_loop_timer_handle timer_netif_check_timeout;
118 
120 
122 
123  struct rdma_event_channel *mcast_channel;
124 
125  struct rdma_cm_id *mcast_cma_id;
126 
127  struct ibv_pd *mcast_pd;
128 
129  struct sockaddr mcast_dest_addr;
130 
131  uint32_t mcast_qpn;
132 
133  uint32_t mcast_qkey;
134 
135  struct ibv_ah *mcast_ah;
136 
137  struct ibv_comp_channel *mcast_send_completion_channel;
138 
139  struct ibv_comp_channel *mcast_recv_completion_channel;
140 
141  struct ibv_cq *mcast_send_cq;
142 
143  struct ibv_cq *mcast_recv_cq;
144 
146 
147  struct rdma_event_channel *recv_token_channel;
148 
149  struct rdma_event_channel *listen_recv_token_channel;
150 
151  struct rdma_cm_id *listen_recv_token_cma_id;
152 
153  struct rdma_cm_id *recv_token_cma_id;
154 
155  struct ibv_pd *recv_token_pd;
156 
157  struct sockaddr recv_token_dest_addr;
158 
159  struct ibv_comp_channel *recv_token_send_completion_channel;
160 
161  struct ibv_comp_channel *recv_token_recv_completion_channel;
162 
163  struct ibv_cq *recv_token_send_cq;
164 
165  struct ibv_cq *recv_token_recv_cq;
166 
168 
169  struct rdma_event_channel *send_token_channel;
170 
171  struct rdma_cm_id *send_token_cma_id;
172 
173  struct ibv_pd *send_token_pd;
174 
175  struct sockaddr send_token_dest_addr;
176 
177  uint32_t send_token_qpn;
178 
179  uint32_t send_token_qkey;
180 
181  struct ibv_ah *send_token_ah;
182 
183  struct ibv_comp_channel *send_token_send_completion_channel;
184 
185  struct ibv_comp_channel *send_token_recv_completion_channel;
186 
187  struct ibv_cq *send_token_send_cq;
188 
189  struct ibv_cq *send_token_recv_cq;
190 
192  int level,
193  int subsys,
194  const char *function,
195  const char *file,
196  int line,
197  const char *format,
198  ...)__attribute__((format(printf, 6, 7)));
199 
200 
201  int totemiba_subsys_id;
202 
204 
206 
208 
210 
212 };
213 union u {
214  uint64_t wr_id;
215  void *v;
216 };
217 
218 #define log_printf(level, format, args...) \
219 do { \
220  instance->totemiba_log_printf ( \
221  level, \
222  instance->totemiba_subsys_id, \
223  __FUNCTION__, __FILE__, __LINE__, \
224  (const char *)format, ##args); \
225 } while (0);
226 
227 struct recv_buf {
229  struct ibv_recv_wr recv_wr;
230  struct ibv_sge sge;
231  struct ibv_mr *mr;
233 };
234 
235 struct send_buf {
238  struct ibv_mr *mr;
240 };
241 
242 static hdb_handle_t
243 void2wrid (void *v) { union u u; u.v = v; return u.wr_id; }
244 
245 static void *
246 wrid2void (uint64_t wr_id) { union u u; u.wr_id = wr_id; return u.v; }
247 
248 static void totemiba_instance_initialize (struct totemiba_instance *instance)
249 {
250  memset (instance, 0, sizeof (struct totemiba_instance));
251  list_init (&instance->mcast_send_buf_free);
252  list_init (&instance->token_send_buf_free);
253  list_init (&instance->mcast_send_buf_head);
254  list_init (&instance->token_send_buf_head);
255  list_init (&instance->recv_token_recv_buf_head);
256 }
257 
258 static inline struct send_buf *mcast_send_buf_get (
259  struct totemiba_instance *instance)
260 {
261  struct send_buf *send_buf;
262 
263  if (list_empty (&instance->mcast_send_buf_free) == 0) {
264  send_buf = list_entry (instance->mcast_send_buf_free.next, struct send_buf, list_free);
265  list_del (&send_buf->list_free);
266  return (send_buf);
267  }
268 
269  send_buf = malloc (sizeof (struct send_buf));
270  if (send_buf == NULL) {
271  return (NULL);
272  }
273  send_buf->mr = ibv_reg_mr (instance->mcast_pd,
274  send_buf->buffer,
275  2048, IBV_ACCESS_LOCAL_WRITE);
276  if (send_buf->mr == NULL) {
277  log_printf (LOGSYS_LEVEL_ERROR, "couldn't register memory range");
278  free (send_buf);
279  return (NULL);
280  }
281  list_init (&send_buf->list_all);
282  list_add_tail (&send_buf->list_all, &instance->mcast_send_buf_head);
283 
284  return (send_buf);
285 }
286 
287 static inline void mcast_send_buf_put (
288  struct totemiba_instance *instance,
289  struct send_buf *send_buf)
290 {
291  list_init (&send_buf->list_free);
292  list_add_tail (&send_buf->list_free, &instance->mcast_send_buf_free);
293 }
294 
295 static inline struct send_buf *token_send_buf_get (
296  struct totemiba_instance *instance)
297 {
298  struct send_buf *send_buf;
299 
300  if (list_empty (&instance->token_send_buf_free) == 0) {
301  send_buf = list_entry (instance->token_send_buf_free.next, struct send_buf, list_free);
302  list_del (&send_buf->list_free);
303  return (send_buf);
304  }
305 
306  send_buf = malloc (sizeof (struct send_buf));
307  if (send_buf == NULL) {
308  return (NULL);
309  }
310  send_buf->mr = ibv_reg_mr (instance->send_token_pd,
311  send_buf->buffer,
312  2048, IBV_ACCESS_LOCAL_WRITE);
313  if (send_buf->mr == NULL) {
314  log_printf (LOGSYS_LEVEL_ERROR, "couldn't register memory range");
315  free (send_buf);
316  return (NULL);
317  }
318  list_init (&send_buf->list_all);
319  list_add_tail (&send_buf->list_all, &instance->token_send_buf_head);
320 
321  return (send_buf);
322 }
323 
324 static inline void token_send_buf_destroy (struct totemiba_instance *instance)
325 {
326  struct list_head *list;
327  struct send_buf *send_buf;
328 
329  for (list = instance->token_send_buf_head.next; list != &instance->token_send_buf_head;) {
330  send_buf = list_entry (list, struct send_buf, list_all);
331  list = list->next;
332  ibv_dereg_mr (send_buf->mr);
333  free (send_buf);
334  }
335 
336  list_init (&instance->token_send_buf_free);
337  list_init (&instance->token_send_buf_head);
338 }
339 
340 static inline void token_send_buf_put (
341  struct totemiba_instance *instance,
342  struct send_buf *send_buf)
343 {
344  list_init (&send_buf->list_free);
345  list_add_tail (&send_buf->list_free, &instance->token_send_buf_free);
346 }
347 
348 static inline struct recv_buf *recv_token_recv_buf_create (
349  struct totemiba_instance *instance)
350 {
351  struct recv_buf *recv_buf;
352 
353  recv_buf = malloc (sizeof (struct recv_buf));
354  if (recv_buf == NULL) {
355  return (NULL);
356  }
357 
358  recv_buf->mr = ibv_reg_mr (instance->recv_token_pd, &recv_buf->buffer,
359  2048,
360  IBV_ACCESS_LOCAL_WRITE);
361 
362  recv_buf->recv_wr.next = NULL;
363  recv_buf->recv_wr.sg_list = &recv_buf->sge;
364  recv_buf->recv_wr.num_sge = 1;
365  recv_buf->recv_wr.wr_id = (uintptr_t)recv_buf;
366 
367  recv_buf->sge.length = 2048;
368  recv_buf->sge.lkey = recv_buf->mr->lkey;
369  recv_buf->sge.addr = (uintptr_t)recv_buf->buffer;
370 
371  list_init (&recv_buf->list_all);
372  list_add (&recv_buf->list_all, &instance->recv_token_recv_buf_head);
373  return (recv_buf);
374 }
375 
376 static inline int recv_token_recv_buf_post (struct totemiba_instance *instance, struct recv_buf *recv_buf)
377 {
378  struct ibv_recv_wr *fail_recv;
379  int res;
380 
381  res = ibv_post_recv (instance->recv_token_cma_id->qp, &recv_buf->recv_wr, &fail_recv);
382 
383  return (res);
384 }
385 
386 static inline void recv_token_recv_buf_post_initial (struct totemiba_instance *instance)
387 {
388  struct recv_buf *recv_buf;
389  unsigned int i;
390 
391  for (i = 0; i < TOTAL_READ_POSTS; i++) {
392  recv_buf = recv_token_recv_buf_create (instance);
393 
394  recv_token_recv_buf_post (instance, recv_buf);
395  }
396 }
397 
398 static inline void recv_token_recv_buf_post_destroy (
399  struct totemiba_instance *instance)
400 {
401  struct recv_buf *recv_buf;
402  struct list_head *list;
403 
404  for (list = instance->recv_token_recv_buf_head.next;
405  list != &instance->recv_token_recv_buf_head;) {
406 
407  recv_buf = list_entry (list, struct recv_buf, list_all);
408  list = list->next;
409  ibv_dereg_mr (recv_buf->mr);
410  free (recv_buf);
411  }
412  list_init (&instance->recv_token_recv_buf_head);
413 }
414 
415 static inline struct recv_buf *mcast_recv_buf_create (struct totemiba_instance *instance)
416 {
417  struct recv_buf *recv_buf;
418  struct ibv_mr *mr;
419 
420  recv_buf = malloc (sizeof (struct recv_buf));
421  if (recv_buf == NULL) {
422  return (NULL);
423  }
424 
425  mr = ibv_reg_mr (instance->mcast_pd, &recv_buf->buffer,
426  2048,
427  IBV_ACCESS_LOCAL_WRITE);
428 
429  recv_buf->recv_wr.next = NULL;
430  recv_buf->recv_wr.sg_list = &recv_buf->sge;
431  recv_buf->recv_wr.num_sge = 1;
432  recv_buf->recv_wr.wr_id = (uintptr_t)recv_buf;
433 
434  recv_buf->sge.length = 2048;
435  recv_buf->sge.lkey = mr->lkey;
436  recv_buf->sge.addr = (uintptr_t)recv_buf->buffer;
437 
438  return (recv_buf);
439 }
440 
441 static inline int mcast_recv_buf_post (struct totemiba_instance *instance, struct recv_buf *recv_buf)
442 {
443  struct ibv_recv_wr *fail_recv;
444  int res;
445 
446  res = ibv_post_recv (instance->mcast_cma_id->qp, &recv_buf->recv_wr, &fail_recv);
447 
448  return (res);
449 }
450 
451 static inline void mcast_recv_buf_post_initial (struct totemiba_instance *instance)
452 {
453  struct recv_buf *recv_buf;
454  unsigned int i;
455 
456  for (i = 0; i < TOTAL_READ_POSTS; i++) {
457  recv_buf = mcast_recv_buf_create (instance);
458 
459  mcast_recv_buf_post (instance, recv_buf);
460  }
461 }
462 
463 static inline void iba_deliver_fn (struct totemiba_instance *instance, uint64_t wr_id, uint32_t bytes)
464 {
465  const char *addr;
466  const struct recv_buf *recv_buf;
467 
468  recv_buf = wrid2void(wr_id);
469  addr = &recv_buf->buffer[sizeof (struct ibv_grh)];
470 
471  instance->totemiba_deliver_fn (instance->rrp_context, addr, bytes);
472 }
473 
474 static int mcast_cq_send_event_fn (int events, int suck, void *context)
475 {
476  struct totemiba_instance *instance = (struct totemiba_instance *)context;
477  struct ibv_wc wc[32];
478  struct ibv_cq *ev_cq;
479  void *ev_ctx;
480  int res;
481  int i;
482 
483  ibv_get_cq_event (instance->mcast_send_completion_channel, &ev_cq, &ev_ctx);
484  ibv_ack_cq_events (ev_cq, 1);
485  res = ibv_req_notify_cq (ev_cq, 0);
486 
487  res = ibv_poll_cq (instance->mcast_send_cq, 32, wc);
488  if (res > 0) {
489  for (i = 0; i < res; i++) {
490  mcast_send_buf_put (instance, wrid2void(wc[i].wr_id));
491  }
492  }
493 
494  return (0);
495 }
496 
497 static int mcast_cq_recv_event_fn (int events, int suck, void *context)
498 {
499  struct totemiba_instance *instance = (struct totemiba_instance *)context;
500  struct ibv_wc wc[64];
501  struct ibv_cq *ev_cq;
502  void *ev_ctx;
503  int res;
504  int i;
505 
506  ibv_get_cq_event (instance->mcast_recv_completion_channel, &ev_cq, &ev_ctx);
507  ibv_ack_cq_events (ev_cq, 1);
508  res = ibv_req_notify_cq (ev_cq, 0);
509 
510  res = ibv_poll_cq (instance->mcast_recv_cq, 64, wc);
511  if (res > 0) {
512  for (i = 0; i < res; i++) {
513  iba_deliver_fn (instance, wc[i].wr_id, wc[i].byte_len);
514  mcast_recv_buf_post (instance, wrid2void(wc[i].wr_id));
515  }
516  }
517 
518  return (0);
519 }
520 
521 static int mcast_rdma_event_fn (int events, int suck, void *context)
522 {
523  struct totemiba_instance *instance = (struct totemiba_instance *)context;
524  struct rdma_cm_event *event;
525 
526  int res;
527 
528  res = rdma_get_cm_event (instance->mcast_channel, &event);
529  if (res != 0) {
530  return (0);
531  }
532 
533  switch (event->event) {
534  /*
535  * occurs when we resolve the multicast address
536  */
537  case RDMA_CM_EVENT_ADDR_RESOLVED:
538  rdma_join_multicast (instance->mcast_cma_id, &instance->mcast_addr, instance);
539  usleep(1000);
540  break;
541  /*
542  * occurs when the CM joins the multicast group
543  */
544  case RDMA_CM_EVENT_MULTICAST_JOIN:
545  instance->mcast_qpn = event->param.ud.qp_num;
546  instance->mcast_qkey = event->param.ud.qkey;
547  instance->mcast_ah = ibv_create_ah (instance->mcast_pd, &event->param.ud.ah_attr);
548 
549  instance->totemiba_iface_change_fn (instance->rrp_context, &instance->my_id);
550  break;
551  case RDMA_CM_EVENT_ADDR_ERROR:
552  case RDMA_CM_EVENT_ROUTE_ERROR:
553  case RDMA_CM_EVENT_MULTICAST_ERROR:
554  log_printf (LOGSYS_LEVEL_ERROR, "multicast error");
555  break;
556  case RDMA_CM_EVENT_DEVICE_REMOVAL:
557  break;
558  default:
559  log_printf (LOGSYS_LEVEL_ERROR, "default %d", event->event);
560  break;
561  }
562 
563  rdma_ack_cm_event (event);
564  return (0);
565 }
566 
567 static int recv_token_cq_send_event_fn (
568  int fd,
569  int revents,
570  void *context)
571 {
572  struct totemiba_instance *instance = (struct totemiba_instance *)context;
573  struct ibv_wc wc[32];
574  struct ibv_cq *ev_cq;
575  void *ev_ctx;
576  int res;
577  int i;
578 
579  ibv_get_cq_event (instance->recv_token_send_completion_channel, &ev_cq, &ev_ctx);
580  ibv_ack_cq_events (ev_cq, 1);
581  res = ibv_req_notify_cq (ev_cq, 0);
582 
583  res = ibv_poll_cq (instance->recv_token_send_cq, 32, wc);
584  if (res > 0) {
585  for (i = 0; i < res; i++) {
586  iba_deliver_fn (instance, wc[i].wr_id, wc[i].byte_len);
587  ibv_dereg_mr (wrid2void(wc[i].wr_id));
588  }
589  }
590 
591  return (0);
592 }
593 
594 static int recv_token_cq_recv_event_fn (int events, int suck, void *context)
595 {
596  struct totemiba_instance *instance = (struct totemiba_instance *)context;
597  struct ibv_wc wc[32];
598  struct ibv_cq *ev_cq;
599  void *ev_ctx;
600  int res;
601  int i;
602 
603  ibv_get_cq_event (instance->recv_token_recv_completion_channel, &ev_cq, &ev_ctx);
604  ibv_ack_cq_events (ev_cq, 1);
605  res = ibv_req_notify_cq (ev_cq, 0);
606 
607  res = ibv_poll_cq (instance->recv_token_recv_cq, 32, wc);
608  if (res > 0) {
609  for (i = 0; i < res; i++) {
610  iba_deliver_fn (instance, wc[i].wr_id, wc[i].byte_len);
611  recv_token_recv_buf_post (instance, wrid2void(wc[i].wr_id));
612  }
613  }
614 
615  return (0);
616 }
617 
618 static int recv_token_accept_destroy (struct totemiba_instance *instance)
619 {
620  if (instance->recv_token_accepted == 0) {
621  return (0);
622  }
623 
624  rdma_destroy_qp (instance->recv_token_cma_id);
625 
626  recv_token_recv_buf_post_destroy (instance);
627 
628  ibv_destroy_cq (instance->recv_token_send_cq);
629 
630  ibv_destroy_cq (instance->recv_token_recv_cq);
631 
632  ibv_destroy_comp_channel (instance->recv_token_send_completion_channel);
633 
634  ibv_destroy_comp_channel (instance->recv_token_recv_completion_channel);
635 
636  ibv_dealloc_pd (instance->recv_token_pd);
637 
638  rdma_destroy_id (instance->recv_token_cma_id);
639 
640  qb_loop_poll_del (
641  instance->totemiba_poll_handle,
642  instance->recv_token_recv_completion_channel->fd);
643 
644  qb_loop_poll_del (
645  instance->totemiba_poll_handle,
646  instance->recv_token_send_completion_channel->fd);
647 
648  return (0);
649 }
650 
651 static int recv_token_accept_setup (struct totemiba_instance *instance)
652 {
653  struct ibv_qp_init_attr init_qp_attr;
654  int res = 0;
655 
656  /*
657  * Allocate the protection domain
658  */
659  instance->recv_token_pd = ibv_alloc_pd (instance->recv_token_cma_id->verbs);
660 
661  /*
662  * Create a completion channel
663  */
664  instance->recv_token_recv_completion_channel = ibv_create_comp_channel (instance->recv_token_cma_id->verbs);
665  if (instance->recv_token_recv_completion_channel == NULL) {
666  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion channel");
667  return (-1);
668  }
669 
670  /*
671  * Create the completion queue
672  */
673  instance->recv_token_recv_cq = ibv_create_cq (instance->recv_token_cma_id->verbs,
674  COMPLETION_QUEUE_ENTRIES, instance,
676  if (instance->recv_token_recv_cq == NULL) {
677  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion queue");
678  return (-1);
679  }
680  res = ibv_req_notify_cq (instance->recv_token_recv_cq, 0);
681  if (res != 0) {
682  log_printf (LOGSYS_LEVEL_ERROR, "couldn't request notifications of the completion queue");
683  return (-1);
684  }
685 
686  /*
687  * Create a completion channel
688  */
689  instance->recv_token_send_completion_channel = ibv_create_comp_channel (instance->recv_token_cma_id->verbs);
690  if (instance->recv_token_send_completion_channel == NULL) {
691  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion channel");
692  return (-1);
693  }
694 
695  /*
696  * Create the completion queue
697  */
698  instance->recv_token_send_cq = ibv_create_cq (instance->recv_token_cma_id->verbs,
699  COMPLETION_QUEUE_ENTRIES, instance,
701  if (instance->recv_token_send_cq == NULL) {
702  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion queue");
703  return (-1);
704  }
705  res = ibv_req_notify_cq (instance->recv_token_send_cq, 0);
706  if (res != 0) {
707  log_printf (LOGSYS_LEVEL_ERROR, "couldn't request notifications of the completion queue");
708  return (-1);
709  }
710  memset (&init_qp_attr, 0, sizeof (struct ibv_qp_init_attr));
711  init_qp_attr.cap.max_send_wr = 50;
712  init_qp_attr.cap.max_recv_wr = TOTAL_READ_POSTS;
713  init_qp_attr.cap.max_send_sge = 1;
714  init_qp_attr.cap.max_recv_sge = 1;
715  init_qp_attr.qp_context = instance;
716  init_qp_attr.sq_sig_all = 0;
717  init_qp_attr.qp_type = IBV_QPT_UD;
718  init_qp_attr.send_cq = instance->recv_token_send_cq;
719  init_qp_attr.recv_cq = instance->recv_token_recv_cq;
720  res = rdma_create_qp (instance->recv_token_cma_id, instance->recv_token_pd,
721  &init_qp_attr);
722  if (res != 0) {
723  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create queue pair");
724  return (-1);
725  }
726 
727  recv_token_recv_buf_post_initial (instance);
728 
729  qb_loop_poll_add (
730  instance->totemiba_poll_handle,
731  QB_LOOP_MED,
733  POLLIN, instance, recv_token_cq_recv_event_fn);
734 
735  qb_loop_poll_add (
736  instance->totemiba_poll_handle,
737  QB_LOOP_MED,
739  POLLIN, instance, recv_token_cq_send_event_fn);
740 
741  instance->recv_token_accepted = 1;
742 
743  return (res);
744 };
745 
746 static int recv_token_rdma_event_fn (int events, int suck, void *context)
747 {
748  struct totemiba_instance *instance = (struct totemiba_instance *)context;
749  struct rdma_cm_event *event;
750  struct rdma_conn_param conn_param;
751 
752  int res;
753 
754  res = rdma_get_cm_event (instance->listen_recv_token_channel, &event);
755  if (res != 0) {
756  return (0);
757  }
758 
759  switch (event->event) {
760  case RDMA_CM_EVENT_CONNECT_REQUEST:
761  recv_token_accept_destroy (instance);
762 
763  instance->recv_token_cma_id = event->id;
764  recv_token_accept_setup (instance);
765  memset (&conn_param, 0, sizeof (struct rdma_conn_param));
766  conn_param.qp_num = instance->recv_token_cma_id->qp->qp_num;
767  res = rdma_accept (instance->recv_token_cma_id, &conn_param);
768  break;
769  default:
770  log_printf (LOGSYS_LEVEL_ERROR, "default %d", event->event);
771  break;
772  }
773 
774  res = rdma_ack_cm_event (event);
775  return (0);
776 }
777 
778 static int send_token_cq_send_event_fn (int events, int suck, void *context)
779 {
780  struct totemiba_instance *instance = (struct totemiba_instance *)context;
781  struct ibv_wc wc[32];
782  struct ibv_cq *ev_cq;
783  void *ev_ctx;
784  int res;
785  int i;
786 
787  ibv_get_cq_event (instance->send_token_send_completion_channel, &ev_cq, &ev_ctx);
788  ibv_ack_cq_events (ev_cq, 1);
789  res = ibv_req_notify_cq (ev_cq, 0);
790 
791  res = ibv_poll_cq (instance->send_token_send_cq, 32, wc);
792  if (res > 0) {
793  for (i = 0; i < res; i++) {
794  token_send_buf_put (instance, wrid2void(wc[i].wr_id));
795  }
796  }
797 
798  return (0);
799 }
800 
801 static int send_token_cq_recv_event_fn (int events, int suck, void *context)
802 {
803  struct totemiba_instance *instance = (struct totemiba_instance *)context;
804  struct ibv_wc wc[32];
805  struct ibv_cq *ev_cq;
806  void *ev_ctx;
807  int res;
808  int i;
809 
810  ibv_get_cq_event (instance->send_token_recv_completion_channel, &ev_cq, &ev_ctx);
811  ibv_ack_cq_events (ev_cq, 1);
812  res = ibv_req_notify_cq (ev_cq, 0);
813 
814  res = ibv_poll_cq (instance->send_token_recv_cq, 32, wc);
815  if (res > 0) {
816  for (i = 0; i < res; i++) {
817  iba_deliver_fn (instance, wc[i].wr_id, wc[i].byte_len);
818  }
819  }
820 
821  return (0);
822 }
823 
824 static int send_token_rdma_event_fn (int events, int suck, void *context)
825 {
826  struct totemiba_instance *instance = (struct totemiba_instance *)context;
827  struct rdma_cm_event *event;
828  struct rdma_conn_param conn_param;
829 
830  int res;
831 
832  res = rdma_get_cm_event (instance->send_token_channel, &event);
833  if (res != 0) {
834  return (0);
835  }
836 
837  switch (event->event) {
838  /*
839  * occurs when we resolve the multicast address
840  */
841  case RDMA_CM_EVENT_ADDR_RESOLVED:
842  res = rdma_resolve_route (instance->send_token_cma_id, 2000);
843  break;
844  /*
845  * occurs when the CM joins the multicast group
846  */
847  case RDMA_CM_EVENT_ROUTE_RESOLVED:
848  memset (&conn_param, 0, sizeof (struct rdma_conn_param));
849  conn_param.private_data = NULL;
850  conn_param.private_data_len = 0;
851  res = rdma_connect (instance->send_token_cma_id, &conn_param);
852  break;
853  case RDMA_CM_EVENT_ESTABLISHED:
854  instance->send_token_qpn = event->param.ud.qp_num;
855  instance->send_token_qkey = event->param.ud.qkey;
856  instance->send_token_ah = ibv_create_ah (instance->send_token_pd, &event->param.ud.ah_attr);
857  instance->totemiba_target_set_completed (instance->rrp_context);
858  break;
859 
860  case RDMA_CM_EVENT_ADDR_ERROR:
861  case RDMA_CM_EVENT_ROUTE_ERROR:
862  case RDMA_CM_EVENT_MULTICAST_ERROR:
864  "send_token_rdma_event_fn multicast error");
865  break;
866  case RDMA_CM_EVENT_DEVICE_REMOVAL:
867  break;
868  case RDMA_CM_EVENT_UNREACHABLE:
870  "send_token_rdma_event_fn unreachable");
871  break;
872  default:
874  "send_token_rdma_event_fn unknown event %d",
875  event->event);
876  break;
877  }
878 
879  rdma_ack_cm_event (event);
880  return (0);
881 }
882 
883 static int send_token_bind (struct totemiba_instance *instance)
884 {
885  int res;
886  struct ibv_qp_init_attr init_qp_attr;
887 
888  instance->send_token_channel = rdma_create_event_channel();
889  if (instance->send_token_channel == NULL) {
890  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create rdma channel");
891  return (-1);
892  }
893 
894  res = rdma_create_id (instance->send_token_channel,
895  &instance->send_token_cma_id, NULL, RDMA_PS_UDP);
896  if (res) {
897  log_printf (LOGSYS_LEVEL_ERROR, "error creating send_token_cma_id");
898  return (-1);
899  }
900 
901  res = rdma_bind_addr (instance->send_token_cma_id,
902  &instance->send_token_bind_addr);
903  if (res) {
904  log_printf (LOGSYS_LEVEL_ERROR, "error doing rdma_bind_addr for send token");
905  return (-1);
906  }
907 
908  /*
909  * Resolve the send_token address into a GUID
910  */
911  res = rdma_resolve_addr (instance->send_token_cma_id,
912  &instance->bind_addr, &instance->token_addr, 2000);
913  if (res) {
914  log_printf (LOGSYS_LEVEL_ERROR, "error resolving send token address %d %d", res, errno);
915  return (-1);
916  }
917 
918  /*
919  * Allocate the protection domain
920  */
921  instance->send_token_pd = ibv_alloc_pd (instance->send_token_cma_id->verbs);
922 
923  /*
924  * Create a completion channel
925  */
926  instance->send_token_recv_completion_channel = ibv_create_comp_channel (instance->send_token_cma_id->verbs);
927  if (instance->send_token_recv_completion_channel == NULL) {
928  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion channel");
929  return (-1);
930  }
931 
932  /*
933  * Create the completion queue
934  */
935  instance->send_token_recv_cq = ibv_create_cq (instance->send_token_cma_id->verbs,
936  COMPLETION_QUEUE_ENTRIES, instance,
938  if (instance->send_token_recv_cq == NULL) {
939  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion queue");
940  return (-1);
941  }
942  res = ibv_req_notify_cq (instance->send_token_recv_cq, 0);
943  if (res != 0) {
945  "couldn't request notifications of the completion queue");
946  return (-1);
947  }
948 
949  /*
950  * Create a completion channel
951  */
953  ibv_create_comp_channel (instance->send_token_cma_id->verbs);
954 
955  if (instance->send_token_send_completion_channel == NULL) {
956  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion channel");
957  return (-1);
958  }
959 
960  /*
961  * Create the completion queue
962  */
963  instance->send_token_send_cq = ibv_create_cq (
964  instance->send_token_cma_id->verbs,
965  COMPLETION_QUEUE_ENTRIES, instance,
967  if (instance->send_token_send_cq == NULL) {
968  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion queue");
969  return (-1);
970  }
971 
972  res = ibv_req_notify_cq (instance->send_token_send_cq, 0);
973  if (res != 0) {
975  "couldn't request notifications of the completion queue");
976  return (-1);
977  }
978  memset (&init_qp_attr, 0, sizeof (struct ibv_qp_init_attr));
979  init_qp_attr.cap.max_send_wr = 50;
980  init_qp_attr.cap.max_recv_wr = TOTAL_READ_POSTS;
981  init_qp_attr.cap.max_send_sge = 1;
982  init_qp_attr.cap.max_recv_sge = 1;
983  init_qp_attr.qp_context = instance;
984  init_qp_attr.sq_sig_all = 0;
985  init_qp_attr.qp_type = IBV_QPT_UD;
986  init_qp_attr.send_cq = instance->send_token_send_cq;
987  init_qp_attr.recv_cq = instance->send_token_recv_cq;
988  res = rdma_create_qp (instance->send_token_cma_id,
989  instance->send_token_pd, &init_qp_attr);
990  if (res != 0) {
991  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create queue pair");
992  return (-1);
993  }
994 
995  qb_loop_poll_add (
996  instance->totemiba_poll_handle,
997  QB_LOOP_MED,
999  POLLIN, instance, send_token_cq_recv_event_fn);
1000 
1001  qb_loop_poll_add (
1002  instance->totemiba_poll_handle,
1003  QB_LOOP_MED,
1004  instance->send_token_send_completion_channel->fd,
1005  POLLIN, instance, send_token_cq_send_event_fn);
1006 
1007  qb_loop_poll_add (
1008  instance->totemiba_poll_handle,
1009  QB_LOOP_MED,
1010  instance->send_token_channel->fd,
1011  POLLIN, instance, send_token_rdma_event_fn);
1012 
1013  instance->send_token_bound = 1;
1014  return (0);
1015 }
1016 
1017 static int send_token_unbind (struct totemiba_instance *instance)
1018 {
1019  if (instance->send_token_bound == 0) {
1020  return (0);
1021  }
1022 
1023  qb_loop_poll_del (
1024  instance->totemiba_poll_handle,
1025  instance->send_token_recv_completion_channel->fd);
1026  qb_loop_poll_del (
1027  instance->totemiba_poll_handle,
1028  instance->send_token_send_completion_channel->fd);
1029  qb_loop_poll_del (
1030  instance->totemiba_poll_handle,
1031  instance->send_token_channel->fd);
1032 
1033  if(instance->send_token_ah)
1034  {
1035  ibv_destroy_ah(instance->send_token_ah);
1036  instance->send_token_ah = 0;
1037  }
1038 
1039  rdma_destroy_qp (instance->send_token_cma_id);
1040  ibv_destroy_cq (instance->send_token_send_cq);
1041  ibv_destroy_cq (instance->send_token_recv_cq);
1042  ibv_destroy_comp_channel (instance->send_token_send_completion_channel);
1043  ibv_destroy_comp_channel (instance->send_token_recv_completion_channel);
1044  token_send_buf_destroy (instance);
1045  ibv_dealloc_pd (instance->send_token_pd);
1046  rdma_destroy_id (instance->send_token_cma_id);
1047  rdma_destroy_event_channel (instance->send_token_channel);
1048  return (0);
1049 }
1050 
1051 static int recv_token_bind (struct totemiba_instance *instance)
1052 {
1053  int res;
1054 
1055  instance->listen_recv_token_channel = rdma_create_event_channel();
1056  if (instance->listen_recv_token_channel == NULL) {
1057  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create rdma channel");
1058  return (-1);
1059  }
1060 
1061  res = rdma_create_id (instance->listen_recv_token_channel,
1062  &instance->listen_recv_token_cma_id, NULL, RDMA_PS_UDP);
1063  if (res) {
1064  log_printf (LOGSYS_LEVEL_ERROR, "error creating recv_token_cma_id");
1065  return (-1);
1066  }
1067 
1068  res = rdma_bind_addr (instance->listen_recv_token_cma_id,
1069  &instance->bind_addr);
1070  if (res) {
1071  log_printf (LOGSYS_LEVEL_ERROR, "error doing rdma_bind_addr for recv token");
1072  return (-1);
1073  }
1074 
1075  /*
1076  * Resolve the recv_token address into a GUID
1077  */
1078  res = rdma_listen (instance->listen_recv_token_cma_id, 10);
1079  if (res) {
1080  log_printf (LOGSYS_LEVEL_ERROR, "error listening %d %d", res, errno);
1081  return (-1);
1082  }
1083 
1084  qb_loop_poll_add (
1085  instance->totemiba_poll_handle,
1086  QB_LOOP_MED,
1087  instance->listen_recv_token_channel->fd,
1088  POLLIN, instance, recv_token_rdma_event_fn);
1089 
1090  return (0);
1091 }
1092 
1093 static int mcast_bind (struct totemiba_instance *instance)
1094 {
1095  int res;
1096  struct ibv_qp_init_attr init_qp_attr;
1097 
1098  instance->mcast_channel = rdma_create_event_channel();
1099  if (instance->mcast_channel == NULL) {
1100  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create rdma channel");
1101  return (-1);
1102  }
1103 
1104  res = rdma_create_id (instance->mcast_channel, &instance->mcast_cma_id, NULL, RDMA_PS_UDP);
1105  if (res) {
1106  log_printf (LOGSYS_LEVEL_ERROR, "error creating mcast_cma_id");
1107  return (-1);
1108  }
1109 
1110  res = rdma_bind_addr (instance->mcast_cma_id, &instance->local_mcast_bind_addr);
1111  if (res) {
1112  log_printf (LOGSYS_LEVEL_ERROR, "error doing rdma_bind_addr for mcast");
1113  return (-1);
1114  }
1115 
1116  /*
1117  * Resolve the multicast address into a GUID
1118  */
1119  res = rdma_resolve_addr (instance->mcast_cma_id, &instance->local_mcast_bind_addr,
1120  &instance->mcast_addr, 5000);
1121  if (res) {
1122  log_printf (LOGSYS_LEVEL_ERROR, "error resolving multicast address %d %d", res, errno);
1123  return (-1);
1124  }
1125 
1126  /*
1127  * Allocate the protection domain
1128  */
1129  instance->mcast_pd = ibv_alloc_pd (instance->mcast_cma_id->verbs);
1130 
1131  /*
1132  * Create a completion channel
1133  */
1134  instance->mcast_recv_completion_channel = ibv_create_comp_channel (instance->mcast_cma_id->verbs);
1135  if (instance->mcast_recv_completion_channel == NULL) {
1136  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion channel");
1137  return (-1);
1138  }
1139 
1140  /*
1141  * Create the completion queue
1142  */
1143  instance->mcast_recv_cq = ibv_create_cq (instance->mcast_cma_id->verbs,
1144  COMPLETION_QUEUE_ENTRIES, instance,
1145  instance->mcast_recv_completion_channel, 0);
1146  if (instance->mcast_recv_cq == NULL) {
1147  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion queue");
1148  return (-1);
1149  }
1150  res = ibv_req_notify_cq (instance->mcast_recv_cq, 0);
1151  if (res != 0) {
1152  log_printf (LOGSYS_LEVEL_ERROR, "couldn't request notifications of the completion queue");
1153  return (-1);
1154  }
1155 
1156  /*
1157  * Create a completion channel
1158  */
1159  instance->mcast_send_completion_channel = ibv_create_comp_channel (instance->mcast_cma_id->verbs);
1160  if (instance->mcast_send_completion_channel == NULL) {
1161  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion channel");
1162  return (-1);
1163  }
1164 
1165  /*
1166  * Create the completion queue
1167  */
1168  instance->mcast_send_cq = ibv_create_cq (instance->mcast_cma_id->verbs,
1169  COMPLETION_QUEUE_ENTRIES, instance,
1170  instance->mcast_send_completion_channel, 0);
1171  if (instance->mcast_send_cq == NULL) {
1172  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create completion queue");
1173  return (-1);
1174  }
1175  res = ibv_req_notify_cq (instance->mcast_send_cq, 0);
1176  if (res != 0) {
1177  log_printf (LOGSYS_LEVEL_ERROR, "couldn't request notifications of the completion queue");
1178  return (-1);
1179  }
1180  memset (&init_qp_attr, 0, sizeof (struct ibv_qp_init_attr));
1181  init_qp_attr.cap.max_send_wr = 50;
1182  init_qp_attr.cap.max_recv_wr = TOTAL_READ_POSTS;
1183  init_qp_attr.cap.max_send_sge = 1;
1184  init_qp_attr.cap.max_recv_sge = 1;
1185  init_qp_attr.qp_context = instance;
1186  init_qp_attr.sq_sig_all = 0;
1187  init_qp_attr.qp_type = IBV_QPT_UD;
1188  init_qp_attr.send_cq = instance->mcast_send_cq;
1189  init_qp_attr.recv_cq = instance->mcast_recv_cq;
1190  res = rdma_create_qp (instance->mcast_cma_id, instance->mcast_pd,
1191  &init_qp_attr);
1192  if (res != 0) {
1193  log_printf (LOGSYS_LEVEL_ERROR, "couldn't create queue pair");
1194  return (-1);
1195  }
1196 
1197  mcast_recv_buf_post_initial (instance);
1198 
1199  qb_loop_poll_add (
1200  instance->totemiba_poll_handle,
1201  QB_LOOP_MED,
1202  instance->mcast_recv_completion_channel->fd,
1203  POLLIN, instance, mcast_cq_recv_event_fn);
1204 
1205  qb_loop_poll_add (
1206  instance->totemiba_poll_handle,
1207  QB_LOOP_MED,
1208  instance->mcast_send_completion_channel->fd,
1209  POLLIN, instance, mcast_cq_send_event_fn);
1210 
1211  qb_loop_poll_add (
1212  instance->totemiba_poll_handle,
1213  QB_LOOP_MED,
1214  instance->mcast_channel->fd,
1215  POLLIN, instance, mcast_rdma_event_fn);
1216 
1217  return (0);
1218 }
1219 static void timer_function_netif_check_timeout (
1220  void *data)
1221 {
1222  struct totemiba_instance *instance = (struct totemiba_instance *)data;
1223  int res;
1224  int interface_up;
1225  int interface_num;
1226  int addr_len;
1227 
1229  &instance->totem_interface->boundto, &interface_up, &interface_num, instance->totem_config->clear_node_high_bit);
1230 
1232  instance->totem_interface->ip_port, (struct sockaddr_storage *)&instance->bind_addr,
1233  &addr_len);
1234 
1236  0, (struct sockaddr_storage *)&instance->send_token_bind_addr,
1237  &addr_len);
1238 
1240  0, (struct sockaddr_storage *)&instance->local_mcast_bind_addr,
1241  &addr_len);
1242 
1244  instance->totem_interface->ip_port, (struct sockaddr_storage *)&instance->my_id,
1245  &addr_len);
1246 
1248  (const struct sockaddr_storage *)&instance->bind_addr,
1249  &instance->my_id);
1250 
1251  memcpy (&instance->my_id, &instance->totem_interface->boundto,
1252  sizeof (struct totem_ip_address));
1253 
1255  instance->totem_interface->ip_port,
1256  (struct sockaddr_storage *)&instance->mcast_addr, &addr_len);
1257 
1258  res = recv_token_bind (instance);
1259 
1260  res = mcast_bind (instance);
1261 }
1262 
1264  void *iba_context,
1265  const char *cipher_type,
1266  const char *hash_type)
1267 {
1268  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1269  int res = 0;
1270 
1271  instance = NULL;
1272 
1273  return (res);
1274 }
1275 
1277  void *iba_context)
1278 {
1279  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1280  int res = 0;
1281 
1282  instance = NULL;
1283 
1284  return (res);
1285 }
1286 
1287 /*
1288  * Create an instance
1289  */
1291  qb_loop_t *qb_poll_handle,
1292  void **iba_context,
1293  struct totem_config *totem_config,
1295  int interface_no,
1296  void *context,
1297 
1298  void (*deliver_fn) (
1299  void *context,
1300  const void *msg,
1301  unsigned int msg_len),
1302 
1303  void (*iface_change_fn) (
1304  void *context,
1305  const struct totem_ip_address *iface_address),
1306 
1307  void (*target_set_completed) (
1308  void *context))
1309 {
1310  struct totemiba_instance *instance;
1311  int res = 0;
1312 
1313  instance = malloc (sizeof (struct totemiba_instance));
1314  if (instance == NULL) {
1315  return (-1);
1316  }
1317 
1318  totemiba_instance_initialize (instance);
1319 
1320  instance->totem_interface = &totem_config->interfaces[interface_no];
1321 
1322  instance->totemiba_poll_handle = qb_poll_handle;
1323 
1324  instance->totem_interface->bindnet.nodeid = totem_config->node_id;
1325 
1326  instance->totemiba_deliver_fn = deliver_fn;
1327 
1328  instance->totemiba_target_set_completed = target_set_completed;
1329 
1330  instance->totemiba_iface_change_fn = iface_change_fn;
1331 
1332  instance->totem_config = totem_config;
1333  instance->stats = stats;
1334 
1335  instance->rrp_context = context;
1336 
1337  qb_loop_timer_add (instance->totemiba_poll_handle,
1338  QB_LOOP_MED,
1339  100*QB_TIME_NS_IN_MSEC,
1340  (void *)instance,
1341  timer_function_netif_check_timeout,
1342  &instance->timer_netif_check_timeout);
1343 
1346 
1347  *iba_context = instance;
1348  return (res);
1349 }
1350 
1352 {
1353  return malloc (MAX_MTU_SIZE);
1354 }
1355 
1356 void totemiba_buffer_release (void *ptr)
1357 {
1358  return free (ptr);
1359 }
1360 
1362  void *iba_context,
1363  int processor_count)
1364 {
1365  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1366  int res = 0;
1367 
1368  instance = NULL;
1369 
1370  return (res);
1371 }
1372 
1373 int totemiba_recv_flush (void *iba_context)
1374 {
1375  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1376  int res = 0;
1377 
1378  instance = NULL;
1379 
1380  return (res);
1381 }
1382 
1383 int totemiba_send_flush (void *iba_context)
1384 {
1385  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1386  int res = 0;
1387 
1388  instance = NULL;
1389 
1390  return (res);
1391 }
1392 
1394  void *iba_context,
1395  const void *ms,
1396  unsigned int msg_len)
1397 {
1398  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1399  int res = 0;
1400  struct ibv_send_wr send_wr, *failed_send_wr;
1401  struct ibv_sge sge;
1402  void *msg;
1403  struct send_buf *send_buf;
1404 
1405  send_buf = token_send_buf_get (instance);
1406  if (send_buf == NULL) {
1407  return (-1);
1408  }
1409  msg = send_buf->buffer;
1410  memcpy (msg, ms, msg_len);
1411 
1412  send_wr.next = NULL;
1413  send_wr.sg_list = &sge;
1414  send_wr.num_sge = 1;
1415  send_wr.opcode = IBV_WR_SEND;
1416  send_wr.send_flags = IBV_SEND_SIGNALED;
1417  send_wr.wr_id = void2wrid(send_buf);
1418  send_wr.imm_data = 0;
1419  send_wr.wr.ud.ah = instance->send_token_ah;
1420  send_wr.wr.ud.remote_qpn = instance->send_token_qpn;
1421  send_wr.wr.ud.remote_qkey = instance->send_token_qkey;
1422 
1423  sge.length = msg_len;
1424  sge.lkey = send_buf->mr->lkey;
1425  sge.addr = (uintptr_t)msg;
1426 
1427  if(instance->send_token_ah != 0 && instance->send_token_bound)
1428  res = ibv_post_send (instance->send_token_cma_id->qp, &send_wr, &failed_send_wr);
1429 
1430  return (res);
1431 }
1432 
1434  void *iba_context,
1435  const void *ms,
1436  unsigned int msg_len)
1437 {
1438  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1439  int res = 0;
1440  struct ibv_send_wr send_wr, *failed_send_wr;
1441  struct ibv_sge sge;
1442  void *msg;
1443  struct send_buf *send_buf;
1444 
1445  send_buf = mcast_send_buf_get (instance);
1446  if (send_buf == NULL) {
1447  return (-1);
1448  }
1449 
1450  msg = send_buf->buffer;
1451  memcpy (msg, ms, msg_len);
1452  send_wr.next = NULL;
1453  send_wr.sg_list = &sge;
1454  send_wr.num_sge = 1;
1455  send_wr.opcode = IBV_WR_SEND;
1456  send_wr.send_flags = IBV_SEND_SIGNALED;
1457  send_wr.wr_id = void2wrid(send_buf);
1458  send_wr.imm_data = 0;
1459  send_wr.wr.ud.ah = instance->mcast_ah;
1460  send_wr.wr.ud.remote_qpn = instance->mcast_qpn;
1461  send_wr.wr.ud.remote_qkey = instance->mcast_qkey;
1462 
1463  sge.length = msg_len;
1464  sge.lkey = send_buf->mr->lkey;
1465  sge.addr = (uintptr_t)msg;
1466 
1467  res = ibv_post_send (instance->mcast_cma_id->qp, &send_wr, &failed_send_wr);
1468  return (res);
1469 }
1470 
1472  void *iba_context,
1473  const void *ms,
1474  unsigned int msg_len)
1475 {
1476  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1477  int res = 0;
1478  struct ibv_send_wr send_wr, *failed_send_wr;
1479  struct ibv_sge sge;
1480  void *msg;
1481  struct send_buf *send_buf;
1482 
1483  send_buf = mcast_send_buf_get (instance);
1484  if (send_buf == NULL) {
1485  return (-1);
1486  }
1487 
1488  msg = send_buf->buffer;
1489  memcpy (msg, ms, msg_len);
1490  send_wr.next = NULL;
1491  send_wr.sg_list = &sge;
1492  send_wr.num_sge = 1;
1493  send_wr.opcode = IBV_WR_SEND;
1494  send_wr.send_flags = IBV_SEND_SIGNALED;
1495  send_wr.wr_id = void2wrid(send_buf);
1496  send_wr.imm_data = 0;
1497  send_wr.wr.ud.ah = instance->mcast_ah;
1498  send_wr.wr.ud.remote_qpn = instance->mcast_qpn;
1499  send_wr.wr.ud.remote_qkey = instance->mcast_qkey;
1500 
1501  sge.length = msg_len;
1502  sge.lkey = send_buf->mr->lkey;
1503  sge.addr = (uintptr_t)msg;
1504 
1505  res = ibv_post_send (instance->mcast_cma_id->qp, &send_wr, &failed_send_wr);
1506  return (res);
1507 }
1508 
1509 extern int totemiba_iface_check (void *iba_context)
1510 {
1511  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1512  int res = 0;
1513 
1514  instance = NULL;
1515 
1516  return (res);
1517 }
1518 
1519 extern void totemiba_net_mtu_adjust (void *iba_context, struct totem_config *totem_config)
1520 {
1521  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1522  instance = NULL;
1523 }
1524 
1525 const char *totemiba_iface_print (void *iba_context) {
1526  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1527 
1528  const char *ret_char;
1529 
1530  ret_char = totemip_print (&instance->my_id);
1531 
1532  return (ret_char);
1533 }
1534 
1536  void *iba_context,
1537  struct totem_ip_address *addr)
1538 {
1539  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1540  int res = 0;
1541 
1542  memcpy (addr, &instance->my_id, sizeof (struct totem_ip_address));
1543 
1544  return (res);
1545 }
1546 
1548  void *iba_context,
1549  const struct totem_ip_address *token_target)
1550 {
1551  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1552  int res = 0;
1553  int addr_len = 16;
1554 
1556  instance->totem_interface->ip_port, (struct sockaddr_storage *)&instance->token_addr,
1557  &addr_len);
1558 
1559  res = send_token_unbind (instance);
1560 
1561  res = send_token_bind (instance);
1562 
1563  return (res);
1564 }
1565 
1567  void *iba_context)
1568 {
1569  struct totemiba_instance *instance = (struct totemiba_instance *)iba_context;
1570  int res = 0;
1571 
1572  instance = NULL;
1573 
1574  return (res);
1575 }
1576 
unsigned int clear_node_high_bit
Definition: totem.h:111
struct ibv_cq * mcast_recv_cq
Definition: totemiba.c:143
struct list_head mcast_send_buf_head
Definition: totemiba.c:207
struct sockaddr mcast_addr
Definition: totemiba.c:91
Definition: exec/cpg.c:1724
struct ibv_comp_channel * send_token_recv_completion_channel
Definition: totemiba.c:185
struct ibv_cq * recv_token_send_cq
Definition: totemiba.c:163
int recv_token_accepted
Definition: totemiba.c:145
int totemiba_recv_mcast_empty(void *iba_context)
Definition: totemiba.c:1566
struct totem_interface * interfaces
Definition: totem.h:108
struct ibv_comp_channel * send_token_send_completion_channel
Definition: totemiba.c:183
struct ibv_cq * send_token_recv_cq
Definition: totemiba.c:189
struct list_head * next
Definition: list.h:47
const char * totemip_print(const struct totem_ip_address *addr)
Definition: totemip.c:214
struct sockaddr send_token_bind_addr
Definition: totemiba.c:89
struct sockaddr local_mcast_bind_addr
Definition: totemiba.c:95
int totemiba_send_flush(void *iba_context)
Definition: totemiba.c:1383
struct ibv_mr * mr
Definition: totemiba.c:238
int totemiba_token_target_set(void *iba_context, const struct totem_ip_address *token_target)
Definition: totemiba.c:1547
char buffer[MAX_MTU_SIZE]
Definition: totemiba.c:239
struct sockaddr token_addr
Definition: totemiba.c:93
struct rdma_event_channel * send_token_channel
Definition: totemiba.c:169
uint32_t send_token_qpn
Definition: totemiba.c:177
struct rdma_event_channel * recv_token_channel
Definition: totemiba.c:147
void(* totemiba_iface_change_fn)(void *context, const struct totem_ip_address *iface_address)
Definition: totemiba.c:103
struct ibv_comp_channel * mcast_recv_completion_channel
Definition: totemiba.c:139
int totemiba_initialize(qb_loop_t *qb_poll_handle, void **iba_context, struct totem_config *totem_config, totemsrp_stats_t *stats, int interface_no, void *context, void(*deliver_fn)(void *context, const void *msg, unsigned int msg_len), void(*iface_change_fn)(void *context, const struct totem_ip_address *iface_address), void(*target_set_completed)(void *context))
Create an instance.
Definition: totemiba.c:1290
int totemiba_mcast_flush_send(void *iba_context, const void *ms, unsigned int msg_len)
Definition: totemiba.c:1433
unsigned char addr[TOTEMIP_ADDRLEN]
Definition: coroapi.h:67
void * totemiba_buffer_alloc(void)
Definition: totemiba.c:1351
void(* totemiba_deliver_fn)(void *context, const void *msg, unsigned int msg_len)
Definition: totemiba.c:107
struct list_head list_all
Definition: totemiba.c:228
uint32_t mcast_qkey
Definition: totemiba.c:133
Definition: list.h:46
int totemiba_iface_check(void *iba_context)
Definition: totemiba.c:1509
void * rrp_context
Definition: totemiba.c:115
struct list_head token_send_buf_free
Definition: totemiba.c:205
struct list_head recv_token_recv_buf_head
Definition: totemiba.c:211
char buffer[MAX_MTU_SIZE]
Definition: totemiba.c:232
void(*) in totemiba_subsys_id)
Definition: totemiba.c:198
void(* totemiba_log_printf)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf
Definition: totemiba.c:191
qb_loop_timer_handle timer_netif_check_timeout
Definition: totemiba.c:117
#define TOTAL_READ_POSTS
Definition: totemiba.c:82
struct totem_interface * totem_interface
Definition: totemiba.c:97
unsigned int node_id
Definition: totem.h:110
int totemiba_crypto_set(void *iba_context, const char *cipher_type, const char *hash_type)
Definition: totemiba.c:1263
int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num, int mask_high_bit)
Definition: totemip.c:405
struct list_head mcast_send_buf_free
Definition: totemiba.c:203
struct ibv_pd * mcast_pd
Definition: totemiba.c:127
int totemiba_token_send(void *iba_context, const void *ms, unsigned int msg_len)
Definition: totemiba.c:1393
unsigned int nodeid
Definition: coroapi.h:96
void(* totemiba_target_set_completed)(void *context)
Definition: totemiba.c:112
#define MAX_MTU_SIZE
Definition: totemiba.c:84
struct ibv_comp_channel * recv_token_recv_completion_channel
Definition: totemiba.c:161
struct sockaddr bind_addr
Definition: totemiba.c:87
int totemiba_iface_get(void *iba_context, struct totem_ip_address *addr)
Definition: totemiba.c:1535
struct totem_ip_address mcast_addr
Definition: totem.h:67
struct sockaddr recv_token_dest_addr
Definition: totemiba.c:157
struct ibv_cq * recv_token_recv_cq
Definition: totemiba.c:165
#define LOGSYS_LEVEL_ERROR
Definition: logsys.h:70
Linked list API.
struct ibv_cq * mcast_send_cq
Definition: totemiba.c:141
struct list_head list_all
Definition: totemiba.c:237
struct list_head token_send_buf_head
Definition: totemiba.c:209
void(* log_printf)(int level, int subsys, const char *function_name, const char *file_name, int file_line, const char *format,...) __attribute__((format(printf
Definition: totem.h:75
void totemiba_net_mtu_adjust(void *iba_context, struct totem_config *totem_config)
Definition: totemiba.c:1519
struct ibv_comp_channel * mcast_send_completion_channel
Definition: totemiba.c:137
struct totem_ip_address boundto
Definition: totem.h:66
struct ibv_mr * mr
Definition: totemiba.c:231
struct ibv_pd * send_token_pd
Definition: totemiba.c:173
const char * totemiba_iface_print(void *iba_context)
Definition: totemiba.c:1525
uint16_t ip_port
Definition: totem.h:68
const void * v
Definition: schedwrk.c:54
struct ibv_cq * send_token_send_cq
Definition: totemiba.c:187
struct rdma_event_channel * mcast_channel
Definition: totemiba.c:123
struct rdma_cm_id * listen_recv_token_cma_id
Definition: totemiba.c:151
struct rdma_event_channel * listen_recv_token_channel
Definition: totemiba.c:149
struct ibv_ah * send_token_ah
Definition: totemiba.c:181
int totemiba_finalize(void *iba_context)
Definition: totemiba.c:1276
struct list_head list_free
Definition: totemiba.c:236
struct ibv_ah * mcast_ah
Definition: totemiba.c:135
qb_handle_t hdb_handle_t
Definition: hdb.h:52
qb_loop_t * totemiba_poll_handle
Definition: totemiba.c:119
#define COMPLETION_QUEUE_ENTRIES
Definition: totemiba.c:80
#define log_printf(level, format, args...)
Definition: totemiba.c:218
struct sockaddr mcast_dest_addr
Definition: totemiba.c:129
struct sockaddr send_token_dest_addr
Definition: totemiba.c:175
struct totem_ip_address my_id
Definition: totemiba.c:121
struct ibv_recv_wr recv_wr
Definition: totemiba.c:229
struct ibv_sge sge
Definition: totemiba.c:230
struct rdma_cm_id * mcast_cma_id
Definition: totemiba.c:125
int totemiba_mcast_noflush_send(void *iba_context, const void *ms, unsigned int msg_len)
Definition: totemiba.c:1471
totemsrp_stats_t * stats
Definition: totemiba.c:101
uint32_t mcast_qpn
Definition: totemiba.c:131
struct totem_config * totem_config
Definition: totemiba.c:99
struct ibv_pd * recv_token_pd
Definition: totemiba.c:155
uint32_t send_token_qkey
Definition: totemiba.c:179
uint64_t wr_id
Definition: totemiba.c:214
struct rdma_cm_id * recv_token_cma_id
Definition: totemiba.c:153
#define list_entry(ptr, type, member)
Definition: list.h:84
struct rdma_cm_id * send_token_cma_id
Definition: totemiba.c:171
int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
Definition: totemip.c:222
struct totem_logging_configuration totem_logging_configuration
Definition: totem.h:157
typedef __attribute__
struct ibv_comp_channel * recv_token_send_completion_channel
Definition: totemiba.c:159
int totemiba_processor_count_set(void *iba_context, int processor_count)
Definition: totemiba.c:1361
int totemiba_recv_flush(void *iba_context)
Definition: totemiba.c:1373
int totemip_sockaddr_to_totemip_convert(const struct sockaddr_storage *saddr, struct totem_ip_address *ip_addr)
Definition: totemip.c:295
struct totem_ip_address bindnet
Definition: totem.h:65
void * v
Definition: totemiba.c:215
void totemiba_buffer_release(void *ptr)
Definition: totemiba.c:1356