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.
Signed-off-by: Ian Stokes <ian.sto...@intel.com> --- lib/netdev-dpdk.c | 29 ++++++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index c208f32..c382270 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -2679,12 +2679,19 @@ 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); + } + + if (!error) { ovs_assert((error == 0) == (dev->qos_conf != NULL)); } + else { + VLOG_ERR("Failed to set QoS type %s on port %s, returned error %d", + type, netdev->name, error); + ovs_assert(dev->qos_conf == NULL); + } ovs_mutex_unlock(&dev->mutex); return error; @@ -2726,6 +2733,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; + } + rte_spinlock_unlock(&dev->qos_lock); return err; @@ -2756,11 +2772,13 @@ 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); const char *cir_s; const char *cbs_s; int err = 0; policer = egress_policer_get__(netdev); + rte_spinlock_lock(&dev->qos_lock); cir_s = smap_get(details, "cir"); cbs_s = smap_get(details, "cbs"); policer->app_srtcm_params.cir = cir_s ? strtoull(cir_s, NULL, 10) : 0; @@ -2769,6 +2787,15 @@ egress_policer_qos_set(struct netdev *netdev, const struct smap *details) 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; + } + rte_spinlock_unlock(&dev->qos_lock); + return err; } -- 1.7.4.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev