]> git.baikalelectronics.ru Git - kernel.git/commitdiff
sfc: disable softirqs for ptp TX
authorAlejandro Lucero <alejandro.lucero-palau@amd.com>
Tue, 26 Jul 2022 06:45:04 +0000 (08:45 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 28 Jul 2022 01:20:43 +0000 (18:20 -0700)
Sending a PTP packet can imply to use the normal TX driver datapath but
invoked from the driver's ptp worker. The kernel generic TX code
disables softirqs and preemption before calling specific driver TX code,
but the ptp worker does not. Although current ptp driver functionality
does not require it, there are several reasons for doing so:

   1) The invoked code is always executed with softirqs disabled for non
      PTP packets.
   2) Better if a ptp packet transmission is not interrupted by softirq
      handling which could lead to high latencies.
   3) netdev_xmit_more used by the TX code requires preemption to be
      disabled.

Indeed a solution for dealing with kernel preemption state based on static
kernel configuration is not possible since the introduction of dynamic
preemption level configuration at boot time using the static calls
functionality.

Fixes: 3ac514f76df8f ("drivers: net: sfc: use netdev_xmit_more helper")
Signed-off-by: Alejandro Lucero <alejandro.lucero-palau@amd.com>
Link: https://lore.kernel.org/r/20220726064504.49613-1-alejandro.lucero-palau@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/sfc/ptp.c

index 4625f85acab2ea9b2016a89a0ca146dab13a52bb..10ad0b93d283b01a98d3dca215023d334d257ee3 100644 (file)
@@ -1100,7 +1100,29 @@ static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb)
 
        tx_queue = efx_channel_get_tx_queue(ptp_data->channel, type);
        if (tx_queue && tx_queue->timestamping) {
+               /* This code invokes normal driver TX code which is always
+                * protected from softirqs when called from generic TX code,
+                * which in turn disables preemption. Look at __dev_queue_xmit
+                * which uses rcu_read_lock_bh disabling preemption for RCU
+                * plus disabling softirqs. We do not need RCU reader
+                * protection here.
+                *
+                * Although it is theoretically safe for current PTP TX/RX code
+                * running without disabling softirqs, there are three good
+                * reasond for doing so:
+                *
+                *      1) The code invoked is mainly implemented for non-PTP
+                *         packets and it is always executed with softirqs
+                *         disabled.
+                *      2) This being a single PTP packet, better to not
+                *         interrupt its processing by softirqs which can lead
+                *         to high latencies.
+                *      3) netdev_xmit_more checks preemption is disabled and
+                *         triggers a BUG_ON if not.
+                */
+               local_bh_disable();
                efx_enqueue_skb(tx_queue, skb);
+               local_bh_enable();
        } else {
                WARN_ONCE(1, "PTP channel has no timestamped tx queue\n");
                dev_kfree_skb_any(skb);