@@ -570,7 +570,9 @@ static int ena_rss_reta_update(struct rte_eth_dev *dev,
}
}
+ rte_spinlock_lock(&adapter->admin_lock);
rc = ena_com_indirect_table_set(ena_dev);
+ rte_spinlock_unlock(&adapter->admin_lock);
if (unlikely(rc && rc != ENA_COM_UNSUPPORTED)) {
PMD_DRV_LOG(ERR, "Cannot flush the indirect table\n");
return rc;
@@ -599,7 +601,9 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
(reta_size > RTE_RETA_GROUP_SIZE && ((reta_conf + 1) == NULL)))
return -EINVAL;
+ rte_spinlock_lock(&adapter->admin_lock);
rc = ena_com_indirect_table_get(ena_dev, indirect_table);
+ rte_spinlock_unlock(&adapter->admin_lock);
if (unlikely(rc && rc != ENA_COM_UNSUPPORTED)) {
PMD_DRV_LOG(ERR, "cannot get indirect table\n");
return -ENOTSUP;
@@ -954,7 +958,10 @@ static int ena_stats_get(struct rte_eth_dev *dev,
return -ENOTSUP;
memset(&ena_stats, 0, sizeof(ena_stats));
+
+ rte_spinlock_lock(&adapter->admin_lock);
rc = ena_com_get_dev_basic_stats(ena_dev, &ena_stats);
+ rte_spinlock_unlock(&adapter->admin_lock);
if (unlikely(rc)) {
PMD_DRV_LOG(ERR, "Could not retrieve statistics from ENA\n");
return rc;
@@ -1876,6 +1883,8 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)
goto err_delete_debug_area;
}
+ rte_spinlock_init(&adapter->admin_lock);
+
rte_intr_callback_register(intr_handle,
ena_interrupt_handler_rte,
adapter);
@@ -200,6 +200,13 @@ struct ena_adapter {
u16 max_mtu;
struct ena_offloads offloads;
+ /* The admin queue isn't protected by the lock and is used to
+ * retrieve statistics from the device. As there is no guarantee that
+ * application won't try to get statistics from multiple threads, it is
+ * safer to lock the queue to avoid admin queue failure.
+ */
+ rte_spinlock_t admin_lock;
+
int id_number;
char name[ENA_NAME_MAX_LEN];
u8 mac_addr[RTE_ETHER_ADDR_LEN];