summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros/atl1c
diff options
context:
space:
mode:
authorGatis Peisenieks <gatis@mikrotik.com>2021-05-13 14:43:23 +0300
committerDavid S. Miller <davem@davemloft.net>2021-05-13 15:48:10 -0700
commitd7ab6419bdee50dbc4a53e69c290a1ef05dae7f9 (patch)
treeaffa2123efd9376c44002965d1ce5a1d36a3145d /drivers/net/ethernet/atheros/atl1c
parentf19d4997fd1fb01bed127e1056ce3a5de922d9ee (diff)
downloadlinux-stable-d7ab6419bdee50dbc4a53e69c290a1ef05dae7f9.tar.gz
linux-stable-d7ab6419bdee50dbc4a53e69c290a1ef05dae7f9.tar.bz2
linux-stable-d7ab6419bdee50dbc4a53e69c290a1ef05dae7f9.zip
atl1c: improve performance by avoiding unnecessary pcie writes on xmit
The kernel has xmit_more facility that hints the networking driver xmit path about whether more packets are coming soon. This information can be used to avoid unnecessary expensive PCIe transaction per tx packet. Max TX pps on Mikrotik 10/25G NIC in a Threadripper 3960X system improved from 1150Kpps to 1700Kpps. Testing L2 forwarding on AR8151 hardware did not reveal a measurable increase in latency. Signed-off-by: Gatis Peisenieks <gatis@mikrotik.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros/atl1c')
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 28c30d5288e4..08a0f49e03ce 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2211,8 +2211,8 @@ err_dma:
return -1;
}
-static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
- struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
+static void atl1c_tx_queue(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
{
struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
u16 reg;
@@ -2238,6 +2238,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
if (atl1c_tpd_avail(adapter, type) < tpd_req) {
/* no enough descriptor, just stop queue */
+ atl1c_tx_queue(adapter, type);
netif_stop_queue(netdev);
return NETDEV_TX_BUSY;
}
@@ -2246,6 +2247,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
/* do TSO and check sum */
if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) {
+ atl1c_tx_queue(adapter, type);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2270,8 +2272,10 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
atl1c_tx_rollback(adapter, tpd, type);
dev_kfree_skb_any(skb);
} else {
- netdev_sent_queue(adapter->netdev, skb->len);
- atl1c_tx_queue(adapter, skb, tpd, type);
+ bool more = netdev_xmit_more();
+
+ if (__netdev_sent_queue(adapter->netdev, skb->len, more))
+ atl1c_tx_queue(adapter, type);
}
return NETDEV_TX_OK;