diff options
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 4 |
3 files changed, 14 insertions, 13 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index b4832230d744..34788fbb4c66 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -631,11 +631,14 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
631 | 631 | ||
632 | /* Initialise the channels */ | 632 | /* Initialise the channels */ |
633 | efx_for_each_channel(channel, efx) { | 633 | efx_for_each_channel(channel, efx) { |
634 | efx_for_each_channel_tx_queue(tx_queue, channel) | 634 | efx_for_each_channel_tx_queue(tx_queue, channel) { |
635 | efx_init_tx_queue(tx_queue); | 635 | efx_init_tx_queue(tx_queue); |
636 | atomic_inc(&efx->active_queues); | ||
637 | } | ||
636 | 638 | ||
637 | efx_for_each_channel_rx_queue(rx_queue, channel) { | 639 | efx_for_each_channel_rx_queue(rx_queue, channel) { |
638 | efx_init_rx_queue(rx_queue); | 640 | efx_init_rx_queue(rx_queue); |
641 | atomic_inc(&efx->active_queues); | ||
639 | efx_nic_generate_fill_event(rx_queue); | 642 | efx_nic_generate_fill_event(rx_queue); |
640 | } | 643 | } |
641 | 644 | ||
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index eb754cfff1ef..842f92e45517 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c | |||
@@ -594,7 +594,7 @@ static bool efx_farch_flush_wake(struct efx_nic *efx) | |||
594 | /* Ensure that all updates are visible to efx_farch_flush_queues() */ | 594 | /* Ensure that all updates are visible to efx_farch_flush_queues() */ |
595 | smp_mb(); | 595 | smp_mb(); |
596 | 596 | ||
597 | return (atomic_read(&efx->drain_pending) == 0 || | 597 | return (atomic_read(&efx->active_queues) == 0 || |
598 | (atomic_read(&efx->rxq_flush_outstanding) < EFX_RX_FLUSH_COUNT | 598 | (atomic_read(&efx->rxq_flush_outstanding) < EFX_RX_FLUSH_COUNT |
599 | && atomic_read(&efx->rxq_flush_pending) > 0)); | 599 | && atomic_read(&efx->rxq_flush_pending) > 0)); |
600 | } | 600 | } |
@@ -626,7 +626,7 @@ static bool efx_check_tx_flush_complete(struct efx_nic *efx) | |||
626 | netif_dbg(efx, hw, efx->net_dev, | 626 | netif_dbg(efx, hw, efx->net_dev, |
627 | "flush complete on TXQ %d, so drain " | 627 | "flush complete on TXQ %d, so drain " |
628 | "the queue\n", tx_queue->queue); | 628 | "the queue\n", tx_queue->queue); |
629 | /* Don't need to increment drain_pending as it | 629 | /* Don't need to increment active_queues as it |
630 | * has already been incremented for the queues | 630 | * has already been incremented for the queues |
631 | * which did not drain | 631 | * which did not drain |
632 | */ | 632 | */ |
@@ -653,17 +653,15 @@ static int efx_farch_do_flush(struct efx_nic *efx) | |||
653 | 653 | ||
654 | efx_for_each_channel(channel, efx) { | 654 | efx_for_each_channel(channel, efx) { |
655 | efx_for_each_channel_tx_queue(tx_queue, channel) { | 655 | efx_for_each_channel_tx_queue(tx_queue, channel) { |
656 | atomic_inc(&efx->drain_pending); | ||
657 | efx_farch_flush_tx_queue(tx_queue); | 656 | efx_farch_flush_tx_queue(tx_queue); |
658 | } | 657 | } |
659 | efx_for_each_channel_rx_queue(rx_queue, channel) { | 658 | efx_for_each_channel_rx_queue(rx_queue, channel) { |
660 | atomic_inc(&efx->drain_pending); | ||
661 | rx_queue->flush_pending = true; | 659 | rx_queue->flush_pending = true; |
662 | atomic_inc(&efx->rxq_flush_pending); | 660 | atomic_inc(&efx->rxq_flush_pending); |
663 | } | 661 | } |
664 | } | 662 | } |
665 | 663 | ||
666 | while (timeout && atomic_read(&efx->drain_pending) > 0) { | 664 | while (timeout && atomic_read(&efx->active_queues) > 0) { |
667 | /* If SRIOV is enabled, then offload receive queue flushing to | 665 | /* If SRIOV is enabled, then offload receive queue flushing to |
668 | * the firmware (though we will still have to poll for | 666 | * the firmware (though we will still have to poll for |
669 | * completion). If that fails, fall back to the old scheme. | 667 | * completion). If that fails, fall back to the old scheme. |
@@ -699,15 +697,15 @@ static int efx_farch_do_flush(struct efx_nic *efx) | |||
699 | timeout); | 697 | timeout); |
700 | } | 698 | } |
701 | 699 | ||
702 | if (atomic_read(&efx->drain_pending) && | 700 | if (atomic_read(&efx->active_queues) && |
703 | !efx_check_tx_flush_complete(efx)) { | 701 | !efx_check_tx_flush_complete(efx)) { |
704 | netif_err(efx, hw, efx->net_dev, "failed to flush %d queues " | 702 | netif_err(efx, hw, efx->net_dev, "failed to flush %d queues " |
705 | "(rx %d+%d)\n", atomic_read(&efx->drain_pending), | 703 | "(rx %d+%d)\n", atomic_read(&efx->active_queues), |
706 | atomic_read(&efx->rxq_flush_outstanding), | 704 | atomic_read(&efx->rxq_flush_outstanding), |
707 | atomic_read(&efx->rxq_flush_pending)); | 705 | atomic_read(&efx->rxq_flush_pending)); |
708 | rc = -ETIMEDOUT; | 706 | rc = -ETIMEDOUT; |
709 | 707 | ||
710 | atomic_set(&efx->drain_pending, 0); | 708 | atomic_set(&efx->active_queues, 0); |
711 | atomic_set(&efx->rxq_flush_pending, 0); | 709 | atomic_set(&efx->rxq_flush_pending, 0); |
712 | atomic_set(&efx->rxq_flush_outstanding, 0); | 710 | atomic_set(&efx->rxq_flush_outstanding, 0); |
713 | } | 711 | } |
@@ -1123,8 +1121,8 @@ efx_farch_handle_drain_event(struct efx_channel *channel) | |||
1123 | { | 1121 | { |
1124 | struct efx_nic *efx = channel->efx; | 1122 | struct efx_nic *efx = channel->efx; |
1125 | 1123 | ||
1126 | WARN_ON(atomic_read(&efx->drain_pending) == 0); | 1124 | WARN_ON(atomic_read(&efx->active_queues) == 0); |
1127 | atomic_dec(&efx->drain_pending); | 1125 | atomic_dec(&efx->active_queues); |
1128 | if (efx_farch_flush_wake(efx)) | 1126 | if (efx_farch_flush_wake(efx)) |
1129 | wake_up(&efx->flush_wq); | 1127 | wake_up(&efx->flush_wq); |
1130 | } | 1128 | } |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 5341c76b1d02..c9b6f2dcb539 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -723,7 +723,7 @@ struct vfdi_status; | |||
723 | * @rps_flow_id: Flow IDs of filters allocated for accelerated RFS, | 723 | * @rps_flow_id: Flow IDs of filters allocated for accelerated RFS, |
724 | * indexed by filter ID | 724 | * indexed by filter ID |
725 | * @rps_expire_index: Next index to check for expiry in @rps_flow_id | 725 | * @rps_expire_index: Next index to check for expiry in @rps_flow_id |
726 | * @drain_pending: Count of RX and TX queues that haven't been flushed and drained. | 726 | * @active_queues: Count of RX and TX queues that haven't been flushed and drained. |
727 | * @rxq_flush_pending: Count of number of receive queues that need to be flushed. | 727 | * @rxq_flush_pending: Count of number of receive queues that need to be flushed. |
728 | * Decremented when the efx_flush_rx_queue() is called. | 728 | * Decremented when the efx_flush_rx_queue() is called. |
729 | * @rxq_flush_outstanding: Count of number of RX flushes started but not yet | 729 | * @rxq_flush_outstanding: Count of number of RX flushes started but not yet |
@@ -864,7 +864,7 @@ struct efx_nic { | |||
864 | unsigned int rps_expire_index; | 864 | unsigned int rps_expire_index; |
865 | #endif | 865 | #endif |
866 | 866 | ||
867 | atomic_t drain_pending; | 867 | atomic_t active_queues; |
868 | atomic_t rxq_flush_pending; | 868 | atomic_t rxq_flush_pending; |
869 | atomic_t rxq_flush_outstanding; | 869 | atomic_t rxq_flush_outstanding; |
870 | wait_queue_head_t flush_wq; | 870 | wait_queue_head_t flush_wq; |