Commit 0e1f4c76 authored by David S. Miller's avatar David S. Miller

Merge branch 'ena-fixes'

Netanel Belgazal says:

====================
bug fixes for ENA Ethernet driver
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5cf4a853 37dff155
...@@ -459,12 +459,12 @@ static void ena_com_handle_admin_completion(struct ena_com_admin_queue *admin_qu ...@@ -459,12 +459,12 @@ static void ena_com_handle_admin_completion(struct ena_com_admin_queue *admin_qu
cqe = &admin_queue->cq.entries[head_masked]; cqe = &admin_queue->cq.entries[head_masked];
/* Go over all the completions */ /* 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) { ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) {
/* Do not read the rest of the completion entry before the /* Do not read the rest of the completion entry before the
* phase bit was validated * phase bit was validated
*/ */
rmb(); dma_rmb();
ena_com_handle_single_admin_completion(admin_queue, cqe); ena_com_handle_single_admin_completion(admin_queue, cqe);
head_masked++; head_masked++;
...@@ -627,17 +627,10 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset) ...@@ -627,17 +627,10 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
mmio_read_reg |= mmio_read->seq_num & mmio_read_reg |= mmio_read->seq_num &
ENA_REGS_MMIO_REG_READ_REQ_ID_MASK; ENA_REGS_MMIO_REG_READ_REQ_ID_MASK;
/* make sure read_resp->req_id get updated before the hw can write writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
* there
*/
wmb();
writel_relaxed(mmio_read_reg,
ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
mmiowb();
for (i = 0; i < timeout; i++) { 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; break;
udelay(1); udelay(1);
...@@ -1796,8 +1789,13 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data) ...@@ -1796,8 +1789,13 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
aenq_common = &aenq_e->aenq_common_desc; aenq_common = &aenq_e->aenq_common_desc;
/* Go over all the events */ /* Go over all the events */
while ((aenq_common->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == while ((READ_ONCE(aenq_common->flags) &
phase) { 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", pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n",
aenq_common->group, aenq_common->syndrom, aenq_common->group, aenq_common->syndrom,
(u64)aenq_common->timestamp_low + (u64)aenq_common->timestamp_low +
......
...@@ -51,6 +51,11 @@ static inline struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc( ...@@ -51,6 +51,11 @@ static inline struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc(
if (desc_phase != expected_phase) if (desc_phase != expected_phase)
return NULL; return NULL;
/* Make sure we read the rest of the descriptor after the phase bit
* has been read
*/
dma_rmb();
return cdesc; return cdesc;
} }
...@@ -493,6 +498,7 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id) ...@@ -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) if (cdesc_phase != expected_phase)
return -EAGAIN; return -EAGAIN;
dma_rmb();
if (unlikely(cdesc->req_id >= io_cq->q_depth)) { if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
pr_err("Invalid req id %d\n", cdesc->req_id); pr_err("Invalid req id %d\n", cdesc->req_id);
return -EINVAL; return -EINVAL;
......
...@@ -107,8 +107,7 @@ static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq) ...@@ -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; 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; u16 tail;
...@@ -117,9 +116,6 @@ static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq, ...@@ -117,9 +116,6 @@ 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", pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
io_sq->qid, tail); 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; return 0;
......
...@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl); ...@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
static int ena_rss_init_default(struct ena_adapter *adapter); static int ena_rss_init_default(struct ena_adapter *adapter);
static void check_for_admin_com_state(struct ena_adapter *adapter); static void check_for_admin_com_state(struct ena_adapter *adapter);
static void ena_destroy_device(struct ena_adapter *adapter); static void ena_destroy_device(struct ena_adapter *adapter, bool graceful);
static int ena_restore_device(struct ena_adapter *adapter); static int ena_restore_device(struct ena_adapter *adapter);
static void ena_tx_timeout(struct net_device *dev) static void ena_tx_timeout(struct net_device *dev)
...@@ -461,7 +461,7 @@ static inline int ena_alloc_rx_page(struct ena_ring *rx_ring, ...@@ -461,7 +461,7 @@ static inline int ena_alloc_rx_page(struct ena_ring *rx_ring,
return -ENOMEM; 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); DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(rx_ring->dev, dma))) { if (unlikely(dma_mapping_error(rx_ring->dev, dma))) {
u64_stats_update_begin(&rx_ring->syncp); u64_stats_update_begin(&rx_ring->syncp);
...@@ -478,7 +478,7 @@ static inline int ena_alloc_rx_page(struct ena_ring *rx_ring, ...@@ -478,7 +478,7 @@ static inline int ena_alloc_rx_page(struct ena_ring *rx_ring,
rx_info->page_offset = 0; rx_info->page_offset = 0;
ena_buf = &rx_info->ena_buf; ena_buf = &rx_info->ena_buf;
ena_buf->paddr = dma; ena_buf->paddr = dma;
ena_buf->len = PAGE_SIZE; ena_buf->len = ENA_PAGE_SIZE;
return 0; return 0;
} }
...@@ -495,7 +495,7 @@ static void ena_free_rx_page(struct ena_ring *rx_ring, ...@@ -495,7 +495,7 @@ static void ena_free_rx_page(struct ena_ring *rx_ring,
return; 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); DMA_FROM_DEVICE);
__free_page(page); __free_page(page);
...@@ -551,14 +551,9 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num) ...@@ -551,14 +551,9 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
rx_ring->qid, i, num); rx_ring->qid, i, num);
} }
if (likely(i)) { /* ena_com_write_sq_doorbell issues a wmb() */
/* Add memory barrier to make sure the desc were written before if (likely(i))
* issue a doorbell ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
*/
wmb();
ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq, true);
mmiowb();
}
rx_ring->next_to_use = next_to_use; rx_ring->next_to_use = next_to_use;
...@@ -916,10 +911,10 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, ...@@ -916,10 +911,10 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
do { do {
dma_unmap_page(rx_ring->dev, dma_unmap_page(rx_ring->dev,
dma_unmap_addr(&rx_info->ena_buf, paddr), 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, 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, netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
"rx skb updated. len %d. data_len %d\n", "rx skb updated. len %d. data_len %d\n",
...@@ -1900,7 +1895,7 @@ static int ena_close(struct net_device *netdev) ...@@ -1900,7 +1895,7 @@ static int ena_close(struct net_device *netdev)
"Destroy failure, restarting device\n"); "Destroy failure, restarting device\n");
ena_dump_stats_to_dmesg(adapter); ena_dump_stats_to_dmesg(adapter);
/* rtnl lock already obtained in dev_ioctl() layer */ /* rtnl lock already obtained in dev_ioctl() layer */
ena_destroy_device(adapter); ena_destroy_device(adapter, false);
ena_restore_device(adapter); ena_restore_device(adapter);
} }
...@@ -2112,12 +2107,6 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2112,12 +2107,6 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use, tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
tx_ring->ring_size); tx_ring->ring_size);
/* This WMB is aimed to:
* 1 - perform smp barrier before reading next_to_completion
* 2 - make sure the desc were written before trigger DB
*/
wmb();
/* stop the queue when no more space available, the packet can have up /* stop the queue when no more space available, the packet can have up
* to sgl_size + 2. one for the meta descriptor and one for header * to sgl_size + 2. one for the meta descriptor and one for header
* (if the header is larger than tx_max_header_size). * (if the header is larger than tx_max_header_size).
...@@ -2136,10 +2125,11 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2136,10 +2125,11 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
* stop the queue but meanwhile clean_tx_irq updates * stop the queue but meanwhile clean_tx_irq updates
* next_to_completion and terminates. * next_to_completion and terminates.
* The queue will remain stopped forever. * The queue will remain stopped forever.
* To solve this issue this function perform rmb, check * To solve this issue add a mb() to make sure that
* the wakeup condition and wake up the queue if needed. * netif_tx_stop_queue() write is vissible before checking if
* there is additional space in the queue.
*/ */
smp_rmb(); smp_mb();
if (ena_com_sq_empty_space(tx_ring->ena_com_io_sq) if (ena_com_sq_empty_space(tx_ring->ena_com_io_sq)
> ENA_TX_WAKEUP_THRESH) { > ENA_TX_WAKEUP_THRESH) {
...@@ -2151,8 +2141,10 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2151,8 +2141,10 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
} }
if (netif_xmit_stopped(txq) || !skb->xmit_more) { if (netif_xmit_stopped(txq) || !skb->xmit_more) {
/* trigger the dma engine */ /* trigger the dma engine. ena_com_write_sq_doorbell()
ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq, false); * has a mb
*/
ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
u64_stats_update_begin(&tx_ring->syncp); u64_stats_update_begin(&tx_ring->syncp);
tx_ring->tx_stats.doorbells++; tx_ring->tx_stats.doorbells++;
u64_stats_update_end(&tx_ring->syncp); u64_stats_update_end(&tx_ring->syncp);
...@@ -2550,12 +2542,15 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter, ...@@ -2550,12 +2542,15 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return rc; return rc;
} }
static void ena_destroy_device(struct ena_adapter *adapter) static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ena_com_dev *ena_dev = adapter->ena_dev; struct ena_com_dev *ena_dev = adapter->ena_dev;
bool dev_up; bool dev_up;
if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
return;
netif_carrier_off(netdev); netif_carrier_off(netdev);
del_timer_sync(&adapter->timer_service); del_timer_sync(&adapter->timer_service);
...@@ -2563,6 +2558,7 @@ static void ena_destroy_device(struct ena_adapter *adapter) ...@@ -2563,6 +2558,7 @@ static void ena_destroy_device(struct ena_adapter *adapter)
dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
adapter->dev_up_before_reset = dev_up; adapter->dev_up_before_reset = dev_up;
if (!graceful)
ena_com_set_admin_running_state(ena_dev, false); ena_com_set_admin_running_state(ena_dev, false);
if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
...@@ -2591,6 +2587,7 @@ static void ena_destroy_device(struct ena_adapter *adapter) ...@@ -2591,6 +2587,7 @@ static void ena_destroy_device(struct ena_adapter *adapter)
adapter->reset_reason = ENA_REGS_RESET_NORMAL; adapter->reset_reason = ENA_REGS_RESET_NORMAL;
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); 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) static int ena_restore_device(struct ena_adapter *adapter)
...@@ -2635,6 +2632,7 @@ static int ena_restore_device(struct ena_adapter *adapter) ...@@ -2635,6 +2632,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)); mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
dev_err(&pdev->dev, "Device reset completed successfully\n"); dev_err(&pdev->dev, "Device reset completed successfully\n");
...@@ -2665,7 +2663,7 @@ static void ena_fw_reset_device(struct work_struct *work) ...@@ -2665,7 +2663,7 @@ static void ena_fw_reset_device(struct work_struct *work)
return; return;
} }
rtnl_lock(); rtnl_lock();
ena_destroy_device(adapter); ena_destroy_device(adapter, false);
ena_restore_device(adapter); ena_restore_device(adapter);
rtnl_unlock(); rtnl_unlock();
} }
...@@ -3409,30 +3407,24 @@ static void ena_remove(struct pci_dev *pdev) ...@@ -3409,30 +3407,24 @@ static void ena_remove(struct pci_dev *pdev)
netdev->rx_cpu_rmap = NULL; netdev->rx_cpu_rmap = NULL;
} }
#endif /* CONFIG_RFS_ACCEL */ #endif /* CONFIG_RFS_ACCEL */
unregister_netdev(netdev);
del_timer_sync(&adapter->timer_service); del_timer_sync(&adapter->timer_service);
cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->reset_task);
/* Reset the device only if the device is running. */ unregister_netdev(netdev);
if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
ena_com_dev_reset(ena_dev, adapter->reset_reason);
ena_free_mgmnt_irq(adapter); /* 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))
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
ena_disable_msix(adapter); rtnl_lock();
ena_destroy_device(adapter, true);
rtnl_unlock();
free_netdev(netdev); 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_rss_destroy(ena_dev);
ena_com_delete_debug_area(ena_dev); ena_com_delete_debug_area(ena_dev);
...@@ -3467,7 +3459,7 @@ static int ena_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3467,7 +3459,7 @@ static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
"ignoring device reset request as the device is being suspended\n"); "ignoring device reset request as the device is being suspended\n");
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
} }
ena_destroy_device(adapter); ena_destroy_device(adapter, true);
rtnl_unlock(); rtnl_unlock();
return 0; return 0;
} }
......
...@@ -355,4 +355,15 @@ void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf); ...@@ -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); 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) */ #endif /* !(ENA_H) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment