linux/drivers/net
Vladimir Oltean 4f8e71a770 net: enetc: allow hardware timestamping on TX queues with tc-etf enabled
commit 29d98f54a4 upstream.

The txtime is passed to the driver in skb->skb_mstamp_ns, which is
actually in a union with skb->tstamp (the place where software
timestamps are kept).

Since commit b50a5c70ff ("net: allow simultaneous SW and HW transmit
timestamping"), __sock_recv_timestamp has some logic for making sure
that the two calls to skb_tstamp_tx:

skb_tx_timestamp(skb) # Software timestamp in the driver
-> skb_tstamp_tx(skb, NULL)

and

skb_tstamp_tx(skb, &shhwtstamps) # Hardware timestamp in the driver

will both do the right thing and in a race-free manner, meaning that
skb_tx_timestamp will deliver a cmsg with the software timestamp only,
and skb_tstamp_tx with a non-NULL hwtstamps argument will deliver a cmsg
with the hardware timestamp only.

Why are races even possible? Well, because although the software timestamp
skb->tstamp is private per skb, the hardware timestamp skb_hwtstamps(skb)
lives in skb_shinfo(skb), an area which is shared between skbs and their
clones. And skb_tstamp_tx works by cloning the packets when timestamping
them, therefore attempting to perform hardware timestamping on an skb's
clone will also change the hardware timestamp of the original skb. And
the original skb might have been yet again cloned for software
timestamping, at an earlier stage.

So the logic in __sock_recv_timestamp can't be as simple as saying
"does this skb have a hardware timestamp? if yes I'll send the hardware
timestamp to the socket, otherwise I'll send the software timestamp",
precisely because the hardware timestamp is shared.
Instead, it's quite the other way around: __sock_recv_timestamp says
"does this skb have a software timestamp? if yes, I'll send the software
timestamp, otherwise the hardware one". This works because the software
timestamp is not shared with clones.

But that means we have a problem when we attempt hardware timestamping
with skbs that don't have the skb->tstamp == 0. __sock_recv_timestamp
will say "oh, yeah, this must be some sort of odd clone" and will not
deliver the hardware timestamp to the socket. And this is exactly what
is happening when we have txtime enabled on the socket: as mentioned,
that is put in a union with skb->tstamp, so it is quite easy to mistake
it.

Do what other drivers do (intel igb/igc) and write zero to skb->tstamp
before taking the hardware timestamp. It's of no use to us now (we're
already on the TX confirmation path).

Fixes: 0d08c9ec7d ("enetc: add support time specific departure base on the qos etf")
Cc: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-03-17 17:06:15 +01:00
..
appletalk docs updates for v5.10-rc1 2020-10-16 15:02:21 -07:00
arcnet
bonding bonding: fix feature flag setting at init time 2020-12-08 11:26:08 -08:00
caif
can can: tcan4x5x: tcan4x5x_init(): fix initialization - clear MRAM before entering Normal Mode 2021-03-17 17:06:11 +01:00
dsa net: dsa: sja1105: fix SGMII PCS being forced to SPEED_UNKNOWN instead of SPEED_10 2021-03-17 17:06:15 +01:00
ethernet net: enetc: allow hardware timestamping on TX queues with tc-etf enabled 2021-03-17 17:06:15 +01:00
fddi
fjes
hamradio
hippi
hyperv hv_netvsc: Reset the RSC count if NVSP_STAT_FAIL in netvsc_receive() 2021-02-17 11:02:26 +01:00
ieee802154
ipa net: ipa: set error code in gsi_channel_setup() 2021-02-17 11:02:26 +01:00
ipvlan
mdio
netdevsim netdevsim: init u64 stats for 32bit hardware 2021-03-17 17:06:15 +01:00
pcs net: pcs-xpcs: depend on MDIO_BUS instead of selecting it 2020-10-16 16:54:11 -07:00
phy net: phy: fix save wrong speed and duplex problem if autoneg is on 2021-03-17 17:06:12 +01:00
plip
ppp tty: convert tty_ldisc_ops 'read()' function to take a kernel pointer 2021-03-04 11:37:36 +01:00
slip
team team: protect features update by RCU to avoid deadlock 2021-02-03 23:28:51 +01:00
usb net: usb: qmi_wwan: allow qmimux add/del with master up 2021-03-17 17:06:15 +01:00
vmxnet3
wan net: lapbether: Remove netif_start_queue / netif_stop_queue 2021-03-17 17:06:15 +01:00
wimax
wireguard wireguard: queueing: get rid of per-peer ring buffers 2021-03-04 11:38:47 +01:00
wireless mt76: dma: do not report truncated frames to mac80211 2021-03-17 17:06:13 +01:00
xen-netback xen-netback: respect gnttab_map_refs()'s return value 2021-03-07 12:34:15 +01:00
bareudp.c net: bareudp: add missing error handling for bareudp_link_config() 2021-01-17 14:16:55 +01:00
dummy.c
eql.c
geneve.c Revert "geneve: pull IP header before ECN decapsulation" 2020-12-09 14:40:07 -08:00
gtp.c net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending 2021-03-04 11:38:46 +01:00
ifb.c
Kconfig crypto: mips/poly1305 - enable for all MIPS processors 2021-03-17 17:06:10 +01:00
LICENSE.SRC
loopback.c
macsec.c
macvlan.c
macvtap.c
Makefile
mdio.c
mii.c
net_failover.c
netconsole.c
nlmon.c
ntb_netdev.c
rionet.c
sb1000.c
Space.c
sungem_phy.c
tap.c net: fix dev_ifsioc_locked() race condition 2021-03-07 12:34:07 +01:00
thunderbolt.c
tun.c net: fix dev_ifsioc_locked() race condition 2021-03-07 12:34:07 +01:00
veth.c
virtio_net.c virtio_net: Fix recursive call to cpus_read_lock() 2021-01-12 20:18:10 +01:00
vrf.c vrf: packets with lladdr src needs dst at input with orig_iif when needs strict 2020-12-05 13:46:07 -08:00
vsockmon.c
vxlan.c vxlan: move debug check after netdev unregister 2021-03-04 11:38:18 +01:00
xen-netfront.c