/** * Iterator function for rte_mempool_walk() to register existing mempools and * fill the MP to MR cache of a TX queue. * * @param[in] mp * Memory Pool to register. * @param *arg * Pointer to TX queue structure. */ void txq_mp2mr_iter(const struct rte_mempool *mp, void *arg) { struct txq *txq = arg; struct txq_mp2mr_mbuf_check_data data = { .mp = mp, .ret = -1, }; /* Discard empty mempools. */ if (mp->size == 0) return; /* Register mempool only if the first element looks like a mbuf. */ rte_mempool_obj_iter((void *)mp->elt_va_start, 1, mp->header_size + mp->elt_size + mp->trailer_size, 1, mp->elt_pa, mp->pg_num, mp->pg_shift, txq_mp2mr_mbuf_check, &data); if (data.ret) return; txq_mp2mr(txq, mp); } /** * Insert VLAN using mbuf headroom space. * * @param buf * Buffer for VLAN insertion. * * @return * 0 on success, errno value on failure. */ static inline int insert_vlan_sw(struct rte_mbuf *buf) { uintptr_t addr; uint32_t vlan; uint16_t head_room_len = rte_pktmbuf_headroom(buf); if (head_room_len < 4) return EINVAL; addr = rte_pktmbuf_mtod(buf, uintptr_t); vlan = htonl(0x81000000 | buf->vlan_tci); memmove((void *)(addr - 4), (void *)addr, 12); memcpy((void *)(addr + 8), &vlan, sizeof(vlan)); SET_DATA_OFF(buf, head_room_len - 4); DATA_LEN(buf) += 4; return 0; }
/** * Iterator function for rte_mempool_walk() to register existing mempools and * fill the MP to MR cache of a TX queue. * * @param[in] mp * Memory Pool to register. * @param *arg * Pointer to TX queue structure. */ void txq_mp2mr_iter(struct rte_mempool *mp, void *arg) { struct txq_ctrl *txq_ctrl = arg; struct txq_mp2mr_mbuf_check_data data = { .ret = 0, }; unsigned int i; /* Register mempool only if the first element looks like a mbuf. */ if (rte_mempool_obj_iter(mp, txq_mp2mr_mbuf_check, &data) == 0 || data.ret == -1) return; for (i = 0; (i != RTE_DIM(txq_ctrl->txq.mp2mr)); ++i) { if (unlikely(txq_ctrl->txq.mp2mr[i].mp == NULL)) { /* Unknown MP, add a new MR for it. */ break; } if (txq_ctrl->txq.mp2mr[i].mp == mp) return; } txq_mp2mr_reg(&txq_ctrl->txq, mp, i); }
static void setup_mempool_for_rx_task(struct lcore_cfg *lconf, struct task_args *targ) { const uint8_t socket = rte_lcore_to_socket_id(lconf->id); struct prox_port_cfg *port_cfg = &prox_port_cfg[targ->rx_port_queue[0].port]; const struct rte_memzone *mz; struct rte_mempool *mp = NULL; uint32_t flags = 0; char memzone_name[64]; char name[64]; /* mbuf size can be set * - from config file (highest priority, overwriting any other config) - should only be used as workaround * - through each 'mode', overwriting the default mbuf_size * - defaulted to MBUF_SIZE i.e. 1518 Bytes * Except is set expliciteky, ensure that size is big enough for vmxnet3 driver */ if (targ->mbuf_size_set_explicitely) { flags = MEMPOOL_F_NO_SPREAD; /* targ->mbuf_size already set */ } else if (targ->task_init->mbuf_size != 0) { /* mbuf_size not set through config file but set through mode */ targ->mbuf_size = targ->task_init->mbuf_size; } else if (strcmp(port_cfg->short_name, "vmxnet3") == 0) { if (targ->mbuf_size < MBUF_SIZE + RTE_PKTMBUF_HEADROOM) targ->mbuf_size = MBUF_SIZE + RTE_PKTMBUF_HEADROOM; } /* allocate memory pool for packets */ PROX_ASSERT(targ->nb_mbuf != 0); if (targ->pool_name[0] == '\0') { sprintf(name, "core_%u_port_%u_pool", lconf->id, targ->id); } snprintf(memzone_name, sizeof(memzone_name)-1, "MP_%s", targ->pool_name); mz = rte_memzone_lookup(memzone_name); if (mz != NULL) { mp = (struct rte_mempool*)mz->addr; targ->nb_mbuf = mp->size; targ->pool = mp; } #ifdef RTE_LIBRTE_IVSHMEM_FALSE if (mz != NULL && mp != NULL && mp->phys_addr != mz->ioremap_addr) { /* Init mbufs with ioremap_addr for dma */ mp->phys_addr = mz->ioremap_addr; mp->elt_pa[0] = mp->phys_addr + (mp->elt_va_start - (uintptr_t)mp); struct prox_pktmbuf_reinit_args init_args; init_args.mp = mp; init_args.lconf = lconf; uint32_t elt_sz = mp->elt_size + mp->header_size + mp->trailer_size; rte_mempool_obj_iter((void*)mp->elt_va_start, mp->size, elt_sz, 1, mp->elt_pa, mp->pg_num, mp->pg_shift, prox_pktmbuf_reinit, &init_args); } #endif /* Use this pool for the interface that the core is receiving from if one core receives from multiple ports, all the ports use the same mempool */ if (targ->pool == NULL) { plog_info("\t\tCreating mempool with name '%s'\n", name); targ->pool = rte_mempool_create(name, targ->nb_mbuf - 1, targ->mbuf_size, targ->nb_cache_mbuf, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, prox_pktmbuf_init, lconf, socket, flags); } PROX_PANIC(targ->pool == NULL, "\t\tError: cannot create mempool for core %u port %u: %s\n", lconf->id, targ->id, rte_strerror(rte_errno)); plog_info("\t\tMempool %p size = %u * %u cache %u, socket %d\n", targ->pool, targ->nb_mbuf, targ->mbuf_size, targ->nb_cache_mbuf, socket); if (prox_cfg.flags & DSF_SHUFFLE) { shuffle_mempool(targ->pool, targ->nb_mbuf); } }