sfc: rewrite efx_tx_may_pio
authorEdward Cree <ecree@solarflare.com>
Thu, 3 Sep 2020 21:35:29 +0000 (22:35 +0100)
committerJakub Kicinski <kuba@kernel.org>
Sat, 5 Sep 2020 19:21:40 +0000 (12:21 -0700)
Use efx_for_each_channel_tx_queue() rather than efx_tx_queue_partner().
Make some related simplifications of efx_nic_tx_is_empty() to remove
 entry points that aren't used.

Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/sfc/nic_common.h
drivers/net/ethernet/sfc/tx.c

index 9741073..3f88c64 100644 (file)
@@ -65,8 +65,7 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
 /* Report whether this TX queue would be empty for the given write_count.
  * May return false negative.
  */
-static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue,
-                                        unsigned int write_count)
+static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue, unsigned int write_count)
 {
        unsigned int empty_read_count = READ_ONCE(tx_queue->empty_read_count);
 
@@ -76,17 +75,6 @@ static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue,
        return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
 }
 
-/* Report whether the NIC considers this TX queue empty, using
- * packet_write_count (the write count recorded for the last completable
- * doorbell push).  May return false negative.  EF10 only, which is OK
- * because only EF10 supports PIO.
- */
-static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue)
-{
-       EFX_WARN_ON_ONCE_PARANOID(!tx_queue->efx->type->option_descriptors);
-       return __efx_nic_tx_is_empty(tx_queue, tx_queue->packet_write_count);
-}
-
 /* Get partner of a TX queue, seen as part of the same net core queue */
 /* XXX is this a thing on EF100? */
 static inline struct efx_tx_queue *efx_tx_queue_partner(struct efx_tx_queue *tx_queue)
@@ -97,20 +85,6 @@ static inline struct efx_tx_queue *efx_tx_queue_partner(struct efx_tx_queue *tx_
                return tx_queue + EFX_TXQ_TYPE_OFFLOAD;
 }
 
-/* Decide whether we can use TX PIO, ie. write packet data directly into
- * a buffer on the device.  This can reduce latency at the expense of
- * throughput, so we only do this if both hardware and software TX rings
- * are empty.  This also ensures that only one packet at a time can be
- * using the PIO buffer.
- */
-static inline bool efx_nic_may_tx_pio(struct efx_tx_queue *tx_queue)
-{
-       struct efx_tx_queue *partner = efx_tx_queue_partner(tx_queue);
-
-       return tx_queue->piobuf && efx_nic_tx_is_empty(tx_queue) &&
-              efx_nic_tx_is_empty(partner);
-}
-
 int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
                        bool *data_mapped);
 
@@ -125,7 +99,7 @@ int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
 static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue,
                                            unsigned int write_count)
 {
-       bool was_empty = __efx_nic_tx_is_empty(tx_queue, write_count);
+       bool was_empty = efx_nic_tx_is_empty(tx_queue, write_count);
 
        tx_queue->empty_read_count = 0;
        return was_empty && tx_queue->write_count - write_count == 1;
index b868920..48d91b2 100644 (file)
@@ -264,6 +264,30 @@ static int efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue,
        ++tx_queue->insert_count;
        return 0;
 }
+
+/* Decide whether we can use TX PIO, ie. write packet data directly into
+ * a buffer on the device.  This can reduce latency at the expense of
+ * throughput, so we only do this if both hardware and software TX rings
+ * are empty, including all queues for the channel.  This also ensures that
+ * only one packet at a time can be using the PIO buffer. If the xmit_more
+ * flag is set then we don't use this - there'll be another packet along
+ * shortly and we want to hold off the doorbell.
+ */
+static bool efx_tx_may_pio(struct efx_tx_queue *tx_queue)
+{
+       struct efx_channel *channel = tx_queue->channel;
+
+       if (!tx_queue->piobuf)
+               return false;
+
+       EFX_WARN_ON_ONCE_PARANOID(!channel->efx->type->option_descriptors);
+
+       efx_for_each_channel_tx_queue(tx_queue, channel)
+               if (!efx_nic_tx_is_empty(tx_queue, tx_queue->packet_write_count))
+                       return false;
+
+       return true;
+}
 #endif /* EFX_USE_PIO */
 
 /* Send any pending traffic for a channel. xmit_more is shared across all
@@ -326,7 +350,7 @@ netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb
                        goto err;
 #ifdef EFX_USE_PIO
        } else if (skb_len <= efx_piobuf_size && !xmit_more &&
-                  efx_nic_may_tx_pio(tx_queue)) {
+                  efx_tx_may_pio(tx_queue)) {
                /* Use PIO for short packets with an empty queue. */
                if (efx_enqueue_skb_pio(tx_queue, skb))
                        goto err;