[PATCH V2 net-next] net: ena: Fix Kconfig dependency on X86

2018-10-17 Thread netanel
From: Netanel Belgazal 

The Kconfig limitation of X86 is to too wide.
The ENA driver only requires a little endian dependency.

Change the dependency to be on little endian CPU.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/Kconfig 
b/drivers/net/ethernet/amazon/Kconfig
index 99b30353541a..9e87d7b8360f 100644
--- a/drivers/net/ethernet/amazon/Kconfig
+++ b/drivers/net/ethernet/amazon/Kconfig
@@ -17,7 +17,7 @@ if NET_VENDOR_AMAZON
 
 config ENA_ETHERNET
tristate "Elastic Network Adapter (ENA) support"
-   depends on (PCI_MSI && X86)
+   depends on PCI_MSI && !CPU_BIG_ENDIAN
---help---
  This driver supports Elastic Network Adapter (ENA)"
 
-- 
2.15.2.AMZN



Re: [PATCH net-next] net: ena: Fix Kconfig dependencies X86

2018-10-17 Thread Belgazal, Netanel
Sure.
Removing them and resubmit.

On 10/17/18, 11:37 AM, "Sergei Shtylyov"  
wrote:

Hello!

On 17.10.2018 11:16, neta...@amazon.com wrote:

    > From: Netanel Belgazal 
>
> The Kconfig limitation of X86 is to too wide.
> The ENA driver only requires a little endian dependency.
>
> Change the dependency to be on little endian CPU.
>
> Signed-off-by: Netanel Belgazal 
> ---
>  drivers/net/ethernet/amazon/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/amazon/Kconfig 
b/drivers/net/ethernet/amazon/Kconfig
> index 99b30353541a..f4d16c7e104f 100644
> --- a/drivers/net/ethernet/amazon/Kconfig
> +++ b/drivers/net/ethernet/amazon/Kconfig
> @@ -17,7 +17,7 @@ if NET_VENDOR_AMAZON
>
>  config ENA_ETHERNET
>   tristate "Elastic Network Adapter (ENA) support"
> - depends on (PCI_MSI && X86)
> + depends on (PCI_MSI && !CPU_BIG_ENDIAN)

 Parens not needed here. High time to remove them, I think.

[...]

MBR, Sergei






[PATCH net-next] net: ena: Fix Kconfig dependencies X86

2018-10-17 Thread netanel
From: Netanel Belgazal 

The Kconfig limitation of X86 is to too wide.
The ENA driver only requires a little endian dependency.

Change the dependency to be on little endian CPU.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/Kconfig 
b/drivers/net/ethernet/amazon/Kconfig
index 99b30353541a..f4d16c7e104f 100644
--- a/drivers/net/ethernet/amazon/Kconfig
+++ b/drivers/net/ethernet/amazon/Kconfig
@@ -17,7 +17,7 @@ if NET_VENDOR_AMAZON
 
 config ENA_ETHERNET
tristate "Elastic Network Adapter (ENA) support"
-   depends on (PCI_MSI && X86)
+   depends on (PCI_MSI && !CPU_BIG_ENDIAN)
---help---
  This driver supports Elastic Network Adapter (ENA)"
 
-- 
2.15.2.AMZN



[PATCH net V2 3/7] net: ena: fix device destruction to gracefully free resources

2018-09-09 Thread netanel
From: Netanel Belgazal 

When ena_destroy_device() is called from ena_suspend(), the device is
still reachable from the driver. Therefore, the driver can send a command
to the device to free all resources.
However, in all other cases of calling ena_destroy_device(), the device is
potentially in an error state and unreachable from the driver. In these
cases the driver must not send commands to the device.

The current implementation does not request resource freeing from the
device even when possible. We add the graceful parameter to
ena_destroy_device() to enable resource freeing when possible, and
use it in ena_suspend().

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 69e684fd2787..035d47d2179a 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
 
 static int ena_rss_init_default(struct ena_adapter *adapter);
 static void check_for_admin_com_state(struct ena_adapter *adapter);
-static void ena_destroy_device(struct ena_adapter *adapter);
+static void ena_destroy_device(struct ena_adapter *adapter, bool graceful);
 static int ena_restore_device(struct ena_adapter *adapter);
 
 static void ena_tx_timeout(struct net_device *dev)
@@ -1900,7 +1900,7 @@ static int ena_close(struct net_device *netdev)
  "Destroy failure, restarting device\n");
ena_dump_stats_to_dmesg(adapter);
/* rtnl lock already obtained in dev_ioctl() layer */
-   ena_destroy_device(adapter);
+   ena_destroy_device(adapter, false);
ena_restore_device(adapter);
}
 
@@ -2550,7 +2550,7 @@ static int 
ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return rc;
 }
 
-static void ena_destroy_device(struct ena_adapter *adapter)
+static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
 {
struct net_device *netdev = adapter->netdev;
struct ena_com_dev *ena_dev = adapter->ena_dev;
@@ -2563,7 +2563,8 @@ static void ena_destroy_device(struct ena_adapter 
*adapter)
dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
adapter->dev_up_before_reset = dev_up;
 
-   ena_com_set_admin_running_state(ena_dev, false);
+   if (!graceful)
+   ena_com_set_admin_running_state(ena_dev, false);
 
if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
ena_down(adapter);
@@ -2665,7 +2666,7 @@ static void ena_fw_reset_device(struct work_struct *work)
return;
}
rtnl_lock();
-   ena_destroy_device(adapter);
+   ena_destroy_device(adapter, false);
ena_restore_device(adapter);
rtnl_unlock();
 }
@@ -3467,7 +3468,7 @@ static int ena_suspend(struct pci_dev *pdev,  
pm_message_t state)
"ignoring device reset request as the device is being 
suspended\n");
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
}
-   ena_destroy_device(adapter);
+   ena_destroy_device(adapter, true);
rtnl_unlock();
return 0;
 }
-- 
2.15.2.AMZN



[PATCH net V2 0/7] bug fixes for ENA Ethernet driver

2018-09-09 Thread netanel
From: Netanel Belgazal 

Netanel Belgazal (7):
  net: ena: fix surprise unplug NULL dereference kernel crash
  net: ena: fix driver when PAGE_SIZE == 64kB
  net: ena: fix device destruction to gracefully free resources
  net: ena: fix potential double ena_destroy_device()
  net: ena: fix missing lock during device destruction
  net: ena: fix missing calls to READ_ONCE
  net: ena: fix incorrect usage of memory barriers

 drivers/net/ethernet/amazon/ena/ena_com.c | 24 
 drivers/net/ethernet/amazon/ena/ena_eth_com.c |  6 ++
 drivers/net/ethernet/amazon/ena/ena_eth_com.h |  8 +--
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 82 ---
 drivers/net/ethernet/amazon/ena/ena_netdev.h  | 11 
 5 files changed, 67 insertions(+), 64 deletions(-)

-- 
2.15.2.AMZN



[PATCH net V2 4/7] net: ena: fix potential double ena_destroy_device()

2018-09-09 Thread netanel
From: Netanel Belgazal 

ena_destroy_device() can potentially be called twice.
To avoid this, check that the device is running and
only then proceed destroying it.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 035d47d2179a..a68c2a8d4da2 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2556,6 +2556,9 @@ static void ena_destroy_device(struct ena_adapter 
*adapter, bool graceful)
struct ena_com_dev *ena_dev = adapter->ena_dev;
bool dev_up;
 
+   if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
+   return;
+
netif_carrier_off(netdev);
 
del_timer_sync(&adapter->timer_service);
@@ -2592,6 +2595,7 @@ static void ena_destroy_device(struct ena_adapter 
*adapter, bool graceful)
adapter->reset_reason = ENA_REGS_RESET_NORMAL;
 
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+   clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
 }
 
 static int ena_restore_device(struct ena_adapter *adapter)
@@ -2636,6 +2640,7 @@ static int ena_restore_device(struct ena_adapter *adapter)
}
}
 
+   set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
dev_err(&pdev->dev, "Device reset completed successfully\n");
 
-- 
2.15.2.AMZN



[PATCH net V2 6/7] net: ena: fix missing calls to READ_ONCE

2018-09-09 Thread netanel
From: Netanel Belgazal 

Add READ_ONCE calls where necessary (for example when iterating
over a memory field that gets updated by the hardware).

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 17f12c18d225..c37deef3bcf1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -459,7 +459,7 @@ static void ena_com_handle_admin_completion(struct 
ena_com_admin_queue *admin_qu
cqe = &admin_queue->cq.entries[head_masked];
 
/* Go over all the completions */
-   while ((cqe->acq_common_descriptor.flags &
+   while ((READ_ONCE(cqe->acq_common_descriptor.flags) &
ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) {
/* Do not read the rest of the completion entry before the
 * phase bit was validated
@@ -637,7 +637,7 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev 
*ena_dev, u16 offset)
 
mmiowb();
for (i = 0; i < timeout; i++) {
-   if (read_resp->req_id == mmio_read->seq_num)
+   if (READ_ONCE(read_resp->req_id) == mmio_read->seq_num)
break;
 
udelay(1);
@@ -1796,8 +1796,8 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, 
void *data)
aenq_common = &aenq_e->aenq_common_desc;
 
/* Go over all the events */
-   while ((aenq_common->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) ==
-  phase) {
+   while ((READ_ONCE(aenq_common->flags) &
+   ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == phase) {
pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n",
 aenq_common->group, aenq_common->syndrom,
 (u64)aenq_common->timestamp_low +
-- 
2.15.2.AMZN



[PATCH net V2 7/7] net: ena: fix incorrect usage of memory barriers

2018-09-09 Thread netanel
From: Netanel Belgazal 

Added memory barriers where they were missing to support multiple
architectures, and removed redundant ones.

As part of removing the redundant memory barriers and improving
performance, we moved to more relaxed versions of memory barriers,
as well as to the more relaxed version of writel - writel_relaxed,
while maintaining correctness.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 16 +++---
 drivers/net/ethernet/amazon/ena/ena_eth_com.c |  6 ++
 drivers/net/ethernet/amazon/ena/ena_eth_com.h |  8 ++-
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 30 ++-
 4 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index c37deef3bcf1..7635c38e77dd 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -464,7 +464,7 @@ static void ena_com_handle_admin_completion(struct 
ena_com_admin_queue *admin_qu
/* Do not read the rest of the completion entry before the
 * phase bit was validated
 */
-   rmb();
+   dma_rmb();
ena_com_handle_single_admin_completion(admin_queue, cqe);
 
head_masked++;
@@ -627,15 +627,8 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev 
*ena_dev, u16 offset)
mmio_read_reg |= mmio_read->seq_num &
ENA_REGS_MMIO_REG_READ_REQ_ID_MASK;
 
-   /* make sure read_resp->req_id get updated before the hw can write
-* there
-*/
-   wmb();
-
-   writel_relaxed(mmio_read_reg,
-  ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
+   writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
-   mmiowb();
for (i = 0; i < timeout; i++) {
if (READ_ONCE(read_resp->req_id) == mmio_read->seq_num)
break;
@@ -1798,6 +1791,11 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, 
void *data)
/* Go over all the events */
while ((READ_ONCE(aenq_common->flags) &
ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == phase) {
+   /* Make sure the phase bit (ownership) is as expected before
+* reading the rest of the descriptor.
+*/
+   dma_rmb();
+
pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n",
 aenq_common->group, aenq_common->syndrom,
 (u64)aenq_common->timestamp_low +
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
index ea149c134e15..1c682b76190f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -51,6 +51,11 @@ static inline struct ena_eth_io_rx_cdesc_base 
*ena_com_get_next_rx_cdesc(
if (desc_phase != expected_phase)
return NULL;
 
+   /* Make sure we read the rest of the descriptor after the phase bit
+* has been read
+*/
+   dma_rmb();
+
return cdesc;
 }
 
@@ -493,6 +498,7 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, 
u16 *req_id)
if (cdesc_phase != expected_phase)
return -EAGAIN;
 
+   dma_rmb();
if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
pr_err("Invalid req id %d\n", cdesc->req_id);
return -EINVAL;
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
index 6fdc753d9483..2f7657227cfe 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -107,8 +107,7 @@ static inline int ena_com_sq_empty_space(struct 
ena_com_io_sq *io_sq)
return io_sq->q_depth - 1 - cnt;
 }
 
-static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq,
-   bool relaxed)
+static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
 {
u16 tail;
 
@@ -117,10 +116,7 @@ static inline int ena_com_write_sq_doorbell(struct 
ena_com_io_sq *io_sq,
pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
 io_sq->qid, tail);
 
-   if (relaxed)
-   writel_relaxed(tail, io_sq->db_addr);
-   else
-   writel(tail, io_sq->db_addr);
+   writel(tail, io_sq->db_addr);
 
return 0;
 }
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index b9ce2a6a87ed..29b5774dd32d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -551,14 +551,9 @@ static int ena_r

[PATCH net V2 2/7] net: ena: fix driver when PAGE_SIZE == 64kB

2018-09-09 Thread netanel
From: Netanel Belgazal 

The buffer length field in the ena rx descriptor is 16 bit, and the
current driver passes a full page in each ena rx descriptor.
When PAGE_SIZE equals 64kB or more, the buffer length field becomes
zero.
To solve this issue, limit the ena Rx descriptor to use 16kB even
when allocating 64kB kernel pages. This change would not impact ena
device functionality, as 16kB is still larger than maximum MTU.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.h | 11 +++
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 170830b807fe..69e684fd2787 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -461,7 +461,7 @@ static inline int ena_alloc_rx_page(struct ena_ring 
*rx_ring,
return -ENOMEM;
}
 
-   dma = dma_map_page(rx_ring->dev, page, 0, PAGE_SIZE,
+   dma = dma_map_page(rx_ring->dev, page, 0, ENA_PAGE_SIZE,
   DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(rx_ring->dev, dma))) {
u64_stats_update_begin(&rx_ring->syncp);
@@ -478,7 +478,7 @@ static inline int ena_alloc_rx_page(struct ena_ring 
*rx_ring,
rx_info->page_offset = 0;
ena_buf = &rx_info->ena_buf;
ena_buf->paddr = dma;
-   ena_buf->len = PAGE_SIZE;
+   ena_buf->len = ENA_PAGE_SIZE;
 
return 0;
 }
@@ -495,7 +495,7 @@ static void ena_free_rx_page(struct ena_ring *rx_ring,
return;
}
 
-   dma_unmap_page(rx_ring->dev, ena_buf->paddr, PAGE_SIZE,
+   dma_unmap_page(rx_ring->dev, ena_buf->paddr, ENA_PAGE_SIZE,
   DMA_FROM_DEVICE);
 
__free_page(page);
@@ -916,10 +916,10 @@ static struct sk_buff *ena_rx_skb(struct ena_ring 
*rx_ring,
do {
dma_unmap_page(rx_ring->dev,
   dma_unmap_addr(&rx_info->ena_buf, paddr),
-  PAGE_SIZE, DMA_FROM_DEVICE);
+  ENA_PAGE_SIZE, DMA_FROM_DEVICE);
 
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
-   rx_info->page_offset, len, PAGE_SIZE);
+   rx_info->page_offset, len, ENA_PAGE_SIZE);
 
netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
  "rx skb updated. len %d. data_len %d\n",
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index f1972b5ab650..7c7ae56c52cf 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -355,4 +355,15 @@ void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 
*buf);
 
 int ena_get_sset_count(struct net_device *netdev, int sset);
 
+/* The ENA buffer length fields is 16 bit long. So when PAGE_SIZE == 64kB the
+ * driver passas 0.
+ * Since the max packet size the ENA handles is ~9kB limit the buffer length to
+ * 16kB.
+ */
+#if PAGE_SIZE > SZ_16K
+#define ENA_PAGE_SIZE SZ_16K
+#else
+#define ENA_PAGE_SIZE PAGE_SIZE
+#endif
+
 #endif /* !(ENA_H) */
-- 
2.15.2.AMZN



[PATCH net V2 5/7] net: ena: fix missing lock during device destruction

2018-09-09 Thread netanel
From: Netanel Belgazal 

acquire the rtnl_lock during device destruction to avoid
using partially destroyed device.

ena_remove() shares almost the same logic as ena_destroy_device(),
so use ena_destroy_device() and avoid duplications.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 20 +++-
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index a68c2a8d4da2..b9ce2a6a87ed 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3421,24 +3421,18 @@ static void ena_remove(struct pci_dev *pdev)
 
unregister_netdev(netdev);
 
-   /* Reset the device only if the device is running. */
+   /* If the device is running then we want to make sure the device will be
+* reset to make sure no more events will be issued by the device.
+*/
if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
-   ena_com_dev_reset(ena_dev, adapter->reset_reason);
-
-   ena_free_mgmnt_irq(adapter);
+   set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
 
-   ena_disable_msix(adapter);
+   rtnl_lock();
+   ena_destroy_device(adapter, true);
+   rtnl_unlock();
 
free_netdev(netdev);
 
-   ena_com_mmio_reg_read_request_destroy(ena_dev);
-
-   ena_com_abort_admin_commands(ena_dev);
-
-   ena_com_wait_for_abort_completion(ena_dev);
-
-   ena_com_admin_destroy(ena_dev);
-
ena_com_rss_destroy(ena_dev);
 
ena_com_delete_debug_area(ena_dev);
-- 
2.15.2.AMZN



[PATCH net V2 1/7] net: ena: fix surprise unplug NULL dereference kernel crash

2018-09-09 Thread netanel
From: Netanel Belgazal 

Starting with driver version 1.5.0, in case of a surprise device
unplug, there is a race caused by invoking ena_destroy_device()
from two different places. As a result, the readless register might
be accessed after it was destroyed.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index c673ac2df65b..170830b807fe 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3409,12 +3409,12 @@ static void ena_remove(struct pci_dev *pdev)
netdev->rx_cpu_rmap = NULL;
}
 #endif /* CONFIG_RFS_ACCEL */
-
-   unregister_netdev(netdev);
del_timer_sync(&adapter->timer_service);
 
cancel_work_sync(&adapter->reset_task);
 
+   unregister_netdev(netdev);
+
/* Reset the device only if the device is running. */
if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
ena_com_dev_reset(ena_dev, adapter->reset_reason);
-- 
2.15.2.AMZN



Re: [PATCH v4 17/17] net: ena: Eliminate duplicate barriers on weakly-ordered archs

2018-03-25 Thread Belgazal, Netanel
I think you should either add a parameter to ena_com_write_sq_doorbell() or add 
ena_com_write_sq_doorbell_rel().
Right now, you have unused function.

On 3/20/18, 4:43 AM, "Sinan Kaya"  wrote:

Code includes barrier() followed by writel(). writel() already has a
barrier
on some architectures like arm64.

This ends up CPU observing two barriers back to back before executing the
register write.

Create a new wrapper function with relaxed write operator. Use the new
wrapper when a write is following a barrier().

Since code already has an explicit barrier call, changing writel() to
writel_relaxed().

Signed-off-by: Sinan Kaya 
---
 drivers/net/ethernet/amazon/ena/ena_com.c |  6 --
 drivers/net/ethernet/amazon/ena/ena_eth_com.h | 22 --
 drivers/net/ethernet/amazon/ena/ena_netdev.c  |  4 ++--
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index bf2de52..b6e628f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -631,7 +631,8 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev 
*ena_dev, u16 offset)
 */
wmb();
 
-   writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
+   writel_relaxed(mmio_read_reg,
+  ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
for (i = 0; i < timeout; i++) {
if (read_resp->req_id == mmio_read->seq_num)
@@ -1826,7 +1827,8 @@ void ena_com_aenq_intr_handler(struct ena_com_dev 
*dev, void *data)
 
/* write the aenq doorbell after all AENQ descriptors were read */
mb();
-   writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
+   writel_relaxed((u32)aenq->head,
+  dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
 }
 
 int ena_com_dev_reset(struct ena_com_dev *ena_dev,
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
index 2f76572..09ef7cd 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -107,7 +107,8 @@ static inline int ena_com_sq_empty_space(struct 
ena_com_io_sq *io_sq)
return io_sq->q_depth - 1 - cnt;
 }
 
-static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
+static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq,
+   bool relaxed)
 {
u16 tail;
 
@@ -116,7 +117,24 @@ static inline int ena_com_write_sq_doorbell(struct 
ena_com_io_sq *io_sq)
pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
 io_sq->qid, tail);
 
-   writel(tail, io_sq->db_addr);
+   if (relaxed)
+   writel_relaxed(tail, io_sq->db_addr);
+   else
+   writel(tail, io_sq->db_addr);
+
+   return 0;
+}
+
+static inline int ena_com_write_sq_doorbell_rel(struct ena_com_io_sq 
*io_sq)
+{
+   u16 tail;
+
+   tail = io_sq->tail;
+
+   pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
+io_sq->qid, tail);
+
+   writel_relaxed(tail, io_sq->db_addr);
 
return 0;
 }
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 6975150..0530201 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -556,7 +556,7 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, 
u32 num)
 * issue a doorbell
 */
wmb();
-   ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
+   ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq, true);
}
 
rx_ring->next_to_use = next_to_use;
@@ -2151,7 +2151,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff 
*skb, struct net_device *dev)
 
if (netif_xmit_stopped(txq) || !skb->xmit_more) {
/* trigger the dma engine */
-   ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
+   ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq, false);
u64_stats_update_begin(&tx_ring->syncp);
tx_ring->tx_stats.doorbells++;
u64_stats_update_end(&tx_ring->syncp);
-- 
2.7.4






[PATCH net V2 2/2] net: ena: fix error handling in ena_down() sequence

2018-01-02 Thread netanel
From: Netanel Belgazal 

ENA admin command queue errors are not handled as part of ena_down().
As a result, in case of error admin queue transitions to non-running
state and aborts all subsequent commands including those coming from
ena_up(). Reset scheduled by the driver from the timer service
context would not proceed due to sharing rtnl with ena_up()/ena_down()

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 6fb28fd43eb3..fbe21a817bd8 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -75,6 +75,9 @@ static struct workqueue_struct *ena_wq;
 MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
 
 static int ena_rss_init_default(struct ena_adapter *adapter);
+static void check_for_admin_com_state(struct ena_adapter *adapter);
+static void ena_destroy_device(struct ena_adapter *adapter);
+static int ena_restore_device(struct ena_adapter *adapter);
 
 static void ena_tx_timeout(struct net_device *dev)
 {
@@ -1884,6 +1887,17 @@ static int ena_close(struct net_device *netdev)
if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
ena_down(adapter);
 
+   /* Check for device status and issue reset if needed*/
+   check_for_admin_com_state(adapter);
+   if (unlikely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
+   netif_err(adapter, ifdown, adapter->netdev,
+ "Destroy failure, restarting device\n");
+   ena_dump_stats_to_dmesg(adapter);
+   /* rtnl lock already obtained in dev_ioctl() layer */
+   ena_destroy_device(adapter);
+   ena_restore_device(adapter);
+   }
+
return 0;
 }
 
@@ -2544,11 +2558,12 @@ static void ena_destroy_device(struct ena_adapter 
*adapter)
 
ena_com_set_admin_running_state(ena_dev, false);
 
-   ena_close(netdev);
+   if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+   ena_down(adapter);
 
/* Before releasing the ENA resources, a device reset is required.
 * (to prevent the device from accessing them).
-* In case the reset flag is set and the device is up, ena_close
+* In case the reset flag is set and the device is up, ena_down()
 * already perform the reset, so it can be skipped.
 */
if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
-- 
2.7.3.AMZN



[PATCH net V2 1/2] net: ena: unmask MSI-X only after device initialization is completed

2018-01-02 Thread netanel
From: Netanel Belgazal 

Under certain conditions MSI-X interrupt might arrive right after it
was unmasked in ena_up(). There is a chance it would be processed by
the driver before device ENA_FLAG_DEV_UP flag is set. In such a case
the interrupt is ignored.
ENA device operates in auto-masked mode, therefore ignoring
interrupt leaves it masked for good.
Moving unmask of interrupt to be the last step in ena_up().

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 97c5a89a9cf7..6fb28fd43eb3 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1565,7 +1565,7 @@ static int ena_rss_configure(struct ena_adapter *adapter)
 
 static int ena_up_complete(struct ena_adapter *adapter)
 {
-   int rc, i;
+   int rc;
 
rc = ena_rss_configure(adapter);
if (rc)
@@ -1584,17 +1584,6 @@ static int ena_up_complete(struct ena_adapter *adapter)
 
ena_napi_enable_all(adapter);
 
-   /* Enable completion queues interrupt */
-   for (i = 0; i < adapter->num_queues; i++)
-   ena_unmask_interrupt(&adapter->tx_ring[i],
-&adapter->rx_ring[i]);
-
-   /* schedule napi in case we had pending packets
-* from the last time we disable napi
-*/
-   for (i = 0; i < adapter->num_queues; i++)
-   napi_schedule(&adapter->ena_napi[i].napi);
-
return 0;
 }
 
@@ -1731,7 +1720,7 @@ static int ena_create_all_io_rx_queues(struct ena_adapter 
*adapter)
 
 static int ena_up(struct ena_adapter *adapter)
 {
-   int rc;
+   int rc, i;
 
netdev_dbg(adapter->netdev, "%s\n", __func__);
 
@@ -1774,6 +1763,17 @@ static int ena_up(struct ena_adapter *adapter)
 
set_bit(ENA_FLAG_DEV_UP, &adapter->flags);
 
+   /* Enable completion queues interrupt */
+   for (i = 0; i < adapter->num_queues; i++)
+   ena_unmask_interrupt(&adapter->tx_ring[i],
+&adapter->rx_ring[i]);
+
+   /* schedule napi in case we had pending packets
+* from the last time we disable napi
+*/
+   for (i = 0; i < adapter->num_queues; i++)
+   napi_schedule(&adapter->ena_napi[i].napi);
+
return rc;
 
 err_up:
-- 
2.7.3.AMZN



[PATCH net V2 0/2] bug fixes for ENA Ethernet driver

2018-01-02 Thread netanel
From: Netanel Belgazal 

Changes from V1:
Revome incorrect "ena: invoke netif_carrier_off() only after netdev 
  registered" patch

This patchset contains 2 bug fixes:
* handle rare race condition during MSI-X initialization
* fix error processing in ena_down()

Netanel Belgazal (2):
  net: ena: unmask MSI-X only after device initialization is completed
  net: ena: fix error handling in ena_down() sequence

 drivers/net/ethernet/amazon/ena/ena_netdev.c | 45 ++--
 1 file changed, 30 insertions(+), 15 deletions(-)

-- 
2.7.3.AMZN



Re: [PATCH net 3/3] eet: ena: invoke netif_carrier_off() only after netdev registered

2018-01-02 Thread Belgazal, Netanel
Right.
I’ll remove this patch.

On 1/2/18, 9:08 PM, "David Miller"  wrote:

From: 
Date: Thu, 28 Dec 2017 21:30:20 +

    > From: Netanel Belgazal 
> 
> netif_carrier_off() should be called only after register netdev.
> Move the function's call after the registration.
    > 
> Signed-off-by: Netanel Belgazal 
> ---
>  drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> index fbe21a817bd8..ee50c56765a4 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> @@ -3276,14 +3276,14 @@ static int ena_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
>  
>   memcpy(adapter->netdev->perm_addr, adapter->mac_addr, netdev->addr_len);
>  
> - netif_carrier_off(netdev);
> -
>   rc = register_netdev(netdev);
>   if (rc) {
>   dev_err(&pdev->dev, "Cannot register net device\n");
>   goto err_rss;
>   }
>  
> + netif_carrier_off(netdev);
> +

You cannot invoke this after register_netdev(), asynchronous activity can 
cause this
call to lose information and lose a link up event.





Re: [PATCH net 3/3] eet: ena: invoke netif_carrier_off() only after netdev registered

2017-12-29 Thread Belgazal, Netanel
Yes, I mean in my driver.
netif_carrier_off() have no effect when netdev is uninitialized.
So I must call it after register_netdev().

On 12/29/17, 9:46 AM, "Jakub Kicinski"  wrote:

By "should" you mean in your driver, right?  I think calling
netif_carrier_off() on an unregistered netdev is a pretty standard
thing to do for drivers which manage carrier state.



[PATCH net-next 1/2] update ENA driver to version 1.5.0

2017-12-28 Thread netanel
From: Netanel Belgazal 

This patchset contains two changes:
* Add a robust mechanism for detection of stuck Rx/Tx rings due to
  missed or misrouted MSI-X
* Increase the driver version to 1.5.0

Netanel Belgazal (2):
  net: ena: add detection and recovery mechanism for handling
missed/misrouted MSI-X
  net: ena: increase ena driver version to 1.5.0

 drivers/net/ethernet/amazon/ena/ena_eth_com.c   | 12 +
 drivers/net/ethernet/amazon/ena/ena_eth_com.h   |  2 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c| 68 ++---
 drivers/net/ethernet/amazon/ena/ena_netdev.h|  6 ++-
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h |  2 +
 5 files changed, 82 insertions(+), 8 deletions(-)

-- 
2.7.3.AMZN



[PATCH net-next 2/2] net: ena: increase ena driver version to 1.5.0

2017-12-28 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 734ff2e84494..f1972b5ab650 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -44,7 +44,7 @@
 #include "ena_eth_com.h"
 
 #define DRV_MODULE_VER_MAJOR   1
-#define DRV_MODULE_VER_MINOR   3
+#define DRV_MODULE_VER_MINOR   5
 #define DRV_MODULE_VER_SUBMINOR 0
 
 #define DRV_MODULE_NAME"ena"
-- 
2.7.3.AMZN



[PATCH net-next 1/2] net: ena: add detection and recovery mechanism for handling missed/misrouted MSI-X

2017-12-28 Thread netanel
From: Netanel Belgazal 

A mechanism for detection of stuck Rx/Tx rings due to missed or
misrouted interrupts.
Check if there are unhandled completion descriptors before the first
MSI-X interrupt arrived.
The check is per queue and per interrupt vector.
Once such condition is detected, driver and device reset is scheduled.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_eth_com.c   | 12 +
 drivers/net/ethernet/amazon/ena/ena_eth_com.h   |  2 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c| 68 ++---
 drivers/net/ethernet/amazon/ena/ena_netdev.h|  4 ++
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h |  2 +
 5 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
index b11e573ad57a..04ed2b57ff20 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -504,3 +504,15 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq 
*io_cq, u16 *req_id)
 
return 0;
 }
+
+bool ena_com_cq_empty(struct ena_com_io_cq *io_cq)
+{
+   struct ena_eth_io_rx_cdesc_base *cdesc;
+
+   cdesc = ena_com_get_next_rx_cdesc(io_cq);
+   if (cdesc)
+   return false;
+   else
+   return true;
+}
+
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
index bb53c3a4f8e9..2f7657227cfe 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -88,6 +88,8 @@ int ena_com_add_single_rx_desc(struct ena_com_io_sq *io_sq,
 
 int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id);
 
+bool ena_com_cq_empty(struct ena_com_io_cq *io_cq);
+
 static inline void ena_com_unmask_intr(struct ena_com_io_cq *io_cq,
   struct ena_eth_io_intr_reg *intr_reg)
 {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 97c5a89a9cf7..a6f283232cb7 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -158,6 +158,8 @@ static void ena_init_io_rings_common(struct ena_adapter 
*adapter,
ring->per_napi_packets = 0;
ring->per_napi_bytes = 0;
ring->cpu = 0;
+   ring->first_interrupt = false;
+   ring->no_interrupt_event_cnt = 0;
u64_stats_init(&ring->syncp);
 }
 
@@ -1274,6 +1276,9 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
 {
struct ena_napi *ena_napi = data;
 
+   ena_napi->tx_ring->first_interrupt = true;
+   ena_napi->rx_ring->first_interrupt = true;
+
napi_schedule_irqoff(&ena_napi->napi);
 
return IRQ_HANDLED;
@@ -2648,8 +2653,32 @@ static void ena_fw_reset_device(struct work_struct *work)
rtnl_unlock();
 }
 
-static int check_missing_comp_in_queue(struct ena_adapter *adapter,
-  struct ena_ring *tx_ring)
+static int check_for_rx_interrupt_queue(struct ena_adapter *adapter,
+   struct ena_ring *rx_ring)
+{
+   if (likely(rx_ring->first_interrupt))
+   return 0;
+
+   if (ena_com_cq_empty(rx_ring->ena_com_io_cq))
+   return 0;
+
+   rx_ring->no_interrupt_event_cnt++;
+
+   if (rx_ring->no_interrupt_event_cnt == ENA_MAX_NO_INTERRUPT_ITERATIONS) 
{
+   netif_err(adapter, rx_err, adapter->netdev,
+ "Potential MSIX issue on Rx side Queue = %d. Reset 
the device\n",
+ rx_ring->qid);
+   adapter->reset_reason = ENA_REGS_RESET_MISS_INTERRUPT;
+   smp_mb__before_atomic();
+   set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static int check_missing_comp_in_tx_queue(struct ena_adapter *adapter,
+ struct ena_ring *tx_ring)
 {
struct ena_tx_buffer *tx_buf;
unsigned long last_jiffies;
@@ -2659,8 +2688,27 @@ static int check_missing_comp_in_queue(struct 
ena_adapter *adapter,
for (i = 0; i < tx_ring->ring_size; i++) {
tx_buf = &tx_ring->tx_buffer_info[i];
last_jiffies = tx_buf->last_jiffies;
-   if (unlikely(last_jiffies &&
-time_is_before_jiffies(last_jiffies + 
adapter->missing_tx_completion_to))) {
+
+   if (last_jiffies == 0)
+   /* no pending Tx at this location */
+   continue;
+
+   if (unlikely(!tx_ring->first_interrupt && 
time_is_before_jiffies(last_jiffies +
+2 * adapter->missing_tx_completion_to))) {
+  

[PATCH net 3/3] eet: ena: invoke netif_carrier_off() only after netdev registered

2017-12-28 Thread netanel
From: Netanel Belgazal 

netif_carrier_off() should be called only after register netdev.
Move the function's call after the registration.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index fbe21a817bd8..ee50c56765a4 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3276,14 +3276,14 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
memcpy(adapter->netdev->perm_addr, adapter->mac_addr, netdev->addr_len);
 
-   netif_carrier_off(netdev);
-
rc = register_netdev(netdev);
if (rc) {
dev_err(&pdev->dev, "Cannot register net device\n");
goto err_rss;
}
 
+   netif_carrier_off(netdev);
+
INIT_WORK(&adapter->reset_task, ena_fw_reset_device);
 
adapter->last_keep_alive_jiffies = jiffies;
-- 
2.7.3.AMZN



[PATCH net 2/3] net: ena: fix error handling in ena_down() sequence

2017-12-28 Thread netanel
From: Netanel Belgazal 

ENA admin command queue errors are not handled as part of ena_down().
As a result, in case of error admin queue transitions to non-running
state and aborts all subsequent commands including those coming from
ena_up(). Reset scheduled by the driver from the timer service
context would not proceed due to sharing rtnl with ena_up()/ena_down()

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 6fb28fd43eb3..fbe21a817bd8 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -75,6 +75,9 @@ static struct workqueue_struct *ena_wq;
 MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
 
 static int ena_rss_init_default(struct ena_adapter *adapter);
+static void check_for_admin_com_state(struct ena_adapter *adapter);
+static void ena_destroy_device(struct ena_adapter *adapter);
+static int ena_restore_device(struct ena_adapter *adapter);
 
 static void ena_tx_timeout(struct net_device *dev)
 {
@@ -1884,6 +1887,17 @@ static int ena_close(struct net_device *netdev)
if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
ena_down(adapter);
 
+   /* Check for device status and issue reset if needed*/
+   check_for_admin_com_state(adapter);
+   if (unlikely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
+   netif_err(adapter, ifdown, adapter->netdev,
+ "Destroy failure, restarting device\n");
+   ena_dump_stats_to_dmesg(adapter);
+   /* rtnl lock already obtained in dev_ioctl() layer */
+   ena_destroy_device(adapter);
+   ena_restore_device(adapter);
+   }
+
return 0;
 }
 
@@ -2544,11 +2558,12 @@ static void ena_destroy_device(struct ena_adapter 
*adapter)
 
ena_com_set_admin_running_state(ena_dev, false);
 
-   ena_close(netdev);
+   if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+   ena_down(adapter);
 
/* Before releasing the ENA resources, a device reset is required.
 * (to prevent the device from accessing them).
-* In case the reset flag is set and the device is up, ena_close
+* In case the reset flag is set and the device is up, ena_down()
 * already perform the reset, so it can be skipped.
 */
if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
-- 
2.7.3.AMZN



[PATCH net 1/3] net: ena: unmask MSI-X only after device initialization is completed

2017-12-28 Thread netanel
From: Netanel Belgazal 

Under certain conditions MSI-X interrupt might arrive right after it
was unmasked in ena_up(). There is a chance it would be processed by
the driver before device ENA_FLAG_DEV_UP flag is set. In such a case
the interrupt is ignored.
ENA device operates in auto-masked mode, therefore ignoring
interrupt leaves it masked for good.
Moving unmask of interrupt to be the last step in ena_up().

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 97c5a89a9cf7..6fb28fd43eb3 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1565,7 +1565,7 @@ static int ena_rss_configure(struct ena_adapter *adapter)
 
 static int ena_up_complete(struct ena_adapter *adapter)
 {
-   int rc, i;
+   int rc;
 
rc = ena_rss_configure(adapter);
if (rc)
@@ -1584,17 +1584,6 @@ static int ena_up_complete(struct ena_adapter *adapter)
 
ena_napi_enable_all(adapter);
 
-   /* Enable completion queues interrupt */
-   for (i = 0; i < adapter->num_queues; i++)
-   ena_unmask_interrupt(&adapter->tx_ring[i],
-&adapter->rx_ring[i]);
-
-   /* schedule napi in case we had pending packets
-* from the last time we disable napi
-*/
-   for (i = 0; i < adapter->num_queues; i++)
-   napi_schedule(&adapter->ena_napi[i].napi);
-
return 0;
 }
 
@@ -1731,7 +1720,7 @@ static int ena_create_all_io_rx_queues(struct ena_adapter 
*adapter)
 
 static int ena_up(struct ena_adapter *adapter)
 {
-   int rc;
+   int rc, i;
 
netdev_dbg(adapter->netdev, "%s\n", __func__);
 
@@ -1774,6 +1763,17 @@ static int ena_up(struct ena_adapter *adapter)
 
set_bit(ENA_FLAG_DEV_UP, &adapter->flags);
 
+   /* Enable completion queues interrupt */
+   for (i = 0; i < adapter->num_queues; i++)
+   ena_unmask_interrupt(&adapter->tx_ring[i],
+&adapter->rx_ring[i]);
+
+   /* schedule napi in case we had pending packets
+* from the last time we disable napi
+*/
+   for (i = 0; i < adapter->num_queues; i++)
+   napi_schedule(&adapter->ena_napi[i].napi);
+
return rc;
 
 err_up:
-- 
2.7.3.AMZN



[PATCH net 0/3] bug fixes for ENA Ethernet driver

2017-12-28 Thread netanel
From: Netanel Belgazal 



This patchset contains 3 bug fixes:
* handle rare race condition during MSI-X initialization
* fix error processing in ena_down()
* call netif_carrier_off() only after netdev is registered

Netanel Belgazal (3):
  net: ena: unmask MSI-X only after device initialization is completed
  net: ena: fix error handling in ena_down() sequence
  eet: ena: invoke netif_carrier_off() only after netdev registered

 drivers/net/ethernet/amazon/ena/ena_netdev.c | 49 ++--
 1 file changed, 32 insertions(+), 17 deletions(-)

-- 
2.7.3.AMZN



[PATCH net] net: ena: fix race condition between device reset and link up setup

2017-11-19 Thread netanel
From: Netanel Belgazal 

In rare cases, ena driver would reset and re-start the device,
for example, in case of misbehaving application that causes
transmit timeout

The first step in the reset procedure is to stop the Tx traffic by
calling ena_carrier_off().

After the driver have just started the device reset procedure, device
happens to send an asynchronous notification (via AENQ) to the driver
than there was a link change (to link-up state).
This link change is mapped to a call to netif_carrier_on() which
re-activates the Tx queues, violating the assumption of no tx traffic
until device reset is completed, as the reset task might still be in
the process of queues initialization, leading to an access to
uninitialized memory.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 11 +--
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  3 ++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 5417e4da64ca..988d0383b4e7 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2579,6 +2579,7 @@ static int ena_restore_device(struct ena_adapter *adapter)
bool wd_state;
int rc;
 
+   set_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state);
if (rc) {
dev_err(&pdev->dev, "Can not initialize device\n");
@@ -2592,6 +2593,11 @@ static int ena_restore_device(struct ena_adapter 
*adapter)
goto err_device_destroy;
}
 
+   clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
+   /* Make sure we don't have a race with AENQ Links state handler */
+   if (test_bit(ENA_FLAG_LINK_UP, &adapter->flags))
+   netif_carrier_on(adapter->netdev);
+
rc = ena_enable_msix_and_set_admin_interrupts(adapter,
  adapter->num_queues);
if (rc) {
@@ -2618,7 +2624,7 @@ static int ena_restore_device(struct ena_adapter *adapter)
ena_com_admin_destroy(ena_dev);
 err:
clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
-
+   clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
dev_err(&pdev->dev,
"Reset attempt failed. Can not reset the device\n");
 
@@ -3495,7 +3501,8 @@ static void ena_update_on_link_change(void *adapter_data,
if (status) {
netdev_dbg(adapter->netdev, "%s\n", __func__);
set_bit(ENA_FLAG_LINK_UP, &adapter->flags);
-   netif_carrier_on(adapter->netdev);
+   if (!test_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags))
+   netif_carrier_on(adapter->netdev);
} else {
clear_bit(ENA_FLAG_LINK_UP, &adapter->flags);
netif_carrier_off(adapter->netdev);
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index ed8bd0a579c4..3bbc003871de 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -272,7 +272,8 @@ enum ena_flags_t {
ENA_FLAG_DEV_UP,
ENA_FLAG_LINK_UP,
ENA_FLAG_MSIX_ENABLED,
-   ENA_FLAG_TRIGGER_RESET
+   ENA_FLAG_TRIGGER_RESET,
+   ENA_FLAG_ONGOING_RESET
 };
 
 /* adapter specific private data structure */
-- 
2.7.3.AMZN



[PATCH net] net: ena: fix race condition between device reset and link up setup

2017-11-17 Thread netanel
From: Netanel Belgazal 

In rare cases, ena driver would reset and re-start the device,
for example, in case of misbehaving application that causes
transmit timeout

The first step in the reset procedure is to stop the Tx traffic by
calling ena_carrier_off().

After the driver have just started the device reset procedure, device
happens to send an asynchronous notification (via AENQ) to the driver
than there was a link change (to link-up state).
This link change is mapped to a call to netif_carrier_on() which
re-activates the Tx queues, violating the assumption of no tx traffic
until device reset is completed, as the reset task might still be in
the process of queues initialization, leading to an access to
uninitialized memory.
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 11 +--
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  3 ++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 5417e4da64ca..988d0383b4e7 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2579,6 +2579,7 @@ static int ena_restore_device(struct ena_adapter *adapter)
bool wd_state;
int rc;
 
+   set_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state);
if (rc) {
dev_err(&pdev->dev, "Can not initialize device\n");
@@ -2592,6 +2593,11 @@ static int ena_restore_device(struct ena_adapter 
*adapter)
goto err_device_destroy;
}
 
+   clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
+   /* Make sure we don't have a race with AENQ Links state handler */
+   if (test_bit(ENA_FLAG_LINK_UP, &adapter->flags))
+   netif_carrier_on(adapter->netdev);
+
rc = ena_enable_msix_and_set_admin_interrupts(adapter,
  adapter->num_queues);
if (rc) {
@@ -2618,7 +2624,7 @@ static int ena_restore_device(struct ena_adapter *adapter)
ena_com_admin_destroy(ena_dev);
 err:
clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
-
+   clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
dev_err(&pdev->dev,
"Reset attempt failed. Can not reset the device\n");
 
@@ -3495,7 +3501,8 @@ static void ena_update_on_link_change(void *adapter_data,
if (status) {
netdev_dbg(adapter->netdev, "%s\n", __func__);
set_bit(ENA_FLAG_LINK_UP, &adapter->flags);
-   netif_carrier_on(adapter->netdev);
+   if (!test_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags))
+   netif_carrier_on(adapter->netdev);
} else {
clear_bit(ENA_FLAG_LINK_UP, &adapter->flags);
netif_carrier_off(adapter->netdev);
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index ed8bd0a579c4..3bbc003871de 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -272,7 +272,8 @@ enum ena_flags_t {
ENA_FLAG_DEV_UP,
ENA_FLAG_LINK_UP,
ENA_FLAG_MSIX_ENABLED,
-   ENA_FLAG_TRIGGER_RESET
+   ENA_FLAG_TRIGGER_RESET,
+   ENA_FLAG_ONGOING_RESET
 };
 
 /* adapter specific private data structure */
-- 
2.7.3.AMZN



[PATCH net-next 4/6] net: ena: add statistics for missed tx packets

2017-10-17 Thread netanel
From: Netanel Belgazal 

Add a new statistic to ethtool stats that show the number of packets
without transmit acknowledgement from ENA device.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 30 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  1 +
 3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 2aa1fd0e15ec..060cb18fa659 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -81,6 +81,7 @@ struct ena_stats {
ENA_STAT_TX_ENTRY(doorbells),
ENA_STAT_TX_ENTRY(prepare_ctx_err),
ENA_STAT_TX_ENTRY(bad_req_id),
+   ENA_STAT_TX_ENTRY(missed_tx),
 };
 
 static const struct ena_stats ena_stats_rx_strings[] = {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0aa56707d7cc..5417e4da64ca 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2648,7 +2648,7 @@ static int check_missing_comp_in_queue(struct ena_adapter 
*adapter,
struct ena_tx_buffer *tx_buf;
unsigned long last_jiffies;
u32 missed_tx = 0;
-   int i;
+   int i, rc = 0;
 
for (i = 0; i < tx_ring->ring_size; i++) {
tx_buf = &tx_ring->tx_buffer_info[i];
@@ -2662,21 +2662,25 @@ static int check_missing_comp_in_queue(struct 
ena_adapter *adapter,
 
tx_buf->print_once = 1;
missed_tx++;
-
-   if (unlikely(missed_tx > 
adapter->missing_tx_completion_threshold)) {
-   netif_err(adapter, tx_err, adapter->netdev,
- "The number of lost tx completions is 
above the threshold (%d > %d). Reset the device\n",
- missed_tx,
- 
adapter->missing_tx_completion_threshold);
-   adapter->reset_reason =
-   ENA_REGS_RESET_MISS_TX_CMPL;
-   set_bit(ENA_FLAG_TRIGGER_RESET, 
&adapter->flags);
-   return -EIO;
-   }
}
}
 
-   return 0;
+   if (unlikely(missed_tx > adapter->missing_tx_completion_threshold)) {
+   netif_err(adapter, tx_err, adapter->netdev,
+ "The number of lost tx completions is above the 
threshold (%d > %d). Reset the device\n",
+ missed_tx,
+ adapter->missing_tx_completion_threshold);
+   adapter->reset_reason =
+   ENA_REGS_RESET_MISS_TX_CMPL;
+   set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+   rc = -EIO;
+   }
+
+   u64_stats_update_begin(&tx_ring->syncp);
+   tx_ring->tx_stats.missed_tx = missed_tx;
+   u64_stats_update_end(&tx_ring->syncp);
+
+   return rc;
 }
 
 static void check_for_missing_tx_completions(struct ena_adapter *adapter)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 7b07bfbf0fe4..eafc5774dd49 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -185,6 +185,7 @@ struct ena_stats_tx {
u64 tx_poll;
u64 doorbells;
u64 bad_req_id;
+   u64 missed_tx;
 };
 
 struct ena_stats_rx {
-- 
1.8.3.1



[PATCH net-next 2/6] net: ena: remove legacy suspend suspend/resume support

2017-10-17 Thread netanel
From: Netanel Belgazal 

Remove ena_device_io_suspend/resume() methods
Those methods were intend to be used by the device to trigger
suspend/resume but eventually it was dropped.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  2 --
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 50 ---
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  4 ---
 3 files changed, 56 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 967020fb26ee..1cd8eb8e5a15 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -60,8 +60,6 @@ struct ena_stats {
 
 static const struct ena_stats ena_stats_global_strings[] = {
ENA_STAT_GLOBAL_ENTRY(tx_timeout),
-   ENA_STAT_GLOBAL_ENTRY(io_suspend),
-   ENA_STAT_GLOBAL_ENTRY(io_resume),
ENA_STAT_GLOBAL_ENTRY(wd_expired),
ENA_STAT_GLOBAL_ENTRY(interface_up),
ENA_STAT_GLOBAL_ENTRY(interface_down),
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index c6bd5e24005d..dbeff3064c0d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2361,38 +2361,6 @@ static void ena_get_stats64(struct net_device *netdev,
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 };
 
-static void ena_device_io_suspend(struct work_struct *work)
-{
-   struct ena_adapter *adapter =
-   container_of(work, struct ena_adapter, suspend_io_task);
-   struct net_device *netdev = adapter->netdev;
-
-   /* ena_napi_disable_all disables only the IO handling.
-* We are still subject to AENQ keep alive watchdog.
-*/
-   u64_stats_update_begin(&adapter->syncp);
-   adapter->dev_stats.io_suspend++;
-   u64_stats_update_begin(&adapter->syncp);
-   ena_napi_disable_all(adapter);
-   netif_tx_lock(netdev);
-   netif_device_detach(netdev);
-   netif_tx_unlock(netdev);
-}
-
-static void ena_device_io_resume(struct work_struct *work)
-{
-   struct ena_adapter *adapter =
-   container_of(work, struct ena_adapter, resume_io_task);
-   struct net_device *netdev = adapter->netdev;
-
-   u64_stats_update_begin(&adapter->syncp);
-   adapter->dev_stats.io_resume++;
-   u64_stats_update_end(&adapter->syncp);
-
-   netif_device_attach(netdev);
-   ena_napi_enable_all(adapter);
-}
-
 static int ena_device_validate_params(struct ena_adapter *adapter,
  struct ena_com_dev_get_features_ctx 
*get_feat_ctx)
 {
@@ -3276,8 +3244,6 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto err_rss;
}
 
-   INIT_WORK(&adapter->suspend_io_task, ena_device_io_suspend);
-   INIT_WORK(&adapter->resume_io_task, ena_device_io_resume);
INIT_WORK(&adapter->reset_task, ena_fw_reset_device);
 
adapter->last_keep_alive_jiffies = jiffies;
@@ -3311,8 +3277,6 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 err_worker_destroy:
ena_com_destroy_interrupt_moderation(ena_dev);
del_timer(&adapter->timer_service);
-   cancel_work_sync(&adapter->suspend_io_task);
-   cancel_work_sync(&adapter->resume_io_task);
 err_netdev_destroy:
free_netdev(netdev);
 err_device_destroy:
@@ -3382,10 +3346,6 @@ static void ena_remove(struct pci_dev *pdev)
 
cancel_work_sync(&adapter->reset_task);
 
-   cancel_work_sync(&adapter->suspend_io_task);
-
-   cancel_work_sync(&adapter->resume_io_task);
-
/* Reset the device only if the device is running. */
if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
ena_com_dev_reset(ena_dev, adapter->reset_reason);
@@ -3504,16 +3464,6 @@ static void ena_notification(void *adapter_data,
 ENA_ADMIN_NOTIFICATION);
 
switch (aenq_e->aenq_common_desc.syndrom) {
-   case ENA_ADMIN_SUSPEND:
-   /* Suspend just the IO queues.
-* We deliberately don't suspend admin so the timer and
-* the keep_alive events should remain.
-*/
-   queue_work(ena_wq, &adapter->suspend_io_task);
-   break;
-   case ENA_ADMIN_RESUME:
-   queue_work(ena_wq, &adapter->resume_io_task);
-   break;
case ENA_ADMIN_UPDATE_HINTS:
hints = (struct ena_admin_ena_hw_hints *)
(&aenq_e->inline_data_w4);
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 29bb5704260b..fb0c98bb9290 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/ne

[PATCH net-next 1/6] net: ena: improve ENA driver boot time.

2017-10-17 Thread netanel
From: Netanel Belgazal 

The ena admin commands timeout is in resolutions of 100ms.
Therefore, When the driver works in polling mode, it sleeps for 100ms
each time. The overall boot time of the ENA driver is ~1.5 sec.
To reduce the boot time, This change modifies the granularity of
the sleeps to 5ms.
This change improves the boot time to 220ms.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index ded29af648c9..bf2de5298005 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -63,6 +63,8 @@
 
 #define ENA_REGS_ADMIN_INTR_MASK 1
 
+#define ENA_POLL_MS5
+
 /*/
 /*/
 /*/
@@ -533,7 +535,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct 
ena_comp_ctx *comp_c
goto err;
}
 
-   msleep(100);
+   msleep(ENA_POLL_MS);
}
 
if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) {
@@ -746,6 +748,9 @@ static int wait_for_reset_state(struct ena_com_dev 
*ena_dev, u32 timeout,
 {
u32 val, i;
 
+   /* Convert timeout from resolution of 100ms to ENA_POLL_MS */
+   timeout = (timeout * 100) / ENA_POLL_MS;
+
for (i = 0; i < timeout; i++) {
val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
 
@@ -758,8 +763,7 @@ static int wait_for_reset_state(struct ena_com_dev 
*ena_dev, u32 timeout,
exp_state)
return 0;
 
-   /* The resolution of the timeout is 100ms */
-   msleep(100);
+   msleep(ENA_POLL_MS);
}
 
return -ETIME;
@@ -1253,7 +1257,7 @@ void ena_com_wait_for_abort_completion(struct ena_com_dev 
*ena_dev)
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(20);
+   msleep(ENA_POLL_MS);
spin_lock_irqsave(&admin_queue->q_lock, flags);
}
spin_unlock_irqrestore(&admin_queue->q_lock, flags);
-- 
1.8.3.1



[PATCH net-next 3/6] net: ena: add power management ops to the ENA driver

2017-10-17 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |   2 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 117 --
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |   3 +
 3 files changed, 95 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 1cd8eb8e5a15..2aa1fd0e15ec 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -60,6 +60,8 @@ struct ena_stats {
 
 static const struct ena_stats ena_stats_global_strings[] = {
ENA_STAT_GLOBAL_ENTRY(tx_timeout),
+   ENA_STAT_GLOBAL_ENTRY(suspend),
+   ENA_STAT_GLOBAL_ENTRY(resume),
ENA_STAT_GLOBAL_ENTRY(wd_expired),
ENA_STAT_GLOBAL_ENTRY(interface_up),
ENA_STAT_GLOBAL_ENTRY(interface_down),
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index dbeff3064c0d..0aa56707d7cc 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2529,38 +2529,31 @@ static int 
ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return rc;
 }
 
-static void ena_fw_reset_device(struct work_struct *work)
+static void ena_destroy_device(struct ena_adapter *adapter)
 {
-   struct ena_com_dev_get_features_ctx get_feat_ctx;
-   struct ena_adapter *adapter =
-   container_of(work, struct ena_adapter, reset_task);
struct net_device *netdev = adapter->netdev;
struct ena_com_dev *ena_dev = adapter->ena_dev;
-   struct pci_dev *pdev = adapter->pdev;
-   bool dev_up, wd_state;
-   int rc;
-
-   if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
-   dev_err(&pdev->dev,
-   "device reset schedule while reset bit is off\n");
-   return;
-   }
+   bool dev_up;
 
netif_carrier_off(netdev);
 
del_timer_sync(&adapter->timer_service);
 
-   rtnl_lock();
-
dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+   adapter->dev_up_before_reset = dev_up;
+
ena_com_set_admin_running_state(ena_dev, false);
 
-   /* After calling ena_close the tx queues and the napi
-* are disabled so no one can interfere or touch the
-* data structures
-*/
ena_close(netdev);
 
+   /* Before releasing the ENA resources, a device reset is required.
+* (to prevent the device from accessing them).
+* In case the reset flag is set and the device is up, ena_close
+* already perform the reset, so it can be skipped.
+*/
+   if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
+   ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
+
ena_free_mgmnt_irq(adapter);
 
ena_disable_msix(adapter);
@@ -2574,9 +2567,17 @@ static void ena_fw_reset_device(struct work_struct *work)
ena_com_mmio_reg_read_request_destroy(ena_dev);
 
adapter->reset_reason = ENA_REGS_RESET_NORMAL;
+
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+}
 
-   /* Finish with the destroy part. Start the init part */
+static int ena_restore_device(struct ena_adapter *adapter)
+{
+   struct ena_com_dev_get_features_ctx get_feat_ctx;
+   struct ena_com_dev *ena_dev = adapter->ena_dev;
+   struct pci_dev *pdev = adapter->pdev;
+   bool wd_state;
+   int rc;
 
rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state);
if (rc) {
@@ -2598,7 +2599,7 @@ static void ena_fw_reset_device(struct work_struct *work)
goto err_device_destroy;
}
/* If the interface was up before the reset bring it up */
-   if (dev_up) {
+   if (adapter->dev_up_before_reset) {
rc = ena_up(adapter);
if (rc) {
dev_err(&pdev->dev, "Failed to create I/O queues\n");
@@ -2607,24 +2608,38 @@ static void ena_fw_reset_device(struct work_struct 
*work)
}
 
mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
-
-   rtnl_unlock();
-
dev_err(&pdev->dev, "Device reset completed successfully\n");
 
-   return;
+   return rc;
 err_disable_msix:
ena_free_mgmnt_irq(adapter);
ena_disable_msix(adapter);
 err_device_destroy:
ena_com_admin_destroy(ena_dev);
 err:
-   rtnl_unlock();
-
clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
 
dev_err(&pdev->dev,
"Reset attempt failed. Can not reset the device\n");
+
+   return rc;
+}
+
+static void ena_fw_reset_device(struct work_struct *work)
+

[PATCH net-next 5/6] net: ena: add new admin define for future support of IPv6 RSS

2017-10-17 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_admin_defs.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h 
b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
index 305dc1996b4e..4532e574ebcd 100644
--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
@@ -627,6 +627,12 @@ enum ena_admin_flow_hash_proto {
 
ENA_ADMIN_RSS_NOT_IP= 7,
 
+   /* TCPv6 with extension header */
+   ENA_ADMIN_RSS_TCP6_EX   = 8,
+
+   /* IPv6 with extension header */
+   ENA_ADMIN_RSS_IP6_EX= 9,
+
ENA_ADMIN_RSS_PROTO_NUM = 16,
 };
 
-- 
1.8.3.1



[PATCH net-next 6/6] net: ena: increase ena driver version to 1.3.0

2017-10-17 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index eafc5774dd49..ed8bd0a579c4 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -44,7 +44,7 @@
 #include "ena_eth_com.h"
 
 #define DRV_MODULE_VER_MAJOR   1
-#define DRV_MODULE_VER_MINOR   2
+#define DRV_MODULE_VER_MINOR   3
 #define DRV_MODULE_VER_SUBMINOR 0
 
 #define DRV_MODULE_NAME"ena"
@@ -52,7 +52,7 @@
 #define DRV_MODULE_VERSION \
__stringify(DRV_MODULE_VER_MAJOR) "."   \
__stringify(DRV_MODULE_VER_MINOR) "."   \
-   __stringify(DRV_MODULE_VER_SUBMINOR) "k"
+   __stringify(DRV_MODULE_VER_SUBMINOR) "K"
 #endif
 
 #define DEVICE_NAME"Elastic Network Adapter (ENA)"
-- 
1.8.3.1



[PATCH net 1/3] net: ena: reduce the severity of some printouts

2017-10-17 Thread netanel
From: Netanel Belgazal 

Decrease log level of checksum errors as these messages can be
triggered remotely by bad packets.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index f7dc22f65d9f..7040b9052747 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -966,7 +966,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring,
u64_stats_update_begin(&rx_ring->syncp);
rx_ring->rx_stats.bad_csum++;
u64_stats_update_end(&rx_ring->syncp);
-   netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+   netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
  "RX IPv4 header checksum error\n");
return;
}
@@ -979,7 +979,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring,
u64_stats_update_begin(&rx_ring->syncp);
rx_ring->rx_stats.bad_csum++;
u64_stats_update_end(&rx_ring->syncp);
-   netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+   netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
  "RX L4 checksum error\n");
skb->ip_summed = CHECKSUM_NONE;
return;
-- 
1.8.3.1



[PATCH net-next 0/6] update ENA driver to releawse 1.3.0

2017-10-17 Thread netanel
From: Netanel Belgazal 

Netanel Belgazal (6):
  net: ena: improve ENA driver boot time.
  net: ena: remove legacy suspend suspend/resume support
  net: ena: add power management ops to the ENA driver
  net: ena: add statistics for missed tx packets
  net: ena: add new admin define for future support of IPv6 RSS
  net: ena: increase ena driver version to 1.3.0

 drivers/net/ethernet/amazon/ena/ena_admin_defs.h |   6 +
 drivers/net/ethernet/amazon/ena/ena_com.c|  12 +-
 drivers/net/ethernet/amazon/ena/ena_ethtool.c|   5 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 197 ---
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  12 +-
 5 files changed, 130 insertions(+), 102 deletions(-)

-- 
1.8.3.1



[PATCH net 3/3] net: ena: fix wrong max Tx/Rx queues on ethtool

2017-10-17 Thread netanel
From: Netanel Belgazal 

ethtool ena_get_channels() expose the max number of queues as the max
number of queues ENA supports (128 queues) and not the actual number
of created queues.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index b1212debc2e1..967020fb26ee 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -742,8 +742,8 @@ static void ena_get_channels(struct net_device *netdev,
 {
struct ena_adapter *adapter = netdev_priv(netdev);
 
-   channels->max_rx = ENA_MAX_NUM_IO_QUEUES;
-   channels->max_tx = ENA_MAX_NUM_IO_QUEUES;
+   channels->max_rx = adapter->num_queues;
+   channels->max_tx = adapter->num_queues;
channels->max_other = 0;
channels->max_combined = 0;
channels->rx_count = adapter->num_queues;
-- 
1.8.3.1



[PATCH net 0/3] ENA ethernet driver bug fixes

2017-10-17 Thread netanel
From: Netanel Belgazal 

Some fixes for ENA ethernet driver

Netanel Belgazal (3):
  net: ena: reduce the severity of some printouts
  net: ena: fix rare kernel crash when bar memory remap fails
  net: ena: fix wrong max Tx/Rx queues on ethtool

 drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 ++--
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 7 ---
 2 files changed, 6 insertions(+), 5 deletions(-)

-- 
1.8.3.1



[PATCH net 2/3] net: ena: fix rare kernel crash when bar memory remap fails

2017-10-17 Thread netanel
From: Netanel Belgazal 

This failure is rare and only found on testing where deliberately fail
devm_ioremap()

[  451.170464] ena :04:00.0: failed to remap regs bar
451.170549] Workqueue: pciehp-1 pciehp_power_thread
[  451.170551] task: 88085a5f2d00 task.stack: c9000756c000
[  451.170552] RIP: 0010:devm_iounmap+0x2d/0x40
[  451.170553] RSP: 0018:c9000756fac0 EFLAGS: 00010282
[  451.170554] RAX: fffe RBX:  RCX:

[  451.170555] RDX: 813a7e00 RSI: 0282 RDI:
0282
[  451.170556] RBP: c9000756fac8 R08: fffe R09:
09b7
[  451.170557] R10: 0005 R11: 09b6 R12:
880856c9d0a0
[  451.170558] R13: c9000f5c90c0 R14: 880856c9d0a0 R15:
0028
[  451.170559] FS:  () GS:88085f40()
knlGS:
[  451.170560] CS:  0010 DS:  ES:  CR0: 80050033
[  451.170561] CR2: 7f169038b000 CR3: 01c09000 CR4:
003406f0
[  451.170562] DR0:  DR1:  DR2:

[  451.170562] DR3:  DR6: fffe0ff0 DR7:
0400
[  451.170563] Call Trace:
[  451.170572]  ena_release_bars.isra.48+0x34/0x60 [ena]
[  451.170574]  ena_probe+0x144/0xd90 [ena]
[  451.170579]  ? ida_simple_get+0x98/0x100
[  451.170585]  ? kernfs_next_descendant_post+0x40/0x50
[  451.170591]  local_pci_probe+0x45/0xa0
[  451.170592]  pci_device_probe+0x157/0x180
[  451.170599]  driver_probe_device+0x2a8/0x460
[  451.170600]  __device_attach_driver+0x7e/0xe0
[  451.170602]  ? driver_allows_async_probing+0x30/0x30
[  451.170603]  bus_for_each_drv+0x68/0xb0
[  451.170605]  __device_attach+0xdd/0x160
[  451.170607]  device_attach+0x10/0x20
[  451.170610]  pci_bus_add_device+0x4f/0xa0
[  451.170611]  pci_bus_add_devices+0x39/0x70
[  451.170613]  pciehp_configure_device+0x96/0x120
[  451.170614]  pciehp_enable_slot+0x1b3/0x290
[  451.170616]  pciehp_power_thread+0x3b/0xb0
[  451.170622]  process_one_work+0x149/0x360
[  451.170623]  worker_thread+0x4d/0x3c0
[  451.170626]  kthread+0x109/0x140
[  451.170627]  ? rescuer_thread+0x380/0x380
[  451.170628]  ? kthread_park+0x60/0x60
[  451.170632]  ret_from_fork+0x25/0x30

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7040b9052747..c6bd5e24005d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3064,7 +3064,8 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, 
struct pci_dev *pdev)
if (ena_dev->mem_bar)
devm_iounmap(&pdev->dev, ena_dev->mem_bar);
 
-   devm_iounmap(&pdev->dev, ena_dev->reg_bar);
+   if (ena_dev->reg_bar)
+   devm_iounmap(&pdev->dev, ena_dev->reg_bar);
 
release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
pci_release_selected_regions(pdev, release_bars);
-- 
1.8.3.1



[PATCH net-next] MAINTAINERS: change ENA driver maintainers email domain

2017-10-17 Thread netanel
From: Netanel Belgazal 

ENA driver was developed by developers from Annapurna Labs.
Annapurna Labs was acquired by Amazon and the company's domain
(@annapurnalabs.com) will become deprecated soon.

Update the email addresses of the maintainers to the alternative amazon
emails (@amazon.com)

Signed-off-by: Netanel Belgazal 
---
 MAINTAINERS | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3944f1626911..f218fe1e43fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -700,9 +700,9 @@ F:  include/linux/altera_uart.h
 F: include/linux/altera_jtaguart.h
 
 AMAZON ETHERNET DRIVERS
-M: Netanel Belgazal 
-R: Saeed Bishara 
-R: Zorik Machulsky 
+M: Netanel Belgazal 
+R: Saeed Bishara 
+R: Zorik Machulsky 
 L: netdev@vger.kernel.org
 S: Supported
 F: Documentation/networking/ena.txt
-- 
1.8.3.1



[PATCH V2 net-next 01/11] net: ena: change return value for unsupported features unsupported return value

2017-06-23 Thread netanel
From: Netanel Belgazal 

return -EOPNOTSUPP instead of -EPERM.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 22 +++---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c | 10 +++---
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 20 ++--
 3 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index f5b237e0bd60..02752d5b5b60 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -494,7 +494,7 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
case ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE:
return -ENOMEM;
case ENA_ADMIN_UNSUPPORTED_OPCODE:
-   return -EPERM;
+   return -EOPNOTSUPP;
case ENA_ADMIN_BAD_OPCODE:
case ENA_ADMIN_MALFORMED_REQUEST:
case ENA_ADMIN_ILLEGAL_PARAMETER:
@@ -786,7 +786,7 @@ static int ena_com_get_feature_ex(struct ena_com_dev 
*ena_dev,
 
if (!ena_com_check_supported_feature_id(ena_dev, feature_id)) {
pr_debug("Feature %d isn't supported\n", feature_id);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&get_cmd, 0x0, sizeof(get_cmd));
@@ -1324,7 +1324,7 @@ int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, 
u32 groups_flag)
if ((get_resp.u.aenq.supported_groups & groups_flag) != groups_flag) {
pr_warn("Trying to set unsupported aenq events. supported flag: 
%x asked flag: %x\n",
get_resp.u.aenq.supported_groups, groups_flag);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -1909,7 +1909,7 @@ int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int 
mtu)
 
if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_MTU)) {
pr_debug("Feature %d isn't supported\n", ENA_ADMIN_MTU);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -1963,7 +1963,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
ENA_ADMIN_RSS_HASH_FUNCTION)) {
pr_debug("Feature %d isn't supported\n",
 ENA_ADMIN_RSS_HASH_FUNCTION);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
/* Validate hash function is supported */
@@ -1975,7 +1975,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func)) {
pr_err("Func hash %d isn't supported by device, abort\n",
   rss->hash_func);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -2034,7 +2034,7 @@ int ena_com_fill_hash_function(struct ena_com_dev 
*ena_dev,
 
if (!((1 << func) & get_resp.u.flow_hash_func.supported_func)) {
pr_err("Flow hash function %d isn't supported\n", func);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
switch (func) {
@@ -2127,7 +2127,7 @@ int ena_com_set_hash_ctrl(struct ena_com_dev *ena_dev)
ENA_ADMIN_RSS_HASH_INPUT)) {
pr_debug("Feature %d isn't supported\n",
 ENA_ADMIN_RSS_HASH_INPUT);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -2208,7 +2208,7 @@ int ena_com_set_default_hash_ctrl(struct ena_com_dev 
*ena_dev)
pr_err("hash control doesn't support all the desire 
configuration. proto %x supported %x selected %x\n",
   i, hash_ctrl->supported_fields[i].fields,
   hash_ctrl->selected_fields[i].fields);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
}
 
@@ -2286,7 +2286,7 @@ int ena_com_indirect_table_set(struct ena_com_dev 
*ena_dev)
ena_dev, ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG)) {
pr_debug("Feature %d isn't supported\n",
 ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
ret = ena_com_ind_tbl_convert_to_device(ena_dev);
@@ -2553,7 +2553,7 @@ int ena_com_init_interrupt_moderation(struct ena_com_dev 
*ena_dev)
 ENA_ADMIN_INTERRUPT_MODERATION);
 
if (rc) {
-   if (rc == -EPERM) {
+   if (rc == -EOP

[PATCH V2 net-next 11/11] net: ena: update ena driver to version 1.2.0

2017-06-23 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 86b0f0dbae65..29bb5704260b 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -44,15 +44,15 @@
 #include "ena_eth_com.h"
 
 #define DRV_MODULE_VER_MAJOR   1
-#define DRV_MODULE_VER_MINOR   1
-#define DRV_MODULE_VER_SUBMINOR 7
+#define DRV_MODULE_VER_MINOR   2
+#define DRV_MODULE_VER_SUBMINOR 0
 
 #define DRV_MODULE_NAME"ena"
 #ifndef DRV_MODULE_VERSION
 #define DRV_MODULE_VERSION \
__stringify(DRV_MODULE_VER_MAJOR) "."   \
__stringify(DRV_MODULE_VER_MINOR) "."   \
-   __stringify(DRV_MODULE_VER_SUBMINOR)
+   __stringify(DRV_MODULE_VER_SUBMINOR) "k"
 #endif
 
 #define DEVICE_NAME"Elastic Network Adapter (ENA)"
-- 
2.7.4



[PATCH V2 net-next 07/11] net: ena: use napi_schedule_irqoff when possible

2017-06-23 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 04aade842097..424b4d7e642f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1264,7 +1264,7 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
 {
struct ena_napi *ena_napi = data;
 
-   napi_schedule(&ena_napi->napi);
+   napi_schedule_irqoff(&ena_napi->napi);
 
return IRQ_HANDLED;
 }
-- 
2.7.4



[PATCH V2 net-next 09/11] net: ena: use lower_32_bits()/upper_32_bits() to split dma address

2017-06-23 Thread netanel
From: Netanel Belgazal 

In ena_com_mem_addr_set(), use the above functions to split dma address
to the lower 32 bits and the higher 16 bits.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index f6e1d30523a6..52beba8c7a39 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -99,8 +99,8 @@ static inline int ena_com_mem_addr_set(struct ena_com_dev 
*ena_dev,
return -EINVAL;
}
 
-   ena_addr->mem_addr_low = (u32)addr;
-   ena_addr->mem_addr_high = (u64)addr >> 32;
+   ena_addr->mem_addr_low = lower_32_bits(addr);
+   ena_addr->mem_addr_high = (u16)upper_32_bits(addr);
 
return 0;
 }
-- 
2.7.4



[PATCH V2 net-next 04/11] net: ena: add reset reason for each device FLR

2017-06-23 Thread netanel
From: Netanel Belgazal 

For each device reset, log to the device what is the cause
the reset occur.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c   |  5 +++-
 drivers/net/ethernet/amazon/ena/ena_com.h   |  4 +++-
 drivers/net/ethernet/amazon/ena/ena_netdev.c| 17 +
 drivers/net/ethernet/amazon/ena/ena_netdev.h|  2 ++
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h | 32 +
 5 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 2721c70492a1..f6e1d30523a6 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -1825,7 +1825,8 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, 
void *data)
writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
 }
 
-int ena_com_dev_reset(struct ena_com_dev *ena_dev)
+int ena_com_dev_reset(struct ena_com_dev *ena_dev,
+ enum ena_regs_reset_reason_types reset_reason)
 {
u32 stat, timeout, cap, reset_val;
int rc;
@@ -1853,6 +1854,8 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)
 
/* start reset */
reset_val = ENA_REGS_DEV_CTL_DEV_RESET_MASK;
+   reset_val |= (reset_reason << ENA_REGS_DEV_CTL_RESET_REASON_SHIFT) &
+ENA_REGS_DEV_CTL_RESET_REASON_MASK;
writel(reset_val, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);
 
/* Write again the MMIO read request address */
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h 
b/drivers/net/ethernet/amazon/ena/ena_com.h
index 630c09ad35a5..7b784f8a06a6 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -420,10 +420,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev);
 
 /* ena_com_dev_reset - Perform device FLR to the device.
  * @ena_dev: ENA communication layer struct
+ * @reset_reason: Specify what is the trigger for the reset in case of an 
error.
  *
  * @return - 0 on success, negative value on failure.
  */
-int ena_com_dev_reset(struct ena_com_dev *ena_dev);
+int ena_com_dev_reset(struct ena_com_dev *ena_dev,
+ enum ena_regs_reset_reason_types reset_reason);
 
 /* ena_com_create_io_queue - Create io queue.
  * @ena_dev: ENA communication layer struct
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 1ee06e11654c..0d35a4cc3525 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -87,6 +87,7 @@ static void ena_tx_timeout(struct net_device *dev)
if (test_and_set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
return;
 
+   adapter->reset_reason = ENA_REGS_RESET_OS_NETDEV_WD;
u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.tx_timeout++;
u64_stats_update_end(&adapter->syncp);
@@ -670,6 +671,7 @@ static int validate_tx_req_id(struct ena_ring *tx_ring, u16 
req_id)
u64_stats_update_end(&tx_ring->syncp);
 
/* Trigger device reset */
+   tx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_TX_REQ_ID;
set_bit(ENA_FLAG_TRIGGER_RESET, &tx_ring->adapter->flags);
return -EFAULT;
 }
@@ -1055,6 +1057,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, 
struct napi_struct *napi,
u64_stats_update_end(&rx_ring->syncp);
 
/* Too many desc from the device. Trigger reset */
+   adapter->reset_reason = ENA_REGS_RESET_TOO_MANY_RX_DESCS;
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
 
return 0;
@@ -1720,7 +1723,7 @@ static void ena_down(struct ena_adapter *adapter)
if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags)) {
int rc;
 
-   rc = ena_com_dev_reset(adapter->ena_dev);
+   rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
if (rc)
dev_err(&adapter->pdev->dev, "Device reset failed\n");
}
@@ -2353,7 +2356,7 @@ static int ena_device_init(struct ena_com_dev *ena_dev, 
struct pci_dev *pdev,
readless_supported = !(pdev->revision & ENA_MMIO_DISABLE_REG_READ);
ena_com_set_mmio_read_mode(ena_dev, readless_supported);
 
-   rc = ena_com_dev_reset(ena_dev);
+   rc = ena_com_dev_reset(ena_dev, ENA_REGS_RESET_NORMAL);
if (rc) {
dev_err(dev, "Can not reset device\n");
goto err_mmio_read_less;
@@ -2512,6 +2515,7 @@ static void ena_fw_reset_device(struct work_struct *work)
 
ena_com_mmio_reg_read_request_destroy(ena_dev);
 
+   adapter->reset_reason = ENA_REGS_RESET_NORMAL;
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flag

[PATCH V2 net-next 10/11] net: ena: update driver's rx drop statistics

2017-06-23 Thread netanel
From: Netanel Belgazal 

rx drop counter is reported by the device in the keep-alive
event.
update the driver's counter with the device counter.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7dee448157bb..f7dc22f65d9f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3478,8 +3478,17 @@ static void ena_keep_alive_wd(void *adapter_data,
  struct ena_admin_aenq_entry *aenq_e)
 {
struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
+   struct ena_admin_aenq_keep_alive_desc *desc;
+   u64 rx_drops;
 
+   desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e;
adapter->last_keep_alive_jiffies = jiffies;
+
+   rx_drops = ((u64)desc->rx_drops_high << 32) | desc->rx_drops_low;
+
+   u64_stats_update_begin(&adapter->syncp);
+   adapter->dev_stats.rx_drops = rx_drops;
+   u64_stats_update_end(&adapter->syncp);
 }
 
 static void ena_notification(void *adapter_data,
-- 
2.7.4



[PATCH V2 net-next 05/11] net: ena: add support for out of order rx buffers refill

2017-06-23 Thread netanel
From: Netanel Belgazal 

ENA driver post Rx buffers through the Rx submission queue
for the ENA device to fill them with receive packets.
Each Rx buffer is marked with req_id in the Rx descriptor.

Newer ENA devices could consume the posted Rx buffer in out of order,
and as result the corresponding Rx completion queue will have Rx
completion descriptors with non contiguous req_id(s)

In this change the driver holds two rings.
The first ring (called free_rx_ids) is a mapping ring.
It holds all the unused request ids.
The values in this ring are from 0 to ring_size -1.

When the driver wants to allocate a new Rx buffer it uses the head of
free_rx_ids and uses it's value as the index for rx_buffer_info ring.
The req_id is also written to the Rx descriptor

Upon Rx completion,
The driver took the req_id from the completion descriptor and uses it
as index in rx_buffer_info.
The req_id is then return to the free_rx_ids ring.

This patch also adds statistics to inform when the driver receive out
of range or unused req_id.

Note:
free_rx_ids is only accessible from the napi handler, so no locking is
required

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_eth_com.c |  5 ++
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 83 ++-
 drivers/net/ethernet/amazon/ena/ena_netdev.h  | 11 +++-
 4 files changed, 83 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
index f999305e1363..b11e573ad57a 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -493,6 +493,11 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq 
*io_cq, u16 *req_id)
if (cdesc_phase != expected_phase)
return -EAGAIN;
 
+   if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
+   pr_err("Invalid req id %d\n", cdesc->req_id);
+   return -EINVAL;
+   }
+
ena_com_cq_inc_head(io_cq);
 
*req_id = READ_ONCE(cdesc->req_id);
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index d51a67f4df02..b1212debc2e1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -93,6 +93,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
ENA_STAT_RX_ENTRY(dma_mapping_err),
ENA_STAT_RX_ENTRY(bad_desc_num),
ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+   ENA_STAT_RX_ENTRY(bad_req_id),
ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0d35a4cc3525..fcbcd188a132 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -304,6 +304,24 @@ static void ena_free_all_io_tx_resources(struct 
ena_adapter *adapter)
ena_free_tx_resources(adapter, i);
 }
 
+static inline int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id)
+{
+   if (likely(req_id < rx_ring->ring_size))
+   return 0;
+
+   netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+ "Invalid rx req_id: %hu\n", req_id);
+
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.bad_req_id++;
+   u64_stats_update_end(&rx_ring->syncp);
+
+   /* Trigger device reset */
+   rx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID;
+   set_bit(ENA_FLAG_TRIGGER_RESET, &rx_ring->adapter->flags);
+   return -EFAULT;
+}
+
 /* ena_setup_rx_resources - allocate I/O Rx resources (Descriptors)
  * @adapter: network interface device structure
  * @qid: queue index
@@ -315,7 +333,7 @@ static int ena_setup_rx_resources(struct ena_adapter 
*adapter,
 {
struct ena_ring *rx_ring = &adapter->rx_ring[qid];
struct ena_irq *ena_irq = &adapter->irq_tbl[ENA_IO_IRQ_IDX(qid)];
-   int size, node;
+   int size, node, i;
 
if (rx_ring->rx_buffer_info) {
netif_err(adapter, ifup, adapter->netdev,
@@ -336,6 +354,20 @@ static int ena_setup_rx_resources(struct ena_adapter 
*adapter,
return -ENOMEM;
}
 
+   size = sizeof(u16) * rx_ring->ring_size;
+   rx_ring->free_rx_ids = vzalloc_node(size, node);
+   if (!rx_ring->free_rx_ids) {
+   rx_ring->free_rx_ids = vzalloc(size);
+   if (!rx_ring->free_rx_ids) {
+   vfree(rx_ring->rx_buffer_info);
+   return -ENOMEM;
+   }
+   }
+
+   /* Req id ring for receiving RX pkts out of order */
+   for (i = 0; i < rx_ring->ring_size; i++)
+   rx_ring->free_rx_ids[i] = i;
+
   

[PATCH V2 net-next 03/11] net: ena: change sizeof() argument to be the type pointer

2017-06-23 Thread netanel
From: Netanel Belgazal 

Instead of using:
memset(ptr, 0x0, sizeof(struct ...))
use:
memset(ptr, 0x0, sizeor(*ptr))

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 65d53d501139..2721c70492a1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -329,7 +329,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
size_t size;
int dev_node = 0;
 
-   memset(&io_sq->desc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+   memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr));
 
io_sq->desc_entry_size =
(io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
@@ -383,7 +383,7 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev,
size_t size;
int prev_node = 0;
 
-   memset(&io_cq->cdesc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+   memset(&io_cq->cdesc_addr, 0x0, sizeof(io_cq->cdesc_addr));
 
/* Use the basic completion descriptor for Rx */
io_cq->cdesc_entry_size_in_bytes =
@@ -685,7 +685,7 @@ static int ena_com_destroy_io_sq(struct ena_com_dev 
*ena_dev,
u8 direction;
int ret;
 
-   memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+   memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));
 
if (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
direction = ENA_ADMIN_SQ_DIRECTION_TX;
@@ -967,7 +967,7 @@ static int ena_com_create_io_sq(struct ena_com_dev *ena_dev,
u8 direction;
int ret;
 
-   memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_sq_cmd));
+   memset(&create_cmd, 0x0, sizeof(create_cmd));
 
create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_SQ;
 
@@ -1159,7 +1159,7 @@ int ena_com_create_io_cq(struct ena_com_dev *ena_dev,
struct ena_admin_acq_create_cq_resp_desc cmd_completion;
int ret;
 
-   memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_cq_cmd));
+   memset(&create_cmd, 0x0, sizeof(create_cmd));
 
create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_CQ;
 
@@ -1267,7 +1267,7 @@ int ena_com_destroy_io_cq(struct ena_com_dev *ena_dev,
struct ena_admin_acq_destroy_cq_resp_desc destroy_resp;
int ret;
 
-   memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+   memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));
 
destroy_cmd.cq_idx = io_cq->idx;
destroy_cmd.aq_common_descriptor.opcode = ENA_ADMIN_DESTROY_CQ;
@@ -1623,8 +1623,8 @@ int ena_com_create_io_queue(struct ena_com_dev *ena_dev,
io_sq = &ena_dev->io_sq_queues[ctx->qid];
io_cq = &ena_dev->io_cq_queues[ctx->qid];
 
-   memset(io_sq, 0x0, sizeof(struct ena_com_io_sq));
-   memset(io_cq, 0x0, sizeof(struct ena_com_io_cq));
+   memset(io_sq, 0x0, sizeof(*io_sq));
+   memset(io_cq, 0x0, sizeof(*io_cq));
 
/* Init CQ */
io_cq->q_depth = ctx->queue_size;
-- 
2.7.4



[PATCH V2 net-next 02/11] net: ena: add hardware hints capability to the driver

2017-06-23 Thread netanel
From: Netanel Belgazal 

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 
---
 drivers/net/ethernet/amazon/ena/ena_admin_defs.h | 31 +++
 drivers/net/ethernet/amazon/ena/ena_com.c| 38 +++---
 drivers/net/ethernet/amazon/ena/ena_com.h|  6 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 66 ++--
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  5 ++
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h  |  2 +
 6 files changed, 137 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h 
b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
index 5b6509d59716..305dc1996b4e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
@@ -70,6 +70,8 @@ enum ena_admin_aq_feature_id {
 
ENA_ADMIN_MAX_QUEUES_NUM= 2,
 
+   ENA_ADMIN_HW_HINTS  = 3,
+
ENA_ADMIN_RSS_HASH_FUNCTION = 10,
 
ENA_ADMIN_STATELESS_OFFLOAD_CONFIG  = 11,
@@ -749,6 +751,31 @@ struct ena_admin_feature_rss_ind_table {
struct ena_admin_rss_ind_table_entry inline_entry;
 };
 
+/* When hint value is 0, driver should use it's own predefined value */
+struct ena_admin_ena_hw_hints {
+   /* value in ms */
+   u16 mmio_read_timeout;
+
+   /* value in ms */
+   u16 driver_watchdog_timeout;
+
+   /* Per packet tx completion timeout. value in ms */
+   u16 missing_tx_completion_timeout;
+
+   u16 missed_tx_completion_count_threshold_to_reset;
+
+   /* value in ms */
+   u16 admin_completion_tx_timeout;
+
+   u16 netdev_wd_timeout;
+
+   u16 max_tx_sgl_size;
+
+   u16 max_rx_sgl_size;
+
+   u16 reserved[8];
+};
+
 struct ena_admin_get_feat_cmd {
struct ena_admin_aq_common_desc aq_common_descriptor;
 
@@ -782,6 +809,8 @@ struct ena_admin_get_feat_resp {
struct ena_admin_feature_rss_ind_table ind_table;
 
struct ena_admin_feature_intr_moder_desc intr_moderation;
+
+   struct ena_admin_ena_hw_hints hw_hints;
} u;
 };
 
@@ -857,6 +886,8 @@ enum ena_admin_aenq_notification_syndrom {
ENA_ADMIN_SUSPEND   = 0,
 
ENA_ADMIN_RESUME= 1,
+
+   ENA_ADMIN_UPDATE_HINTS  = 2,
 };
 
 struct ena_admin_aenq_entry {
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 02752d5b5b60..65d53d501139 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -511,7 +511,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct 
ena_comp_ctx *comp_c
unsigned long flags, timeout;
int ret;
 
-   timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+   timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout);
 
while (1) {
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
int ret;
 
wait_for_completion_timeout(&comp_ctx->wait_event,
-   usecs_to_jiffies(ADMIN_CMD_TIMEOUT_US));
+   usecs_to_jiffies(
+   admin_queue->completion_timeout));
 
/* In case the command wasn't completed find out the root cause.
 * 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)
struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
mmio_read->read_resp;
-   u32 mmio_read_reg, ret;
+   u32 mmio_read_reg, ret, i;
unsigned long flags;
-   int i;
+   u32 timeout = mmio_read->reg_read_to;
 
might_sleep();
 
+   if (timeout == 0)
+   timeout = ENA_REG_READ_TIMEOUT;
+
/* If readless is disabled, perform regular read */
if (!mmio_read->readless_supported)
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)
 
writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
-   for (i = 0; i < ENA_REG_READ_TIMEOUT; i++) {
+   for (i = 0; i < timeout; i++) {
if (read_resp->req_id == mmio_read->seq_num)
break;
 
udelay(1);
}
 
-   if

[PATCH V2 net-next 08/11] net: ena: separate skb allocation to dedicated function

2017-06-23 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 44 +---
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 424b4d7e642f..7dee448157bb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -825,6 +825,28 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 
budget)
return tx_pkts;
 }
 
+static struct sk_buff *ena_alloc_skb(struct ena_ring *rx_ring, bool frags)
+{
+   struct sk_buff *skb;
+
+   if (frags)
+   skb = napi_get_frags(rx_ring->napi);
+   else
+   skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
+   rx_ring->rx_copybreak);
+
+   if (unlikely(!skb)) {
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.skb_alloc_fail++;
+   u64_stats_update_end(&rx_ring->syncp);
+   netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
+ "Failed to allocate skb. frags: %d\n", frags);
+   return NULL;
+   }
+
+   return skb;
+}
+
 static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
  struct ena_com_rx_buf_info *ena_bufs,
  u32 descs,
@@ -854,16 +876,9 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
prefetch(va + NET_IP_ALIGN);
 
if (len <= rx_ring->rx_copybreak) {
-   skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-   rx_ring->rx_copybreak);
-   if (unlikely(!skb)) {
-   u64_stats_update_begin(&rx_ring->syncp);
-   rx_ring->rx_stats.skb_alloc_fail++;
-   u64_stats_update_end(&rx_ring->syncp);
-   netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
- "Failed to allocate skb\n");
+   skb = ena_alloc_skb(rx_ring, false);
+   if (unlikely(!skb))
return NULL;
-   }
 
netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
  "rx allocated small packet. len %d. data_len %d\n",
@@ -882,20 +897,15 @@ static struct sk_buff *ena_rx_skb(struct ena_ring 
*rx_ring,
 
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+   rx_ring->free_rx_ids[*next_to_clean] = req_id;
*next_to_clean = ENA_RX_RING_IDX_ADD(*next_to_clean, descs,
 rx_ring->ring_size);
return skb;
}
 
-   skb = napi_get_frags(rx_ring->napi);
-   if (unlikely(!skb)) {
-   netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
- "Failed allocating skb\n");
-   u64_stats_update_begin(&rx_ring->syncp);
-   rx_ring->rx_stats.skb_alloc_fail++;
-   u64_stats_update_end(&rx_ring->syncp);
+   skb = ena_alloc_skb(rx_ring, true);
+   if (unlikely(!skb))
return NULL;
-   }
 
do {
dma_unmap_page(rx_ring->dev,
-- 
2.7.4



[PATCH V2 net-next 06/11] net: ena: allow the driver to work with small number of msix vectors

2017-06-23 Thread netanel
From: Netanel Belgazal 

Current driver tries to allocate msix vectors as the number of the
negotiated io queues. (with another msix vector for management).
If pci_alloc_irq_vectors() fails, the driver aborts the probe
and the ENA network device is never brought up.

With this patch, the driver's logic will reduce the number of IO
queues to the number of allocated msix vectors (minus one for management)
instead of failing probe().

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 65 
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  6 ++-
 2 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index fcbcd188a132..04aade842097 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1269,9 +1269,20 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
return IRQ_HANDLED;
 }
 
+/* Reserve a single MSI-X vector for management (admin + aenq).
+ * plus reserve one vector for each potential io queue.
+ * the number of potential io queues is the minimum of what the device
+ * supports and the number of vCPUs.
+ */
 static int ena_enable_msix(struct ena_adapter *adapter, int num_queues)
 {
-   int msix_vecs, rc;
+   int msix_vecs, irq_cnt;
+
+   if (test_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags)) {
+   netif_err(adapter, probe, adapter->netdev,
+ "Error, MSI-X is already enabled\n");
+   return -EPERM;
+   }
 
/* Reserved the max msix vectors we might need */
msix_vecs = ENA_MAX_MSIX_VEC(num_queues);
@@ -1279,25 +1290,28 @@ static int ena_enable_msix(struct ena_adapter *adapter, 
int num_queues)
netif_dbg(adapter, probe, adapter->netdev,
  "trying to enable MSI-X, vectors %d\n", msix_vecs);
 
-   rc = pci_alloc_irq_vectors(adapter->pdev, msix_vecs, msix_vecs,
-   PCI_IRQ_MSIX);
-   if (rc < 0) {
+   irq_cnt = pci_alloc_irq_vectors(adapter->pdev, ENA_MIN_MSIX_VEC,
+   msix_vecs, PCI_IRQ_MSIX);
+
+   if (irq_cnt < 0) {
netif_err(adapter, probe, adapter->netdev,
- "Failed to enable MSI-X, vectors %d rc %d\n",
- msix_vecs, rc);
+ "Failed to enable MSI-X. irq_cnt %d\n", irq_cnt);
return -ENOSPC;
}
 
-   netif_dbg(adapter, probe, adapter->netdev, "enable MSI-X, vectors %d\n",
- msix_vecs);
-
-   if (msix_vecs >= 1) {
-   if (ena_init_rx_cpu_rmap(adapter))
-   netif_warn(adapter, probe, adapter->netdev,
-  "Failed to map IRQs to CPUs\n");
+   if (irq_cnt != msix_vecs) {
+   netif_notice(adapter, probe, adapter->netdev,
+"enable only %d MSI-X (out of %d), reduce the 
number of queues\n",
+irq_cnt, msix_vecs);
+   adapter->num_queues = irq_cnt - ENA_ADMIN_MSIX_VEC;
}
 
-   adapter->msix_vecs = msix_vecs;
+   if (ena_init_rx_cpu_rmap(adapter))
+   netif_warn(adapter, probe, adapter->netdev,
+  "Failed to map IRQs to CPUs\n");
+
+   adapter->msix_vecs = irq_cnt;
+   set_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags);
 
return 0;
 }
@@ -1374,6 +1388,12 @@ static int ena_request_io_irq(struct ena_adapter 
*adapter)
struct ena_irq *irq;
int rc = 0, i, k;
 
+   if (!test_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags)) {
+   netif_err(adapter, ifup, adapter->netdev,
+ "Failed to request I/O IRQ: MSI-X is not enabled\n");
+   return -EINVAL;
+   }
+
for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) {
irq = &adapter->irq_tbl[i];
rc = request_irq(irq->vector, irq->handler, flags, irq->name,
@@ -1432,6 +1452,12 @@ static void ena_free_io_irq(struct ena_adapter *adapter)
}
 }
 
+static void ena_disable_msix(struct ena_adapter *adapter)
+{
+   if (test_and_clear_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags))
+   pci_free_irq_vectors(adapter->pdev);
+}
+
 static void ena_disable_io_intr_sync(struct ena_adapter *adapter)
 {
int i;
@@ -2520,7 +2546,8 @@ static int 
ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return 0;
 
 err_disable_msix:
-   pci_free_irq_vectors(adapter->pdev);
+   ena_disable_msix(adapter);
+
return rc;
 }
 
@@ -2558,7 +2585,7 @@ static void ena_fw_reset_device(struct work_struc

[PATCH V2 net-next 00/11] update ena ethernet driver to version 1.2.0

2017-06-23 Thread netanel
From: Netanel Belgazal 

This patchset contains some new features/improvements that were added
to the ENA driver to increase its robustness and are based on
experience of wide ENA deployment.

Change log:

V2:
* Remove patch that add inline to C-file static function (contradict coding 
style).
* Remove patch that moves MTU parameter validation in ena_change_mtu() instead 
of
using the network stack.
* Use upper_32_bits()/lower_32_bits() instead of casting.

Netanel Belgazal (11):
  net: ena: change return value for unsupported features unsupported
return value
  net: ena: add hardware hints capability to the driver
  net: ena: change sizeof() argument to be the type pointer
  net: ena: add reset reason for each device FLR
  net: ena: add support for out of order rx buffers refill
  net: ena: allow the driver to work with small number of msix vectors
  net: ena: use napi_schedule_irqoff when possible
  net: ena: separate skb allocation to dedicated function
  net: ena: use lower_32_bits()/upper_32_bits() to split dma address
  net: ena: update driver's rx drop statistics
  net: ena: update ena driver to version 1.2.0

 drivers/net/ethernet/amazon/ena/ena_admin_defs.h |  31 +++
 drivers/net/ethernet/amazon/ena/ena_com.c|  85 ---
 drivers/net/ethernet/amazon/ena/ena_com.h|  10 +-
 drivers/net/ethernet/amazon/ena/ena_eth_com.c|   5 +
 drivers/net/ethernet/amazon/ena/ena_ethtool.c|  11 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 306 +--
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  30 ++-
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h  |  34 +++
 8 files changed, 399 insertions(+), 113 deletions(-)

-- 
2.7.4



Re: [PATCH net-next 12/13] net: ena: change validate_tx_req_id() to be inline function

2017-06-19 Thread Belgazal, Netanel
The optimization purpose I mention was to inform the compiler to inline this 
function as there is only one caller to this function.
After reading the coding style you refer to I'll discard this patch.

As a side note, I checked the disassembly code and I can see that gcc inline 
the function even without the explicit hint.

Regards,
Netanel

From: Leon Romanovsky 
Sent: Monday, June 19, 2017 7:56 AM
To: Belgazal, Netanel
Cc: da...@davemloft.net; netdev@vger.kernel.org; Woodhouse, David; Machulsky, 
Zorik; Matushevsky, Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; 
Bshara, Nafea; Schmeilin, Evgeny
Subject: Re: [PATCH net-next 12/13] net: ena: change validate_tx_req_id() to be 
inline function

On Sun, Jun 18, 2017 at 02:28:17PM +0300, neta...@amazon.com wrote:
> From: Netanel Belgazal 
>
> for optimization purpose, change validate_tx_req_id() to be
> inline function.
>
> Signed-off-by: Netanel Belgazal 
> ---
>  drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
> b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> index 4540cd3d9f5f..da14b78cc87c 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> @@ -698,7 +698,7 @@ static void ena_destroy_all_io_queues(struct ena_adapter 
> *adapter)
>   ena_destroy_all_rx_queues(adapter);
>  }
>
> -static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
> +static inline int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)

inline in C-file?

Please read Documentation/process/coding-style.rst,
15) The inline disease" section why it is wrong and if you anyway
insists on doing it, please provide support of your claim "optimization
purposes" and show what and how exactly your optimization happened.

Thanks


>  {
>   struct ena_tx_buffer *tx_info = NULL;
>
> --
> 2.7.4
>


Re: [PATCH net-next 09/13] net: ena: adding missing cast in ena_com_mem_addr_set()

2017-06-19 Thread Belgazal, Netanel
Ack,

Will use the proposed functions.

From: Leon Romanovsky 
Sent: Monday, June 19, 2017 8:00 AM
To: Belgazal, Netanel
Cc: da...@davemloft.net; netdev@vger.kernel.org; Woodhouse, David; Machulsky, 
Zorik; Matushevsky, Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; 
Bshara, Nafea; Schmeilin, Evgeny
Subject: Re: [PATCH net-next 09/13] net: ena: adding missing cast in 
ena_com_mem_addr_set()

On Sun, Jun 18, 2017 at 02:28:14PM +0300, neta...@amazon.com wrote:
> From: Netanel Belgazal 
>
> Signed-off-by: Netanel Belgazal 
> ---
>  drivers/net/ethernet/amazon/ena/ena_com.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
> b/drivers/net/ethernet/amazon/ena/ena_com.c
> index f6e1d30523a6..8efb85e25a42 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_com.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_com.c
> @@ -100,7 +100,7 @@ static inline int ena_com_mem_addr_set(struct ena_com_dev 
> *ena_dev,
>   }
>
>   ena_addr->mem_addr_low = (u32)addr;
> - ena_addr->mem_addr_high = (u64)addr >> 32;
> + ena_addr->mem_addr_high = (u16)((u64)addr >> 32);

We have macro for getting upper 32 bits - upper_32_bits(addr), the same
goes for lower 32 bits.

>
>   return 0;
>  }
> --
> 2.7.4
>


Re: [PATCH net-next 10/13] net: ena: add mtu limitation in ena_change_mtu()

2017-06-19 Thread Belgazal, Netanel
I'll discard this patch.

From: David Miller 
Sent: Sunday, June 18, 2017 7:21 PM
To: Belgazal, Netanel
Cc: netdev@vger.kernel.org; Woodhouse, David; Machulsky, Zorik; Matushevsky, 
Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; Bshara, Nafea; 
Schmeilin, Evgeny
Subject: Re: [PATCH net-next 10/13] net: ena: add mtu limitation in 
ena_change_mtu()

From: 
Date: Sun, 18 Jun 2017 14:28:15 +0300

> From: Netanel Belgazal 
>
> Signed-off-by: Netanel Belgazal 

I don't understand this at all.

This whole reason we have those:

> @@ -3008,8 +3015,6 @@ static void ena_set_conf_feat_params(struct ena_adapter 
> *adapter,
>   ena_set_dev_offloads(feat, netdev);
>
>   adapter->max_mtu = feat->dev_attr.max_mtu;
> - netdev->max_mtu = adapter->max_mtu;
> - netdev->min_mtu = ENA_MIN_MTU;
>  }
>

assignments you are removing is so that the core networking can
validate the request and therefore individual drivers don't have to.

If it's just to get that silly driver message out when the MTU asked
for is too large, that's not a good reason to bypass the
infrastructure for MTU changes that we've provided for drivers in the
core.

I don't like this change at all.

You could have helped things a lot by actually writing a commit log
message explaining what you are really doing, and why you are doing
it.  Empty commit log messages are never a good idea.


[PATCH net-next 09/13] net: ena: adding missing cast in ena_com_mem_addr_set()

2017-06-18 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index f6e1d30523a6..8efb85e25a42 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -100,7 +100,7 @@ static inline int ena_com_mem_addr_set(struct ena_com_dev 
*ena_dev,
}
 
ena_addr->mem_addr_low = (u32)addr;
-   ena_addr->mem_addr_high = (u64)addr >> 32;
+   ena_addr->mem_addr_high = (u16)((u64)addr >> 32);
 
return 0;
 }
-- 
2.7.4



[PATCH net-next 03/13] net: ena: change sizeof() argument to be the type pointer

2017-06-18 Thread netanel
From: Netanel Belgazal 

Instead of using:
memset(ptr, 0x0, sizeof(struct ...))
use:
memset(ptr, 0x0, sizeor(*ptr))

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 65d53d501139..2721c70492a1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -329,7 +329,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
size_t size;
int dev_node = 0;
 
-   memset(&io_sq->desc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+   memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr));
 
io_sq->desc_entry_size =
(io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
@@ -383,7 +383,7 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev,
size_t size;
int prev_node = 0;
 
-   memset(&io_cq->cdesc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+   memset(&io_cq->cdesc_addr, 0x0, sizeof(io_cq->cdesc_addr));
 
/* Use the basic completion descriptor for Rx */
io_cq->cdesc_entry_size_in_bytes =
@@ -685,7 +685,7 @@ static int ena_com_destroy_io_sq(struct ena_com_dev 
*ena_dev,
u8 direction;
int ret;
 
-   memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+   memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));
 
if (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
direction = ENA_ADMIN_SQ_DIRECTION_TX;
@@ -967,7 +967,7 @@ static int ena_com_create_io_sq(struct ena_com_dev *ena_dev,
u8 direction;
int ret;
 
-   memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_sq_cmd));
+   memset(&create_cmd, 0x0, sizeof(create_cmd));
 
create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_SQ;
 
@@ -1159,7 +1159,7 @@ int ena_com_create_io_cq(struct ena_com_dev *ena_dev,
struct ena_admin_acq_create_cq_resp_desc cmd_completion;
int ret;
 
-   memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_cq_cmd));
+   memset(&create_cmd, 0x0, sizeof(create_cmd));
 
create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_CQ;
 
@@ -1267,7 +1267,7 @@ int ena_com_destroy_io_cq(struct ena_com_dev *ena_dev,
struct ena_admin_acq_destroy_cq_resp_desc destroy_resp;
int ret;
 
-   memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+   memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));
 
destroy_cmd.cq_idx = io_cq->idx;
destroy_cmd.aq_common_descriptor.opcode = ENA_ADMIN_DESTROY_CQ;
@@ -1623,8 +1623,8 @@ int ena_com_create_io_queue(struct ena_com_dev *ena_dev,
io_sq = &ena_dev->io_sq_queues[ctx->qid];
io_cq = &ena_dev->io_cq_queues[ctx->qid];
 
-   memset(io_sq, 0x0, sizeof(struct ena_com_io_sq));
-   memset(io_cq, 0x0, sizeof(struct ena_com_io_cq));
+   memset(io_sq, 0x0, sizeof(*io_sq));
+   memset(io_cq, 0x0, sizeof(*io_cq));
 
/* Init CQ */
io_cq->q_depth = ctx->queue_size;
-- 
2.7.4



[PATCH net-next 12/13] net: ena: change validate_tx_req_id() to be inline function

2017-06-18 Thread netanel
From: Netanel Belgazal 

for optimization purpose, change validate_tx_req_id() to be
inline function.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 4540cd3d9f5f..da14b78cc87c 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -698,7 +698,7 @@ static void ena_destroy_all_io_queues(struct ena_adapter 
*adapter)
ena_destroy_all_rx_queues(adapter);
 }
 
-static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
+static inline int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
 {
struct ena_tx_buffer *tx_info = NULL;
 
-- 
2.7.4



[PATCH net-next 10/13] net: ena: add mtu limitation in ena_change_mtu()

2017-06-18 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7dee448157bb..7f31f4ce7b8e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -108,6 +108,13 @@ static int ena_change_mtu(struct net_device *dev, int 
new_mtu)
struct ena_adapter *adapter = netdev_priv(dev);
int ret;
 
+   if ((new_mtu > adapter->max_mtu) || (new_mtu < ENA_MIN_MTU)) {
+   netif_err(adapter, drv, dev,
+ "Invalid MTU setting. new_mtu: %d max mtu: %d min 
mtu: %d\n",
+ new_mtu, adapter->max_mtu, ENA_MIN_MTU);
+   return -EINVAL;
+   }
+
ret = ena_com_set_dev_mtu(adapter->ena_dev, new_mtu);
if (!ret) {
netif_dbg(adapter, drv, dev, "set MTU to %d\n", new_mtu);
@@ -3008,8 +3015,6 @@ static void ena_set_conf_feat_params(struct ena_adapter 
*adapter,
ena_set_dev_offloads(feat, netdev);
 
adapter->max_mtu = feat->dev_attr.max_mtu;
-   netdev->max_mtu = adapter->max_mtu;
-   netdev->min_mtu = ENA_MIN_MTU;
 }
 
 static int ena_rss_init_default(struct ena_adapter *adapter)
-- 
2.7.4



[PATCH net-next 13/13] net: ena: update ena driver to version 1.2.0

2017-06-18 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 86b0f0dbae65..29bb5704260b 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -44,15 +44,15 @@
 #include "ena_eth_com.h"
 
 #define DRV_MODULE_VER_MAJOR   1
-#define DRV_MODULE_VER_MINOR   1
-#define DRV_MODULE_VER_SUBMINOR 7
+#define DRV_MODULE_VER_MINOR   2
+#define DRV_MODULE_VER_SUBMINOR 0
 
 #define DRV_MODULE_NAME"ena"
 #ifndef DRV_MODULE_VERSION
 #define DRV_MODULE_VERSION \
__stringify(DRV_MODULE_VER_MAJOR) "."   \
__stringify(DRV_MODULE_VER_MINOR) "."   \
-   __stringify(DRV_MODULE_VER_SUBMINOR)
+   __stringify(DRV_MODULE_VER_SUBMINOR) "k"
 #endif
 
 #define DEVICE_NAME"Elastic Network Adapter (ENA)"
-- 
2.7.4



[PATCH net-next 05/13] net: ena: add support for out of order rx buffers refill

2017-06-18 Thread netanel
From: Netanel Belgazal 

ENA driver post Rx buffers through the Rx submission queue
for the ENA device to fill them with receive packets.
Each Rx buffer is marked with req_id in the Rx descriptor.

Newer ENA devices could consume the posted Rx buffer in out of order,
and as result the corresponding Rx completion queue will have Rx
completion descriptors with non contiguous req_id(s)

In this change the driver holds two rings.
The first ring (called free_rx_ids) is a mapping ring.
It holds all the unused request ids.
The values in this ring are from 0 to ring_size -1.

When the driver wants to allocate a new Rx buffer it uses the head of
free_rx_ids and uses it's value as the index for rx_buffer_info ring.
The req_id is also written to the Rx descriptor

Upon Rx completion,
The driver took the req_id from the completion descriptor and uses it
as index in rx_buffer_info.
The req_id is then return to the free_rx_ids ring.

This patch also adds statistics to inform when the driver receive out
of range or unused req_id.

Note:
free_rx_ids is only accessible from the napi handler, so no locking is
required

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_eth_com.c |  5 ++
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 83 ++-
 drivers/net/ethernet/amazon/ena/ena_netdev.h  | 11 +++-
 4 files changed, 83 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c 
b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
index f999305e1363..b11e573ad57a 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -493,6 +493,11 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq 
*io_cq, u16 *req_id)
if (cdesc_phase != expected_phase)
return -EAGAIN;
 
+   if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
+   pr_err("Invalid req id %d\n", cdesc->req_id);
+   return -EINVAL;
+   }
+
ena_com_cq_inc_head(io_cq);
 
*req_id = READ_ONCE(cdesc->req_id);
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index d51a67f4df02..b1212debc2e1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -93,6 +93,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
ENA_STAT_RX_ENTRY(dma_mapping_err),
ENA_STAT_RX_ENTRY(bad_desc_num),
ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+   ENA_STAT_RX_ENTRY(bad_req_id),
ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0d35a4cc3525..fcbcd188a132 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -304,6 +304,24 @@ static void ena_free_all_io_tx_resources(struct 
ena_adapter *adapter)
ena_free_tx_resources(adapter, i);
 }
 
+static inline int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id)
+{
+   if (likely(req_id < rx_ring->ring_size))
+   return 0;
+
+   netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+ "Invalid rx req_id: %hu\n", req_id);
+
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.bad_req_id++;
+   u64_stats_update_end(&rx_ring->syncp);
+
+   /* Trigger device reset */
+   rx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID;
+   set_bit(ENA_FLAG_TRIGGER_RESET, &rx_ring->adapter->flags);
+   return -EFAULT;
+}
+
 /* ena_setup_rx_resources - allocate I/O Rx resources (Descriptors)
  * @adapter: network interface device structure
  * @qid: queue index
@@ -315,7 +333,7 @@ static int ena_setup_rx_resources(struct ena_adapter 
*adapter,
 {
struct ena_ring *rx_ring = &adapter->rx_ring[qid];
struct ena_irq *ena_irq = &adapter->irq_tbl[ENA_IO_IRQ_IDX(qid)];
-   int size, node;
+   int size, node, i;
 
if (rx_ring->rx_buffer_info) {
netif_err(adapter, ifup, adapter->netdev,
@@ -336,6 +354,20 @@ static int ena_setup_rx_resources(struct ena_adapter 
*adapter,
return -ENOMEM;
}
 
+   size = sizeof(u16) * rx_ring->ring_size;
+   rx_ring->free_rx_ids = vzalloc_node(size, node);
+   if (!rx_ring->free_rx_ids) {
+   rx_ring->free_rx_ids = vzalloc(size);
+   if (!rx_ring->free_rx_ids) {
+   vfree(rx_ring->rx_buffer_info);
+   return -ENOMEM;
+   }
+   }
+
+   /* Req id ring for receiving RX pkts out of order */
+   for (i = 0; i < rx_ring->ring_size; i++)
+   rx_ring->free_rx_ids[i] = i;
+
   

[PATCH net-next 02/13] net: ena: add hardware hints capability to the driver

2017-06-18 Thread netanel
From: Netanel Belgazal 

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 
---
 drivers/net/ethernet/amazon/ena/ena_admin_defs.h | 31 +++
 drivers/net/ethernet/amazon/ena/ena_com.c| 38 +++---
 drivers/net/ethernet/amazon/ena/ena_com.h|  6 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 66 ++--
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  5 ++
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h  |  2 +
 6 files changed, 137 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h 
b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
index 5b6509d59716..305dc1996b4e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
@@ -70,6 +70,8 @@ enum ena_admin_aq_feature_id {
 
ENA_ADMIN_MAX_QUEUES_NUM= 2,
 
+   ENA_ADMIN_HW_HINTS  = 3,
+
ENA_ADMIN_RSS_HASH_FUNCTION = 10,
 
ENA_ADMIN_STATELESS_OFFLOAD_CONFIG  = 11,
@@ -749,6 +751,31 @@ struct ena_admin_feature_rss_ind_table {
struct ena_admin_rss_ind_table_entry inline_entry;
 };
 
+/* When hint value is 0, driver should use it's own predefined value */
+struct ena_admin_ena_hw_hints {
+   /* value in ms */
+   u16 mmio_read_timeout;
+
+   /* value in ms */
+   u16 driver_watchdog_timeout;
+
+   /* Per packet tx completion timeout. value in ms */
+   u16 missing_tx_completion_timeout;
+
+   u16 missed_tx_completion_count_threshold_to_reset;
+
+   /* value in ms */
+   u16 admin_completion_tx_timeout;
+
+   u16 netdev_wd_timeout;
+
+   u16 max_tx_sgl_size;
+
+   u16 max_rx_sgl_size;
+
+   u16 reserved[8];
+};
+
 struct ena_admin_get_feat_cmd {
struct ena_admin_aq_common_desc aq_common_descriptor;
 
@@ -782,6 +809,8 @@ struct ena_admin_get_feat_resp {
struct ena_admin_feature_rss_ind_table ind_table;
 
struct ena_admin_feature_intr_moder_desc intr_moderation;
+
+   struct ena_admin_ena_hw_hints hw_hints;
} u;
 };
 
@@ -857,6 +886,8 @@ enum ena_admin_aenq_notification_syndrom {
ENA_ADMIN_SUSPEND   = 0,
 
ENA_ADMIN_RESUME= 1,
+
+   ENA_ADMIN_UPDATE_HINTS  = 2,
 };
 
 struct ena_admin_aenq_entry {
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 02752d5b5b60..65d53d501139 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -511,7 +511,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct 
ena_comp_ctx *comp_c
unsigned long flags, timeout;
int ret;
 
-   timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+   timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout);
 
while (1) {
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
int ret;
 
wait_for_completion_timeout(&comp_ctx->wait_event,
-   usecs_to_jiffies(ADMIN_CMD_TIMEOUT_US));
+   usecs_to_jiffies(
+   admin_queue->completion_timeout));
 
/* In case the command wasn't completed find out the root cause.
 * 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)
struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
mmio_read->read_resp;
-   u32 mmio_read_reg, ret;
+   u32 mmio_read_reg, ret, i;
unsigned long flags;
-   int i;
+   u32 timeout = mmio_read->reg_read_to;
 
might_sleep();
 
+   if (timeout == 0)
+   timeout = ENA_REG_READ_TIMEOUT;
+
/* If readless is disabled, perform regular read */
if (!mmio_read->readless_supported)
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)
 
writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
-   for (i = 0; i < ENA_REG_READ_TIMEOUT; i++) {
+   for (i = 0; i < timeout; i++) {
if (read_resp->req_id == mmio_read->seq_num)
break;
 
udelay(1);
}
 
-   if

[PATCH net-next 11/13] net: ena: update driver's rx drop statistics

2017-06-18 Thread netanel
From: Netanel Belgazal 

rx drop counter is reported by the device in the keep-alive
event.
update the driver's counter with the device counter.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7f31f4ce7b8e..4540cd3d9f5f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3483,8 +3483,17 @@ static void ena_keep_alive_wd(void *adapter_data,
  struct ena_admin_aenq_entry *aenq_e)
 {
struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
+   struct ena_admin_aenq_keep_alive_desc *desc;
+   u64 rx_drops;
 
+   desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e;
adapter->last_keep_alive_jiffies = jiffies;
+
+   rx_drops = ((u64)desc->rx_drops_high << 32) | desc->rx_drops_low;
+
+   u64_stats_update_begin(&adapter->syncp);
+   adapter->dev_stats.rx_drops = rx_drops;
+   u64_stats_update_end(&adapter->syncp);
 }
 
 static void ena_notification(void *adapter_data,
-- 
2.7.4



[PATCH net-next 08/13] net: ena: separate skb allocation to dedicated function

2017-06-18 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 44 +---
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 424b4d7e642f..7dee448157bb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -825,6 +825,28 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 
budget)
return tx_pkts;
 }
 
+static struct sk_buff *ena_alloc_skb(struct ena_ring *rx_ring, bool frags)
+{
+   struct sk_buff *skb;
+
+   if (frags)
+   skb = napi_get_frags(rx_ring->napi);
+   else
+   skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
+   rx_ring->rx_copybreak);
+
+   if (unlikely(!skb)) {
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.skb_alloc_fail++;
+   u64_stats_update_end(&rx_ring->syncp);
+   netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
+ "Failed to allocate skb. frags: %d\n", frags);
+   return NULL;
+   }
+
+   return skb;
+}
+
 static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
  struct ena_com_rx_buf_info *ena_bufs,
  u32 descs,
@@ -854,16 +876,9 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
prefetch(va + NET_IP_ALIGN);
 
if (len <= rx_ring->rx_copybreak) {
-   skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-   rx_ring->rx_copybreak);
-   if (unlikely(!skb)) {
-   u64_stats_update_begin(&rx_ring->syncp);
-   rx_ring->rx_stats.skb_alloc_fail++;
-   u64_stats_update_end(&rx_ring->syncp);
-   netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
- "Failed to allocate skb\n");
+   skb = ena_alloc_skb(rx_ring, false);
+   if (unlikely(!skb))
return NULL;
-   }
 
netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
  "rx allocated small packet. len %d. data_len %d\n",
@@ -882,20 +897,15 @@ static struct sk_buff *ena_rx_skb(struct ena_ring 
*rx_ring,
 
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+   rx_ring->free_rx_ids[*next_to_clean] = req_id;
*next_to_clean = ENA_RX_RING_IDX_ADD(*next_to_clean, descs,
 rx_ring->ring_size);
return skb;
}
 
-   skb = napi_get_frags(rx_ring->napi);
-   if (unlikely(!skb)) {
-   netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
- "Failed allocating skb\n");
-   u64_stats_update_begin(&rx_ring->syncp);
-   rx_ring->rx_stats.skb_alloc_fail++;
-   u64_stats_update_end(&rx_ring->syncp);
+   skb = ena_alloc_skb(rx_ring, true);
+   if (unlikely(!skb))
return NULL;
-   }
 
do {
dma_unmap_page(rx_ring->dev,
-- 
2.7.4



[PATCH net-next 06/13] net: ena: allow the driver to work with small number of msix vectors

2017-06-18 Thread netanel
From: Netanel Belgazal 

Current driver tries to allocate msix vectors as the number of the
negotiated io queues. (with another msix vector for management).
If pci_alloc_irq_vectors() fails, the driver aborts the probe
and the ENA network device is never brought up.

With this patch, the driver's logic will reduce the number of IO
queues to the number of allocated msix vectors (minus one for management)
instead of failing probe().

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 65 
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  6 ++-
 2 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index fcbcd188a132..04aade842097 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1269,9 +1269,20 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
return IRQ_HANDLED;
 }
 
+/* Reserve a single MSI-X vector for management (admin + aenq).
+ * plus reserve one vector for each potential io queue.
+ * the number of potential io queues is the minimum of what the device
+ * supports and the number of vCPUs.
+ */
 static int ena_enable_msix(struct ena_adapter *adapter, int num_queues)
 {
-   int msix_vecs, rc;
+   int msix_vecs, irq_cnt;
+
+   if (test_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags)) {
+   netif_err(adapter, probe, adapter->netdev,
+ "Error, MSI-X is already enabled\n");
+   return -EPERM;
+   }
 
/* Reserved the max msix vectors we might need */
msix_vecs = ENA_MAX_MSIX_VEC(num_queues);
@@ -1279,25 +1290,28 @@ static int ena_enable_msix(struct ena_adapter *adapter, 
int num_queues)
netif_dbg(adapter, probe, adapter->netdev,
  "trying to enable MSI-X, vectors %d\n", msix_vecs);
 
-   rc = pci_alloc_irq_vectors(adapter->pdev, msix_vecs, msix_vecs,
-   PCI_IRQ_MSIX);
-   if (rc < 0) {
+   irq_cnt = pci_alloc_irq_vectors(adapter->pdev, ENA_MIN_MSIX_VEC,
+   msix_vecs, PCI_IRQ_MSIX);
+
+   if (irq_cnt < 0) {
netif_err(adapter, probe, adapter->netdev,
- "Failed to enable MSI-X, vectors %d rc %d\n",
- msix_vecs, rc);
+ "Failed to enable MSI-X. irq_cnt %d\n", irq_cnt);
return -ENOSPC;
}
 
-   netif_dbg(adapter, probe, adapter->netdev, "enable MSI-X, vectors %d\n",
- msix_vecs);
-
-   if (msix_vecs >= 1) {
-   if (ena_init_rx_cpu_rmap(adapter))
-   netif_warn(adapter, probe, adapter->netdev,
-  "Failed to map IRQs to CPUs\n");
+   if (irq_cnt != msix_vecs) {
+   netif_notice(adapter, probe, adapter->netdev,
+"enable only %d MSI-X (out of %d), reduce the 
number of queues\n",
+irq_cnt, msix_vecs);
+   adapter->num_queues = irq_cnt - ENA_ADMIN_MSIX_VEC;
}
 
-   adapter->msix_vecs = msix_vecs;
+   if (ena_init_rx_cpu_rmap(adapter))
+   netif_warn(adapter, probe, adapter->netdev,
+  "Failed to map IRQs to CPUs\n");
+
+   adapter->msix_vecs = irq_cnt;
+   set_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags);
 
return 0;
 }
@@ -1374,6 +1388,12 @@ static int ena_request_io_irq(struct ena_adapter 
*adapter)
struct ena_irq *irq;
int rc = 0, i, k;
 
+   if (!test_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags)) {
+   netif_err(adapter, ifup, adapter->netdev,
+ "Failed to request I/O IRQ: MSI-X is not enabled\n");
+   return -EINVAL;
+   }
+
for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) {
irq = &adapter->irq_tbl[i];
rc = request_irq(irq->vector, irq->handler, flags, irq->name,
@@ -1432,6 +1452,12 @@ static void ena_free_io_irq(struct ena_adapter *adapter)
}
 }
 
+static void ena_disable_msix(struct ena_adapter *adapter)
+{
+   if (test_and_clear_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags))
+   pci_free_irq_vectors(adapter->pdev);
+}
+
 static void ena_disable_io_intr_sync(struct ena_adapter *adapter)
 {
int i;
@@ -2520,7 +2546,8 @@ static int 
ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return 0;
 
 err_disable_msix:
-   pci_free_irq_vectors(adapter->pdev);
+   ena_disable_msix(adapter);
+
return rc;
 }
 
@@ -2558,7 +2585,7 @@ static void ena_fw_reset_device(struct work_struc

[PATCH net-next 07/13] net: ena: use napi_schedule_irqoff when possible

2017-06-18 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 04aade842097..424b4d7e642f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1264,7 +1264,7 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
 {
struct ena_napi *ena_napi = data;
 
-   napi_schedule(&ena_napi->napi);
+   napi_schedule_irqoff(&ena_napi->napi);
 
return IRQ_HANDLED;
 }
-- 
2.7.4



[PATCH net-next 04/13] net: ena: add reset reason for each device FLR

2017-06-18 Thread netanel
From: Netanel Belgazal 

For each device reset, log to the device what is the cause
the reset occur.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c   |  5 +++-
 drivers/net/ethernet/amazon/ena/ena_com.h   |  4 +++-
 drivers/net/ethernet/amazon/ena/ena_netdev.c| 17 +
 drivers/net/ethernet/amazon/ena/ena_netdev.h|  2 ++
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h | 32 +
 5 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 2721c70492a1..f6e1d30523a6 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -1825,7 +1825,8 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, 
void *data)
writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
 }
 
-int ena_com_dev_reset(struct ena_com_dev *ena_dev)
+int ena_com_dev_reset(struct ena_com_dev *ena_dev,
+ enum ena_regs_reset_reason_types reset_reason)
 {
u32 stat, timeout, cap, reset_val;
int rc;
@@ -1853,6 +1854,8 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)
 
/* start reset */
reset_val = ENA_REGS_DEV_CTL_DEV_RESET_MASK;
+   reset_val |= (reset_reason << ENA_REGS_DEV_CTL_RESET_REASON_SHIFT) &
+ENA_REGS_DEV_CTL_RESET_REASON_MASK;
writel(reset_val, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);
 
/* Write again the MMIO read request address */
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h 
b/drivers/net/ethernet/amazon/ena/ena_com.h
index 630c09ad35a5..7b784f8a06a6 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -420,10 +420,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev);
 
 /* ena_com_dev_reset - Perform device FLR to the device.
  * @ena_dev: ENA communication layer struct
+ * @reset_reason: Specify what is the trigger for the reset in case of an 
error.
  *
  * @return - 0 on success, negative value on failure.
  */
-int ena_com_dev_reset(struct ena_com_dev *ena_dev);
+int ena_com_dev_reset(struct ena_com_dev *ena_dev,
+ enum ena_regs_reset_reason_types reset_reason);
 
 /* ena_com_create_io_queue - Create io queue.
  * @ena_dev: ENA communication layer struct
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 1ee06e11654c..0d35a4cc3525 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -87,6 +87,7 @@ static void ena_tx_timeout(struct net_device *dev)
if (test_and_set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
return;
 
+   adapter->reset_reason = ENA_REGS_RESET_OS_NETDEV_WD;
u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.tx_timeout++;
u64_stats_update_end(&adapter->syncp);
@@ -670,6 +671,7 @@ static int validate_tx_req_id(struct ena_ring *tx_ring, u16 
req_id)
u64_stats_update_end(&tx_ring->syncp);
 
/* Trigger device reset */
+   tx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_TX_REQ_ID;
set_bit(ENA_FLAG_TRIGGER_RESET, &tx_ring->adapter->flags);
return -EFAULT;
 }
@@ -1055,6 +1057,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, 
struct napi_struct *napi,
u64_stats_update_end(&rx_ring->syncp);
 
/* Too many desc from the device. Trigger reset */
+   adapter->reset_reason = ENA_REGS_RESET_TOO_MANY_RX_DESCS;
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
 
return 0;
@@ -1720,7 +1723,7 @@ static void ena_down(struct ena_adapter *adapter)
if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags)) {
int rc;
 
-   rc = ena_com_dev_reset(adapter->ena_dev);
+   rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
if (rc)
dev_err(&adapter->pdev->dev, "Device reset failed\n");
}
@@ -2353,7 +2356,7 @@ static int ena_device_init(struct ena_com_dev *ena_dev, 
struct pci_dev *pdev,
readless_supported = !(pdev->revision & ENA_MMIO_DISABLE_REG_READ);
ena_com_set_mmio_read_mode(ena_dev, readless_supported);
 
-   rc = ena_com_dev_reset(ena_dev);
+   rc = ena_com_dev_reset(ena_dev, ENA_REGS_RESET_NORMAL);
if (rc) {
dev_err(dev, "Can not reset device\n");
goto err_mmio_read_less;
@@ -2512,6 +2515,7 @@ static void ena_fw_reset_device(struct work_struct *work)
 
ena_com_mmio_reg_read_request_destroy(ena_dev);
 
+   adapter->reset_reason = ENA_REGS_RESET_NORMAL;
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flag

[PATCH net-next 01/13] net: ena: change return value for unsupported features unsupported return value

2017-06-18 Thread netanel
From: Netanel Belgazal 

return -EOPNOTSUPP instead of -EPERM.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 22 +++---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c | 10 +++---
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 20 ++--
 3 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index f5b237e0bd60..02752d5b5b60 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -494,7 +494,7 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
case ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE:
return -ENOMEM;
case ENA_ADMIN_UNSUPPORTED_OPCODE:
-   return -EPERM;
+   return -EOPNOTSUPP;
case ENA_ADMIN_BAD_OPCODE:
case ENA_ADMIN_MALFORMED_REQUEST:
case ENA_ADMIN_ILLEGAL_PARAMETER:
@@ -786,7 +786,7 @@ static int ena_com_get_feature_ex(struct ena_com_dev 
*ena_dev,
 
if (!ena_com_check_supported_feature_id(ena_dev, feature_id)) {
pr_debug("Feature %d isn't supported\n", feature_id);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&get_cmd, 0x0, sizeof(get_cmd));
@@ -1324,7 +1324,7 @@ int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, 
u32 groups_flag)
if ((get_resp.u.aenq.supported_groups & groups_flag) != groups_flag) {
pr_warn("Trying to set unsupported aenq events. supported flag: 
%x asked flag: %x\n",
get_resp.u.aenq.supported_groups, groups_flag);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -1909,7 +1909,7 @@ int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int 
mtu)
 
if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_MTU)) {
pr_debug("Feature %d isn't supported\n", ENA_ADMIN_MTU);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -1963,7 +1963,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
ENA_ADMIN_RSS_HASH_FUNCTION)) {
pr_debug("Feature %d isn't supported\n",
 ENA_ADMIN_RSS_HASH_FUNCTION);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
/* Validate hash function is supported */
@@ -1975,7 +1975,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func)) {
pr_err("Func hash %d isn't supported by device, abort\n",
   rss->hash_func);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -2034,7 +2034,7 @@ int ena_com_fill_hash_function(struct ena_com_dev 
*ena_dev,
 
if (!((1 << func) & get_resp.u.flow_hash_func.supported_func)) {
pr_err("Flow hash function %d isn't supported\n", func);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
switch (func) {
@@ -2127,7 +2127,7 @@ int ena_com_set_hash_ctrl(struct ena_com_dev *ena_dev)
ENA_ADMIN_RSS_HASH_INPUT)) {
pr_debug("Feature %d isn't supported\n",
 ENA_ADMIN_RSS_HASH_INPUT);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
memset(&cmd, 0x0, sizeof(cmd));
@@ -2208,7 +2208,7 @@ int ena_com_set_default_hash_ctrl(struct ena_com_dev 
*ena_dev)
pr_err("hash control doesn't support all the desire 
configuration. proto %x supported %x selected %x\n",
   i, hash_ctrl->supported_fields[i].fields,
   hash_ctrl->selected_fields[i].fields);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
}
 
@@ -2286,7 +2286,7 @@ int ena_com_indirect_table_set(struct ena_com_dev 
*ena_dev)
ena_dev, ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG)) {
pr_debug("Feature %d isn't supported\n",
 ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG);
-   return -EPERM;
+   return -EOPNOTSUPP;
}
 
ret = ena_com_ind_tbl_convert_to_device(ena_dev);
@@ -2553,7 +2553,7 @@ int ena_com_init_interrupt_moderation(struct ena_com_dev 
*ena_dev)
 ENA_ADMIN_INTERRUPT_MODERATION);
 
if (rc) {
-   if (rc == -EPERM) {
+   if (rc == -EOP

[PATCH net-next 00/13] update ena ethernet driver to version 1.2.0

2017-06-18 Thread netanel
From: Netanel Belgazal 

This patchset contains some new features/improvements that were added
to the ENA driver to increase its robustness and are based on
experience of wide ENA deployment.

Netanel Belgazal (13):
  net: ena: change return value for unsupported features unsupported
return value
  net: ena: add hardware hints capability to the driver
  net: ena: change sizeof() argument to be the type pointer
  net: ena: add reset reason for each device FLR
  net: ena: add support for out of order rx buffers refill
  net: ena: allow the driver to work with small number of msix vectors
  net: ena: use napi_schedule_irqoff when possible
  net: ena: separate skb allocation to dedicated function
  net: ena: adding missing cast in ena_com_mem_addr_set()
  net: ena: add mtu limitation in ena_change_mtu()
  net: ena: update driver's rx drop statistics
  net: ena: change validate_tx_req_id() to be inline function
  net: ena: update ena driver to version 1.2.0

 drivers/net/ethernet/amazon/ena/ena_admin_defs.h |  31 +++
 drivers/net/ethernet/amazon/ena/ena_com.c|  83 --
 drivers/net/ethernet/amazon/ena/ena_com.h|  10 +-
 drivers/net/ethernet/amazon/ena/ena_eth_com.c|   5 +
 drivers/net/ethernet/amazon/ena/ena_ethtool.c|  11 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 317 +--
 drivers/net/ethernet/amazon/ena/ena_netdev.h |  30 ++-
 drivers/net/ethernet/amazon/ena/ena_regs_defs.h  |  34 +++
 8 files changed, 406 insertions(+), 115 deletions(-)

-- 
2.7.4



Re: [PATCH net 0/9] Bugs fixes in ena ethernet driver

2017-06-12 Thread Belgazal, Netanel
Thank you David,

Do you might have an ETA when do you plan to merge net branch into net-next?  I 
plan to base my new patchset to net-next on top of this one.

Regards,
Netanel

From: David Miller 
Sent: Sunday, June 11, 2017 11:38 PM
To: Belgazal, Netanel
Cc: netdev@vger.kernel.org; Woodhouse, David; Machulsky, Zorik; Matushevsky, 
Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; Bshara, Nafea; 
Schmeilin, Evgeny
Subject: Re: [PATCH net 0/9] Bugs fixes in ena ethernet driver

From: 
Date: Sun, 11 Jun 2017 15:42:42 +0300

> This patchset contains fixes for the bugs that were discovered so far.

Series applied.


[PATCH net 9/9] net: ena: update ena driver to version 1.1.7

2017-06-11 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 88b5e5612338..a4d3d5e21068 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -45,7 +45,7 @@
 
 #define DRV_MODULE_VER_MAJOR   1
 #define DRV_MODULE_VER_MINOR   1
-#define DRV_MODULE_VER_SUBMINOR 2
+#define DRV_MODULE_VER_SUBMINOR 7
 
 #define DRV_MODULE_NAME"ena"
 #ifndef DRV_MODULE_VERSION
-- 
2.7.4



[PATCH net 7/9] net: ena: disable admin msix while working in polling mode

2017-06-11 Thread netanel
From: Netanel Belgazal 

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index ea60b9e67acb..f5b237e0bd60 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -61,6 +61,8 @@
 
 #define ENA_MMIO_READ_TIMEOUT 0x
 
+#define ENA_REGS_ADMIN_INTR_MASK 1
+
 /*/
 /*/
 /*/
@@ -1454,6 +1456,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev)
 
 void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)
 {
+   u32 mask_value = 0;
+
+   if (polling)
+   mask_value = ENA_REGS_ADMIN_INTR_MASK;
+
+   writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF);
ena_dev->admin_queue.polling = polling;
 }
 
-- 
2.7.4



[PATCH net 5/9] net: ena: add missing unmap bars on device removal

2017-06-11 Thread netanel
From: Netanel Belgazal 

This patch also change the mapping functions to devm_ functions

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 1e71e89e1e18..4e9fbddd3b47 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2853,6 +2853,11 @@ static void ena_release_bars(struct ena_com_dev 
*ena_dev, struct pci_dev *pdev)
 {
int release_bars;
 
+   if (ena_dev->mem_bar)
+   devm_iounmap(&pdev->dev, ena_dev->mem_bar);
+
+   devm_iounmap(&pdev->dev, ena_dev->reg_bar);
+
release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
pci_release_selected_regions(pdev, release_bars);
 }
@@ -2940,8 +2945,9 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto err_free_ena_dev;
}
 
-   ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR),
-  pci_resource_len(pdev, ENA_REG_BAR));
+   ena_dev->reg_bar = devm_ioremap(&pdev->dev,
+   pci_resource_start(pdev, ENA_REG_BAR),
+   pci_resource_len(pdev, ENA_REG_BAR));
if (!ena_dev->reg_bar) {
dev_err(&pdev->dev, "failed to remap regs bar\n");
rc = -EFAULT;
@@ -2961,8 +2967,9 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);
 
if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
-   ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, 
ENA_MEM_BAR),
- pci_resource_len(pdev, 
ENA_MEM_BAR));
+   ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
+  pci_resource_start(pdev, 
ENA_MEM_BAR),
+  pci_resource_len(pdev, 
ENA_MEM_BAR));
if (!ena_dev->mem_bar) {
rc = -EFAULT;
goto err_device_destroy;
-- 
2.7.4



[PATCH net 6/9] net: ena: fix theoretical Rx hang on low memory systems

2017-06-11 Thread netanel
From: Netanel Belgazal 

For the rare case where the device runs out of free rx buffer
descriptors (in case of pressure on kernel  memory),
and the napi handler continuously fail to refill new Rx descriptors
until device rx queue totally runs out of all free rx buffers
to post incoming packet, leading to a deadlock:
* The device won't send interrupts since all the new
Rx packets will be dropped.
* The napi handler won't try to allocate new Rx descriptors
since allocation is part of NAPI that's not being invoked any more

The fix involves detecting this scenario and rescheduling NAPI
(to refill buffers) by the keepalive/watchdog task.

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 55 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  2 +
 3 files changed, 58 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 67b2338f8fb3..533b2fbdeef1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -94,6 +94,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
ENA_STAT_RX_ENTRY(dma_mapping_err),
ENA_STAT_RX_ENTRY(bad_desc_num),
ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+   ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
 static const struct ena_stats ena_stats_ena_com_strings[] = {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 4e9fbddd3b47..3c366bfbbab1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter)
rxr->sgl_size = adapter->max_rx_sgl_size;
rxr->smoothed_interval =
ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+   rxr->empty_rx_queue = 0;
}
 }
 
@@ -2619,6 +2620,58 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
adapter->last_monitored_tx_qid = i % adapter->num_queues;
 }
 
+/* trigger napi schedule after 2 consecutive detections */
+#define EMPTY_RX_REFILL 2
+/* For the rare case where the device runs out of Rx descriptors and the
+ * napi handler failed to refill new Rx descriptors (due to a lack of memory
+ * for example).
+ * This case will lead to a deadlock:
+ * The device won't send interrupts since all the new Rx packets will be 
dropped
+ * The napi handler won't allocate new Rx descriptors so the device will be
+ * able to send new packets.
+ *
+ * This scenario can happen when the kernel's vm.min_free_kbytes is too small.
+ * It is recommended to have at least 512MB, with a minimum of 128MB for
+ * constrained environment).
+ *
+ * When such a situation is detected - Reschedule napi
+ */
+static void check_for_empty_rx_ring(struct ena_adapter *adapter)
+{
+   struct ena_ring *rx_ring;
+   int i, refill_required;
+
+   if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+   return;
+
+   if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
+   return;
+
+   for (i = 0; i < adapter->num_queues; i++) {
+   rx_ring = &adapter->rx_ring[i];
+
+   refill_required =
+   ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
+   if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
+   rx_ring->empty_rx_queue++;
+
+   if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL) {
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.empty_rx_ring++;
+   u64_stats_update_end(&rx_ring->syncp);
+
+   netif_err(adapter, drv, adapter->netdev,
+ "trigger refill for ring %d\n", i);
+
+   napi_schedule(rx_ring->napi);
+   rx_ring->empty_rx_queue = 0;
+   }
+   } else {
+   rx_ring->empty_rx_queue = 0;
+   }
+   }
+}
+
 /* Check for keep alive expiration */
 static void check_for_missing_keep_alive(struct ena_adapter *adapter)
 {
@@ -2673,6 +2726,8 @@ static void ena_timer_service(unsigned long data)
 
check_for_missing_tx_completions(adapter);
 
+   check_for_empty_rx_ring(adapter);
+
if (debug_area)
ena_dump_stats_to_buf(adapter, debug_area);
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 0e22bc

[PATCH net 8/9] net: ena: bug fix in lost tx packets detection mechanism

2017-06-11 Thread netanel
From: Netanel Belgazal 

check_for_missing_tx_completions() is called from a timer
task and looking for lost tx packets.
The old implementation accumulate all the lost tx packets
and did not check if those packets were retrieved on a later stage.
This cause to a situation where the driver reset
the device for no reason.

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 -
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 66 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  | 14 +-
 3 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 533b2fbdeef1..3ee55e2fd694 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -80,7 +80,6 @@ static const struct ena_stats ena_stats_tx_strings[] = {
ENA_STAT_TX_ENTRY(tx_poll),
ENA_STAT_TX_ENTRY(doorbells),
ENA_STAT_TX_ENTRY(prepare_ctx_err),
-   ENA_STAT_TX_ENTRY(missing_tx_comp),
ENA_STAT_TX_ENTRY(bad_req_id),
 };
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 3c366bfbbab1..4f16ed38bcf3 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1995,6 +1995,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
tx_info->tx_descs = nb_hw_desc;
tx_info->last_jiffies = jiffies;
+   tx_info->print_once = 0;
 
tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
tx_ring->ring_size);
@@ -2564,13 +2565,44 @@ static void ena_fw_reset_device(struct work_struct 
*work)
"Reset attempt failed. Can not reset the device\n");
 }
 
-static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+static int check_missing_comp_in_queue(struct ena_adapter *adapter,
+  struct ena_ring *tx_ring)
 {
struct ena_tx_buffer *tx_buf;
unsigned long last_jiffies;
+   u32 missed_tx = 0;
+   int i;
+
+   for (i = 0; i < tx_ring->ring_size; i++) {
+   tx_buf = &tx_ring->tx_buffer_info[i];
+   last_jiffies = tx_buf->last_jiffies;
+   if (unlikely(last_jiffies &&
+time_is_before_jiffies(last_jiffies + 
TX_TIMEOUT))) {
+   if (!tx_buf->print_once)
+   netif_notice(adapter, tx_err, adapter->netdev,
+"Found a Tx that wasn't completed 
on time, qid %d, index %d.\n",
+tx_ring->qid, i);
+
+   tx_buf->print_once = 1;
+   missed_tx++;
+
+   if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) 
{
+   netif_err(adapter, tx_err, adapter->netdev,
+ "The number of lost tx completions is 
above the threshold (%d > %d). Reset the device\n",
+ missed_tx, 
MAX_NUM_OF_TIMEOUTED_PACKETS);
+   set_bit(ENA_FLAG_TRIGGER_RESET, 
&adapter->flags);
+   return -EIO;
+   }
+   }
+   }
+
+   return 0;
+}
+
+static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+{
struct ena_ring *tx_ring;
-   int i, j, budget;
-   u32 missed_tx;
+   int i, budget, rc;
 
/* Make sure the driver doesn't turn the device in other process */
smp_rmb();
@@ -2586,31 +2618,9 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
tx_ring = &adapter->tx_ring[i];
 
-   for (j = 0; j < tx_ring->ring_size; j++) {
-   tx_buf = &tx_ring->tx_buffer_info[j];
-   last_jiffies = tx_buf->last_jiffies;
-   if (unlikely(last_jiffies && 
time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
-   netif_notice(adapter, tx_err, adapter->netdev,
-"Found a Tx that wasn't completed 
on time, qid %d, index %d.\n",
-tx_ring->qid, j);
-
-   u64_stats_update_begin(&tx_ring->syncp);
-   missed_tx = tx_ring->tx_stats.missing_tx_comp++;
-  

[PATCH net 2/9] net: ena: fix bug that might cause hang after consecutive open/close interface.

2017-06-11 Thread netanel
From: Netanel Belgazal 

Fixing a bug that the driver does not unmask the IO interrupts
in ndo_open():
occasionally, the MSI-X interrupt (for one or more IO queues)
can be masked when ndo_close() was called.
If that is followed by ndo open(),
then the MSI-X will be still masked so no interrupt
will be received by the driver.

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 41 ++--
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7c1214d78855..0e3c60c7eccf 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1078,6 +1078,26 @@ inline void ena_adjust_intr_moderation(struct ena_ring 
*rx_ring,
rx_ring->per_napi_bytes = 0;
 }
 
+static inline void ena_unmask_interrupt(struct ena_ring *tx_ring,
+   struct ena_ring *rx_ring)
+{
+   struct ena_eth_io_intr_reg intr_reg;
+
+   /* Update intr register: rx intr delay,
+* tx intr delay and interrupt unmask
+*/
+   ena_com_update_intr_reg(&intr_reg,
+   rx_ring->smoothed_interval,
+   tx_ring->smoothed_interval,
+   true);
+
+   /* It is a shared MSI-X.
+* Tx and Rx CQ have pointer to it.
+* So we use one of them to reach the intr reg
+*/
+   ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+}
+
 static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,
 struct ena_ring *rx_ring)
 {
@@ -1108,7 +1128,6 @@ static int ena_io_poll(struct napi_struct *napi, int 
budget)
 {
struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
struct ena_ring *tx_ring, *rx_ring;
-   struct ena_eth_io_intr_reg intr_reg;
 
u32 tx_work_done;
u32 rx_work_done;
@@ -1149,22 +1168,9 @@ static int ena_io_poll(struct napi_struct *napi, int 
budget)
if 
(ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
ena_adjust_intr_moderation(rx_ring, tx_ring);
 
-   /* Update intr register: rx intr delay,
-* tx intr delay and interrupt unmask
-*/
-   ena_com_update_intr_reg(&intr_reg,
-   rx_ring->smoothed_interval,
-   tx_ring->smoothed_interval,
-   true);
-
-   /* It is a shared MSI-X.
-* Tx and Rx CQ have pointer to it.
-* So we use one of them to reach the intr reg
-*/
-   ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+   ena_unmask_interrupt(tx_ring, rx_ring);
}
 
-
ena_update_ring_numa_node(tx_ring, rx_ring);
 
ret = rx_work_done;
@@ -1485,6 +1491,11 @@ static int ena_up_complete(struct ena_adapter *adapter)
 
ena_napi_enable_all(adapter);
 
+   /* Enable completion queues interrupt */
+   for (i = 0; i < adapter->num_queues; i++)
+   ena_unmask_interrupt(&adapter->tx_ring[i],
+&adapter->rx_ring[i]);
+
/* schedule napi in case we had pending packets
 * from the last time we disable napi
 */
-- 
2.7.4



[PATCH net 3/9] net: ena: add missing return when ena_com_get_io_handlers() fails

2017-06-11 Thread netanel
From: Netanel Belgazal 

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0e3c60c7eccf..1e71e89e1e18 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1543,6 +1543,7 @@ static int ena_create_io_tx_queue(struct ena_adapter 
*adapter, int qid)
  "Failed to get TX queue handlers. TX queue num %d rc: 
%d\n",
  qid, rc);
ena_com_destroy_io_queue(ena_dev, ena_qid);
+   return rc;
}
 
ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node);
@@ -1607,6 +1608,7 @@ static int ena_create_io_rx_queue(struct ena_adapter 
*adapter, int qid)
  "Failed to get RX queue handlers. RX queue num %d rc: 
%d\n",
  qid, rc);
ena_com_destroy_io_queue(ena_dev, ena_qid);
+   return rc;
}
 
ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node);
-- 
2.7.4



[PATCH net 0/9] Bugs fixes in ena ethernet driver

2017-06-11 Thread netanel
From: Netanel Belgazal 

This patchset contains fixes for the bugs that were discovered so far.

Netanel Belgazal (9):
  net: ena: fix rare uncompleted admin command false alarm
  net: ena: fix bug that might cause hang after consecutive open/close
interface.
  net: ena: add missing return when ena_com_get_io_handlers() fails
  net: ena: fix race condition between submit and completion admin
command
  net: ena: add missing unmap bars on device removal
  net: ena: fix theoretical Rx hang on low memory systems
  net: ena: disable admin msix while working in polling mode
  net: ena: bug fix in lost tx packets detection mechanism
  net: ena: update ena driver to version 1.1.7

 drivers/net/ethernet/amazon/ena/ena_com.c |  35 +++--
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |   2 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 179 +++---
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  18 ++-
 4 files changed, 169 insertions(+), 65 deletions(-)

-- 
2.7.4



[PATCH net 4/9] net: ena: fix race condition between submit and completion admin command

2017-06-11 Thread netanel
From: Netanel Belgazal 

Bug:
"Completion context is occupied" error printout will be noticed in
dmesg.
This error will cause the admin command to fail, which will lead to
an ena_probe() failure or a watchdog reset (depends on which admin
command failed).

Root cause:
__ena_com_submit_admin_cmd() is the function that submits new entries to
the admin queue.
The function have a check that makes sure the queue is not full and the
function does not override any outstanding command.
It uses head and tail indexes for this check.
The head is increased by ena_com_handle_admin_completion() which runs
from interrupt context, and the tail index is increased by the submit
function (the function is running under ->q_lock, so there is no risk
of multithread increment).
Each command is associated with a completion context. This context
allocated before call to __ena_com_submit_admin_cmd() and freed by
ena_com_wait_and_process_admin_cq_interrupts(), right after the command
was completed.

This can lead to a state where the head was increased, the check passed,
but the completion context is still in use.

Solution:
Use the atomic variable ->outstanding_cmds instead of using the head and
the tail indexes.
This variable is safe for use since it is bumped in get_comp_ctx() in
__ena_com_submit_admin_cmd() and is freed by comp_ctxt_release()

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index e1c2fab6292f..ea60b9e67acb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -232,11 +232,9 @@ static struct ena_comp_ctx 
*__ena_com_submit_admin_cmd(struct ena_com_admin_queu
tail_masked = admin_queue->sq.tail & queue_size_mask;
 
/* In case of queue FULL */
-   cnt = admin_queue->sq.tail - admin_queue->sq.head;
+   cnt = atomic_read(&admin_queue->outstanding_cmds);
if (cnt >= admin_queue->q_depth) {
-   pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n",
-admin_queue->sq.tail, admin_queue->sq.head,
-admin_queue->q_depth);
+   pr_debug("admin queue is full.\n");
admin_queue->stats.out_of_space++;
return ERR_PTR(-ENOSPC);
}
-- 
2.7.4



[PATCH net 1/9] net: ena: fix rare uncompleted admin command false alarm

2017-06-11 Thread netanel
From: Netanel Belgazal 

The current flow to detect admin completion is:
while (command_not_completed) {
if (timeout)
error

check_for_completion()
sleep()
   }
So in case the sleep took more than the timeout
(in case the thread/workqueue was not scheduled due to higher priority
task or prolonged VMexit), the driver can detect a stall even if
the completion is present.

The fix changes the order of this function to first check for
completion and only after that check if the timeout expired.

Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 08d11cede9c9..e1c2fab6292f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
 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;
-   u32 start_time;
+   unsigned long flags, timeout;
int ret;
 
-   start_time = ((u32)jiffies_to_usecs(jiffies));
+   timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+
+   while (1) {
+   spin_lock_irqsave(&admin_queue->q_lock, flags);
+   ena_com_handle_admin_completion(admin_queue);
+   spin_unlock_irqrestore(&admin_queue->q_lock, flags);
 
-   while (comp_ctx->status == ENA_CMD_SUBMITTED) {
-   if u32)jiffies_to_usecs(jiffies)) - start_time) >
-   ADMIN_CMD_TIMEOUT_US) {
+   if (comp_ctx->status != ENA_CMD_SUBMITTED)
+   break;
+
+   if (time_is_before_jiffies(timeout)) {
pr_err("Wait for completion (polling) timeout\n");
/* ENA didn't have any completion */
spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -528,10 +533,6 @@ static int 
ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
goto err;
}
 
-   spin_lock_irqsave(&admin_queue->q_lock, flags);
-   ena_com_handle_admin_completion(admin_queue);
-   spin_unlock_irqrestore(&admin_queue->q_lock, flags);
-
msleep(100);
}
 
-- 
2.7.4



Re: [PATCH net-next 0/8] Bug fixes in ena ethernet driver

2017-06-11 Thread Belgazal, Netanel
Ack.
resubmitting to net branch and adding "Fixes" mark.

From: David Miller 
Sent: Saturday, June 10, 2017 11:11 PM
To: f.faine...@gmail.com
Cc: Belgazal, Netanel; netdev@vger.kernel.org; Woodhouse, David; Machulsky, 
Zorik; Matushevsky, Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; 
Bshara, Nafea; Schmeilin, Evgeny
Subject: Re: [PATCH net-next 0/8] Bug fixes in ena ethernet driver

From: Florian Fainelli 
Date: Fri, 9 Jun 2017 15:19:54 -0700

> On 06/09/2017 03:13 PM, neta...@amazon.com wrote:
>> From: Netanel Belgazal 
>>
>> This patchset contains fixes for the bugs that were discovered so far.
>
> If these are all fixes you should submit them against the "net" tree.
> net-next is for features [1].
>
> Since these are fixes, you may also want to provide a Fixes: 12-digit
> commit ("commit subject") [2] such that David can queue these patches
> for stable trees and this can be retrofitted into kernel distributions.
>
> [1]:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/netdev-FAQ.txt#n25
>
> [2]:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst#n183

Yeah I agree.  If they are genuine bug fixes they should be submitted
against 'net'.  And yes, Fixes: tags are quite desirable as well.



[PATCH net-next 4/8] net: ena: fix race condition between submit and completion admin command

2017-06-09 Thread netanel
From: Netanel Belgazal 

Bug:
"Completion context is occupied" error printout will be noticed in
dmesg.
This error will cause the admin command to fail, which will lead to
an ena_probe() failure or a watchdog reset (depends on which admin
command failed).

Root cause:
__ena_com_submit_admin_cmd() is the function that submits new entries to
the admin queue.
The function have a check that makes sure the queue is not full and the
function does not override any outstanding command.
It uses head and tail indexes for this check.
The head is increased by ena_com_handle_admin_completion() which runs
from interrupt context, and the tail index is increased by the submit
function (the function is running under ->q_lock, so there is no risk
of multithread increment).
Each command is associated with a completion context. This context
allocated before call to __ena_com_submit_admin_cmd() and freed by
ena_com_wait_and_process_admin_cq_interrupts(), right after the command
was completed.

This can lead to a state where the head was increased, the check passed,
but the completion context is still in use.

Solution:
Use the atomic variable ->outstanding_cmds instead of using the head and
the tail indexes.
This variable is safe for use since it is bumped in get_comp_ctx() in
__ena_com_submit_admin_cmd() and is freed by comp_ctxt_release()

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index e1c2fab..ea60b9e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -232,11 +232,9 @@ static struct ena_comp_ctx 
*__ena_com_submit_admin_cmd(struct ena_com_admin_queu
tail_masked = admin_queue->sq.tail & queue_size_mask;
 
/* In case of queue FULL */
-   cnt = admin_queue->sq.tail - admin_queue->sq.head;
+   cnt = atomic_read(&admin_queue->outstanding_cmds);
if (cnt >= admin_queue->q_depth) {
-   pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n",
-admin_queue->sq.tail, admin_queue->sq.head,
-admin_queue->q_depth);
+   pr_debug("admin queue is full.\n");
admin_queue->stats.out_of_space++;
return ERR_PTR(-ENOSPC);
}
-- 
2.7.4



[PATCH net-next 6/8] net: ena: fix theoretical Rx hang on low memory systems

2017-06-09 Thread netanel
From: Netanel Belgazal 

For the rare case where the device runs out of free rx buffer
descriptors (in case of pressure on kernel  memory),
and the napi handler continuously fail to refill new Rx descriptors
until device rx queue totally runs out of all free rx buffers
to post incoming packet, leading to a deadlock:
* The device won't send interrupts since all the new
Rx packets will be dropped.
* The napi handler won't try to allocate new Rx descriptors
since allocation is part of NAPI that's not being invoked any more

The fix involves detecting this scenario and rescheduling NAPI
(to refill buffers) by the keepalive/watchdog task.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 55 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  2 +
 3 files changed, 58 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 67b2338f..533b2fb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -94,6 +94,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
ENA_STAT_RX_ENTRY(dma_mapping_err),
ENA_STAT_RX_ENTRY(bad_desc_num),
ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+   ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
 static const struct ena_stats ena_stats_ena_com_strings[] = {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 4e9fbdd..3c366bf 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter)
rxr->sgl_size = adapter->max_rx_sgl_size;
rxr->smoothed_interval =
ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+   rxr->empty_rx_queue = 0;
}
 }
 
@@ -2619,6 +2620,58 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
adapter->last_monitored_tx_qid = i % adapter->num_queues;
 }
 
+/* trigger napi schedule after 2 consecutive detections */
+#define EMPTY_RX_REFILL 2
+/* For the rare case where the device runs out of Rx descriptors and the
+ * napi handler failed to refill new Rx descriptors (due to a lack of memory
+ * for example).
+ * This case will lead to a deadlock:
+ * The device won't send interrupts since all the new Rx packets will be 
dropped
+ * The napi handler won't allocate new Rx descriptors so the device will be
+ * able to send new packets.
+ *
+ * This scenario can happen when the kernel's vm.min_free_kbytes is too small.
+ * It is recommended to have at least 512MB, with a minimum of 128MB for
+ * constrained environment).
+ *
+ * When such a situation is detected - Reschedule napi
+ */
+static void check_for_empty_rx_ring(struct ena_adapter *adapter)
+{
+   struct ena_ring *rx_ring;
+   int i, refill_required;
+
+   if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+   return;
+
+   if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
+   return;
+
+   for (i = 0; i < adapter->num_queues; i++) {
+   rx_ring = &adapter->rx_ring[i];
+
+   refill_required =
+   ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
+   if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
+   rx_ring->empty_rx_queue++;
+
+   if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL) {
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.empty_rx_ring++;
+   u64_stats_update_end(&rx_ring->syncp);
+
+   netif_err(adapter, drv, adapter->netdev,
+ "trigger refill for ring %d\n", i);
+
+   napi_schedule(rx_ring->napi);
+   rx_ring->empty_rx_queue = 0;
+   }
+   } else {
+   rx_ring->empty_rx_queue = 0;
+   }
+   }
+}
+
 /* Check for keep alive expiration */
 static void check_for_missing_keep_alive(struct ena_adapter *adapter)
 {
@@ -2673,6 +2726,8 @@ static void ena_timer_service(unsigned long data)
 
check_for_missing_tx_completions(adapter);
 
+   check_for_empty_rx_ring(adapter);
+
if (debug_area)
ena_dump_stats_to_buf(adapter, debug_area);
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 0e22bce..8828f1d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/ama

[PATCH net-next 7/8] net: ena: disable admin msix while working in polling mode

2017-06-09 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index ea60b9e..f5b237e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -61,6 +61,8 @@
 
 #define ENA_MMIO_READ_TIMEOUT 0x
 
+#define ENA_REGS_ADMIN_INTR_MASK 1
+
 /*/
 /*/
 /*/
@@ -1454,6 +1456,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev)
 
 void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)
 {
+   u32 mask_value = 0;
+
+   if (polling)
+   mask_value = ENA_REGS_ADMIN_INTR_MASK;
+
+   writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF);
ena_dev->admin_queue.polling = polling;
 }
 
-- 
2.7.4



[PATCH net-next 8/8] net: ena: bug fix in lost tx packets detection mechanism

2017-06-09 Thread netanel
From: Netanel Belgazal 

check_for_missing_tx_completions() is called from a timer
task and looking for lost tx packets.
The old implementation accumulate all the lost tx packets
and did not check if those packets were retrieved on a later stage.
This cause to a situation where the driver reset
the device for no reason.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 -
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 66 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  | 14 +-
 3 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 533b2fb..3ee55e2 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -80,7 +80,6 @@ static const struct ena_stats ena_stats_tx_strings[] = {
ENA_STAT_TX_ENTRY(tx_poll),
ENA_STAT_TX_ENTRY(doorbells),
ENA_STAT_TX_ENTRY(prepare_ctx_err),
-   ENA_STAT_TX_ENTRY(missing_tx_comp),
ENA_STAT_TX_ENTRY(bad_req_id),
 };
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 3c366bf..4f16ed3 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1995,6 +1995,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
tx_info->tx_descs = nb_hw_desc;
tx_info->last_jiffies = jiffies;
+   tx_info->print_once = 0;
 
tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
tx_ring->ring_size);
@@ -2564,13 +2565,44 @@ static void ena_fw_reset_device(struct work_struct 
*work)
"Reset attempt failed. Can not reset the device\n");
 }
 
-static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+static int check_missing_comp_in_queue(struct ena_adapter *adapter,
+  struct ena_ring *tx_ring)
 {
struct ena_tx_buffer *tx_buf;
unsigned long last_jiffies;
+   u32 missed_tx = 0;
+   int i;
+
+   for (i = 0; i < tx_ring->ring_size; i++) {
+   tx_buf = &tx_ring->tx_buffer_info[i];
+   last_jiffies = tx_buf->last_jiffies;
+   if (unlikely(last_jiffies &&
+time_is_before_jiffies(last_jiffies + 
TX_TIMEOUT))) {
+   if (!tx_buf->print_once)
+   netif_notice(adapter, tx_err, adapter->netdev,
+"Found a Tx that wasn't completed 
on time, qid %d, index %d.\n",
+tx_ring->qid, i);
+
+   tx_buf->print_once = 1;
+   missed_tx++;
+
+   if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) 
{
+   netif_err(adapter, tx_err, adapter->netdev,
+ "The number of lost tx completions is 
above the threshold (%d > %d). Reset the device\n",
+ missed_tx, 
MAX_NUM_OF_TIMEOUTED_PACKETS);
+   set_bit(ENA_FLAG_TRIGGER_RESET, 
&adapter->flags);
+   return -EIO;
+   }
+   }
+   }
+
+   return 0;
+}
+
+static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+{
struct ena_ring *tx_ring;
-   int i, j, budget;
-   u32 missed_tx;
+   int i, budget, rc;
 
/* Make sure the driver doesn't turn the device in other process */
smp_rmb();
@@ -2586,31 +2618,9 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
tx_ring = &adapter->tx_ring[i];
 
-   for (j = 0; j < tx_ring->ring_size; j++) {
-   tx_buf = &tx_ring->tx_buffer_info[j];
-   last_jiffies = tx_buf->last_jiffies;
-   if (unlikely(last_jiffies && 
time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
-   netif_notice(adapter, tx_err, adapter->netdev,
-"Found a Tx that wasn't completed 
on time, qid %d, index %d.\n",
-tx_ring->qid, j);
-
-   u64_stats_update_begin(&tx_ring->syncp);
-   missed_tx = tx_ring->tx_stats.missing_tx_comp++;
-   u64_stats_update_end(&tx_ring->syncp);
-
-   /* Clear last jiffies so the lost buffer won't
-  

[PATCH net-next 5/8] net: ena: add missing unmap bars on device removal

2017-06-09 Thread netanel
From: Netanel Belgazal 

This patch also change the mapping functions to devm_ functions

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 1e71e89..4e9fbdd 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2853,6 +2853,11 @@ static void ena_release_bars(struct ena_com_dev 
*ena_dev, struct pci_dev *pdev)
 {
int release_bars;
 
+   if (ena_dev->mem_bar)
+   devm_iounmap(&pdev->dev, ena_dev->mem_bar);
+
+   devm_iounmap(&pdev->dev, ena_dev->reg_bar);
+
release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
pci_release_selected_regions(pdev, release_bars);
 }
@@ -2940,8 +2945,9 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto err_free_ena_dev;
}
 
-   ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR),
-  pci_resource_len(pdev, ENA_REG_BAR));
+   ena_dev->reg_bar = devm_ioremap(&pdev->dev,
+   pci_resource_start(pdev, ENA_REG_BAR),
+   pci_resource_len(pdev, ENA_REG_BAR));
if (!ena_dev->reg_bar) {
dev_err(&pdev->dev, "failed to remap regs bar\n");
rc = -EFAULT;
@@ -2961,8 +2967,9 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);
 
if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
-   ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, 
ENA_MEM_BAR),
- pci_resource_len(pdev, 
ENA_MEM_BAR));
+   ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
+  pci_resource_start(pdev, 
ENA_MEM_BAR),
+  pci_resource_len(pdev, 
ENA_MEM_BAR));
if (!ena_dev->mem_bar) {
rc = -EFAULT;
goto err_device_destroy;
-- 
2.7.4



[PATCH net-next 3/8] net: ena: add missing return when ena_com_get_io_handlers() fails

2017-06-09 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0e3c60c7..1e71e89 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1543,6 +1543,7 @@ static int ena_create_io_tx_queue(struct ena_adapter 
*adapter, int qid)
  "Failed to get TX queue handlers. TX queue num %d rc: 
%d\n",
  qid, rc);
ena_com_destroy_io_queue(ena_dev, ena_qid);
+   return rc;
}
 
ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node);
@@ -1607,6 +1608,7 @@ static int ena_create_io_rx_queue(struct ena_adapter 
*adapter, int qid)
  "Failed to get RX queue handlers. RX queue num %d rc: 
%d\n",
  qid, rc);
ena_com_destroy_io_queue(ena_dev, ena_qid);
+   return rc;
}
 
ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node);
-- 
2.7.4



[PATCH net-next 0/8] Bug fixes in ena ethernet driver

2017-06-09 Thread netanel
From: Netanel Belgazal 

This patchset contains fixes for the bugs that were discovered so far.

Netanel Belgazal (8):
  net: ena: fix rare uncompleted admin command false alarm
  net: ena: fix bug that might cause hang after consecutive open/close
interface.
  net: ena: add missing return when ena_com_get_io_handlers() fails
  net: ena: fix race condition between submit and completion admin
command
  net: ena: add missing unmap bars on device removal
  net: ena: fix theoretical Rx hang on low memory systems
  net: ena: disable admin msix while working in polling mode
  net: ena: bug fix in lost tx packets detection mechanism

 drivers/net/ethernet/amazon/ena/ena_com.c |  35 +++--
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |   2 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 179 +++---
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  16 ++-
 4 files changed, 168 insertions(+), 64 deletions(-)

-- 
2.7.4



Re: [PATCH net-next 0/8] Bug fixes in ena ethernet driver

2017-06-09 Thread Belgazal, Netanel
I the last minute I fixed patchset #6 commit subject from stuck to hang and I 
forget to remove it.
Sorry for that.
resubmitted.

From: David Miller 
Sent: Friday, June 9, 2017 10:33 PM
To: Belgazal, Netanel
Cc: netdev@vger.kernel.org; Woodhouse, David; Machulsky, Zorik; Matushevsky, 
Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; Bshara, Nafea; 
Schmeilin, Evgeny
Subject: Re: [PATCH net-next 0/8] Bug fixes in ena ethernet driver

From: 
Date: Fri, 9 Jun 2017 09:55:16 +0300

> This patchset contains fixes for the bugs that were discovered so far.

You submitted patch #6 twice, once with the word "stuck" in the subject
line, once with the word "hang" in the subject line.

Please sort this out and resubmit, thanks.



[PATCH net-next 1/8] net: ena: fix rare uncompleted admin command false alarm

2017-06-09 Thread netanel
From: Netanel Belgazal 

The current flow to detect admin completion is:
while (command_not_completed) {
if (timeout)
error

check_for_completion()
sleep()
   }
So in case the sleep took more than the timeout
(in case the thread/workqueue was not scheduled due to higher priority
task or prolonged VMexit), the driver can detect a stall even if
the completion is present.

The fix changes the order of this function to first check for
completion and only after that check if the timeout expired.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 08d11ce..e1c2fab 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
 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;
-   u32 start_time;
+   unsigned long flags, timeout;
int ret;
 
-   start_time = ((u32)jiffies_to_usecs(jiffies));
+   timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+
+   while (1) {
+   spin_lock_irqsave(&admin_queue->q_lock, flags);
+   ena_com_handle_admin_completion(admin_queue);
+   spin_unlock_irqrestore(&admin_queue->q_lock, flags);
 
-   while (comp_ctx->status == ENA_CMD_SUBMITTED) {
-   if u32)jiffies_to_usecs(jiffies)) - start_time) >
-   ADMIN_CMD_TIMEOUT_US) {
+   if (comp_ctx->status != ENA_CMD_SUBMITTED)
+   break;
+
+   if (time_is_before_jiffies(timeout)) {
pr_err("Wait for completion (polling) timeout\n");
/* ENA didn't have any completion */
spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -528,10 +533,6 @@ static int 
ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
goto err;
}
 
-   spin_lock_irqsave(&admin_queue->q_lock, flags);
-   ena_com_handle_admin_completion(admin_queue);
-   spin_unlock_irqrestore(&admin_queue->q_lock, flags);
-
msleep(100);
}
 
-- 
2.7.4



[PATCH net-next 2/8] net: ena: fix bug that might cause hang after consecutive open/close interface.

2017-06-09 Thread netanel
From: Netanel Belgazal 

Fixing a bug that the driver does not unmask the IO interrupts
in ndo_open():
occasionally, the MSI-X interrupt (for one or more IO queues)
can be masked when ndo_close() was called.
If that is followed by ndo open(),
then the MSI-X will be still masked so no interrupt
will be received by the driver.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 41 ++--
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7c1214d..0e3c60c7 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1078,6 +1078,26 @@ inline void ena_adjust_intr_moderation(struct ena_ring 
*rx_ring,
rx_ring->per_napi_bytes = 0;
 }
 
+static inline void ena_unmask_interrupt(struct ena_ring *tx_ring,
+   struct ena_ring *rx_ring)
+{
+   struct ena_eth_io_intr_reg intr_reg;
+
+   /* Update intr register: rx intr delay,
+* tx intr delay and interrupt unmask
+*/
+   ena_com_update_intr_reg(&intr_reg,
+   rx_ring->smoothed_interval,
+   tx_ring->smoothed_interval,
+   true);
+
+   /* It is a shared MSI-X.
+* Tx and Rx CQ have pointer to it.
+* So we use one of them to reach the intr reg
+*/
+   ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+}
+
 static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,
 struct ena_ring *rx_ring)
 {
@@ -1108,7 +1128,6 @@ static int ena_io_poll(struct napi_struct *napi, int 
budget)
 {
struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
struct ena_ring *tx_ring, *rx_ring;
-   struct ena_eth_io_intr_reg intr_reg;
 
u32 tx_work_done;
u32 rx_work_done;
@@ -1149,22 +1168,9 @@ static int ena_io_poll(struct napi_struct *napi, int 
budget)
if 
(ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
ena_adjust_intr_moderation(rx_ring, tx_ring);
 
-   /* Update intr register: rx intr delay,
-* tx intr delay and interrupt unmask
-*/
-   ena_com_update_intr_reg(&intr_reg,
-   rx_ring->smoothed_interval,
-   tx_ring->smoothed_interval,
-   true);
-
-   /* It is a shared MSI-X.
-* Tx and Rx CQ have pointer to it.
-* So we use one of them to reach the intr reg
-*/
-   ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+   ena_unmask_interrupt(tx_ring, rx_ring);
}
 
-
ena_update_ring_numa_node(tx_ring, rx_ring);
 
ret = rx_work_done;
@@ -1485,6 +1491,11 @@ static int ena_up_complete(struct ena_adapter *adapter)
 
ena_napi_enable_all(adapter);
 
+   /* Enable completion queues interrupt */
+   for (i = 0; i < adapter->num_queues; i++)
+   ena_unmask_interrupt(&adapter->tx_ring[i],
+&adapter->rx_ring[i]);
+
/* schedule napi in case we had pending packets
 * from the last time we disable napi
 */
-- 
2.7.4



Re: [PATCH net-next 0/8] Bug fixes in ena ethernet driver

2017-06-09 Thread Belgazal, Netanel
My apologies,
I was not aware.
Will make sure this won't happen again.

Regards,
Netanel

From: David Miller 
Sent: Friday, June 9, 2017 2:17 AM
To: Belgazal, Netanel
Cc: netdev@vger.kernel.org; Woodhouse, David; Machulsky, Zorik; Matushevsky, 
Alexander; BSHARA, Said; Wilson, Matt; Liguori, Anthony; Bshara, Nafea; 
Schmeilin, Evgeny
Subject: Re: [PATCH net-next 0/8] Bug fixes in ena ethernet driver

Two parallel patch series to the same driver and targetting the
same GIT tree is extremely undesirable, please don't do this.

Submit one series, and once applied submit the second series.

I'm deleting all of your patches from my queue, please resubmit
things properly.

Thank you.


[PATCH net-next 8/8] net: ena: bug fix in lost tx packets detection mechanism

2017-06-08 Thread netanel
From: Netanel Belgazal 

check_for_missing_tx_completions() is called from a timer
task and looking for lost tx packets.
The old implementation accumulate all the lost tx packets
and did not check if those packets were retrieved on a later stage.
This cause to a situation where the driver reset
the device for no reason.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 -
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 66 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  | 14 +-
 3 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 533b2fb..3ee55e2 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -80,7 +80,6 @@ static const struct ena_stats ena_stats_tx_strings[] = {
ENA_STAT_TX_ENTRY(tx_poll),
ENA_STAT_TX_ENTRY(doorbells),
ENA_STAT_TX_ENTRY(prepare_ctx_err),
-   ENA_STAT_TX_ENTRY(missing_tx_comp),
ENA_STAT_TX_ENTRY(bad_req_id),
 };
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 3c366bf..4f16ed3 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1995,6 +1995,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
tx_info->tx_descs = nb_hw_desc;
tx_info->last_jiffies = jiffies;
+   tx_info->print_once = 0;
 
tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
tx_ring->ring_size);
@@ -2564,13 +2565,44 @@ static void ena_fw_reset_device(struct work_struct 
*work)
"Reset attempt failed. Can not reset the device\n");
 }
 
-static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+static int check_missing_comp_in_queue(struct ena_adapter *adapter,
+  struct ena_ring *tx_ring)
 {
struct ena_tx_buffer *tx_buf;
unsigned long last_jiffies;
+   u32 missed_tx = 0;
+   int i;
+
+   for (i = 0; i < tx_ring->ring_size; i++) {
+   tx_buf = &tx_ring->tx_buffer_info[i];
+   last_jiffies = tx_buf->last_jiffies;
+   if (unlikely(last_jiffies &&
+time_is_before_jiffies(last_jiffies + 
TX_TIMEOUT))) {
+   if (!tx_buf->print_once)
+   netif_notice(adapter, tx_err, adapter->netdev,
+"Found a Tx that wasn't completed 
on time, qid %d, index %d.\n",
+tx_ring->qid, i);
+
+   tx_buf->print_once = 1;
+   missed_tx++;
+
+   if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) 
{
+   netif_err(adapter, tx_err, adapter->netdev,
+ "The number of lost tx completions is 
above the threshold (%d > %d). Reset the device\n",
+ missed_tx, 
MAX_NUM_OF_TIMEOUTED_PACKETS);
+   set_bit(ENA_FLAG_TRIGGER_RESET, 
&adapter->flags);
+   return -EIO;
+   }
+   }
+   }
+
+   return 0;
+}
+
+static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+{
struct ena_ring *tx_ring;
-   int i, j, budget;
-   u32 missed_tx;
+   int i, budget, rc;
 
/* Make sure the driver doesn't turn the device in other process */
smp_rmb();
@@ -2586,31 +2618,9 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
tx_ring = &adapter->tx_ring[i];
 
-   for (j = 0; j < tx_ring->ring_size; j++) {
-   tx_buf = &tx_ring->tx_buffer_info[j];
-   last_jiffies = tx_buf->last_jiffies;
-   if (unlikely(last_jiffies && 
time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
-   netif_notice(adapter, tx_err, adapter->netdev,
-"Found a Tx that wasn't completed 
on time, qid %d, index %d.\n",
-tx_ring->qid, j);
-
-   u64_stats_update_begin(&tx_ring->syncp);
-   missed_tx = tx_ring->tx_stats.missing_tx_comp++;
-   u64_stats_update_end(&tx_ring->syncp);
-
-   /* Clear last jiffies so the lost buffer won't
-  

[PATCH net-next 6/8] net: ena: fix theoretical Rx stuck on low memory systems

2017-06-08 Thread netanel
From: Netanel Belgazal 

For the rare case where the device runs out of free rx buffer
descriptors (in case of pressure on kernel  memory),
and the napi handler continuously fail to refill new Rx descriptors
until device rx queue totally runs out of all free rx buffers
to post incoming packet, leading to a deadlock:
* The device won't send interrupts since all the new
Rx packets will be dropped.
* The napi handler won't try to allocate new Rx descriptors
since allocation is part of NAPI that's not being invoked any more

The fix involves detecting this scenario and rescheduling NAPI
(to refill buffers) by the keepalive/watchdog task.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 55 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  2 +
 3 files changed, 58 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 67b2338f..533b2fb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -94,6 +94,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
ENA_STAT_RX_ENTRY(dma_mapping_err),
ENA_STAT_RX_ENTRY(bad_desc_num),
ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+   ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
 static const struct ena_stats ena_stats_ena_com_strings[] = {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 4e9fbdd..3c366bf 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter)
rxr->sgl_size = adapter->max_rx_sgl_size;
rxr->smoothed_interval =
ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+   rxr->empty_rx_queue = 0;
}
 }
 
@@ -2619,6 +2620,58 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
adapter->last_monitored_tx_qid = i % adapter->num_queues;
 }
 
+/* trigger napi schedule after 2 consecutive detections */
+#define EMPTY_RX_REFILL 2
+/* For the rare case where the device runs out of Rx descriptors and the
+ * napi handler failed to refill new Rx descriptors (due to a lack of memory
+ * for example).
+ * This case will lead to a deadlock:
+ * The device won't send interrupts since all the new Rx packets will be 
dropped
+ * The napi handler won't allocate new Rx descriptors so the device will be
+ * able to send new packets.
+ *
+ * This scenario can happen when the kernel's vm.min_free_kbytes is too small.
+ * It is recommended to have at least 512MB, with a minimum of 128MB for
+ * constrained environment).
+ *
+ * When such a situation is detected - Reschedule napi
+ */
+static void check_for_empty_rx_ring(struct ena_adapter *adapter)
+{
+   struct ena_ring *rx_ring;
+   int i, refill_required;
+
+   if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+   return;
+
+   if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
+   return;
+
+   for (i = 0; i < adapter->num_queues; i++) {
+   rx_ring = &adapter->rx_ring[i];
+
+   refill_required =
+   ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
+   if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
+   rx_ring->empty_rx_queue++;
+
+   if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL) {
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.empty_rx_ring++;
+   u64_stats_update_end(&rx_ring->syncp);
+
+   netif_err(adapter, drv, adapter->netdev,
+ "trigger refill for ring %d\n", i);
+
+   napi_schedule(rx_ring->napi);
+   rx_ring->empty_rx_queue = 0;
+   }
+   } else {
+   rx_ring->empty_rx_queue = 0;
+   }
+   }
+}
+
 /* Check for keep alive expiration */
 static void check_for_missing_keep_alive(struct ena_adapter *adapter)
 {
@@ -2673,6 +2726,8 @@ static void ena_timer_service(unsigned long data)
 
check_for_missing_tx_completions(adapter);
 
+   check_for_empty_rx_ring(adapter);
+
if (debug_area)
ena_dump_stats_to_buf(adapter, debug_area);
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 0e22bce..8828f1d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/ama

[PATCH net-next 7/8] net: ena: disable admin msix while working in polling mode

2017-06-08 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index ea60b9e..f5b237e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -61,6 +61,8 @@
 
 #define ENA_MMIO_READ_TIMEOUT 0x
 
+#define ENA_REGS_ADMIN_INTR_MASK 1
+
 /*/
 /*/
 /*/
@@ -1454,6 +1456,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev)
 
 void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)
 {
+   u32 mask_value = 0;
+
+   if (polling)
+   mask_value = ENA_REGS_ADMIN_INTR_MASK;
+
+   writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF);
ena_dev->admin_queue.polling = polling;
 }
 
-- 
2.7.4



[PATCH net-next 5/8] net: ena: add missing unmap bars on device removal

2017-06-08 Thread netanel
From: Netanel Belgazal 

This patch also change the mapping functions to devm_ functions

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 1e71e89..4e9fbdd 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2853,6 +2853,11 @@ static void ena_release_bars(struct ena_com_dev 
*ena_dev, struct pci_dev *pdev)
 {
int release_bars;
 
+   if (ena_dev->mem_bar)
+   devm_iounmap(&pdev->dev, ena_dev->mem_bar);
+
+   devm_iounmap(&pdev->dev, ena_dev->reg_bar);
+
release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
pci_release_selected_regions(pdev, release_bars);
 }
@@ -2940,8 +2945,9 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto err_free_ena_dev;
}
 
-   ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR),
-  pci_resource_len(pdev, ENA_REG_BAR));
+   ena_dev->reg_bar = devm_ioremap(&pdev->dev,
+   pci_resource_start(pdev, ENA_REG_BAR),
+   pci_resource_len(pdev, ENA_REG_BAR));
if (!ena_dev->reg_bar) {
dev_err(&pdev->dev, "failed to remap regs bar\n");
rc = -EFAULT;
@@ -2961,8 +2967,9 @@ static int ena_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);
 
if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
-   ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, 
ENA_MEM_BAR),
- pci_resource_len(pdev, 
ENA_MEM_BAR));
+   ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
+  pci_resource_start(pdev, 
ENA_MEM_BAR),
+  pci_resource_len(pdev, 
ENA_MEM_BAR));
if (!ena_dev->mem_bar) {
rc = -EFAULT;
goto err_device_destroy;
-- 
2.7.4



[PATCH net-next 3/8] net: ena: add missing return when ena_com_get_io_handlers() fails

2017-06-08 Thread netanel
From: Netanel Belgazal 

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0e3c60c7..1e71e89 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1543,6 +1543,7 @@ static int ena_create_io_tx_queue(struct ena_adapter 
*adapter, int qid)
  "Failed to get TX queue handlers. TX queue num %d rc: 
%d\n",
  qid, rc);
ena_com_destroy_io_queue(ena_dev, ena_qid);
+   return rc;
}
 
ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node);
@@ -1607,6 +1608,7 @@ static int ena_create_io_rx_queue(struct ena_adapter 
*adapter, int qid)
  "Failed to get RX queue handlers. RX queue num %d rc: 
%d\n",
  qid, rc);
ena_com_destroy_io_queue(ena_dev, ena_qid);
+   return rc;
}
 
ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node);
-- 
2.7.4



[PATCH net-next 6/8] net: ena: fix theoretical Rx hang on low memory systems

2017-06-08 Thread netanel
From: Netanel Belgazal 

For the rare case where the device runs out of free rx buffer
descriptors (in case of pressure on kernel  memory),
and the napi handler continuously fail to refill new Rx descriptors
until device rx queue totally runs out of all free rx buffers
to post incoming packet, leading to a deadlock:
* The device won't send interrupts since all the new
Rx packets will be dropped.
* The napi handler won't try to allocate new Rx descriptors
since allocation is part of NAPI that's not being invoked any more

The fix involves detecting this scenario and rescheduling NAPI
(to refill buffers) by the keepalive/watchdog task.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |  1 +
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 55 +++
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  2 +
 3 files changed, 58 insertions(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 67b2338f..533b2fb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -94,6 +94,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
ENA_STAT_RX_ENTRY(dma_mapping_err),
ENA_STAT_RX_ENTRY(bad_desc_num),
ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+   ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
 static const struct ena_stats ena_stats_ena_com_strings[] = {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 4e9fbdd..3c366bf 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter)
rxr->sgl_size = adapter->max_rx_sgl_size;
rxr->smoothed_interval =
ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+   rxr->empty_rx_queue = 0;
}
 }
 
@@ -2619,6 +2620,58 @@ static void check_for_missing_tx_completions(struct 
ena_adapter *adapter)
adapter->last_monitored_tx_qid = i % adapter->num_queues;
 }
 
+/* trigger napi schedule after 2 consecutive detections */
+#define EMPTY_RX_REFILL 2
+/* For the rare case where the device runs out of Rx descriptors and the
+ * napi handler failed to refill new Rx descriptors (due to a lack of memory
+ * for example).
+ * This case will lead to a deadlock:
+ * The device won't send interrupts since all the new Rx packets will be 
dropped
+ * The napi handler won't allocate new Rx descriptors so the device will be
+ * able to send new packets.
+ *
+ * This scenario can happen when the kernel's vm.min_free_kbytes is too small.
+ * It is recommended to have at least 512MB, with a minimum of 128MB for
+ * constrained environment).
+ *
+ * When such a situation is detected - Reschedule napi
+ */
+static void check_for_empty_rx_ring(struct ena_adapter *adapter)
+{
+   struct ena_ring *rx_ring;
+   int i, refill_required;
+
+   if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+   return;
+
+   if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
+   return;
+
+   for (i = 0; i < adapter->num_queues; i++) {
+   rx_ring = &adapter->rx_ring[i];
+
+   refill_required =
+   ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
+   if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
+   rx_ring->empty_rx_queue++;
+
+   if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL) {
+   u64_stats_update_begin(&rx_ring->syncp);
+   rx_ring->rx_stats.empty_rx_ring++;
+   u64_stats_update_end(&rx_ring->syncp);
+
+   netif_err(adapter, drv, adapter->netdev,
+ "trigger refill for ring %d\n", i);
+
+   napi_schedule(rx_ring->napi);
+   rx_ring->empty_rx_queue = 0;
+   }
+   } else {
+   rx_ring->empty_rx_queue = 0;
+   }
+   }
+}
+
 /* Check for keep alive expiration */
 static void check_for_missing_keep_alive(struct ena_adapter *adapter)
 {
@@ -2673,6 +2726,8 @@ static void ena_timer_service(unsigned long data)
 
check_for_missing_tx_completions(adapter);
 
+   check_for_empty_rx_ring(adapter);
+
if (debug_area)
ena_dump_stats_to_buf(adapter, debug_area);
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h 
b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 0e22bce..8828f1d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/ama

[PATCH net-next 2/8] net: ena: fix bug that might cause hang after consecutive open/close interface.

2017-06-08 Thread netanel
From: Netanel Belgazal 

Fixing a bug that the driver does not unmask the IO interrupts
in ndo_open():
occasionally, the MSI-X interrupt (for one or more IO queues)
can be masked when ndo_close() was called.
If that is followed by ndo open(),
then the MSI-X will be still masked so no interrupt
will be received by the driver.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 41 ++--
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c 
b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 7c1214d..0e3c60c7 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1078,6 +1078,26 @@ inline void ena_adjust_intr_moderation(struct ena_ring 
*rx_ring,
rx_ring->per_napi_bytes = 0;
 }
 
+static inline void ena_unmask_interrupt(struct ena_ring *tx_ring,
+   struct ena_ring *rx_ring)
+{
+   struct ena_eth_io_intr_reg intr_reg;
+
+   /* Update intr register: rx intr delay,
+* tx intr delay and interrupt unmask
+*/
+   ena_com_update_intr_reg(&intr_reg,
+   rx_ring->smoothed_interval,
+   tx_ring->smoothed_interval,
+   true);
+
+   /* It is a shared MSI-X.
+* Tx and Rx CQ have pointer to it.
+* So we use one of them to reach the intr reg
+*/
+   ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+}
+
 static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,
 struct ena_ring *rx_ring)
 {
@@ -1108,7 +1128,6 @@ static int ena_io_poll(struct napi_struct *napi, int 
budget)
 {
struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
struct ena_ring *tx_ring, *rx_ring;
-   struct ena_eth_io_intr_reg intr_reg;
 
u32 tx_work_done;
u32 rx_work_done;
@@ -1149,22 +1168,9 @@ static int ena_io_poll(struct napi_struct *napi, int 
budget)
if 
(ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
ena_adjust_intr_moderation(rx_ring, tx_ring);
 
-   /* Update intr register: rx intr delay,
-* tx intr delay and interrupt unmask
-*/
-   ena_com_update_intr_reg(&intr_reg,
-   rx_ring->smoothed_interval,
-   tx_ring->smoothed_interval,
-   true);
-
-   /* It is a shared MSI-X.
-* Tx and Rx CQ have pointer to it.
-* So we use one of them to reach the intr reg
-*/
-   ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+   ena_unmask_interrupt(tx_ring, rx_ring);
}
 
-
ena_update_ring_numa_node(tx_ring, rx_ring);
 
ret = rx_work_done;
@@ -1485,6 +1491,11 @@ static int ena_up_complete(struct ena_adapter *adapter)
 
ena_napi_enable_all(adapter);
 
+   /* Enable completion queues interrupt */
+   for (i = 0; i < adapter->num_queues; i++)
+   ena_unmask_interrupt(&adapter->tx_ring[i],
+&adapter->rx_ring[i]);
+
/* schedule napi in case we had pending packets
 * from the last time we disable napi
 */
-- 
2.7.4



[PATCH net-next 1/8] net: ena: fix rare uncompleted admin command false alarm

2017-06-08 Thread netanel
From: Netanel Belgazal 

The current flow to detect admin completion is:
while (command_not_completed) {
if (timeout)
error

check_for_completion()
sleep()
   }
So in case the sleep took more than the timeout
(in case the thread/workqueue was not scheduled due to higher priority
task or prolonged VMexit), the driver can detect a stall even if
the completion is present.

The fix changes the order of this function to first check for
completion and only after that check if the timeout expired.

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index 08d11ce..e1c2fab 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
 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;
-   u32 start_time;
+   unsigned long flags, timeout;
int ret;
 
-   start_time = ((u32)jiffies_to_usecs(jiffies));
+   timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+
+   while (1) {
+   spin_lock_irqsave(&admin_queue->q_lock, flags);
+   ena_com_handle_admin_completion(admin_queue);
+   spin_unlock_irqrestore(&admin_queue->q_lock, flags);
 
-   while (comp_ctx->status == ENA_CMD_SUBMITTED) {
-   if u32)jiffies_to_usecs(jiffies)) - start_time) >
-   ADMIN_CMD_TIMEOUT_US) {
+   if (comp_ctx->status != ENA_CMD_SUBMITTED)
+   break;
+
+   if (time_is_before_jiffies(timeout)) {
pr_err("Wait for completion (polling) timeout\n");
/* ENA didn't have any completion */
spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -528,10 +533,6 @@ static int 
ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
goto err;
}
 
-   spin_lock_irqsave(&admin_queue->q_lock, flags);
-   ena_com_handle_admin_completion(admin_queue);
-   spin_unlock_irqrestore(&admin_queue->q_lock, flags);
-
msleep(100);
}
 
-- 
2.7.4



[PATCH net-next 0/8] Bug fixes in ena ethernet driver

2017-06-08 Thread netanel
From: Netanel Belgazal 

This patchset contains fixes for the bugs that were discovered so far.

Netanel Belgazal (8):
  net: ena: fix rare uncompleted admin command false alarm
  net: ena: fix bug that might cause hang after consecutive open/close
interface.
  net: ena: add missing return when ena_com_get_io_handlers() fails
  net: ena: fix race condition between submit and completion admin
command
  net: ena: add missing unmap bars on device removal
  net: ena: fix theoretical Rx hang on low memory systems
  net: ena: disable admin msix while working in polling mode
  net: ena: bug fix in lost tx packets detection mechanism

 drivers/net/ethernet/amazon/ena/ena_com.c |  35 +++--
 drivers/net/ethernet/amazon/ena/ena_ethtool.c |   2 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 179 +++---
 drivers/net/ethernet/amazon/ena/ena_netdev.h  |  16 ++-
 4 files changed, 168 insertions(+), 64 deletions(-)

-- 
2.7.4



[PATCH net-next 4/8] net: ena: fix race condition between submit and completion admin command

2017-06-08 Thread netanel
From: Netanel Belgazal 

Bug:
"Completion context is occupied" error printout will be noticed in
dmesg.
This error will cause the admin command to fail, which will lead to
an ena_probe() failure or a watchdog reset (depends on which admin
command failed).

Root cause:
__ena_com_submit_admin_cmd() is the function that submits new entries to
the admin queue.
The function have a check that makes sure the queue is not full and the
function does not override any outstanding command.
It uses head and tail indexes for this check.
The head is increased by ena_com_handle_admin_completion() which runs
from interrupt context, and the tail index is increased by the submit
function (the function is running under ->q_lock, so there is no risk
of multithread increment).
Each command is associated with a completion context. This context
allocated before call to __ena_com_submit_admin_cmd() and freed by
ena_com_wait_and_process_admin_cq_interrupts(), right after the command
was completed.

This can lead to a state where the head was increased, the check passed,
but the completion context is still in use.

Solution:
Use the atomic variable ->outstanding_cmds instead of using the head and
the tail indexes.
This variable is safe for use since it is bumped in get_comp_ctx() in
__ena_com_submit_admin_cmd() and is freed by comp_ctxt_release()

Signed-off-by: Netanel Belgazal 
---
 drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c 
b/drivers/net/ethernet/amazon/ena/ena_com.c
index e1c2fab..ea60b9e 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -232,11 +232,9 @@ static struct ena_comp_ctx 
*__ena_com_submit_admin_cmd(struct ena_com_admin_queu
tail_masked = admin_queue->sq.tail & queue_size_mask;
 
/* In case of queue FULL */
-   cnt = admin_queue->sq.tail - admin_queue->sq.head;
+   cnt = atomic_read(&admin_queue->outstanding_cmds);
if (cnt >= admin_queue->q_depth) {
-   pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n",
-admin_queue->sq.tail, admin_queue->sq.head,
-admin_queue->q_depth);
+   pr_debug("admin queue is full.\n");
admin_queue->stats.out_of_space++;
return ERR_PTR(-ENOSPC);
}
-- 
2.7.4



  1   2   3   >