When egress policer is set as a QoS type for a port, an error may occur during
setup if incorrect parameters are used for the rte_meter. If this occurs
the egress policer construct and set functions should free any allocated
memory relevant to the policer and set the QoS configuration pointer to
null. The netdev_dpdk_set_qos function should check the error value returned
for any QoS construct/set calls with an assertion to avoid segfault.
Also this commit modifies egress_policer_qos_set() to correctly lock the QoS
spinlock while the egress policer configuration is updated to avoid
segfault.

Signed-off-by: Ian Stokes <ian.sto...@intel.com>
---
v2
* netdev-dpdk.c
- Simplify assertion in netdev_dpdk_set_qos() to check that no error
  has been returned and that a QoS configuration exists before checking
  and logging an error.
- Use rte_strerror  in netdev_dpdk_set_qos() when logging error for a
  textual representation.
- Align VLOG message for correct formatting in netdev_dpdk_set_qos().
- egress_policer_qos_construct() now returns positive error.
- egress_policer_qos_set() now return positive error.
- Document addition of spinlock in egress_policer_qos_set() in commit
  message.
---
 lib/netdev-dpdk.c |   30 ++++++++++++++++++++++++++++--
 1 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index bf3a898..f37130e 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -2731,11 +2731,16 @@ netdev_dpdk_set_qos(struct netdev *netdev,
 
             /* Install new QoS configuration. */
             error = new_ops->qos_construct(netdev, details);
-            ovs_assert((error == 0) == (dev->qos_conf != NULL));
         }
     } else {
         error = new_ops->qos_construct(netdev, details);
-        ovs_assert((error == 0) == (dev->qos_conf != NULL));
+    }
+
+    ovs_assert((error == 0) == (dev->qos_conf != NULL));
+    if (error) {
+        VLOG_ERR("Failed to set QoS type %s on port %s, returned error: %s",
+                 type, netdev->name, rte_strerror(-error));
+        ovs_assert(dev->qos_conf == NULL);
     }
 
     ovs_mutex_unlock(&dev->mutex);
@@ -2774,6 +2779,15 @@ egress_policer_qos_construct(struct netdev *netdev,
     policer->app_srtcm_params.ebs = 0;
     err = rte_meter_srtcm_config(&policer->egress_meter,
                                     &policer->app_srtcm_params);
+
+    if (err < 0) {
+        /* Error occurred during rte_meter creation, destroy the policer
+         * and set the qos configuration for the netdev dpdk to NULL
+         */
+        free(policer);
+        dev->qos_conf = NULL;
+        err = -err;
+    }
     rte_spinlock_unlock(&dev->qos_lock);
 
     return err;
@@ -2804,15 +2818,27 @@ static int
 egress_policer_qos_set(struct netdev *netdev, const struct smap *details)
 {
     struct egress_policer *policer;
+    struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     int err = 0;
 
     policer = egress_policer_get__(netdev);
+    rte_spinlock_lock(&dev->qos_lock);
     policer->app_srtcm_params.cir = smap_get_ullong(details, "cir", 0);
     policer->app_srtcm_params.cbs = smap_get_ullong(details, "cbs", 0);
     policer->app_srtcm_params.ebs = 0;
     err = rte_meter_srtcm_config(&policer->egress_meter,
                                     &policer->app_srtcm_params);
 
+    if (err < 0) {
+        /* Error occurred during rte_meter creation, destroy the policer
+         * and set the qos configuration for the netdev dpdk to NULL
+         */
+        free(policer);
+        dev->qos_conf = NULL;
+        err = -err;
+    }
+    rte_spinlock_unlock(&dev->qos_lock);
+
     return err;
 }
 
-- 
1.7.4.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to