Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net-timestamp: COMPLETION timestamp on packet tx completion

Add SOF_TIMESTAMPING_TX_COMPLETION, for requesting a software timestamp
when hardware reports a packet completed.

Completion tstamp is useful for Bluetooth, as hardware timestamps do not
exist in the HCI specification except for ISO packets, and the hardware
has a queue where packets may wait. In this case the software SND
timestamp only reflects the kernel-side part of the total latency
(usually small) and queue length (usually 0 unless HW buffers
congested), whereas the completion report time is more informative of
the true latency.

It may also be useful in other cases where HW TX timestamps cannot be
obtained and user wants to estimate an upper bound to when the TX
probably happened.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Pauli Virtanen and committed by
Luiz Augusto von Dentz
983e0e4e b257e02e

+23 -5
+8
Documentation/networking/timestamping.rst
··· 140 140 cumulative acknowledgment. The mechanism ignores SACK and FACK. 141 141 This flag can be enabled via both socket options and control messages. 142 142 143 + SOF_TIMESTAMPING_TX_COMPLETION: 144 + Request tx timestamps on packet tx completion. The completion 145 + timestamp is generated by the kernel when it receives packet a 146 + completion report from the hardware. Hardware may report multiple 147 + packets at once, and completion timestamps reflect the timing of the 148 + report and not actual tx time. This flag can be enabled via both 149 + socket options and control messages. 150 + 143 151 144 152 1.3.2 Timestamp Reporting 145 153 ^^^^^^^^^^^^^^^^^^^^^^^^^
+4 -3
include/linux/skbuff.h
··· 478 478 /* device driver is going to provide hardware time stamp */ 479 479 SKBTX_IN_PROGRESS = 1 << 2, 480 480 481 - /* reserved */ 482 - SKBTX_RESERVED = 1 << 3, 481 + /* generate software time stamp on packet tx completion */ 482 + SKBTX_COMPLETION_TSTAMP = 1 << 3, 483 483 484 484 /* generate wifi status information (where possible) */ 485 485 SKBTX_WIFI_STATUS = 1 << 4, ··· 498 498 499 499 #define SKBTX_ANY_SW_TSTAMP (SKBTX_SW_TSTAMP | \ 500 500 SKBTX_SCHED_TSTAMP | \ 501 - SKBTX_BPF) 501 + SKBTX_BPF | \ 502 + SKBTX_COMPLETION_TSTAMP) 502 503 #define SKBTX_ANY_TSTAMP (SKBTX_HW_TSTAMP | \ 503 504 SKBTX_ANY_SW_TSTAMP) 504 505
+1
include/uapi/linux/errqueue.h
··· 73 73 SCM_TSTAMP_SND, /* driver passed skb to NIC, or HW */ 74 74 SCM_TSTAMP_SCHED, /* data entered the packet scheduler */ 75 75 SCM_TSTAMP_ACK, /* data acknowledged by peer */ 76 + SCM_TSTAMP_COMPLETION, /* packet tx completion */ 76 77 }; 77 78 78 79 #endif /* _UAPI_LINUX_ERRQUEUE_H */
+4 -2
include/uapi/linux/net_tstamp.h
··· 44 44 SOF_TIMESTAMPING_BIND_PHC = (1 << 15), 45 45 SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16), 46 46 SOF_TIMESTAMPING_OPT_RX_FILTER = (1 << 17), 47 + SOF_TIMESTAMPING_TX_COMPLETION = (1 << 18), 47 48 48 - SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_RX_FILTER, 49 + SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_TX_COMPLETION, 49 50 SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | 50 51 SOF_TIMESTAMPING_LAST 51 52 }; ··· 59 58 #define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | \ 60 59 SOF_TIMESTAMPING_TX_SOFTWARE | \ 61 60 SOF_TIMESTAMPING_TX_SCHED | \ 62 - SOF_TIMESTAMPING_TX_ACK) 61 + SOF_TIMESTAMPING_TX_ACK | \ 62 + SOF_TIMESTAMPING_TX_COMPLETION) 63 63 64 64 /** 65 65 * struct so_timestamping - SO_TIMESTAMPING parameter
+2
net/core/skbuff.c
··· 5523 5523 SKBTX_SW_TSTAMP); 5524 5524 case SCM_TSTAMP_ACK: 5525 5525 return TCP_SKB_CB(skb)->txstamp_ack & TSTAMP_ACK_SK; 5526 + case SCM_TSTAMP_COMPLETION: 5527 + return skb_shinfo(skb)->tx_flags & SKBTX_COMPLETION_TSTAMP; 5526 5528 } 5527 5529 5528 5530 return false;
+1
net/ethtool/common.c
··· 476 476 [const_ilog2(SOF_TIMESTAMPING_BIND_PHC)] = "bind-phc", 477 477 [const_ilog2(SOF_TIMESTAMPING_OPT_ID_TCP)] = "option-id-tcp", 478 478 [const_ilog2(SOF_TIMESTAMPING_OPT_RX_FILTER)] = "option-rx-filter", 479 + [const_ilog2(SOF_TIMESTAMPING_TX_COMPLETION)] = "tx-completion", 479 480 }; 480 481 static_assert(ARRAY_SIZE(sof_timestamping_names) == __SOF_TIMESTAMPING_CNT); 481 482
+3
net/socket.c
··· 689 689 if (tsflags & SOF_TIMESTAMPING_TX_SCHED) 690 690 flags |= SKBTX_SCHED_TSTAMP; 691 691 692 + if (tsflags & SOF_TIMESTAMPING_TX_COMPLETION) 693 + flags |= SKBTX_COMPLETION_TSTAMP; 694 + 692 695 *tx_flags = flags; 693 696 } 694 697 EXPORT_SYMBOL(__sock_tx_timestamp);