On 7/10/2018 12:06 PM, Tiago Lam wrote:
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]>

Hi Tiago,

I don't think these changes are acceptable as they break from the expected behavior of the shared mempool model.

The reason we introduced the shared mempool model was that it was used from OVS 2.6 -> 2.9.

A user with the same deployment moving between releases would not have to re-calculate the memory they dimension for OVS DPDK.

With these changes however they may have to.

Consider the following example:

A user adds a port with mtu 1500 and a second port with mtu 1800. Assuming both ports are on the same socket, the same mempool would be re-used for both ports in the current shared mempool model.

However with this change, separate mempools would have to be created as the MTU is different, potentially requiring an increase in the memory provisioned by the user. It may not be possible for users to upgrade from OVS 2.9 to 2.10 without re-dimension their memory with this.

We had a similar issue to this in OVS 2.9 release with the per port memory model, it was flagged as a blocking factor for Red Hat and Ericsson upgrades which led to the removal of the per port model in 2.9.

One possible solution here is that multiseg is supported for the per port memory model only?

Ian

---
  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",


_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to