]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
qede: Utilize xmit_more
authorManish Chopra <manish.chopra@qlogic.com>
Thu, 30 Jun 2016 06:35:20 +0000 (02:35 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 10 Aug 2016 21:04:44 +0000 (14:04 -0700)
This patch uses xmit_more optimization to reduce
number of TX doorbells write per packet.

Signed-off-by: Manish <manish.chopra@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Orabug: 24361996
Signed-off-by: Manjunath Govindashetty <manjunath.govindashetty@oracle.com>
drivers/net/ethernet/qlogic/qede/qede_main.c

index 4c2f29d436f88d0b25e23289e45d458862ab7d4b..d3ccf462ea692d579dcb6e801cea00315d3428ee 100644 (file)
@@ -487,6 +487,24 @@ static bool qede_pkt_req_lin(struct qede_dev *edev, struct sk_buff *skb,
 }
 #endif
 
+static inline void qede_update_tx_producer(struct qede_tx_queue *txq)
+{
+       /* wmb makes sure that the BDs data is updated before updating the
+        * producer, otherwise FW may read old data from the BDs.
+        */
+       wmb();
+       barrier();
+       writel(txq->tx_db.raw, txq->doorbell_addr);
+
+       /* mmiowb is needed to synchronize doorbell writes from more than one
+        * processor. It guarantees that the write arrives to the device before
+        * the queue lock is released and another start_xmit is called (possibly
+        * on another CPU). Without this barrier, the next doorbell can bypass
+        * this doorbell. This is applicable to IA64/Altix systems.
+        */
+       mmiowb();
+}
+
 /* Main transmit function */
 static
 netdev_tx_t qede_start_xmit(struct sk_buff *skb,
@@ -545,6 +563,7 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb,
        if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) {
                DP_NOTICE(edev, "SKB mapping failed\n");
                qede_free_failed_tx_pkt(edev, txq, first_bd, 0, false);
+               qede_update_tx_producer(txq);
                return NETDEV_TX_OK;
        }
        nbd++;
@@ -659,6 +678,7 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb,
                if (rc) {
                        qede_free_failed_tx_pkt(edev, txq, first_bd, nbd,
                                                data_split);
+                       qede_update_tx_producer(txq);
                        return NETDEV_TX_OK;
                }
 
@@ -683,6 +703,7 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb,
                if (rc) {
                        qede_free_failed_tx_pkt(edev, txq, first_bd, nbd,
                                                data_split);
+                       qede_update_tx_producer(txq);
                        return NETDEV_TX_OK;
                }
        }
@@ -703,20 +724,8 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb,
        txq->tx_db.data.bd_prod =
                cpu_to_le16(qed_chain_get_prod_idx(&txq->tx_pbl));
 
-       /* wmb makes sure that the BDs data is updated before updating the
-        * producer, otherwise FW may read old data from the BDs.
-        */
-       wmb();
-       barrier();
-       writel(txq->tx_db.raw, txq->doorbell_addr);
-
-       /* mmiowb is needed to synchronize doorbell writes from more than one
-        * processor. It guarantees that the write arrives to the device before
-        * the queue lock is released and another start_xmit is called (possibly
-        * on another CPU). Without this barrier, the next doorbell can bypass
-        * this doorbell. This is applicable to IA64/Altix systems.
-        */
-       mmiowb();
+       if (!skb->xmit_more || netif_tx_queue_stopped(netdev_txq))
+               qede_update_tx_producer(txq);
 
        if (unlikely(qed_chain_get_elem_left(&txq->tx_pbl)
                      < (MAX_SKB_FRAGS + 1))) {