Commit 9af9b891 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'ena-driver-changes-may-2024'

David Arinzon says:

====================
ENA driver changes May 2024

This patchset contains several misc and minor
changes to the ENA driver.
====================

Link: https://lore.kernel.org/r/20240512134637.25299-1-darinzon@amazon.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 5fcc17df 1cc0a47d
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
/* ENA adaptive interrupt moderation settings */ /* ENA adaptive interrupt moderation settings */
#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 64 #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 64
#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0 #define ENA_INTR_INITIAL_RX_INTERVAL_USECS 20
#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1 #define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1
#define ENA_HASH_KEY_SIZE 40 #define ENA_HASH_KEY_SIZE 40
...@@ -305,6 +305,8 @@ struct ena_com_dev { ...@@ -305,6 +305,8 @@ struct ena_com_dev {
u16 stats_func; /* Selected function for extended statistic dump */ u16 stats_func; /* Selected function for extended statistic dump */
u16 stats_queue; /* Selected queue for extended statistic dump */ u16 stats_queue; /* Selected queue for extended statistic dump */
u32 ena_min_poll_delay_us;
struct ena_com_mmio_read mmio_read; struct ena_com_mmio_read mmio_read;
struct ena_rss rss; struct ena_rss rss;
...@@ -325,8 +327,6 @@ struct ena_com_dev { ...@@ -325,8 +327,6 @@ struct ena_com_dev {
struct ena_intr_moder_entry *intr_moder_tbl; struct ena_intr_moder_entry *intr_moder_tbl;
struct ena_com_llq_info llq_info; struct ena_com_llq_info llq_info;
u32 ena_min_poll_delay_us;
}; };
struct ena_com_dev_get_features_ctx { struct ena_com_dev_get_features_ctx {
......
...@@ -229,30 +229,43 @@ static struct ena_eth_io_rx_cdesc_base * ...@@ -229,30 +229,43 @@ static struct ena_eth_io_rx_cdesc_base *
idx * io_cq->cdesc_entry_size_in_bytes); idx * io_cq->cdesc_entry_size_in_bytes);
} }
static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
u16 *first_cdesc_idx) u16 *first_cdesc_idx,
u16 *num_descs)
{ {
u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked;
struct ena_eth_io_rx_cdesc_base *cdesc; struct ena_eth_io_rx_cdesc_base *cdesc;
u16 count = 0, head_masked;
u32 last = 0; u32 last = 0;
do { do {
u32 status;
cdesc = ena_com_get_next_rx_cdesc(io_cq); cdesc = ena_com_get_next_rx_cdesc(io_cq);
if (!cdesc) if (!cdesc)
break; break;
status = READ_ONCE(cdesc->status);
ena_com_cq_inc_head(io_cq); ena_com_cq_inc_head(io_cq);
if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >>
ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) {
struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq);
netdev_err(dev->net_device,
"First bit is on in descriptor #%d on q_id: %d, req_id: %u\n",
count, io_cq->qid, cdesc->req_id);
return -EFAULT;
}
count++; count++;
last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
} while (!last); } while (!last);
if (last) { if (last) {
*first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx; *first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx;
count += io_cq->cur_rx_pkt_cdesc_count;
head_masked = io_cq->head & (io_cq->q_depth - 1); head_masked = io_cq->head & (io_cq->q_depth - 1);
*num_descs = count;
io_cq->cur_rx_pkt_cdesc_count = 0; io_cq->cur_rx_pkt_cdesc_count = 0;
io_cq->cur_rx_pkt_cdesc_start_idx = head_masked; io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;
...@@ -260,11 +273,11 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, ...@@ -260,11 +273,11 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
"ENA q_id: %d packets were completed. first desc idx %u descs# %d\n", "ENA q_id: %d packets were completed. first desc idx %u descs# %d\n",
io_cq->qid, *first_cdesc_idx, count); io_cq->qid, *first_cdesc_idx, count);
} else { } else {
io_cq->cur_rx_pkt_cdesc_count += count; io_cq->cur_rx_pkt_cdesc_count = count;
count = 0; *num_descs = 0;
} }
return count; return 0;
} }
static int ena_com_create_meta(struct ena_com_io_sq *io_sq, static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
...@@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq, ...@@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
u16 cdesc_idx = 0; u16 cdesc_idx = 0;
u16 nb_hw_desc; u16 nb_hw_desc;
u16 i = 0; u16 i = 0;
int rc;
WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type"); WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx); rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc);
if (unlikely(rc != 0))
return -EFAULT;
if (nb_hw_desc == 0) { if (nb_hw_desc == 0) {
ena_rx_ctx->descs = nb_hw_desc; ena_rx_ctx->descs = nb_hw_desc;
return 0; return 0;
......
...@@ -47,7 +47,7 @@ struct ena_com_rx_ctx { ...@@ -47,7 +47,7 @@ struct ena_com_rx_ctx {
bool frag; bool frag;
u32 hash; u32 hash;
u16 descs; u16 descs;
int max_bufs; u16 max_bufs;
u8 pkt_offset; u8 pkt_offset;
}; };
......
...@@ -49,6 +49,7 @@ static const struct ena_stats ena_stats_global_strings[] = { ...@@ -49,6 +49,7 @@ static const struct ena_stats ena_stats_global_strings[] = {
ENA_STAT_GLOBAL_ENTRY(interface_up), ENA_STAT_GLOBAL_ENTRY(interface_up),
ENA_STAT_GLOBAL_ENTRY(interface_down), ENA_STAT_GLOBAL_ENTRY(interface_down),
ENA_STAT_GLOBAL_ENTRY(admin_q_pause), ENA_STAT_GLOBAL_ENTRY(admin_q_pause),
ENA_STAT_GLOBAL_ENTRY(reset_fail),
}; };
static const struct ena_stats ena_stats_eni_strings[] = { static const struct ena_stats ena_stats_eni_strings[] = {
...@@ -459,10 +460,18 @@ static void ena_get_drvinfo(struct net_device *dev, ...@@ -459,10 +460,18 @@ static void ena_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info) struct ethtool_drvinfo *info)
{ {
struct ena_adapter *adapter = netdev_priv(dev); struct ena_adapter *adapter = netdev_priv(dev);
ssize_t ret = 0;
strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ret = strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
strscpy(info->bus_info, pci_name(adapter->pdev), if (ret < 0)
netif_dbg(adapter, drv, dev,
"module name will be truncated, status = %zd\n", ret);
ret = strscpy(info->bus_info, pci_name(adapter->pdev),
sizeof(info->bus_info)); sizeof(info->bus_info));
if (ret < 0)
netif_dbg(adapter, drv, dev,
"bus info will be truncated, status = %zd\n", ret);
} }
static void ena_get_ringparam(struct net_device *netdev, static void ena_get_ringparam(struct net_device *netdev,
......
...@@ -42,7 +42,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl); ...@@ -42,7 +42,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
static int ena_rss_init_default(struct ena_adapter *adapter); static int ena_rss_init_default(struct ena_adapter *adapter);
static void check_for_admin_com_state(struct ena_adapter *adapter); static void check_for_admin_com_state(struct ena_adapter *adapter);
static void ena_destroy_device(struct ena_adapter *adapter, bool graceful); static int ena_destroy_device(struct ena_adapter *adapter, bool graceful);
static int ena_restore_device(struct ena_adapter *adapter); static int ena_restore_device(struct ena_adapter *adapter);
static void ena_tx_timeout(struct net_device *dev, unsigned int txqueue) static void ena_tx_timeout(struct net_device *dev, unsigned int txqueue)
...@@ -1347,6 +1347,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, ...@@ -1347,6 +1347,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
if (rc == -ENOSPC) { if (rc == -ENOSPC) {
ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp); ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp);
ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS); ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS);
} else if (rc == -EFAULT) {
ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED);
} else { } else {
ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1, ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1,
&rx_ring->syncp); &rx_ring->syncp);
...@@ -2701,6 +2703,7 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pd ...@@ -2701,6 +2703,7 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pd
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ena_admin_host_info *host_info; struct ena_admin_host_info *host_info;
ssize_t ret;
int rc; int rc;
/* Allocate only the host info */ /* Allocate only the host info */
...@@ -2715,11 +2718,19 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pd ...@@ -2715,11 +2718,19 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pd
host_info->bdf = pci_dev_id(pdev); host_info->bdf = pci_dev_id(pdev);
host_info->os_type = ENA_ADMIN_OS_LINUX; host_info->os_type = ENA_ADMIN_OS_LINUX;
host_info->kernel_ver = LINUX_VERSION_CODE; host_info->kernel_ver = LINUX_VERSION_CODE;
strscpy(host_info->kernel_ver_str, utsname()->version, ret = strscpy(host_info->kernel_ver_str, utsname()->version,
sizeof(host_info->kernel_ver_str) - 1); sizeof(host_info->kernel_ver_str));
if (ret < 0)
dev_dbg(dev,
"kernel version string will be truncated, status = %zd\n", ret);
host_info->os_dist = 0; host_info->os_dist = 0;
strscpy(host_info->os_dist_str, utsname()->release, ret = strscpy(host_info->os_dist_str, utsname()->release,
sizeof(host_info->os_dist_str)); sizeof(host_info->os_dist_str));
if (ret < 0)
dev_dbg(dev,
"OS distribution string will be truncated, status = %zd\n", ret);
host_info->driver_version = host_info->driver_version =
(DRV_MODULE_GEN_MAJOR) | (DRV_MODULE_GEN_MAJOR) |
(DRV_MODULE_GEN_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) | (DRV_MODULE_GEN_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) |
...@@ -3235,14 +3246,15 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter) ...@@ -3235,14 +3246,15 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter)
return rc; return rc;
} }
static void ena_destroy_device(struct ena_adapter *adapter, bool graceful) static int ena_destroy_device(struct ena_adapter *adapter, bool graceful)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ena_com_dev *ena_dev = adapter->ena_dev; struct ena_com_dev *ena_dev = adapter->ena_dev;
bool dev_up; bool dev_up;
int rc = 0;
if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
return; return 0;
netif_carrier_off(netdev); netif_carrier_off(netdev);
...@@ -3260,7 +3272,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful) ...@@ -3260,7 +3272,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
* and device is up, ena_down() already reset the device. * and device is up, ena_down() already reset the device.
*/ */
if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
ena_free_mgmnt_irq(adapter); ena_free_mgmnt_irq(adapter);
...@@ -3279,6 +3291,8 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful) ...@@ -3279,6 +3291,8 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
return rc;
} }
static int ena_restore_device(struct ena_adapter *adapter) static int ena_restore_device(struct ena_adapter *adapter)
...@@ -3355,14 +3369,17 @@ static int ena_restore_device(struct ena_adapter *adapter) ...@@ -3355,14 +3369,17 @@ static int ena_restore_device(struct ena_adapter *adapter)
static void ena_fw_reset_device(struct work_struct *work) static void ena_fw_reset_device(struct work_struct *work)
{ {
int rc = 0;
struct ena_adapter *adapter = struct ena_adapter *adapter =
container_of(work, struct ena_adapter, reset_task); container_of(work, struct ena_adapter, reset_task);
rtnl_lock(); rtnl_lock();
if (likely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { if (likely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
ena_destroy_device(adapter, false); rc |= ena_destroy_device(adapter, false);
ena_restore_device(adapter); rc |= ena_restore_device(adapter);
adapter->dev_stats.reset_fail += !!rc;
dev_err(&adapter->pdev->dev, "Device reset completed successfully\n"); dev_err(&adapter->pdev->dev, "Device reset completed successfully\n");
} }
......
...@@ -290,6 +290,7 @@ struct ena_stats_dev { ...@@ -290,6 +290,7 @@ struct ena_stats_dev {
u64 admin_q_pause; u64 admin_q_pause;
u64 rx_drops; u64 rx_drops;
u64 tx_drops; u64 tx_drops;
u64 reset_fail;
}; };
enum ena_flags_t { enum ena_flags_t {
......
...@@ -22,6 +22,7 @@ enum ena_regs_reset_reason_types { ...@@ -22,6 +22,7 @@ enum ena_regs_reset_reason_types {
ENA_REGS_RESET_GENERIC = 13, ENA_REGS_RESET_GENERIC = 13,
ENA_REGS_RESET_MISS_INTERRUPT = 14, ENA_REGS_RESET_MISS_INTERRUPT = 14,
ENA_REGS_RESET_SUSPECTED_POLL_STARVATION = 15, ENA_REGS_RESET_SUSPECTED_POLL_STARVATION = 15,
ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED = 16,
}; };
/* ena_registers offsets */ /* ena_registers offsets */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment