mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-02 10:43:57 +08:00
ixgb: Maybe stop TX if not enough free descriptors
A similar patch to commit 65c7973fa5
but now for ixgb.
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
This commit is contained in:
parent
5d92785375
commit
dfd341e4e4
@ -171,6 +171,7 @@ struct ixgb_adapter {
|
||||
|
||||
/* TX */
|
||||
struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
|
||||
unsigned int restart_queue;
|
||||
unsigned long timeo_start;
|
||||
uint32_t tx_cmd_type;
|
||||
uint64_t hw_csum_tx_good;
|
||||
|
@ -79,6 +79,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
|
||||
{"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)},
|
||||
{"tx_deferred_ok", IXGB_STAT(stats.dc)},
|
||||
{"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
|
||||
{"tx_restart_queue", IXGB_STAT(restart_queue) },
|
||||
{"rx_long_length_errors", IXGB_STAT(stats.roc)},
|
||||
{"rx_short_length_errors", IXGB_STAT(stats.ruc)},
|
||||
#ifdef NETIF_F_TSO
|
||||
|
@ -1411,6 +1411,37 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
|
||||
IXGB_WRITE_REG(&adapter->hw, TDT, i);
|
||||
}
|
||||
|
||||
static int __ixgb_maybe_stop_tx(struct net_device *netdev, int size)
|
||||
{
|
||||
struct ixgb_adapter *adapter = netdev_priv(netdev);
|
||||
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
|
||||
|
||||
netif_stop_queue(netdev);
|
||||
/* Herbert's original patch had:
|
||||
* smp_mb__after_netif_stop_queue();
|
||||
* but since that doesn't exist yet, just open code it. */
|
||||
smp_mb();
|
||||
|
||||
/* We need to check again in a case another CPU has just
|
||||
* made room available. */
|
||||
if (likely(IXGB_DESC_UNUSED(tx_ring) < size))
|
||||
return -EBUSY;
|
||||
|
||||
/* A reprieve! */
|
||||
netif_start_queue(netdev);
|
||||
++adapter->restart_queue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ixgb_maybe_stop_tx(struct net_device *netdev,
|
||||
struct ixgb_desc_ring *tx_ring, int size)
|
||||
{
|
||||
if (likely(IXGB_DESC_UNUSED(tx_ring) >= size))
|
||||
return 0;
|
||||
return __ixgb_maybe_stop_tx(netdev, size);
|
||||
}
|
||||
|
||||
|
||||
/* Tx Descriptors needed, worst case */
|
||||
#define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \
|
||||
(((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
|
||||
@ -1444,7 +1475,8 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||
spin_lock_irqsave(&adapter->tx_lock, flags);
|
||||
#endif
|
||||
|
||||
if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
|
||||
if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring,
|
||||
DESC_NEEDED))) {
|
||||
netif_stop_queue(netdev);
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
return NETDEV_TX_BUSY;
|
||||
@ -1482,8 +1514,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||
|
||||
#ifdef NETIF_F_LLTX
|
||||
/* Make sure there is space in the ring for the next send. */
|
||||
if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED))
|
||||
netif_stop_queue(netdev);
|
||||
ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
|
||||
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user