Commit 97b1ebb1 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-timestamp-introduce-a-flag-to-filter-out-rx-software-and-hardware-report'

Jason Xing says:

====================
net-timestamp: introduce a flag to filter out rx software and hardware report

When one socket is set SOF_TIMESTAMPING_RX_SOFTWARE which means the
whole system turns on the netstamp_needed_key button, other sockets
that only have SOF_TIMESTAMPING_SOFTWARE will be affected and then
print the rx timestamp information even without setting
SOF_TIMESTAMPING_RX_SOFTWARE generation flag.

How to solve it without breaking users?
We introduce a new flag named SOF_TIMESTAMPING_OPT_RX_FILTER. Using
it together with SOF_TIMESTAMPING_SOFTWARE can stop reporting the
rx software timestamp.

Similarly, we also filter out the hardware case where one process
enables the rx hardware generation flag, then another process only
passing SOF_TIMESTAMPING_RAW_HARDWARE gets the timestamp. So we can set
both SOF_TIMESTAMPING_RAW_HARDWARE and SOF_TIMESTAMPING_OPT_RX_FILTER
to stop reporting rx hardware timestamp after this patch applied.

v6: https://lore.kernel.org/20240906095640.77533-1-kerneljasonxing@gmail.com
v5: https://lore.kernel.org/20240905071738.3725-1-kerneljasonxing@gmail.com
v4: https://lore.kernel.org/20240830153751.86895-1-kerneljasonxing@gmail.com
v3: https://lore.kernel.org/20240828160145.68805-1-kerneljasonxing@gmail.com
v2: https://lore.kernel.org/20240825152440.93054-1-kerneljasonxing@gmail.com
====================

Link: https://patch.msgid.link/20240909015612.3856-1-kerneljasonxing@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents e503f82e fffe8efd
...@@ -267,6 +267,23 @@ SOF_TIMESTAMPING_OPT_TX_SWHW: ...@@ -267,6 +267,23 @@ SOF_TIMESTAMPING_OPT_TX_SWHW:
two separate messages will be looped to the socket's error queue, two separate messages will be looped to the socket's error queue,
each containing just one timestamp. each containing just one timestamp.
SOF_TIMESTAMPING_OPT_RX_FILTER:
Filter out spurious receive timestamps: report a receive timestamp
only if the matching timestamp generation flag is enabled.
Receive timestamps are generated early in the ingress path, before a
packet's destination socket is known. If any socket enables receive
timestamps, packets for all socket will receive timestamped packets.
Including those that request timestamp reporting with
SOF_TIMESTAMPING_SOFTWARE and/or SOF_TIMESTAMPING_RAW_HARDWARE, but
do not request receive timestamp generation. This can happen when
requesting transmit timestamps only.
Receiving spurious timestamps is generally benign. A process can
ignore the unexpected non-zero value. But it makes behavior subtly
dependent on other sockets. This flag isolates the socket for more
deterministic behavior.
New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to
disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate
regardless of the setting of sysctl net.core.tstamp_allow_data. regardless of the setting of sysctl net.core.tstamp_allow_data.
......
...@@ -32,8 +32,9 @@ enum { ...@@ -32,8 +32,9 @@ enum {
SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14), SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14),
SOF_TIMESTAMPING_BIND_PHC = (1 << 15), SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16), SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16),
SOF_TIMESTAMPING_OPT_RX_FILTER = (1 << 17),
SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_ID_TCP, SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_RX_FILTER,
SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
SOF_TIMESTAMPING_LAST SOF_TIMESTAMPING_LAST
}; };
......
...@@ -427,6 +427,7 @@ const char sof_timestamping_names[][ETH_GSTRING_LEN] = { ...@@ -427,6 +427,7 @@ const char sof_timestamping_names[][ETH_GSTRING_LEN] = {
[const_ilog2(SOF_TIMESTAMPING_OPT_TX_SWHW)] = "option-tx-swhw", [const_ilog2(SOF_TIMESTAMPING_OPT_TX_SWHW)] = "option-tx-swhw",
[const_ilog2(SOF_TIMESTAMPING_BIND_PHC)] = "bind-phc", [const_ilog2(SOF_TIMESTAMPING_BIND_PHC)] = "bind-phc",
[const_ilog2(SOF_TIMESTAMPING_OPT_ID_TCP)] = "option-id-tcp", [const_ilog2(SOF_TIMESTAMPING_OPT_ID_TCP)] = "option-id-tcp",
[const_ilog2(SOF_TIMESTAMPING_OPT_RX_FILTER)] = "option-rx-filter",
}; };
static_assert(ARRAY_SIZE(sof_timestamping_names) == __SOF_TIMESTAMPING_CNT); static_assert(ARRAY_SIZE(sof_timestamping_names) == __SOF_TIMESTAMPING_CNT);
......
...@@ -2235,6 +2235,7 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, ...@@ -2235,6 +2235,7 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
struct scm_timestamping_internal *tss) struct scm_timestamping_internal *tss)
{ {
int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW); int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
u32 tsflags = READ_ONCE(sk->sk_tsflags);
bool has_timestamping = false; bool has_timestamping = false;
if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) { if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
...@@ -2274,14 +2275,18 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, ...@@ -2274,14 +2275,18 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
} }
} }
if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_SOFTWARE) if (tsflags & SOF_TIMESTAMPING_SOFTWARE &&
(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
!(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
has_timestamping = true; has_timestamping = true;
else else
tss->ts[0] = (struct timespec64) {0}; tss->ts[0] = (struct timespec64) {0};
} }
if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) { if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_RAW_HARDWARE) if (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
(tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
!(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
has_timestamping = true; has_timestamping = true;
else else
tss->ts[2] = (struct timespec64) {0}; tss->ts[2] = (struct timespec64) {0};
......
...@@ -946,11 +946,17 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, ...@@ -946,11 +946,17 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
memset(&tss, 0, sizeof(tss)); memset(&tss, 0, sizeof(tss));
tsflags = READ_ONCE(sk->sk_tsflags); tsflags = READ_ONCE(sk->sk_tsflags);
if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) && if ((tsflags & SOF_TIMESTAMPING_SOFTWARE &&
(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
skb_is_err_queue(skb) ||
!(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0)) ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
empty = 0; empty = 0;
if (shhwtstamps && if (shhwtstamps &&
(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
(tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
skb_is_err_queue(skb) ||
!(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
!skb_is_swtx_tstamp(skb, false_tstamp)) { !skb_is_swtx_tstamp(skb, false_tstamp)) {
if_index = 0; if_index = 0;
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV)
......
...@@ -57,6 +57,8 @@ static struct sof_flag sof_flags[] = { ...@@ -57,6 +57,8 @@ static struct sof_flag sof_flags[] = {
SOF_FLAG(SOF_TIMESTAMPING_SOFTWARE), SOF_FLAG(SOF_TIMESTAMPING_SOFTWARE),
SOF_FLAG(SOF_TIMESTAMPING_RX_SOFTWARE), SOF_FLAG(SOF_TIMESTAMPING_RX_SOFTWARE),
SOF_FLAG(SOF_TIMESTAMPING_RX_HARDWARE), SOF_FLAG(SOF_TIMESTAMPING_RX_HARDWARE),
SOF_FLAG(SOF_TIMESTAMPING_OPT_RX_FILTER),
SOF_FLAG(SOF_TIMESTAMPING_RAW_HARDWARE),
}; };
static struct socket_type socket_types[] = { static struct socket_type socket_types[] = {
...@@ -97,6 +99,22 @@ static struct test_case test_cases[] = { ...@@ -97,6 +99,22 @@ static struct test_case test_cases[] = {
| SOF_TIMESTAMPING_RX_HARDWARE }, | SOF_TIMESTAMPING_RX_HARDWARE },
{} {}
}, },
{
{ .so_timestamping = SOF_TIMESTAMPING_RAW_HARDWARE
| SOF_TIMESTAMPING_OPT_RX_FILTER },
{}
},
{
{ .so_timestamping = SOF_TIMESTAMPING_SOFTWARE
| SOF_TIMESTAMPING_OPT_RX_FILTER },
{}
},
{
{ .so_timestamping = SOF_TIMESTAMPING_SOFTWARE
| SOF_TIMESTAMPING_RX_SOFTWARE
| SOF_TIMESTAMPING_OPT_RX_FILTER },
{ .swtstamp = true }
},
{ {
{ .so_timestamping = SOF_TIMESTAMPING_SOFTWARE { .so_timestamping = SOF_TIMESTAMPING_SOFTWARE
| SOF_TIMESTAMPING_RX_SOFTWARE }, | SOF_TIMESTAMPING_RX_SOFTWARE },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment