packet: clarify timestamp overflow
Subsystems (5)
PATCH 1/2 packet: clarify timestamp overflow
The memory mapped packet socket data structure in version 1 through 3 all contain 32-bit second values for the packet time stamps, which makes them suffer from the overflow of time_t in y2038 or y2106 (depending on whether user space interprets the value as signed or unsigned).
The implementation uses the deprecated getnstimeofday() function.
In order to get rid of that, this changes the code to use ktime_get_real_ts64() as a replacement, documenting the nature of the overflow. As long as the user applications treat the timestamps as unsigned, or only use the difference between timestamps, they are fine, and changing the timestamps to 64-bit wouldn't require a more invasive user space API change.
Note: a lot of other APIs suffer from incompatible structures when time_t gets redefined to 64-bit in 32-bit user space, but this one does not.
--- net/packet/af_packet.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
net/packet/af_packet.c +17 -10
@@ -439,17 +439,17 @@ static int __packet_get_status(struct packet_sock *po, void *frame) } } -static __u32 tpacket_get_timestamp (struct sk_buff *skb,struct timespec *ts, +static __u32 tpacket_get_timestamp (struct sk_buff *skb,struct timespec64 *ts,unsigned int flags) {struct skb_shared_hwtstamps *shhwtstamps =skb_hwtstamps (skb);if (shhwtstamps && (flags &SOF_TIMESTAMPING_RAW_HARDWARE ) && -ktime_to_timespec_cond (shhwtstamps->hwtstamp, ts)) +ktime_to_timespec64_cond (shhwtstamps->hwtstamp, ts))return TP_STATUS_TS_RAW_HARDWARE ; -if (ktime_to_timespec_cond (skb->tstamp, ts)) +if (ktime_to_timespec64_cond (skb->tstamp, ts))return TP_STATUS_TS_SOFTWARE ;return 0 ;
@@ -459,13 +459,20 @@ static __u32 __packet_set_timestamp(struct packet_sock *po, void *frame, struct sk_buff *skb) {union tpacket_uhdr h; -struct timespec ts; +struct timespec64 ts;__u32 ts_status;if (!(ts_status =tpacket_get_timestamp (skb, &ts, po->tp_tstamp)))return 0 ; h.raw = frame; +/* +* versions 1 through 3 overflow the timestamps in y2106, since they +* all store the seconds in a 32-bit unsigned integer. +* If we create a version 4, that should have a 64-bit timestamp, +* either 64-bit seconds + 32-bit nanoseconds, or just 64-bit +* nanoseconds. +*/ switch (po->tp_version) {case TPACKET_V1 : h.h1->tp_sec = ts.tv_sec;
@@ -805,8 +812,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,* It shouldn't really happen as we don't close empty * blocks. See prb_retire_rx_blk_timer_expired(). */ -struct timespec ts; -getnstimeofday (&ts); +struct timespec64 ts; +ktime_get_real_ts64 (&ts); h1->ts_last_pkt.ts_sec = ts.tv_sec; h1->ts_last_pkt.ts_nsec = ts.tv_nsec; }
@@ -836,7 +843,7 @@ static void prb_thaw_queue(struct tpacket_kbdq_core *pkc)static void prb_open_block (struct tpacket_kbdq_core *pkc1,struct tpacket_block_desc *pbd1) { -struct timespec ts; +struct timespec64 ts;struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1;smp_rmb ();
@@ -849,7 +856,7 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1,BLOCK_NUM_PKTS (pbd1) =0 ;BLOCK_LEN (pbd1) =BLK_PLUS_PRIV (pkc1->blk_sizeof_priv); -getnstimeofday (&ts); +ktime_get_real_ts64 (&ts); h1->ts_first_pkt.ts_sec = ts.tv_sec; h1->ts_first_pkt.ts_nsec = ts.tv_nsec;
@@ -2184,7 +2191,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,unsigned long status =TP_STATUS_USER ;unsigned short macoff, netoff, hdrlen;struct sk_buff *copy_skb =NULL ; -struct timespec ts; +struct timespec64 ts;__u32 ts_status;bool is_drop_n_account = false;bool do_vnet = false;
@@ -2312,7 +2319,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,skb_copy_bits (skb,0 , h.raw + macoff, snaplen);if (!(ts_status =tpacket_get_timestamp (skb, &ts, po->tp_tstamp))) -getnstimeofday (&ts); +ktime_get_real_ts64 (&ts); status |= ts_status;
Signature · 1 line
2.9.0
RFC PATCH 2/2 packet: experimental support for 64-bit timestamps
I tried to figure out what it would take to do a version 4 mmap packet socket interface to completely avoid the y2106 overflow problem. This is what I came up with, reusing most of the v3 code, except for the parts where we access the timestamps.
For kselftest, I'm adding support for testing v4 in addition to v1-v3, but the test currently does not look at the timestamps, so it won't check that the timestamp format actually works as intended, only that I didn't break the parts that worked in the v3 selftest.
Overall, this is more of a mess than I expected, so it's probably not worth doing a v4 format just for the timestamp, but the patch can serve as a reference for anyone that needs a new format for other reasons and fixes this along with the other changes.
---
Untested and rather invasive, so don't apply this part without discussion and testing
--- include/uapi/linux/if_packet.h | 24 +++++- net/packet/af_packet.c | 115 ++++++++++++++++++++-------- tools/testing/selftests/net/psock_tpacket.c | 65 +++++++++------- 3 files changed, 142 insertions(+), 62 deletions(-)
include/uapi/linux/if_packet.h +22 -2
@@ -177,8 +177,27 @@ struct tpacket3_hdr {__u8 tp_padding[8 ]; }; +struct tpacket4_hdr { +__u32 tp_next_offset; +__u32 tp_nsec_hi; +__u32 tp_nsec_lo; +__u32 tp_snaplen; +__u32 tp_len; +__u32 tp_status; +__u16 tp_mac; +__u16 tp_net; +/* pkt_hdr variants */ +union { +struct tpacket_hdr_variant1 hv1; + }; +__u8 tp_padding[8 ]; +}; +struct tpacket_bd_ts { -unsigned int ts_sec; +union { +unsigned int ts_nsec_hi; +unsigned int ts_sec; + };union {unsigned int ts_usec;unsigned int ts_nsec;
@@ -250,7 +269,8 @@ struct tpacket_block_desc {enum tpacket_versions {TPACKET_V1 ,TPACKET_V2 , -TPACKET_V3 +TPACKET_V3 , +TPACKET_V4 , };/*
net/packet/af_packet.c +82 -33
319 lines not on this page · raw message
tools/testing/selftests/net/psock_tpacket.c +38 -27
210 lines not on this page · raw message
Signature · 6 lines
2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
Quoted 17 lines · Mon, Nov 27, 2017@05:19:25PM CET, [email protected] wrote:
I tried to figure out what it would take to do a version 4 mmap packet socket interface to completely avoid the y2106 overflow problem. This is what I came up with, reusing most of the v3 code, except for the parts where we access the timestamps.
For kselftest, I'm adding support for testing v4 in addition to v1-v3, but the test currently does not look at the timestamps, so it won't check that the timestamp format actually works as intended, only that I didn't break the parts that worked in the v3 selftest.
Overall, this is more of a mess than I expected, so it's probably not worth doing a v4 format just for the timestamp, but the patch can serve as a reference for anyone that needs a new format for other reasons and fixes this along with the other changes.
Signed-off-by Arnd Bergmann <arnd at arndb.de>---
[...]
include/uapi/linux/if_packet.h struct tpacket_block_desc { · line 273
Quoted 7 lines
include/uapi/linux/if_packet.h +2
-1@@ -250,7 +269,8 @@ struct tpacket_block_desc {enum tpacket_versions {TPACKET_V1 ,TPACKET_V2 , -TPACKET_V3 +TPACKET_V3 , +TPACKET_V4 ,
I wonder with how many versions are we going to eventually end up with :O --
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Willem de Bruijn
maintainerRe: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
Quoted 22 lines · Jiri Pirko
Quoted 17 lines · Mon, Nov 27, 2017@05:19:25PM CET, [email protected] wrote:
I tried to figure out what it would take to do a version 4 mmap packet socket interface to completely avoid the y2106 overflow problem. This is what I came up with, reusing most of the v3 code, except for the parts where we access the timestamps.
For kselftest, I'm adding support for testing v4 in addition to v1-v3, but the test currently does not look at the timestamps, so it won't check that the timestamp format actually works as intended, only that I didn't break the parts that worked in the v3 selftest.
Overall, this is more of a mess than I expected, so it's probably not worth doing a v4 format just for the timestamp, but the patch can serve as a reference for anyone that needs a new format for other reasons and fixes this along with the other changes.
Signed-off-by Arnd Bergmann <arnd at arndb.de>---
[...]
Quoted 9 lines
include/uapi/linux/if_packet.h struct tpacket_block_desc { · line 273
Quoted 7 lines
include/uapi/linux/if_packet.h +2
-1@@ -250,7 +269,8 @@ struct tpacket_block_desc {enum tpacket_versions {TPACKET_V1 ,TPACKET_V2 , -TPACKET_V3 +TPACKET_V3 , +TPACKET_V4 ,I wonder with how many versions are we going to eventually end up with :O
There already is an effort to come up with a new AF_PACKET V4 [1]. We should make sure that any new interface does not have the Y2038/Y2106 issue. But, if a new version is being developed and that subsumes all existing use cases, then there probably is no need for another version that is a very small diff to V3.
If adding support for existing applications is useful, another approach would be to add a new socket option that changes the semantics for the two u32 fields in each of V1, V2 and V3 to hold nsec. Add a single check after filling in those structs whether the option is set and, if so, overwrite the two fields.
[1] https://lwn.net/Articles/737947/
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
Quoted 33 lines · Willem de Bruijn
Quoted 22 lines · Jiri Pirko
Quoted 17 lines · Mon, Nov 27, 2017@05:19:25PM CET, [email protected] wrote:
I tried to figure out what it would take to do a version 4 mmap packet socket interface to completely avoid the y2106 overflow problem. This is what I came up with, reusing most of the v3 code, except for the parts where we access the timestamps.
For kselftest, I'm adding support for testing v4 in addition to v1-v3, but the test currently does not look at the timestamps, so it won't check that the timestamp format actually works as intended, only that I didn't break the parts that worked in the v3 selftest.
Overall, this is more of a mess than I expected, so it's probably not worth doing a v4 format just for the timestamp, but the patch can serve as a reference for anyone that needs a new format for other reasons and fixes this along with the other changes.
Signed-off-by Arnd Bergmann <arnd at arndb.de>---
[...]
Quoted 9 lines
include/uapi/linux/if_packet.h struct tpacket_block_desc { · line 273
Quoted 7 lines
include/uapi/linux/if_packet.h +2
-1@@ -250,7 +269,8 @@ struct tpacket_block_desc {enum tpacket_versions {TPACKET_V1 ,TPACKET_V2 , -TPACKET_V3 +TPACKET_V3 , +TPACKET_V4 ,I wonder with how many versions are we going to eventually end up with :O
Quoted 5 lines
There already is an effort to come up with a new
AF_PACKETV4 [1]. We should make sure that any new interface does not have the Y2038/Y2106 issue. But, if a new version is being developed and that subsumes all existing use cases, then there probably is no need for another version that is a very small diff to V3.
Ah, perfect, that's good timing. Adding Björn to Cc here.
Quoted 7 lines
If adding support for existing applications is useful, another approach would be to add a new socket option that changes the semantics for the two u32 fields in each of V1, V2 and V3 to hold nsec. Add a single check after filling in those structs whether the option is set and, if so, overwrite the two fields.
I don't think that's necessary. As long as the V4 capabilities are a superset of V1-V3, we should be able to just require all users to move to V4 (or later) in the next 89 years, and make sure that they use unsigned seconds if they care about 2038.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
2017-11-27 21:51 GMT+01:00 Arnd Bergmann <arnd at arndb.de>:
[...]
Quoted 8 lines
Quoted 5 lines
There already is an effort to come up with a new
AF_PACKETV4 [1]. We should make sure that any new interface does not have the Y2038/Y2106 issue. But, if a new version is being developed and that subsumes all existing use cases, then there probably is no need for another version that is a very small diff to V3.Ah, perfect, that's good timing. Adding Björn to Cc here.
Unfortunately, for the Y2038/Y2106 cases, we'll be (as a result of netdevconf discussions) moving the AF_PACKET V4 implementation to a separate, new, address/packet family.
Quoted 6 lines
Quoted 6 lines
If adding support for existing applications is useful, another approach would be to add a new socket option that changes the semantics for the two u32 fields in each of V1, V2 and V3 to hold nsec. Add a single check after filling in those structs whether the option is set and, if so, overwrite the two fields.
Quoted 7 lines
Quoted 1 line
I don't think that's necessary. As long as the V4 capabilities are a superset of V1-V3, we should be able to just require all users to move to V4 (or later) in the next 89 years, and make sure that they use unsigned seconds if they care about 2038.
Given that V4 wont be around for AF_PACKET -- at least not in the shape of our patches -- Willem's suggestion is probably a good way forward.
Quoted 1 line
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
Quoted 8 lines · Björn Töpel
2017-11-27 21:51 GMT+01:00 Arnd Bergmann <arnd at arndb.de>:
[...]Quoted 6 lines
Quoted 5 lines
There already is an effort to come up with a new
AF_PACKETV4 [1]. We should make sure that any new interface does not have the Y2038/Y2106 issue. But, if a new version is being developed and that subsumes all existing use cases, then there probably is no need for another version that is a very small diff to V3.
Quoted 6 lines
Quoted 2 lines
Ah, perfect, that's good timing. Adding Björn to Cc here.
Unfortunately, for the Y2038/Y2106 cases, we'll be (as a result of netdevconf discussions) moving the
AF_PACKETV4 implementation to a separate, new, address/packet family.
Ok, I see.
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
If adding support for existing applications is useful, another approach would be to add a new socket option that changes the semantics for the two u32 fields in each of V1, V2 and V3 to hold nsec. Add a single check after filling in those structs whether the option is set and, if so, overwrite the two fields.
Quoted 7 lines
Quoted 1 line
I don't think that's necessary. As long as the V4 capabilities are a superset of V1-V3, we should be able to just require all users to move to V4 (or later) in the next 89 years, and make sure that they use unsigned seconds if they care about 2038.
Quoted 3 lines
Given that V4 wont be around for
AF_PACKET-- at least not in the shape of our patches -- Willem's suggestion is probably a good way forward.
That leaves one question: should we do that now, or wait until some other reason for a V4 comes up? I don't mind creating another patch for this, just want to get a feeling of whether the API clutter is worth it when we have a way out that works until y2106 (at which point we run into other problems as well).
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH v2 1/1 packet: experimental support for 64-bit timestamps
This is a second attempt to allow 64-bit timestamps in packet sockets, this time retaining the existing three API versions, and instead using flags for the timestamping interface that let us reinterpret the existing fields.
We already have an interface to select the timestamp source to be either software or hardware timestamps, using the SOF_TIMESTAMPING_RAW_HARDWARE flag in the PACKET_TIMESTAMP option that gets passed to setsockopt().
This patch adds another two flags for the same interface:SOF_TIMESTAMPING_SKIP makes all timestamps zero, which can save a few cycles per packet when we don't have to touch an expensive clocksource hardware. When SOF_TIMESTAMPING_OPT_NS64 gets added to the flag, we reinterpret the tp_sec/tp_nsec fields to be the upper and lower half of the 64-bit nanosecond value. This lets us use the interface until year 2554, when 64-bit unsigned nanoseconds overflow.
The implementation is fairly straightforward, but I'm less sure about the interface. Using SOF_TIMESTAMPING_* flags in PACKET_TIMESTAMP is a bit odd already since most of the other flags make no sense here. Adding two more flags that only make sense for packet sockets but not the normal SO_TIMESTAMPING option on other sockets makes this even more confusing.
---
This is only a proof-of-concept patch, only compile-tested and put here for discussion about whether we want it in principle.
--- include/uapi/linux/net_tstamp.h | 4 +- net/packet/af_packet.c | 129 +++++++++++++++++++++++++--------------- 2 files changed, 85 insertions(+), 48 deletions(-)
include/uapi/linux/net_tstamp.h +3 -1
@@ -30,8 +30,10 @@ enum {SOF_TIMESTAMPING_OPT_STATS = (1 <<12 ),SOF_TIMESTAMPING_OPT_PKTINFO = (1 <<13 ),SOF_TIMESTAMPING_OPT_TX_SWHW = (1 <<14 ), +SOF_TIMESTAMPING_SKIP = (1 <<15 ), +SOF_TIMESTAMPING_OPT_NS64 = (1 <<16 ), -SOF_TIMESTAMPING_LAST =SOF_TIMESTAMPING_OPT_TX_SWHW , +SOF_TIMESTAMPING_LAST =SOF_TIMESTAMPING_OPT_NS64 ,SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST -1 ) | SOF_TIMESTAMPING_LAST };
net/packet/af_packet.c +82 -47
238 lines not on this page · raw message
Signature · 1 line
2.9.0
Willem de Bruijn
maintainerRe: [PATCH] [RFC v2] packet: experimental support for 64-bit timestamps
Quoted 1 line · Arnd Bergmann
This is a second attempt to allow 64-bit timestamps in packet sockets,
Thanks for coding up this variant.
Quoted 5 lines
The implementation is fairly straightforward, but I'm less sure about the interface. Using SOF_TIMESTAMPING_* flags in
PACKET_TIMESTAMPis a bit odd already since most of the other flags make no sense here. Adding two more flags that only make sense for packet sockets but not the normalSO_TIMESTAMPINGoption on other sockets makes this even more confusing.
Agreed.
Unfortunately, we're already stuck with SOL_PACKET/PACKET_TIMESTAMP accepting SOF_TIMESTAMPING_RAW_HARDWARE.
Perhaps we can define a new PF_PACKET specific enum where the equivalent option has the same value, so is backwards compatible:
enum {
PACKET_TIMESTAMP_ORIG = 0,
PACKET_TIMESTAMP_ZERO = 1 << 0,
PACKET_TIMESTAMP_NS64 = 1 << 1,
PACKET_TIMESTAMP_HW = 1 << 6
};
and BUILD_BUG_ON(PACKET_TIMESTAMP_RAW != SOF_TIMESTAMPING_RAW_HARDWARE) to document the dependency.
At high level, the code looks great to me, itself.
Re: [PATCH] [RFC v2] packet: experimental support for 64-bit timestamps
Quoted 15 lines · Willem de Bruijn
On Tue, Nov 28, 2017 at 8:14 AM, Arnd Bergmann <[email protected]> wrote:
Unfortunately, we're already stuck with SOL_PACKET/PACKET_TIMESTAMP accepting
SOF_TIMESTAMPING_RAW_HARDWARE.Perhaps we can define a new
PF_PACKETspecific enum where the equivalent option has the same value, so is backwards compatible:enum {
PACKET_TIMESTAMP_ORIG= 0,
PACKET_TIMESTAMP_ZERO= 1 << 0,
PACKET_TIMESTAMP_NS64= 1 << 1,
PACKET_TIMESTAMP_HW= 1 << 6
};
Quoted 2 lines
and
BUILD_BUG_ON(PACKET_TIMESTAMP_RAW != SOF_TIMESTAMPING_RAW_HARDWARE)to document the dependency.
Yes, that would be much cleaner, but in order to do this, we have to be relatively
confident that existing users don't pass any flags other than SOF_TIMESTAMPING_RAW_HARDWARE. It might be safer to start at bit 31 for the new flags to minimize that risk:
/*
* we used to pass SOF_TIMESTAMPING_RAW_HARDWARE from user space,
* but really want our own flags here, so define PACKET_TIMESTAMP_HW to the
* existing value and use the high bits for new non-overlapping flags. */
enum {
PACKET_TIMESTAMP_ORIG = 0,
PACKET_TIMESTAMP_HW = 1 << 6,
PACKET_TIMESTAMP_ZERO = 1 << 30,
PACKET_TIMESTAMP_NS64 = 1 << 31,
};Quoted 1 line
At high level, the code looks great to me, itself.
Thanks,
Arnd
David Miller
maintainerRe: [PATCH] [RFC v2] packet: experimental support for 64-bit timestamps
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
Date: Tue, 28 Nov 2017 14:14:05 +0100
Quoted 5 lines
The implementation is fairly straightforward, but I'm less sure about the interface. Using SOF_TIMESTAMPING_* flags in
PACKET_TIMESTAMPis a bit odd already since most of the other flags make no sense here. Adding two more flags that only make sense for packet sockets but not the normalSO_TIMESTAMPINGoption on other sockets makes this even more confusing.
We unfortunately never enforced any checking whatsoever of the PACKET_TIMESTAMP mask the user gives us, we accept anything.
That makes any changes in this area effectively a grenade ready to go off potentially at any moment.
We can't add new checks without potentially making existing apps stop working. And at least theoretically if we add new bits it is possible for an existing app passing those bits in by accident to start behaving improperly.
I know it sounds like overkill for this, but maybe we can add a new socket option for the SKIP and 64-bit stuff. That would be %100 safe.
Re: [PATCH] [RFC v2] packet: experimental support for 64-bit timestamps
Quoted 15 lines · David Miller
From: Arnd Bergmann <[email protected]>
Date: Tue, 28 Nov 2017 14:14:05 +0100Quoted 5 lines
The implementation is fairly straightforward, but I'm less sure about the interface. Using SOF_TIMESTAMPING_* flags in
PACKET_TIMESTAMPis a bit odd already since most of the other flags make no sense here. Adding two more flags that only make sense for packet sockets but not the normalSO_TIMESTAMPINGoption on other sockets makes this even more confusing.We unfortunately never enforced any checking whatsoever of the
PACKET_TIMESTAMPmask the user gives us, we accept anything.That makes any changes in this area effectively a grenade ready to go off potentially at any moment.
Quoted 7 lines
We can't add new checks without potentially making existing apps stop working. And at least theoretically if we add new bits it is possible for an existing app passing those bits in by accident to start behaving improperly.
I know it sounds like overkill for this, but maybe we can add a new socket option for the SKIP and 64-bit stuff. That would be %100 safe.
Sure, it's easy enough to do, I'll cook something up.
Does this mean you think the general idea of an extended interface for 64-bit timestamps is useful for traditional packet sockets? I think that was still an open question, though we seem to be getting closer to consensus on the implementation and the interface that it should use if we want it.
Arnd
David Miller
maintainerRe: [PATCH] [RFC v2] packet: experimental support for 64-bit timestamps
From: Arnd Bergmann <[email protected]>
Date: Tue, 28 Nov 2017 21:02:05 +0100
Quoted 5 lines
Does this mean you think the general idea of an extended interface for 64-bit timestamps is useful for traditional packet sockets? I think that was still an open question, though we seem to be getting closer to consensus on the implementation and the interface that it should use if we want it.
If it can be done reasonably easy, which you patches seem to indicate is the case, I have no objections to extending packet socket for 64-bit timestamps.
I hope that AF_CAPTURE will be designed in such a way that all apps can migrate to it, and I will be making sure it is implemented appropriately with that in mind.
But I don't think AF_CAPTURE should block your work here.
Re: [PATCH] [RFC v2] packet: experimental support for 64-bit timestamps
Quoted 13 lines · David Miller
From: Arnd Bergmann <[email protected]>
Date: Tue, 28 Nov 2017 21:02:05 +0100Quoted 5 lines
Does this mean you think the general idea of an extended interface for 64-bit timestamps is useful for traditional packet sockets? I think that was still an open question, though we seem to be getting closer to consensus on the implementation and the interface that it should use if we want it.
If it can be done reasonably easy, which you patches seem to indicate is the case, I have no objections to extending packet socket for 64-bit timestamps.
Quoted 5 lines
I hope that
AF_CAPTUREwill be designed in such a way that all apps can migrate to it, and I will be making sure it is implemented appropriately with that in mind.But I don't think
AF_CAPTUREshould block your work here.
To clarify where I'm coming from, my interest is mainly in the first patch to remove all users of 'struct timespec' in order to weed out the users that are actually broken in 2038. I added the comment about it breaking in 2106 and how it could be fixed, and then decided to try out how ugly that fix would get.
I'll follow up with v3 that should address the comments I got so far, but a conclusion of 'nobody is asking for it' would be fine too, and then the patch could get dropped.
I'll also look at the AF_CAPTURE patches to make sure that the timestamping aspect is handled in a safe way there.
Arnd
RFC PATCH v3 1/1 packet: experimental support for 64-bit timestamps
As I noticed in my previous patch to remove the 'timespec' usage in the packet socket, the timestamps in the packet socket are slightly inefficient as they convert a nanosecond value into seconds/nanoseconds or seconds/microseconds.
This adds two new socket options for the timestamp to resolve that:
PACKET_SKIPTIMESTAMP sets a flag to indicate whether to generate timestamps at all. When this is set, all timestamps are hardcoded to zero, which saves a few cycles for the conversion and the access of the hardware clocksource. The idea was taken from pktgen, which has an F_NO_TIMESTAMP option for the same purpose.
PACKET_TIMESTAMP_NS64 changes the interpretation of the time stamp fields:
instead of having 32 bits for seconds plus 32 bits for nanoseconds or microseconds, we now always send down 64 bits worth of nanoseconds when this flag is set.
---
I still have not done any runtime testing on this patch, only implemented the suggestions from the previous versions.
While I don't think anyone is actively looking for this feature, I don't think there are any reasons left against merging it either, and it might come in handy for someone.
--- include/uapi/linux/if_packet.h | 2 + net/packet/af_packet.c | 159 +++++++++++++++++++++++++++++------------ net/packet/internal.h | 2 + 3 files changed, 116 insertions(+), 47 deletions(-)
include/uapi/linux/if_packet.h +2 -0
@@ -57,6 +57,8 @@ struct sockaddr_ll {#define PACKET_QDISC_BYPASS 20#define PACKET_ROLLOVER_STATS 21#define PACKET_FANOUT_DATA 22 +#define PACKET_SKIPTIMESTAMP 23 +#define PACKET_TIMESTAMP_NS64 24#define PACKET_FANOUT_HASH 0#define PACKET_FANOUT_LB 1
net/packet/af_packet.c +112 -47
280 lines not on this page · raw message
net/packet/internal.h +2 -0
@@ -128,6 +128,8 @@ struct packet_sock {unsigned int tp_reserve; unsigned int tp_loss:1; unsigned int tp_tx_has_off:1; + unsigned int tp_skiptstamp:1; + unsigned int tp_tstamp_ns64:1;unsigned int tp_tstamp;struct net_device __rcu *cached_dev;int (*xmit)(struct sk_buff *skb);
Signature · 1 line
2.9.0
Willem de Bruijn
maintainerRe: [PATCH] [RFC v3] packet: experimental support for 64-bit timestamps
Quoted 13 lines · Arnd Bergmann
As I noticed in my previous patch to remove the 'timespec' usage in the packet socket, the timestamps in the packet socket are slightly inefficient as they convert a nanosecond value into seconds/nanoseconds or seconds/microseconds.
This adds two new socket options for the timestamp to resolve that:
PACKET_SKIPTIMESTAMPsets a flag to indicate whether to generate timestamps at all. When this is set, all timestamps are hardcoded to zero, which saves a few cycles for the conversion and the access of the hardware clocksource. The idea was taken from pktgen, which has anF_NO_TIMESTAMPoption for the same purpose.
Quoted 8 lines
PACKET_TIMESTAMP_NS64changes the interpretation of the time stamp fields:
instead of having 32 bits for seconds plus 32 bits for nanoseconds or microseconds, we now always send down 64 bits worth of nanoseconds when this flag is set.Suggested-by Willem de Bruijn <[email protected]>Signed-off-by Arnd Bergmann <[email protected]>
This works. Another option would be to add a PACKET_TIMESTAMP_EX with the semantics we discussed previously + fail hard when any undefined bits are set. I don't feel strong either way, we don't intend to extend further.
If taking this approach, it might be good to split into separate patches, one for each flag?
net/packet/af_packet.c static int __packet_get_status(struct packet_sock *po, void *frame) · line 443
Quoted 3 lines
net/packet/af_packet.c +1
-1-static __u32 tpacket_get_timestamp (struct sk_buff *skb,struct timespec64 *ts, +static __u32 tpacket_get_timestamp (struct sk_buff *skb,__u32 *hi,__u32 *lo,unsigned int flags)
Argument flags is no longer used.
Quoted 27 lines
{
net/packet/af_packet.c +17
-5+struct packet_sock *po =pkt_sk (skb->sk);struct skb_shared_hwtstamps *shhwtstamps =skb_hwtstamps (skb); +ktime_t stamp; +u32 type; + +if (po->tp_skiptstamp) +return 0 ;if (shhwtstamps && - (flags &SOF_TIMESTAMPING_RAW_HARDWARE ) && -ktime_to_timespec64_cond (shhwtstamps->hwtstamp, ts)) -return TP_STATUS_TS_RAW_HARDWARE ; + (po->tp_tstamp &SOF_TIMESTAMPING_RAW_HARDWARE ) && + shhwtstamps->hwtstamp) { + stamp = shhwtstamps->hwtstamp; + type =TP_STATUS_TS_RAW_HARDWARE ; + }else if (skb->tstamp) { + stamp = skb->tstamp; + type =TP_STATUS_TS_SOFTWARE ; + }else { +return 0 ; + } -if (ktime_to_timespec64_cond (skb->tstamp, ts)) -return TP_STATUS_TS_SOFTWARE ; +if (po->tp_tstamp_ns64) {
net/packet/af_packet.c static int __packet_get_status(struct packet_sock *po, void *frame) · line 474
Quoted 10 lines
net/packet/af_packet.c +8
-1+__u64 ns =ktime_to_ns (stamp); -return 0 ; + *hi =upper_32_bits (ns); + *lo =lower_32_bits (ns); + }else { +struct timespec64 ts =ktime_to_timespec64 (stamp); + + *hi = ts.tv_sec; +if (po->tp_version ==TPACKET_V1 )
Very minor: may want to invert test to make newer the protocols the likely branch.
Quoted 10 lines
static
__u32__packet_set_timestamp(structpacket_sock*po, void *frame,
structsk_buff*skb){ union tpacket_uhdr h;net/packet/af_packet.c +2
-3-struct timespec64 ts; -__u32 ts_status; +__u32 ts_status, hi, lo; -if (!(ts_status =tpacket_get_timestamp (skb, &ts, po->tp_tstamp))) +if (!(ts_status =tpacket_get_timestamp (skb, &hi, &lo, po->tp_tstamp)))
net/packet/af_packet.c static int __packet_get_status(struct packet_sock *po, void *frame) · line 475
Quoted 10 lines
net/packet/af_packet.c +0
-7return 0 ; h.raw = frame; -/* -* versions 1 through 3 overflow the timestamps in y2106, since they -* all store the seconds in a 32-bit unsigned integer. -* If we create a version 4, that should have a 64-bit timestamp, -* either 64-bit seconds + 32-bit nanoseconds, or just 64-bit -* nanoseconds. -*/
Probably no need to introduce this in patch 1/2 when removing it in 2/2.
net/packet/af_packet.c static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, · line 2230
Quoted 7 lines
net/packet/af_packet.c +1
-1@@ -2191,8 +2226,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,unsigned long status =TP_STATUS_USER ;unsigned short macoff, netoff, hdrlen;struct sk_buff *copy_skb =NULL ; -struct timespec64 ts;__u32 ts_status; +__u32 hi, lo;
since this function is not time-specific, the context of hi and lo is not immediately obvious here. tstamp_hi, tstamp_lo? Or even __u32 tstamp[2] and have tpacket_get_timestamp and packet_get_time take one fewer argument.
Re: [PATCH] [RFC v3] packet: experimental support for 64-bit timestamps
Quoted 27 lines · Willem de Bruijn
Quoted 13 lines · Arnd Bergmann
As I noticed in my previous patch to remove the 'timespec' usage in the packet socket, the timestamps in the packet socket are slightly inefficient as they convert a nanosecond value into seconds/nanoseconds or seconds/microseconds.
This adds two new socket options for the timestamp to resolve that:
PACKET_SKIPTIMESTAMPsets a flag to indicate whether to generate timestamps at all. When this is set, all timestamps are hardcoded to zero, which saves a few cycles for the conversion and the access of the hardware clocksource. The idea was taken from pktgen, which has anF_NO_TIMESTAMPoption for the same purpose.Quoted 8 lines
PACKET_TIMESTAMP_NS64changes the interpretation of the time stamp fields:
instead of having 32 bits for seconds plus 32 bits for nanoseconds or microseconds, we now always send down 64 bits worth of nanoseconds when this flag is set.Suggested-by Willem de Bruijn <[email protected]>Signed-off-by Arnd Bergmann <[email protected]>This works. Another option would be to add a
PACKET_TIMESTAMP_EXwith the semantics we discussed previously + fail hard when any undefined bits are set. I don't feel strong either way, we don't intend to extend further.
Quoted 8 lines
If taking this approach, it might be good to split into separate patches, one for each flag?
net/packet/af_packet.c static int __packet_get_status(struct packet_sock *po, void *frame) · line 443
Quoted 3 lines
net/packet/af_packet.c +1
-1-static __u32 tpacket_get_timestamp (struct sk_buff *skb,struct timespec64 *ts, +static __u32 tpacket_get_timestamp (struct sk_buff *skb,__u32 *hi,__u32 *lo,unsigned int flags)Argument flags is no longer used.
Fixed
Quoted 11 lines
net/packet/af_packet.c static int __packet_get_status(struct packet_sock *po, void *frame) · line 474
Quoted 8 lines
net/packet/af_packet.c +7
-1-return 0 ; + *hi =upper_32_bits (ns); + *lo =lower_32_bits (ns); + }else { +struct timespec64 ts =ktime_to_timespec64 (stamp); + + *hi = ts.tv_sec; +if (po->tp_version ==TPACKET_V1 )Very minor: may want to invert test to make newer the protocols the likely branch.
Ok. I didn't think this would make any difference to the compiler, but for readability it seems at least as good, so I've changed it as you suggested and use "po->tp_version > TPACKET_V1".
Quoted 21 lines
Quoted 10 lines
static
__u32__packet_set_timestamp(structpacket_sock*po, void *frame,
structsk_buff*skb){ union tpacket_uhdr h;net/packet/af_packet.c +2
-3-struct timespec64 ts; -__u32 ts_status; +__u32 ts_status, hi, lo; -if (!(ts_status =tpacket_get_timestamp (skb, &ts, po->tp_tstamp))) +if (!(ts_status =tpacket_get_timestamp (skb, &hi, &lo, po->tp_tstamp)))net/packet/af_packet.c static int __packet_get_status(struct packet_sock *po, void *frame) · line 475
Quoted 10 lines
net/packet/af_packet.c +0
-7return 0 ; h.raw = frame; -/* -* versions 1 through 3 overflow the timestamps in y2106, since they -* all store the seconds in a 32-bit unsigned integer. -* If we create a version 4, that should have a 64-bit timestamp, -* either 64-bit seconds + 32-bit nanoseconds, or just 64-bit -* nanoseconds. -*/
Quoted 1 line
Probably no need to introduce this in patch 1/2 when removing it in 2/2.
I'm still considering this patch as experimental, since I haven't done any actual testing on it, so I'm not sure it gets merged at the same time. If patch 1 gets merged separately, I'd rather keep the comment in place.
Quoted 4 lines
Quoted 4 lines
net/packet/af_packet.c +0
-0@@ -2191,8 +2226,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,unsigned long status =TP_STATUS_USER ;unsigned short macoff, netoff, hdrlen;struct sk_buff *copy_skb =NULL ;
Quoted 8 lines
net/packet/af_packet.c static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, · line 2230
Quoted 3 lines
net/packet/af_packet.c +1
-1-struct timespec64 ts;__u32 ts_status; +__u32 hi, lo;since this function is not time-specific, the context of hi and lo is not immediately obvious here.
tstamp_hi,tstamp_lo? Or even__u32tstamp[2] and havetpacket_get_timestampandpacket_get_timetake one fewer argument.
Fixed.
Thanks for the review! Any suggestions for how to do the testing? If you have existing test cases, could you give my next version a test run to see if there are any regressions and if the timestamps work as expected?
I see that there are test cases in tools/testing/selftests/net/, but none of them seem to use the time stamps so far, and I'm not overly familiar with how it works in the details to extend it in a meaningful way.
arnd
Willem de Bruijn
maintainerRe: [PATCH] [RFC v3] packet: experimental support for 64-bit timestamps
Quoted 7 lines
Thanks for the review! Any suggestions for how to do the testing? If you have existing test cases, could you give my next version a test run to see if there are any regressions and if the timestamps work as expected?
I see that there are test cases in
tools/testing/selftests/net/, but none of them seem to use the time stamps so far, and I'm not overly familiar with how it works in the details to extend it in a meaningful way.
I could not find any good tests for this interface, either. The only user of the interface I found was a little tool I wrote a few years ago that compares timestamps at multiple points in the transmit path for latency measurement [1]. But it may be easier to just write a new test under tools/testing/selftests/net for this purpose. I can help with that, too, if you want.
[1] https://github.com/wdebruij/kerneltools/blob/master/tools/tcplate/tcplate.c
Re: [PATCH] [RFC v3] packet: experimental support for 64-bit timestamps
Quoted 8 lines · Willem de Bruijn
Quoted 7 lines
Thanks for the review! Any suggestions for how to do the testing? If you have existing test cases, could you give my next version a test run to see if there are any regressions and if the timestamps work as expected?
I see that there are test cases in
tools/testing/selftests/net/, but none of them seem to use the time stamps so far, and I'm not overly familiar with how it works in the details to extend it in a meaningful way.
Quoted 6 lines
I could not find any good tests for this interface, either. The only user of the interface I found was a little tool I wrote a few years ago that compares timestamps at multiple points in the transmit path for latency measurement [1]. But it may be easier to just write a new test under
tools/testing/selftests/netfor this purpose. I can help with that, too, if you want.
Thanks, that would be great!
Arnd
Willem de Bruijn
maintainerRe: [PATCH] [RFC v3] packet: experimental support for 64-bit timestamps
Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · Willem de Bruijn
Quoted 7 lines
Thanks for the review! Any suggestions for how to do the testing? If you have existing test cases, could you give my next version a test run to see if there are any regressions and if the timestamps work as expected?
I see that there are test cases in
tools/testing/selftests/net/, but none of them seem to use the time stamps so far, and I'm not overly familiar with how it works in the details to extend it in a meaningful way.
Quoted 8 lines
Quoted 6 lines
I could not find any good tests for this interface, either. The only user of the interface I found was a little tool I wrote a few years ago that compares timestamps at multiple points in the transmit path for latency measurement [1]. But it may be easier to just write a new test under
tools/testing/selftests/netfor this purpose. I can help with that, too, if you want.Thanks, that would be great!
I'll reply to this thread with git send-email with an extension to tools/testing/selftests/net/psock_tpacket.c. I can resend that for submission after your feature is merged (as it depends on it) or feel free to include it in your patchset. The test currently fails for the ns64 case. I probably did not convert correctly, but have to leave the office and want to send what I have.
Two other comments: the test crashed the kernel due to a NULL ptr in tpacket_get_timestamp. We cannot rely on skb->sk being set to the packet socket here. And assignment to bitfield requires a cast to boolean.
net/packet/af_packet.c +0 -0
@@ -439,9 +439,9 @@ static int __packet_get_status(struct packet_sock
*po, void *frame)
}
}
-static __u32 tpacket_get_timestamp(struct sk_buff *skb, __u32 *hi, __u32 *lo) +static __u32 tpacket_get_timestamp(struct packet_sock *po, struct sk_buff *skb,
+ __u32 *hi, __u32 *lo)
{
- struct packet_sock *po = pkt_sk(skb->sk);
struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
ktime_t stamp;
u32 type;
@@ -508,7 +508,7 @@ static __u32 __packet_set_timestamp(struct
packet_sock *po, void *frame,
union tpacket_uhdr h;
__u32 ts_status, hi, lo;- if (!(ts_status = tpacket_get_timestamp(skb, &hi, &lo)))
+ if (!(ts_status = tpacket_get_timestamp(po, skb, &hi, &lo)))
return 0;
h.raw = frame;@@ -2352,7 +2352,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
- if (!(ts_status = tpacket_get_timestamp(skb, &tstamp_hi, &tstamp_lo)))
+ if (!(ts_status = tpacket_get_timestamp(po, skb, &tstamp_hi,&tstamp_lo)))
packet_get_time(po, &tstamp_hi, &tstamp_lo);
status |= ts_status;@@ -3835,7 +3835,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
- po->tp_skiptstamp = val;
+ po->tp_skiptstamp = !!val;
return 0;
}
case PACKET_TIMESTAMP_NS64:@@ -3847,7 +3847,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
- po->tp_tstamp_ns64 = val;
+ po->tp_tstamp_ns64 = !!val;
return 0;
}
case PACKET_FANOUT:Willem de Bruijn
maintainerRFC PATCH 1/1 selftests: test timestamps in psock_tpacket
From: Willem de Bruijn <[email protected]>
Packet rings can return timestamps. Optionally test this path.
Verify that the returned values are sane.
Also test new timestamp modes skip and ns64.
--- tools/testing/selftests/net/psock_tpacket.c | 125 +++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-)
tools/testing/selftests/net/psock_tpacket.c +124 -1
@@ -36,6 +36,7 @@* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h>
@@ -57,6 +58,7 @@#include <net/if.h> #include <inttypes.h> #include <poll.h> +#include <sys/time.h> #include "psock_lib.h"
@@ -75,6 +77,19 @@#define NUM_PACKETS 100#define ALIGN_8 (x) (((x) + 8 - 1) & ~(8 - 1)) +const uint64_t tstamp_bound_ns64 =1000UL *1000 *1000 ; + +enum cfg_tstamp_type { + tstype_none, + tstype_default, + tstype_skip, + tstype_ns64 +}; + +static enum cfg_tstamp_type cfg_tstamp; + +static uint64_t tstamp_start_ns64; +struct ring {struct iovec *rd;uint8_t *mm_space;
@@ -150,6 +165,43 @@ static void test_payload(void *pay, size_t len) } } +static void test_tstamp (uint32_t sec,uint32_t nsec) +{ +uint64_t tstamp_ns64; + +if (!cfg_tstamp) +return ; + +if (cfg_tstamp == tstype_skip) { +if (sec || nsec) { +fprintf (stderr,"%s: unexpected tstamp %u:%u\n" , + __func__, sec, nsec); +exit (1 ); + } +return ; + } + +if (cfg_tstamp == tstype_ns64) + tstamp_ns64 = (((uint64_t ) sec) <<32 ) | nsec; +else + tstamp_ns64 = (sec *1000UL *1000 *1000 ) + nsec; + +if (tstamp_ns64 < tstamp_start_ns64) { +fprintf (stderr,"tstamp: %lu lowerbound=%lu under=%lu\n" , + tstamp_ns64, tstamp_start_ns64, + tstamp_start_ns64 - tstamp_ns64); +exit (1 ); + } +if (tstamp_ns64 > tstamp_start_ns64 + tstamp_bound_ns64) { +fprintf (stderr,"tstamp: %lu upperbound=%lu over=%lu\n" , + tstamp_ns64, + tstamp_start_ns64 + tstamp_bound_ns64, + tstamp_ns64 - (tstamp_start_ns64 + + tstamp_bound_ns64)); +exit (1 ); + } +} +static void create_payload (void *pay,size_t *len) {int i;
@@ -256,12 +308,18 @@ static void walk_v1_v2_rx(int sock, struct ring *ring)case TPACKET_V1 :test_payload ((uint8_t *) ppd.raw + ppd.v1->tp_h.tp_mac, ppd.v1->tp_h.tp_snaplen); +test_tstamp (ppd.v1->tp_h.tp_sec, + cfg_tstamp == tstype_ns64 ? + ppd.v1->tp_h.tp_usec : + ppd.v1->tp_h.tp_usec *1000 ); total_bytes += ppd.v1->tp_h.tp_snaplen;break ;case TPACKET_V2 :test_payload ((uint8_t *) ppd.raw + ppd.v2->tp_h.tp_mac, ppd.v2->tp_h.tp_snaplen); +test_tstamp (ppd.v2->tp_h.tp_sec, + ppd.v2->tp_h.tp_nsec); total_bytes += ppd.v2->tp_h.tp_snaplen;break ; }
@@ -572,6 +630,7 @@ static void __v3_walk_block(struct block_desc *pbd, const int block_num) bytes_with_padding +=ALIGN_8 (ppd->tp_snaplen + ppd->tp_mac);test_payload ((uint8_t *) ppd + ppd->tp_mac, ppd->tp_snaplen); +test_tstamp (ppd->tp_sec, ppd->tp_nsec);status_bar_update (); total_packets++;
@@ -766,6 +825,38 @@ static void unmap_ring(int sock, struct ring *ring)free (ring->rd); } +static void setup_tstamp (int sock) +{ +struct timeval tv; +int one =1 ; + +gettimeofday (&tv,NULL ); + tstamp_start_ns64 = (tv.tv_sec *1000UL *1000 *1000 ) + + (tv.tv_usec *1000UL ); + +/* TODO: remove before submit: temporary */ +#ifndef PACKET_SKIPTIMESTAMP +#define PACKET_SKIPTIMESTAMP 23 +#endif +#ifndef PACKET_TIMESTAMP_NS64 +#define PACKET_TIMESTAMP_NS64 24 +#endif + +if (cfg_tstamp == tstype_skip) { +if (setsockopt (sock,SOL_PACKET ,PACKET_SKIPTIMESTAMP , + &one,sizeof (one))) { +perror ("setsockopt skiptimestamp" ); +exit (1 ); + } + }else if (cfg_tstamp == tstype_ns64) { +if (setsockopt (sock,SOL_PACKET ,PACKET_TIMESTAMP_NS64 , + &one,sizeof (one))) { +perror ("setsockopt timestamp ns64" ); +exit (1 ); + } + } +} +static int test_kernel_bit_width (void ) {char in[512 ], *ptr;
@@ -829,6 +920,8 @@ static int test_tpacket(int version, int type) } sock =pfsocket (version); +if (cfg_tstamp) +setup_tstamp (sock);memset (&ring,0 ,sizeof (ring));setup_ring (sock, &ring, version, type);mmap_ring (sock, &ring);
@@ -841,10 +934,40 @@ static int test_tpacket(int version, int type)return 0 ; } -int main (void ) +static void usage (const char *filepath) +{ +fprintf (stderr,"Usage: %s [-t <default|skip|ns64>]\n" , filepath); +exit (1 ); +} + +static void parse_opts (int argc,char **argv) +{ +int c; + +while ((c =getopt (argc, argv,"t:" )) !=-1 ) { +switch (c) { +case 't' : +if (!strcmp (optarg,"default" )) + cfg_tstamp = tstype_default; +else if (!strcmp (optarg,"skip" )) + cfg_tstamp = tstype_skip; +else if (!strcmp (optarg,"ns64" )) + cfg_tstamp = tstype_ns64; +else +usage (argv[0 ]); +break ; +default : +usage (argv[0 ]); + } + } +} + +int main (int argc,char **argv) {int ret =0 ; +parse_opts (argc, argv); + ret |=test_tpacket (TPACKET_V1 ,PACKET_RX_RING ); ret |=test_tpacket (TPACKET_V1 ,PACKET_TX_RING );
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Willem de Bruijn
maintainerRe: [PATCH] [RFC v3] packet: experimental support for 64-bit timestamps
In reply to Willem de BruijnQuoted 18 lines · Willem de Bruijn
Quoted 17 lines · Arnd Bergmann
Quoted 14 lines · Willem de Bruijn
Quoted 7 lines
Thanks for the review! Any suggestions for how to do the testing? If you have existing test cases, could you give my next version a test run to see if there are any regressions and if the timestamps work as expected?
I see that there are test cases in
tools/testing/selftests/net/, but none of them seem to use the time stamps so far, and I'm not overly familiar with how it works in the details to extend it in a meaningful way.I could not find any good tests for this interface, either. The only user of the interface I found was a little tool I wrote a few years ago that compares timestamps at multiple points in the transmit path for latency measurement [1]. But it may be easier to just write a new test under
tools/testing/selftests/netfor this purpose. I can help with that, too, if you want.
Quoted 4 lines
Quoted 1 line
Thanks, that would be great!
I'll reply to this thread with git send-email with an extension to
tools/testing/selftests/net/psock_tpacket.c.
It appears that it did not end up in this thread. At least not when using gmail threading. Patch at http://patchwork.ozlabs.org/patch/842854/
RFC PATCH v4 1/1 packet: experimental support for 64-bit timestamps
In reply to Arnd BergmannAs I noticed in my previous patch to remove the 'timespec' usage in the packet socket, the timestamps in the packet socket are slightly inefficient as they convert a nanosecond value into seconds/nanoseconds or seconds/microseconds.
This adds two new socket options for the timestamp to resolve that:
PACKET_SKIPTIMESTAMP sets a flag to indicate whether to generate timestamps at all. When this is set, all timestamps are hardcoded to zero, which saves a few cycles for the conversion and the access of the hardware clocksource. The idea was taken from pktgen, which has an F_NO_TIMESTAMP option for the same purpose.
PACKET_TIMESTAMP_NS64 changes the interpretation of the time stamp fields:
instead of having 32 bits for seconds plus 32 bits for nanoseconds or microseconds, we now always send down 64 bits worth of nanoseconds when this flag is set.
---
I still have not done any runtime testing on this patch, only implemented the suggestions from the previous versions.
While I don't think anyone is actively looking for this feature, I don't think there are any reasons left against merging it either, and it might come in handy for someone.
v4: address minor comments from Willem
v3: rework to use setsockopt
v2: use new tstamp flags instead of a new version
v1: original implementation using TPACKET_V4
--- include/uapi/linux/if_packet.h | 2 + net/packet/af_packet.c | 160 ++++++++++++++++++++++++++++------------- net/packet/internal.h | 2 + 3 files changed, 116 insertions(+), 48 deletions(-)
include/uapi/linux/if_packet.h +2 -0
@@ -57,6 +57,8 @@ struct sockaddr_ll {#define PACKET_QDISC_BYPASS 20#define PACKET_ROLLOVER_STATS 21#define PACKET_FANOUT_DATA 22 +#define PACKET_SKIPTIMESTAMP 23 +#define PACKET_TIMESTAMP_NS64 24#define PACKET_FANOUT_HASH 0#define PACKET_FANOUT_LB 1
net/packet/af_packet.c +112 -48
280 lines not on this page · raw message
net/packet/internal.h +2 -0
@@ -128,6 +128,8 @@ struct packet_sock {unsigned int tp_reserve; unsigned int tp_loss:1; unsigned int tp_tx_has_off:1; + unsigned int tp_skiptstamp:1; + unsigned int tp_tstamp_ns64:1;unsigned int tp_tstamp;struct net_device __rcu *cached_dev;int (*xmit)(struct sk_buff *skb);
Signature · 1 line
2.9.0
Willem de Bruijn
maintainerRe: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
In reply to Arnd BergmannQuoted 9 lines · Arnd Bergmann
Quoted 8 lines · Björn Töpel
2017-11-27 21:51 GMT+01:00 Arnd Bergmann <arnd at arndb.de>:
[...]Quoted 6 lines
Quoted 5 lines
There already is an effort to come up with a new
AF_PACKETV4 [1]. We should make sure that any new interface does not have the Y2038/Y2106 issue. But, if a new version is being developed and that subsumes all existing use cases, then there probably is no need for another version that is a very small diff to V3.
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Ah, perfect, that's good timing. Adding Björn to Cc here.
Unfortunately, for the Y2038/Y2106 cases, we'll be (as a result of netdevconf discussions) moving the
AF_PACKETV4 implementation to a separate, new, address/packet family.Ok, I see.
Does it matter whether the replacement is a new version or a new packet family?
Quoted 18 lines
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
If adding support for existing applications is useful, another approach would be to add a new socket option that changes the semantics for the two u32 fields in each of V1, V2 and V3 to hold nsec. Add a single check after filling in those structs whether the option is set and, if so, overwrite the two fields.
Quoted 7 lines
Quoted 1 line
I don't think that's necessary. As long as the V4 capabilities are a superset of V1-V3, we should be able to just require all users to move to V4 (or later) in the next 89 years, and make sure that they use unsigned seconds if they care about 2038.
Quoted 3 lines
Given that V4 wont be around for
AF_PACKET-- at least not in the shape of our patches -- Willem's suggestion is probably a good way forward.
Quoted 5 lines
That leaves one question: should we do that now, or wait until some other reason for a V4 comes up? I don't mind creating another patch for this, just want to get a feeling of whether the API clutter is worth it when we have a way out that works until y2106 (at which point we run into other problems as well).
I don't expect that we'll have another packet version independent from the work that Björn is doing. The choice to implement using a new packet family is given by the complexity of the existing code, especially the various locking mechanisms.
Quoted 1 line
From that point of view, and if we want to offer a Y2106 proof
AF_PACKET independent from the above, no reason to wait.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] [RFC] packet: experimental support for 64-bit timestamps
Quoted 13 lines · Willem de Bruijn
Quoted 12 lines · Arnd Bergmann
Quoted 11 lines · Björn Töpel
2017-11-27 21:51 GMT+01:00 Arnd Bergmann <arnd at arndb.de>:
[...]Quoted 8 lines
Quoted 5 lines
There already is an effort to come up with a new
AF_PACKETV4 [1]. We should make sure that any new interface does not have the Y2038/Y2106 issue. But, if a new version is being developed and that subsumes all existing use cases, then there probably is no need for another version that is a very small diff to V3.Ah, perfect, that's good timing. Adding Björn to Cc here.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Unfortunately, for the Y2038/Y2106 cases, we'll be (as a result of netdevconf discussions) moving the
AF_PACKETV4 implementation to a separate, new, address/packet family.Ok, I see.
Does it matter whether the replacement is a new version or a new packet family?
It depends on whether the new packet family provides a superset of the AF_PACKET features or not. If we can expect that all users of AF_PACKET can migrate to the replacement over time, then doing it there is sufficient, otherwise adding 64-bit timestamps into AF_PACKET may be a better way to upgrade existing users.
Quoted 24 lines
Quoted 18 lines
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
If adding support for existing applications is useful, another approach would be to add a new socket option that changes the semantics for the two u32 fields in each of V1, V2 and V3 to hold nsec. Add a single check after filling in those structs whether the option is set and, if so, overwrite the two fields.
Quoted 7 lines
Quoted 1 line
I don't think that's necessary. As long as the V4 capabilities are a superset of V1-V3, we should be able to just require all users to move to V4 (or later) in the next 89 years, and make sure that they use unsigned seconds if they care about 2038.
Quoted 3 lines
Given that V4 wont be around for
AF_PACKET-- at least not in the shape of our patches -- Willem's suggestion is probably a good way forward.Quoted 5 lines
That leaves one question: should we do that now, or wait until some other reason for a V4 comes up? I don't mind creating another patch for this, just want to get a feeling of whether the API clutter is worth it when we have a way out that works until y2106 (at which point we run into other problems as well).
Quoted 4 lines
I don't expect that we'll have another packet version independent from the work that Björn is doing. The choice to implement using a new packet family is given by the complexity of the existing code, especially the various locking mechanisms.
Ok.
Quoted 2 lines
From that point of view, and if we want to offer a Y2106 proof
AF_PACKETindependent from the above, no reason to wait.
Agreed.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html