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 <cloud.wangxiaoyun@huawei.com>
static int hinic_set_dev_promiscuous(struct hinic_nic_dev *nic_dev, bool enable)
{
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);
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;
static int hinic_set_dev_allmulticast(struct hinic_nic_dev *nic_dev,
bool enable)
{
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);
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;
}
rte_bit_relaxed_set32(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
}
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;
/* initialize filter info */
filter_info = &nic_dev->filter;
tcam_info = &nic_dev->tcam;
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
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;
hinic_dev_close(dev);
dev->dev_ops = NULL;
unsigned int flags;
struct nic_service_cap nic_cap;
u32 rx_mode_status; /* promisc or allmulticast */
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];
u32 dev_status;
char proc_dev_name[HINIC_DEV_NAME_LEN];