From: "Wei Hu (Xavier)" <xavier.hu...@huawei.com> Currently, there is a potential problem that changing the content of dev->data->dev_conf.rxmode.offloads even when there is no vlan_offload_set driver callback.
It is a good idea that prevent the side effect and make the API return success if no change requested. This patch fixes the problem, the detail information as below: - keep possibility to do dummy set even if there is no driver callback - do not touch Rx mode offloads in device data before checking the driver callback availability - ensure that Rx mode offloads are rolled back correctly if driver callback returns error Fixes: dfebfc9882fb ("ethdev: support dynamic configuration of QinQ strip") Cc: sta...@dpdk.org Signed-off-by: Wei Hu (Xavier) <xavier.hu...@huawei.com> Signed-off-by: Chunsong Feng <fengchuns...@huawei.com> Signed-off-by: Min Wang (Jushui) <wangm...@huawei.com> Signed-off-by: Min Hu (Connor) <humi...@huawei.com> Reviewed-by: Andrew Rybchenko <arybche...@solarflare.com> --- v2 -> v3: 1. Update the commit log and titile of the patch according to Andrew Rybchenko's comments. The related link as below: http://patches.dpdk.org/patch/64825/ v1 -> v2: 1. Update the modification according to Ferruh Yigit's comment. The related link as below: http://patches.dpdk.org/patch/64779/ 2. Update the commit log and title of the patch. --- lib/librte_ethdev/rte_ethdev.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index aec2d0f70..9232503f7 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -3253,53 +3253,53 @@ rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) int mask = 0; int cur, org = 0; uint64_t orig_offloads; - uint64_t *dev_offloads; + uint64_t dev_offloads; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); dev = &rte_eth_devices[port_id]; /* save original values in case of failure */ orig_offloads = dev->data->dev_conf.rxmode.offloads; - dev_offloads = &dev->data->dev_conf.rxmode.offloads; + dev_offloads = orig_offloads; /*check which option changed by application*/ cur = !!(offload_mask & ETH_VLAN_STRIP_OFFLOAD); - org = !!(*dev_offloads & DEV_RX_OFFLOAD_VLAN_STRIP); + org = !!(dev_offloads & DEV_RX_OFFLOAD_VLAN_STRIP); if (cur != org) { if (cur) - *dev_offloads |= DEV_RX_OFFLOAD_VLAN_STRIP; + dev_offloads |= DEV_RX_OFFLOAD_VLAN_STRIP; else - *dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP; + dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP; mask |= ETH_VLAN_STRIP_MASK; } cur = !!(offload_mask & ETH_VLAN_FILTER_OFFLOAD); - org = !!(*dev_offloads & DEV_RX_OFFLOAD_VLAN_FILTER); + org = !!(dev_offloads & DEV_RX_OFFLOAD_VLAN_FILTER); if (cur != org) { if (cur) - *dev_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; + dev_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; else - *dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER; + dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER; mask |= ETH_VLAN_FILTER_MASK; } cur = !!(offload_mask & ETH_VLAN_EXTEND_OFFLOAD); - org = !!(*dev_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND); + org = !!(dev_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND); if (cur != org) { if (cur) - *dev_offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND; + dev_offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND; else - *dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_EXTEND; + dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_EXTEND; mask |= ETH_VLAN_EXTEND_MASK; } cur = !!(offload_mask & ETH_QINQ_STRIP_OFFLOAD); - org = !!(*dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP); + org = !!(dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP); if (cur != org) { if (cur) - *dev_offloads |= DEV_RX_OFFLOAD_QINQ_STRIP; + dev_offloads |= DEV_RX_OFFLOAD_QINQ_STRIP; else - *dev_offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP; + dev_offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP; mask |= ETH_QINQ_STRIP_MASK; } @@ -3308,10 +3308,11 @@ rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) return ret; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_offload_set, -ENOTSUP); + dev->data->dev_conf.rxmode.offloads = dev_offloads; ret = (*dev->dev_ops->vlan_offload_set)(dev, mask); if (ret) { /* hit an error restore original values */ - *dev_offloads = orig_offloads; + dev->data->dev_conf.rxmode.offloads = orig_offloads; } return eth_err(port_id, ret); -- 2.23.0