Skip to content

Commit

Permalink
net: ena: reduce driver load time
Browse files Browse the repository at this point in the history
This commit reduces the driver load time by using usec resolution
instead of msec when polling for hardware state change.

Also add back-off mechanism to handle cases where minimal sleep
time is not enough.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Arthur Kiyanovski authored and David S. Miller committed May 22, 2020
1 parent b0ae3ac commit 4bb7f4c
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 10 deletions.
36 changes: 26 additions & 10 deletions drivers/net/ethernet/amazon/ena/ena_com.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@

#define ENA_REGS_ADMIN_INTR_MASK 1

#define ENA_POLL_MS 5
#define ENA_MIN_ADMIN_POLL_US 100

#define ENA_MAX_ADMIN_POLL_US 5000

/*****************************************************************************/
/*****************************************************************************/
Expand Down Expand Up @@ -540,12 +542,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
return -EINVAL;
}

static void ena_delay_exponential_backoff_us(u32 exp, u32 delay_us)
{
delay_us = max_t(u32, ENA_MIN_ADMIN_POLL_US, delay_us);
delay_us = min_t(u32, delay_us * (1U << exp), ENA_MAX_ADMIN_POLL_US);
usleep_range(delay_us, 2 * delay_us);
}

static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx,
struct ena_com_admin_queue *admin_queue)
{
unsigned long flags = 0;
unsigned long timeout;
int ret;
u32 exp = 0;

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

Expand All @@ -569,7 +579,8 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
goto err;
}

msleep(ENA_POLL_MS);
ena_delay_exponential_backoff_us(exp++,
admin_queue->ena_dev->ena_min_poll_delay_us);
}

if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) {
Expand Down Expand Up @@ -939,12 +950,13 @@ static void ena_com_io_queue_free(struct ena_com_dev *ena_dev,
static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout,
u16 exp_state)
{
u32 val, i;
u32 val, exp = 0;
unsigned long timeout_stamp;

/* Convert timeout from resolution of 100ms to ENA_POLL_MS */
timeout = (timeout * 100) / ENA_POLL_MS;
/* Convert timeout from resolution of 100ms to us resolution. */
timeout_stamp = jiffies + usecs_to_jiffies(100 * 1000 * timeout);

for (i = 0; i < timeout; i++) {
while (1) {
val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);

if (unlikely(val == ENA_MMIO_READ_TIMEOUT)) {
Expand All @@ -956,10 +968,11 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout,
exp_state)
return 0;

msleep(ENA_POLL_MS);
}
if (time_is_before_jiffies(timeout_stamp))
return -ETIME;

return -ETIME;
ena_delay_exponential_backoff_us(exp++, ena_dev->ena_min_poll_delay_us);
}
}

static bool ena_com_check_supported_feature_id(struct ena_com_dev *ena_dev,
Expand Down Expand Up @@ -1436,11 +1449,13 @@ void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev)
{
struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
unsigned long flags = 0;
u32 exp = 0;

spin_lock_irqsave(&admin_queue->q_lock, flags);
while (atomic_read(&admin_queue->outstanding_cmds) != 0) {
spin_unlock_irqrestore(&admin_queue->q_lock, flags);
msleep(ENA_POLL_MS);
ena_delay_exponential_backoff_us(exp++,
ena_dev->ena_min_poll_delay_us);
spin_lock_irqsave(&admin_queue->q_lock, flags);
}
spin_unlock_irqrestore(&admin_queue->q_lock, flags);
Expand Down Expand Up @@ -1788,6 +1803,7 @@ int ena_com_admin_init(struct ena_com_dev *ena_dev,
if (ret)
goto error;

admin_queue->ena_dev = ena_dev;
admin_queue->running_state = true;

return 0;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/amazon/ena/ena_com.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ struct ena_com_stats_admin {

struct ena_com_admin_queue {
void *q_dmadev;
struct ena_com_dev *ena_dev;
spinlock_t q_lock; /* spinlock for the admin queue */

struct ena_comp_ctx *comp_ctx;
Expand Down Expand Up @@ -351,6 +352,8 @@ struct ena_com_dev {
struct ena_intr_moder_entry *intr_moder_tbl;

struct ena_com_llq_info llq_info;

u32 ena_min_poll_delay_us;
};

struct ena_com_dev_get_features_ctx {
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/amazon/ena/ena_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -4166,6 +4166,8 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_free_region;
}

ena_dev->ena_min_poll_delay_us = ENA_ADMIN_POLL_DELAY_US;

ena_dev->dmadev = &pdev->dev;

rc = ena_device_init(ena_dev, pdev, &get_feat_ctx, &wd_state);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/amazon/ena/ena_netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@
#define ENA_IO_IRQ_FIRST_IDX 1
#define ENA_IO_IRQ_IDX(q) (ENA_IO_IRQ_FIRST_IDX + (q))

#define ENA_ADMIN_POLL_DELAY_US 100

/* ENA device should send keep alive msg every 1 sec.
* We wait for 6 sec just to be on the safe side.
*/
Expand Down

0 comments on commit 4bb7f4c

Please sign in to comment.