Skip to content

Commit 82ef30f

Browse files
NetanelBelgazaldavem330
authored andcommitted
net: ena: add hardware hints capability to the driver
With this patch, ENA device can update the ena driver about the desired timeout values: These values are part of the "hardware hints" which are transmitted to the driver as Asynchronous event through ENA async event notification queue. In case the ENA device does not support this capability, the driver will use its own default values. Signed-off-by: Netanel Belgazal <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d149763 commit 82ef30f

File tree

6 files changed

+137
-11
lines changed

6 files changed

+137
-11
lines changed

drivers/net/ethernet/amazon/ena/ena_admin_defs.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ enum ena_admin_aq_feature_id {
7070

7171
ENA_ADMIN_MAX_QUEUES_NUM = 2,
7272

73+
ENA_ADMIN_HW_HINTS = 3,
74+
7375
ENA_ADMIN_RSS_HASH_FUNCTION = 10,
7476

7577
ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11,
@@ -749,6 +751,31 @@ struct ena_admin_feature_rss_ind_table {
749751
struct ena_admin_rss_ind_table_entry inline_entry;
750752
};
751753

754+
/* When hint value is 0, driver should use it's own predefined value */
755+
struct ena_admin_ena_hw_hints {
756+
/* value in ms */
757+
u16 mmio_read_timeout;
758+
759+
/* value in ms */
760+
u16 driver_watchdog_timeout;
761+
762+
/* Per packet tx completion timeout. value in ms */
763+
u16 missing_tx_completion_timeout;
764+
765+
u16 missed_tx_completion_count_threshold_to_reset;
766+
767+
/* value in ms */
768+
u16 admin_completion_tx_timeout;
769+
770+
u16 netdev_wd_timeout;
771+
772+
u16 max_tx_sgl_size;
773+
774+
u16 max_rx_sgl_size;
775+
776+
u16 reserved[8];
777+
};
778+
752779
struct ena_admin_get_feat_cmd {
753780
struct ena_admin_aq_common_desc aq_common_descriptor;
754781

@@ -782,6 +809,8 @@ struct ena_admin_get_feat_resp {
782809
struct ena_admin_feature_rss_ind_table ind_table;
783810

784811
struct ena_admin_feature_intr_moder_desc intr_moderation;
812+
813+
struct ena_admin_ena_hw_hints hw_hints;
785814
} u;
786815
};
787816

@@ -857,6 +886,8 @@ enum ena_admin_aenq_notification_syndrom {
857886
ENA_ADMIN_SUSPEND = 0,
858887

859888
ENA_ADMIN_RESUME = 1,
889+
890+
ENA_ADMIN_UPDATE_HINTS = 2,
860891
};
861892

862893
struct ena_admin_aenq_entry {

drivers/net/ethernet/amazon/ena/ena_com.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
511511
unsigned long flags, timeout;
512512
int ret;
513513

514-
timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
514+
timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout);
515515

516516
while (1) {
517517
spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -561,7 +561,8 @@ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *com
561561
int ret;
562562

563563
wait_for_completion_timeout(&comp_ctx->wait_event,
564-
usecs_to_jiffies(ADMIN_CMD_TIMEOUT_US));
564+
usecs_to_jiffies(
565+
admin_queue->completion_timeout));
565566

566567
/* In case the command wasn't completed find out the root cause.
567568
* There might be 2 kinds of errors
@@ -601,12 +602,15 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
601602
struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
602603
volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
603604
mmio_read->read_resp;
604-
u32 mmio_read_reg, ret;
605+
u32 mmio_read_reg, ret, i;
605606
unsigned long flags;
606-
int i;
607+
u32 timeout = mmio_read->reg_read_to;
607608

608609
might_sleep();
609610

611+
if (timeout == 0)
612+
timeout = ENA_REG_READ_TIMEOUT;
613+
610614
/* If readless is disabled, perform regular read */
611615
if (!mmio_read->readless_supported)
612616
return readl(ena_dev->reg_bar + offset);
@@ -627,14 +631,14 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
627631

628632
writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
629633

630-
for (i = 0; i < ENA_REG_READ_TIMEOUT; i++) {
634+
for (i = 0; i < timeout; i++) {
631635
if (read_resp->req_id == mmio_read->seq_num)
632636
break;
633637

634638
udelay(1);
635639
}
636640

637-
if (unlikely(i == ENA_REG_READ_TIMEOUT)) {
641+
if (unlikely(i == timeout)) {
638642
pr_err("reading reg failed for timeout. expected: req id[%hu] offset[%hu] actual: req id[%hu] offset[%hu]\n",
639643
mmio_read->seq_num, offset, read_resp->req_id,
640644
read_resp->reg_off);
@@ -1730,6 +1734,20 @@ int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
17301734
memcpy(&get_feat_ctx->offload, &get_resp.u.offload,
17311735
sizeof(get_resp.u.offload));
17321736

1737+
/* Driver hints isn't mandatory admin command. So in case the
1738+
* command isn't supported set driver hints to 0
1739+
*/
1740+
rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS);
1741+
1742+
if (!rc)
1743+
memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints,
1744+
sizeof(get_resp.u.hw_hints));
1745+
else if (rc == -EOPNOTSUPP)
1746+
memset(&get_feat_ctx->hw_hints, 0x0,
1747+
sizeof(get_feat_ctx->hw_hints));
1748+
else
1749+
return rc;
1750+
17331751
return 0;
17341752
}
17351753

@@ -1855,6 +1873,14 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)
18551873
return rc;
18561874
}
18571875

1876+
timeout = (cap & ENA_REGS_CAPS_ADMIN_CMD_TO_MASK) >>
1877+
ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT;
1878+
if (timeout)
1879+
/* the resolution of timeout reg is 100ms */
1880+
ena_dev->admin_queue.completion_timeout = timeout * 100000;
1881+
else
1882+
ena_dev->admin_queue.completion_timeout = ADMIN_CMD_TIMEOUT_US;
1883+
18581884
return 0;
18591885
}
18601886

drivers/net/ethernet/amazon/ena/ena_com.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
#define ENA_INTR_MODER_LEVEL_STRIDE 2
9898
#define ENA_INTR_BYTE_COUNT_NOT_SUPPORTED 0xFFFFFF
9999

100+
#define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF
101+
100102
enum ena_intr_moder_level {
101103
ENA_INTR_MODER_LOWEST = 0,
102104
ENA_INTR_MODER_LOW,
@@ -232,7 +234,9 @@ struct ena_com_stats_admin {
232234
struct ena_com_admin_queue {
233235
void *q_dmadev;
234236
spinlock_t q_lock; /* spinlock for the admin queue */
237+
235238
struct ena_comp_ctx *comp_ctx;
239+
u32 completion_timeout;
236240
u16 q_depth;
237241
struct ena_com_admin_cq cq;
238242
struct ena_com_admin_sq sq;
@@ -267,6 +271,7 @@ struct ena_com_aenq {
267271
struct ena_com_mmio_read {
268272
struct ena_admin_ena_mmio_req_read_less_resp *read_resp;
269273
dma_addr_t read_resp_dma_addr;
274+
u32 reg_read_to; /* in us */
270275
u16 seq_num;
271276
bool readless_supported;
272277
/* spin lock to ensure a single outstanding read */
@@ -336,6 +341,7 @@ struct ena_com_dev_get_features_ctx {
336341
struct ena_admin_device_attr_feature_desc dev_attr;
337342
struct ena_admin_feature_aenq_desc aenq;
338343
struct ena_admin_feature_offload_desc offload;
344+
struct ena_admin_ena_hw_hints hw_hints;
339345
};
340346

341347
struct ena_com_create_io_ctx {

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,7 +2577,7 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter,
25772577
tx_buf = &tx_ring->tx_buffer_info[i];
25782578
last_jiffies = tx_buf->last_jiffies;
25792579
if (unlikely(last_jiffies &&
2580-
time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
2580+
time_is_before_jiffies(last_jiffies + adapter->missing_tx_completion_to))) {
25812581
if (!tx_buf->print_once)
25822582
netif_notice(adapter, tx_err, adapter->netdev,
25832583
"Found a Tx that wasn't completed on time, qid %d, index %d.\n",
@@ -2586,10 +2586,11 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter,
25862586
tx_buf->print_once = 1;
25872587
missed_tx++;
25882588

2589-
if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) {
2589+
if (unlikely(missed_tx > adapter->missing_tx_completion_threshold)) {
25902590
netif_err(adapter, tx_err, adapter->netdev,
25912591
"The number of lost tx completions is above the threshold (%d > %d). Reset the device\n",
2592-
missed_tx, MAX_NUM_OF_TIMEOUTED_PACKETS);
2592+
missed_tx,
2593+
adapter->missing_tx_completion_threshold);
25932594
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
25942595
return -EIO;
25952596
}
@@ -2613,6 +2614,9 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter)
26132614
if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
26142615
return;
26152616

2617+
if (adapter->missing_tx_completion_to == ENA_HW_HINTS_NO_TIMEOUT)
2618+
return;
2619+
26162620
budget = ENA_MONITORED_TX_QUEUES;
26172621

26182622
for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
@@ -2690,8 +2694,11 @@ static void check_for_missing_keep_alive(struct ena_adapter *adapter)
26902694
if (!adapter->wd_state)
26912695
return;
26922696

2693-
keep_alive_expired = round_jiffies(adapter->last_keep_alive_jiffies
2694-
+ ENA_DEVICE_KALIVE_TIMEOUT);
2697+
if (adapter->keep_alive_timeout == ENA_HW_HINTS_NO_TIMEOUT)
2698+
return;
2699+
2700+
keep_alive_expired = round_jiffies(adapter->last_keep_alive_jiffies +
2701+
adapter->keep_alive_timeout);
26952702
if (unlikely(time_is_before_jiffies(keep_alive_expired))) {
26962703
netif_err(adapter, drv, adapter->netdev,
26972704
"Keep alive watchdog timeout.\n");
@@ -2714,6 +2721,44 @@ static void check_for_admin_com_state(struct ena_adapter *adapter)
27142721
}
27152722
}
27162723

2724+
static void ena_update_hints(struct ena_adapter *adapter,
2725+
struct ena_admin_ena_hw_hints *hints)
2726+
{
2727+
struct net_device *netdev = adapter->netdev;
2728+
2729+
if (hints->admin_completion_tx_timeout)
2730+
adapter->ena_dev->admin_queue.completion_timeout =
2731+
hints->admin_completion_tx_timeout * 1000;
2732+
2733+
if (hints->mmio_read_timeout)
2734+
/* convert to usec */
2735+
adapter->ena_dev->mmio_read.reg_read_to =
2736+
hints->mmio_read_timeout * 1000;
2737+
2738+
if (hints->missed_tx_completion_count_threshold_to_reset)
2739+
adapter->missing_tx_completion_threshold =
2740+
hints->missed_tx_completion_count_threshold_to_reset;
2741+
2742+
if (hints->missing_tx_completion_timeout) {
2743+
if (hints->missing_tx_completion_timeout == ENA_HW_HINTS_NO_TIMEOUT)
2744+
adapter->missing_tx_completion_to = ENA_HW_HINTS_NO_TIMEOUT;
2745+
else
2746+
adapter->missing_tx_completion_to =
2747+
msecs_to_jiffies(hints->missing_tx_completion_timeout);
2748+
}
2749+
2750+
if (hints->netdev_wd_timeout)
2751+
netdev->watchdog_timeo = msecs_to_jiffies(hints->netdev_wd_timeout);
2752+
2753+
if (hints->driver_watchdog_timeout) {
2754+
if (hints->driver_watchdog_timeout == ENA_HW_HINTS_NO_TIMEOUT)
2755+
adapter->keep_alive_timeout = ENA_HW_HINTS_NO_TIMEOUT;
2756+
else
2757+
adapter->keep_alive_timeout =
2758+
msecs_to_jiffies(hints->driver_watchdog_timeout);
2759+
}
2760+
}
2761+
27172762
static void ena_update_host_info(struct ena_admin_host_info *host_info,
27182763
struct net_device *netdev)
27192764
{
@@ -3136,6 +3181,11 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
31363181
INIT_WORK(&adapter->reset_task, ena_fw_reset_device);
31373182

31383183
adapter->last_keep_alive_jiffies = jiffies;
3184+
adapter->keep_alive_timeout = ENA_DEVICE_KALIVE_TIMEOUT;
3185+
adapter->missing_tx_completion_to = TX_TIMEOUT;
3186+
adapter->missing_tx_completion_threshold = MAX_NUM_OF_TIMEOUTED_PACKETS;
3187+
3188+
ena_update_hints(adapter, &get_feat_ctx.hw_hints);
31393189

31403190
setup_timer(&adapter->timer_service, ena_timer_service,
31413191
(unsigned long)adapter);
@@ -3337,6 +3387,7 @@ static void ena_notification(void *adapter_data,
33373387
struct ena_admin_aenq_entry *aenq_e)
33383388
{
33393389
struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
3390+
struct ena_admin_ena_hw_hints *hints;
33403391

33413392
WARN(aenq_e->aenq_common_desc.group != ENA_ADMIN_NOTIFICATION,
33423393
"Invalid group(%x) expected %x\n",
@@ -3354,6 +3405,11 @@ static void ena_notification(void *adapter_data,
33543405
case ENA_ADMIN_RESUME:
33553406
queue_work(ena_wq, &adapter->resume_io_task);
33563407
break;
3408+
case ENA_ADMIN_UPDATE_HINTS:
3409+
hints = (struct ena_admin_ena_hw_hints *)
3410+
(&aenq_e->inline_data_w4);
3411+
ena_update_hints(adapter, hints);
3412+
break;
33573413
default:
33583414
netif_err(adapter, drv, adapter->netdev,
33593415
"Invalid aenq notification link state %d\n",

drivers/net/ethernet/amazon/ena/ena_netdev.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ struct ena_adapter {
280280

281281
int msix_vecs;
282282

283+
u32 missing_tx_completion_threshold;
284+
283285
u32 tx_usecs, rx_usecs; /* interrupt moderation */
284286
u32 tx_frames, rx_frames; /* interrupt moderation */
285287

@@ -293,6 +295,9 @@ struct ena_adapter {
293295

294296
u8 mac_addr[ETH_ALEN];
295297

298+
unsigned long keep_alive_timeout;
299+
unsigned long missing_tx_completion_to;
300+
296301
char name[ENA_NAME_MAX_LEN];
297302

298303
unsigned long flags;

drivers/net/ethernet/amazon/ena/ena_regs_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK 0x3e
7979
#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT 8
8080
#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK 0xff00
81+
#define ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT 16
82+
#define ENA_REGS_CAPS_ADMIN_CMD_TO_MASK 0xf0000
8183

8284
/* aq_caps register */
8385
#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK 0xffff

0 commit comments

Comments
 (0)