When configuring a mempool, in netdev_dpdk_mempool_configure(), the result of a call to dpdk_buf_size() is being used as the MTU. This, however, is not the MTU but a ROUND_UP aligned number based on the MTU, which could lead to the reuse of mempools even when the real MTUs between different ports differ but somehow round up to the same mbuf size.
To support multi-segment mbufs, which is coming in later commits, this distinction is important. For multi-segment mbufs the mbuf size is always the same (multiple mbufs are chained together to hold the packet's data), which means that using the mbuf size as the mtu would lead to reusing always the same mempool, independent of the MTU set. To fix this, two fields are now passed to dpdk_mp_create(), the mtu and the mbuf_size, thus creating a distinction between the two. The latter is used for telling rte_pktmbuf_pool_create() the size of each mbuf, while the former is used for tracking purposes in struct dpdk_mp and as an input to create a unique hash for the mempool's name. Signed-off-by: Tiago Lam <[email protected]> --- lib/netdev-dpdk.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index bb4d60f..be8e8b9 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -632,7 +632,8 @@ dpdk_calculate_mbufs(struct netdev_dpdk *dev, int mtu, bool per_port_mp) } static struct dpdk_mp * -dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool per_port_mp) +dpdk_mp_create(struct netdev_dpdk *dev, int mtu, uint32_t mbuf_size, + bool per_port_mp) { char mp_name[RTE_MEMPOOL_NAMESIZE]; const char *netdev_name = netdev_get_name(&dev->up); @@ -666,21 +667,23 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool per_port_mp) if (ret < 0 || ret >= RTE_MEMPOOL_NAMESIZE) { VLOG_DBG("snprintf returned %d. " "Failed to generate a mempool name for \"%s\". " - "Hash:0x%x, socket_id: %d, mtu:%d, mbufs:%u.", - ret, netdev_name, hash, socket_id, mtu, n_mbufs); + "Hash:0x%x, socket_id: %d, mtu:%d, mbufs:%u, " + "mbuf size: %u", + ret, netdev_name, hash, socket_id, mtu, n_mbufs, + mbuf_size); break; } - VLOG_DBG("Port %s: Requesting a mempool of %u mbufs " + VLOG_DBG("Port %s: Requesting a mempool of %u mbufs of size %u " "on socket %d for %d Rx and %d Tx queues.", - netdev_name, n_mbufs, socket_id, + netdev_name, n_mbufs, mbuf_size, socket_id, dev->requested_n_rxq, dev->requested_n_txq); dmp->mp = rte_pktmbuf_pool_create(mp_name, n_mbufs, MP_CACHE_SZ, sizeof (struct dp_packet) - sizeof (struct rte_mbuf), - MBUF_SIZE(mtu) + MBUF_SIZE(mbuf_size) - sizeof(struct dp_packet), socket_id); @@ -718,7 +721,8 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool per_port_mp) } static struct dpdk_mp * -dpdk_mp_get(struct netdev_dpdk *dev, int mtu, bool per_port_mp) +dpdk_mp_get(struct netdev_dpdk *dev, int mtu, uint32_t mbuf_size, + bool per_port_mp) { struct dpdk_mp *dmp, *next; bool reuse = false; @@ -741,7 +745,7 @@ dpdk_mp_get(struct netdev_dpdk *dev, int mtu, bool per_port_mp) dpdk_mp_sweep(); if (!reuse) { - dmp = dpdk_mp_create(dev, mtu, per_port_mp); + dmp = dpdk_mp_create(dev, mtu, mbuf_size, per_port_mp); if (dmp) { /* Shared memory will hit the reuse case above so will not * request a mempool that already exists but we need to check @@ -807,7 +811,7 @@ netdev_dpdk_mempool_configure(struct netdev_dpdk *dev) return ret; } - dmp = dpdk_mp_get(dev, FRAME_LEN_TO_MTU(buf_size), per_port_mp); + dmp = dpdk_mp_get(dev, dev->requested_mtu, buf_size, per_port_mp); if (!dmp) { VLOG_ERR("Failed to create memory pool for netdev " "%s, with MTU %d on socket %d: %s\n", -- 2.7.4 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
