From 224cff4bbaa307c6b8e38478d9492af8463720dd Mon Sep 17 00:00:00 2001 From: Xiaoyun Wang Date: Sat, 27 Jun 2020 11:55:46 +0800 Subject: [PATCH] net/hinic: fix setting promiscuous mode When setting promiscuous or allmulticast mode, increase multi-thread resource protection, because the patch "net/bonding: prefer allmulti to promiscuous for LACP" adds trying to use allmulti when adding a slave, and EVS bond driver also sets promisc with another thread, which may lead to thread reentry and cause failure to set promiscuous mode. Fixes: cb7b6606ebff ("net/hinic: add RSS stats and promiscuous ops") Cc: stable@dpdk.org Signed-off-by: Xiaoyun Wang --- drivers/net/hinic/hinic_pmd_ethdev.c | 34 ++++++++++++++++++++++++---- drivers/net/hinic/hinic_pmd_ethdev.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c index 8f81e22300..0d3d62bd0b 100644 --- a/drivers/net/hinic/hinic_pmd_ethdev.c +++ b/drivers/net/hinic/hinic_pmd_ethdev.c @@ -1268,14 +1268,25 @@ static void hinic_disable_interrupt(struct rte_eth_dev *dev) static int hinic_set_dev_promiscuous(struct hinic_nic_dev *nic_dev, bool enable) { - u32 rx_mode_ctrl = nic_dev->rx_mode_status; + u32 rx_mode_ctrl; + int err; + + err = hinic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode_ctrl = nic_dev->rx_mode_status; if (enable) rx_mode_ctrl |= HINIC_RX_MODE_PROMISC; else rx_mode_ctrl &= (~HINIC_RX_MODE_PROMISC); - return hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + + (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex); + + return err; } /** @@ -1728,14 +1739,25 @@ static void hinic_remove_all_vlanid(struct rte_eth_dev *eth_dev) static int hinic_set_dev_allmulticast(struct hinic_nic_dev *nic_dev, bool enable) { - u32 rx_mode_ctrl = nic_dev->rx_mode_status; + u32 rx_mode_ctrl; + int err; + + err = hinic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode_ctrl = nic_dev->rx_mode_status; if (enable) rx_mode_ctrl |= HINIC_RX_MODE_MC_ALL; else rx_mode_ctrl &= (~HINIC_RX_MODE_MC_ALL); - return hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + + (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex); + + return err; } /** @@ -3127,6 +3149,8 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) } rte_bit_relaxed_set32(HINIC_DEV_INTR_EN, &nic_dev->dev_status); + hinic_mutex_init(&nic_dev->rx_mode_mutex, NULL); + /* initialize filter info */ filter_info = &nic_dev->filter; tcam_info = &nic_dev->tcam; @@ -3201,6 +3225,8 @@ static int hinic_dev_uninit(struct rte_eth_dev *dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; + hinic_mutex_destroy(&nic_dev->rx_mode_mutex); + hinic_dev_close(dev); dev->dev_ops = NULL; diff --git a/drivers/net/hinic/hinic_pmd_ethdev.h b/drivers/net/hinic/hinic_pmd_ethdev.h index 77b4b91096..3f2d51d752 100644 --- a/drivers/net/hinic/hinic_pmd_ethdev.h +++ b/drivers/net/hinic/hinic_pmd_ethdev.h @@ -329,6 +329,7 @@ struct hinic_nic_dev { unsigned int flags; struct nic_service_cap nic_cap; u32 rx_mode_status; /* promisc or allmulticast */ + pthread_mutex_t rx_mode_mutex; u32 dev_status; char proc_dev_name[HINIC_DEV_NAME_LEN]; -- 2.20.1