Example #1
0
int ibv_buffer(struct ibvif *m) {

  size_t sz_bytes = ALIGN_TO_PAGE_SIZE(m->buf_size + HUGE_PAGE_SIZE);

  m->recv_shmid = shmget(IPC_PRIVATE, sz_bytes,
                     SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);

  if (m->recv_shmid < 0) {
    perror("shmget failed !!!");
    return 0;
  }

  m->send_buf = (char *)shmat(m->recv_shmid, NULL, 0);
  if (m->send_buf == (void*)-1) {
    shmctl(m->recv_shmid, IPC_RMID, NULL);
    m->recv_shmid = -1;
    m->send_buf = NULL;
    perror("shmat failed !!!");
    return 0;
  }

  if (shmctl(m->recv_shmid, IPC_RMID, NULL)) {
    perror("shared memory marking to be destroyed - FAILED");
  }

  m->buf_size = sz_bytes;
  return 1;
}
Example #2
0
inline void *malloc_huge_pages(size_t size)
{
// Use 1 extra page to store allocation metadata
// (libhugetlbfs is more efficient in this regard)
size_t real_size = ALIGN_TO_PAGE_SIZE(size + HUGE_PAGE_SIZE);
char *ptr = (char *)mmap(NULL, real_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS |
MAP_POPULATE | MAP_HUGETLB, -1, 0);
if (ptr == MAP_FAILED) {
// The mmap() call failed. Try to malloc instead
posix_memalign((void **)&ptr, 4096, real_size);
if (ptr == NULL) return NULL;
real_size = 0;
}
// Save real_size since mmunmap() requires a size parameter
*((size_t *)ptr) = real_size;
// Skip the page with metadata
return ptr + HUGE_PAGE_SIZE;
}
Example #3
0
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
  struct ibvif *ibvif;
  int num_of_device, flags = IBV_ACCESS_LOCAL_WRITE;
  struct ibv_qp_init_attr attr;
  struct ibv_qp_attr qp_attr;
  uint8_t port_num = 1;
  int    qp_flags;
  struct ibv_device **ib_dev_list;
  struct tcpip_thread *thread;
  struct ibv_exp_cq_init_attr cq_attr;

  ibvif = (struct ibvif *)netif->state;

  /* Obtain MAC address from network interface. */
  ibvif->ethaddr->addr[0] = 0x00;
  ibvif->ethaddr->addr[1] = 0x02;
  ibvif->ethaddr->addr[2] = 0xc9;
  ibvif->ethaddr->addr[3] = 0xa4;
  ibvif->ethaddr->addr[4] = 0x59;
  ibvif->ethaddr->addr[5] = 0x41;

  ibvif->buf_size = ALIGN_TO_PAGE_SIZE(PBUF_POOL_SIZE * TCP_MAX_PACKET_SIZE);

  /* Do things needed for using Raw Packet Verbs */

  ib_dev_list = ibv_get_device_list(&num_of_device);
  if (num_of_device <= 0 || !ib_dev_list || !ib_dev_list[0]) {
    perror("IBV no device found\n");
    exit(1);
  }

  ibvif->context = ibv_open_device(ib_dev_list[1]);
  if (!ibvif->context) {
    perror("IBV can't open device\n");
    exit(1);
  }

  ibv_free_device_list(ib_dev_list);

  if (set_link_layer(ibvif->context, 1) == LINK_FAILURE) {
    perror("IBV can't allocate PD\n");
    exit(1); 
  }

  ibvif->pd = ibv_alloc_pd(ibvif->context);
  if (!ibvif->pd) {
    perror("IBV can't allocate PD\n");
    exit(1);
  }

  /*if (!ibv_buffer(ibvif)) {
    LWIP_DEBUGF(NETIF_DEBUG, ("Buffer allocation failed\n"));
    exit(1);
  }*/

  ibvif->recv_buf     = netif->prot_thread->pbuf_rx_handle.buf;
  ibvif->send_buf     = netif->prot_thread->pbuf_tx_handle.buf;
  ibvif->send_size    = TCP_MAX_PACKET_SIZE;
  ibvif->rx_depth     = PBUF_POOL_SIZE;
  ibvif->tx_depth     = PBUF_POOL_SIZE;

  ibvif->send_mr = ibv_reg_mr(ibvif->pd, ibvif->send_buf, ibvif->buf_size, flags);
  if (!ibvif->send_mr) {
    perror("IBV error reg send mr\n");
    exit(1);
  }

  ibvif->recv_mr = ibv_reg_mr(ibvif->pd, ibvif->recv_buf, ibvif->buf_size, flags);
  if (!ibvif->recv_mr) {
    perror("IBV error reg recv mr\n");
    exit(1);
  }

  ibvif->send_cq = ibv_create_cq(ibvif->context, ibvif->tx_depth, NULL, NULL, 0);
  if (!ibvif->send_cq) {
    perror("IBV can't create send cq\n");
    exit(1);
  }

  cq_attr.flags = IBV_EXP_CQ_TIMESTAMP;
  cq_attr.comp_mask = IBV_EXP_CQ_INIT_ATTR_FLAGS;
  ibvif->recv_cq = ibv_exp_create_cq(ibvif->context, ibvif->rx_depth, NULL, NULL, 0, &cq_attr);
  if (!ibvif->recv_cq) {
    perror("IBV can't create recv cq\n");
    exit(1);
  }

  memset(&attr, 0, sizeof(struct ibv_qp_init_attr));
  attr.send_cq = ibvif->send_cq;
  attr.recv_cq = ibvif->recv_cq;
  attr.cap.max_send_wr = ibvif->tx_depth;
  attr.cap.max_send_sge = 1;
  attr.cap.max_recv_wr = ibvif->rx_depth;
  attr.cap.max_recv_sge = 1;
  attr.qp_type = IBV_QPT_RAW_PACKET;

  ibvif->qp = ibv_create_qp(ibvif->pd, &attr);
  if (!ibvif->qp) {
    perror("IBV can't create QP\n");
    exit(1);
  }

  qp_flags = IBV_QP_STATE | IBV_QP_PORT;
  memset(&qp_attr, 0, sizeof(struct ibv_qp_attr));
  qp_attr.qp_state = IBV_QPS_INIT;
  qp_attr.pkey_index = 0;
  qp_attr.port_num = port_num;
  qp_attr.qp_access_flags = 0;

  if (ibv_modify_qp(ibvif->qp, &qp_attr, qp_flags)) {
    perror("IBV can't set qp to init\n");
    exit(1);
  }
  ibv_attach_device(netif);
}