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; }
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; }
/*-----------------------------------------------------------------------------------*/ 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); }