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 the pointer named dev->dev_ops->vlan_offload_set is NULL in the API function named rte_eth_dev_set_vlan_offload.
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: - Update a local 'dev_offloads' variable, instead of directly updating the device config data - if no change requested, "mask == 0", return success - if change requested, check the 'vlan_offload_set' dev_ops in this stage - assign the local 'dev_offloads' to 'dev->data->dev_conf.rxmode.offloads' and call the dev_ops - On error recover the 'dev->data->dev_conf.rxmode.offloads' to 'orig_offloads' Fixes: 01eb53eefeb4 ("ethdev: rename folder to library name") 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> --- 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