Esempio n. 1
0
int on_connection(struct rdma_cm_id *id)
{
  on_connect(id->context);
  send_mr(id->context);

  return 0;
}
Esempio n. 2
0
void on_completion(struct ibv_wc *wc)
{
  struct connection *conn = (struct connection *)(uintptr_t)wc->wr_id;

  if (wc->status != IBV_WC_SUCCESS)
    die("on_completion: status is not IBV_WC_SUCCESS.");

  if (wc->opcode & IBV_WC_RECV) {
    conn->recv_state++;
    printf("RECV: Recieved: TYPE=%d\n", conn->recv_msg->type);
    if (conn->recv_msg->type == MSG_MR) {
      memcpy(&conn->peer_mr, &conn->recv_msg->data.mr, sizeof(conn->peer_mr));
      post_receives(conn); /* only rearm for MSG_MR */
      if (conn->send_state == SS_INIT) /* received peer's MR before sending ours, so send ours back */
        send_mr(conn);
    }

  } else {
    conn->send_state++;
    printf("SEND: Sent out: TYPE=%d\n", conn->send_msg->type);
  }

  if (conn->send_state == SS_MR_SENT && conn->recv_state == RS_MR_RECV) {
    /*
    struct ibv_send_wr wr, *bad_wr = NULL;
    struct ibv_sge sge;

    if (s_mode == M_WRITE)
      printf(" -> received MSG_MR. writing message to remote memory...\n");
    else
      printf(" -> received MSG_MR. reading message from remote memory...\n");

    memset(&wr, 0, sizeof(wr));

    wr.wr_id = (uintptr_t)conn;
    wr.opcode = (s_mode == M_WRITE) ? IBV_WR_RDMA_WRITE : IBV_WR_RDMA_READ;
    wr.sg_list = &sge;
    wr.num_sge = 1;
    wr.send_flags = IBV_SEND_SIGNALED;
    wr.wr.rdma.remote_addr = (uintptr_t)conn->peer_mr.addr;
    wr.wr.rdma.rkey = conn->peer_mr.rkey;

    sge.addr = (uintptr_t)conn->rdma_local_region;
    sge.length = RDMA_BUFFER_SIZE;
    sge.lkey = conn->rdma_local_mr->lkey;

    TEST_NZ(ibv_post_send(conn->qp, &wr, &bad_wr));
    printf("PSEND: Posted send request: MSG=%s\n", conn->rdma_local_region);
    */

    conn->send_msg->type = MSG_DONE;
    send_message(conn);

  } else if (conn->send_state == SS_DONE_SENT && conn->recv_state == RS_DONE_RECV) {
    printf(" -> remote buffer: %s\n", get_peer_message_region(conn));
    rdma_disconnect(conn->id);
  }
  printf("== STATE: send=%d / recv=%d ==\n", conn->send_state, conn->recv_state);
}
Esempio n. 3
0
int client_on_connection(struct rdma_cm_id *id)
{
    on_connect(id->context);
    send_mr(id->context);

    /// if built connection, return 1, and break the while in wait_rdma_event()
    return 1;
}
Esempio n. 4
0
static void
on_completion(struct ibv_wc *wc, bool is_server)
{
    IbvConnection *conn = (IbvConnection *)(uintptr_t)wc->wr_id;

    check_msgsanity(wc);

    switch (wc->opcode) {
      case IBV_WC_RECV:
        switch (conn->recv_msg->type) {
          case MSG_MR:
            memcpy(&conn->peer_mr, &conn->recv_msg->data.mr, sizeof(conn->peer_mr));
            // server receives MR before sending ours, so send ours back.
            if (is_server) {
                send_mr(conn);
            }
            conn->rdma_state = STATE_READY;
            break;
          case MSG_DONE:
            break;
          default:
            fprintf(stderr, "received a message of unknown type.\n");
            exit(EXIT_FAILURE);
        }
        post_receives(conn); // rearm for next message.
        break;

      case IBV_WC_SEND:
        // nop.
        break;

      case IBV_WC_RDMA_WRITE:
        switch (conn->rdma_state) {
          case STATE_READY:
            break;
          case STATE_BUSY0:
            conn->rdma_state = STATE_BUSY1;
            break;
          case STATE_BUSY1:
            conn->rdma_state = STATE_READY;
            break;
          default:
            fprintf(stderr, "invalid conn->rdma_state:%d\n", conn->rdma_state);
            exit(1);
        }
        break;

      default:
        fprintf(stderr, "completion with unexpected opcode : 0x%x\n", wc->opcode);
        exit(1);
    }
}
Esempio n. 5
0
void on_completion(struct ibv_wc *wc)
{
  struct connection *conn = (struct connection *)(uintptr_t)wc->wr_id;

  if (wc->status != IBV_WC_SUCCESS)
    die("on_completion: status is not IBV_WC_SUCCESS.");

  if (wc->opcode & IBV_WC_RECV) {
    conn->recv_state++;

    if (conn->recv_msg->type == MSG_MR) {
      memcpy(&conn->peer_mr, &conn->recv_msg->data.mr, sizeof(conn->peer_mr));
      post_receives(conn); /* only rearm for MSG_MR */

      if (conn->send_state == SS_INIT) /* received peer's MR before sending ours, so send ours back */
        send_mr(conn);
    }

  } else {
    conn->send_state++;
    printf("send completed successfully.\n");
  }

  if (conn->send_state == SS_MR_SENT && conn->recv_state == RS_MR_RECV) {
    struct ibv_send_wr wr, *bad_wr = NULL;
    struct ibv_sge sge;

    if (s_mode == M_WRITE)
      printf("received MSG_MR. writing message to remote memory...\n");
    else
      printf("received MSG_MR. reading message from remote memory...\n");

    memset(&wr, 0, sizeof(wr));

    wr.wr_id = (uintptr_t)conn;
    wr.opcode = (s_mode == M_WRITE) ? IBV_WR_RDMA_WRITE : IBV_WR_RDMA_READ;
    wr.sg_list = &sge;
    wr.num_sge = 1;
    wr.send_flags = IBV_SEND_SIGNALED;
    wr.wr.rdma.remote_addr = (uintptr_t)conn->peer_mr.addr;
    wr.wr.rdma.rkey = conn->peer_mr.rkey;

    sge.addr = (uintptr_t)conn->rdma_local_region;
    sge.length = RDMA_BUFFER_SIZE;
    sge.lkey = conn->rdma_local_mr->lkey;

    /* CODE TO MESS UP PSN */
    srand48(getpid());
    struct ibv_qp_attr attr;
    attr.sq_psn = lrand48() & 0xffffff;
    attr.rq_psn = lrand48() & 0xffffff;
    if (ibv_modify_qp(conn->qp, &attr, IBV_QP_RQ_PSN | IBV_QP_SQ_PSN)) {
      fprintf(stderr, "Failed to set the PSN.");
      return;
    }
    /* END CODE TO MESS UP PSN */

    TEST_NZ(ibv_post_send(conn->qp, &wr, &bad_wr));

    conn->send_msg->type = MSG_DONE;
    send_message(conn);

  } else if (conn->send_state == SS_DONE_SENT && conn->recv_state == RS_DONE_RECV) {
    printf("remote buffer: %s\n", get_peer_message_region(conn));
    rdma_disconnect(conn->id);
  }
}
Esempio n. 6
0
void on_connection(struct rdma_cm_id *id)
{
    send_mr(id->context);
    return;//exit while loop
}
Esempio n. 7
0
static int run(int argc, char **argv)
{
  struct addrinfo *addr;
  //struct rdma_cm_event *event = NULL;
  struct rdma_cm_id *cmid= NULL;
  struct rdma_event_channel *ec = NULL;
  struct rdma_conn_param cm_params;

  if (argc != 4)
    usage(argv[0]);

  if (strcmp(argv[1], "write") == 0)
    set_mode(M_WRITE);
  else if (strcmp(argv[1], "read") == 0)
    set_mode(M_READ);
  else
    usage(argv[0]);

  TEST_NZ(getaddrinfo(argv[2], argv[3], NULL, &addr));

  TEST_Z(ec = rdma_create_event_channel());
  /*create rdma socket*/
  TEST_NZ(rdma_create_id(ec, &cmid, NULL, RDMA_PS_TCP));

  /* int rdma_resolve_addr (struct rdma_cm_id *id, struct sockaddr *src_addr, 
                            struct sockaddr dst_addr, int timeout_ms)
       id          RDMA identifier
       src_addr    Source address information. This parameter may be NULL.
       dst_addr    Destination address information
       timeout_ms  Time to wait for resolution to complete
     Description:
       Resolve destination and optional source addresses from IP addresses 
       to an RDMA address. If suc- cessful, 
       the specified rdma_cm_id will be bound to a local device.
  */
  TEST_NZ(rdma_resolve_addr(cmid, NULL, addr->ai_addr, TIMEOUT_IN_MS));
  TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ADDR_RESOLVED));
  freeaddrinfo(addr);
  build_connection(cmid);
  
  sprintf(get_local_message_region(cmid->context), "message from active/client side with pid %d", getpid());
  /*--------------------*/

  /* int rdma_resolve_route (struct rdma_cm_id *id, int timeout_ms); 
       id            RDMA identifier
       timeout_ms    Time to wait for resolution to complete
     Description:
       Resolves an RDMA route to the destination address in order 
       to establish a connection. The destination address must have 
       already been resolved by calling rdma_resolve_addr. 
   */
  TEST_NZ(rdma_resolve_route(cmid, TIMEOUT_IN_MS));
  TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ROUTE_RESOLVED));
  /* -------------------- */
  
  print_path_rec(cmid);

  /* int rdma_connect (struct rdma_cm_id *id, struct rdma_conn_param *conn_param); 
       id            RDMA identifier
       conn_param    connection parameters

       Description:
       For an rdma_cm_id of type RDMA_PS_TCP, this call initiates a connection 
       request to a remote destination. For an rdma_cm_id of type RDMA_PS_UDP, 
       it initiates a lookup of the remote QP providing the datagram service
  */
  build_params(&cm_params);
  printf("Connecting ...\n");
  TEST_NZ(rdma_connect(cmid, &cm_params));
  TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ESTABLISHED));
  printf("Connected !\n");
  /* --------------------- */
  
  /*TODO: do something */
  on_connect(cmid->context);
  send_mr(cmid->context);
  /*--------------------*/

  rdma_disconnect(cmid);
  rdma_destroy_id(cmid);
  rdma_destroy_event_channel(ec);

  return 0;
  /*=================*/
  /*=================*/

  /*
  while (rdma_get_cm_event(ec, &event) == 0) {


    memcpy(&event_copy, event, sizeof(*event));
    rdma_ack_cm_event(event);

    if (on_event(&event_copy))
      break;
  }
  */
}
Esempio n. 8
0
void on_completion(struct ibv_wc *wc)
{
  struct connection *conn = (struct connection *)(uintptr_t)wc->wr_id;

  if (wc->status != IBV_WC_SUCCESS)
    die("on_completion: status is not IBV_WC_SUCCESS.");

  if (wc->opcode == IBV_WC_RDMA_WRITE) {
    e[idx] = get_dtime();
    int *v = (int*)conn->rdma_local_region;
    printf("RDMA Write: %f (v=%d)\n", e[idx] - s[idx], v[0]);
    idx++;
    return;
  } else if (wc->opcode & IBV_WC_RDMA_READ) {
    //    printf("RDMA Read: %f\n", e - s);
    return;
  }

  if (wc->opcode & IBV_WC_RECV) {
    conn->recv_state++;

    if (conn->recv_msg->type == MSG_MR) {
      memcpy(&conn->peer_mr, &conn->recv_msg->data.mr, sizeof(conn->peer_mr));
      post_receives(conn); /* only rearm for MSG_MR */

      if (conn->send_state == SS_INIT) /* received peer's MR before sending ours, so send ours back */
        send_mr(conn);
    }

  } else {
    conn->send_state++;
    printf("send completed successfully.\n");
  }

  if (conn->send_state == SS_MR_SENT && conn->recv_state == RS_MR_RECV) {
    struct ibv_send_wr wr, *bad_wr = NULL;
    struct ibv_sge sge;

    if (s_mode == M_WRITE)
      printf("received MSG_MR. writing message to remote memory...\n");
    else
      printf("received MSG_MR. reading message from remote memory...\n");

    memset(&wr, 0, sizeof(wr));

    wr.wr_id = (uintptr_t)conn;
    wr.opcode = (s_mode == M_WRITE) ? IBV_WR_RDMA_WRITE : IBV_WR_RDMA_READ;
    wr.sg_list = &sge;
    wr.num_sge = 1;
    wr.send_flags = IBV_SEND_SIGNALED;
    wr.wr.rdma.remote_addr = (uintptr_t)conn->peer_mr.addr;
    wr.wr.rdma.rkey = conn->peer_mr.rkey;

    sge.addr = (uintptr_t)conn->rdma_local_region;
    sge.length = RDMA_BUFFER_SIZE;
    sge.lkey = conn->rdma_local_mr->lkey;

    

    int *v = (int*)conn->peer_mr.addr;
    v[0] = 15;
    int i;
    for (i = 0; i < CNUM; i++) {
      s[i] = get_dtime();
      TEST_NZ(ibv_post_send(conn->qp, &wr, &bad_wr));
    }
    v[0] = 11;    

    conn->send_msg->type = MSG_DONE;
    send_message(conn);

  } else if (conn->send_state == SS_DONE_SENT && conn->recv_state == RS_DONE_RECV) {
    printf("remote buffer: %s\n", get_peer_message_region(conn));
    rdma_disconnect(conn->id);
  }
}