Skip to content

Commit 007747a

Browse files
mlichvardavem330
authored andcommitted
net: fix SOF_TIMESTAMPING_BIND_PHC to work with multiple sockets
When multiple sockets using the SOF_TIMESTAMPING_BIND_PHC flag received a packet with a hardware timestamp (e.g. multiple PTP instances in different PTP domains using the UDPv4/v6 multicast or L2 transport), the timestamps received on some sockets were corrupted due to repeated conversion of the same timestamp (by the same or different vclocks). Fix ptp_convert_timestamp() to not modify the shared skb timestamp and return the converted timestamp as a ktime_t instead. If the conversion fails, return 0 to not confuse the application with timestamps corresponding to an unexpected PHC. Fixes: d7c0882 ("net: socket: support hardware timestamp conversion to PHC bound") Signed-off-by: Miroslav Lichvar <[email protected]> Cc: Yangbo Lu <[email protected]> Cc: Richard Cochran <[email protected]> Acked-by: Richard Cochran <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1b26d36 commit 007747a

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

drivers/ptp/ptp_vclock.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index)
185185
}
186186
EXPORT_SYMBOL(ptp_get_vclocks_index);
187187

188-
void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
189-
int vclock_index)
188+
ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps,
189+
int vclock_index)
190190
{
191191
char name[PTP_CLOCK_NAME_LEN] = "";
192192
struct ptp_vclock *vclock;
@@ -198,12 +198,12 @@ void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
198198
snprintf(name, PTP_CLOCK_NAME_LEN, "ptp%d", vclock_index);
199199
dev = class_find_device_by_name(ptp_class, name);
200200
if (!dev)
201-
return;
201+
return 0;
202202

203203
ptp = dev_get_drvdata(dev);
204204
if (!ptp->is_virtual_clock) {
205205
put_device(dev);
206-
return;
206+
return 0;
207207
}
208208

209209
vclock = info_to_vclock(ptp->info);
@@ -215,7 +215,7 @@ void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
215215
spin_unlock_irqrestore(&vclock->lock, flags);
216216

217217
put_device(dev);
218-
hwtstamps->hwtstamp = ns_to_ktime(ns);
218+
return ns_to_ktime(ns);
219219
}
220220
EXPORT_SYMBOL(ptp_convert_timestamp);
221221
#endif

include/linux/ptp_clock_kernel.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,17 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index);
351351
*
352352
* @hwtstamps: skb_shared_hwtstamps structure pointer
353353
* @vclock_index: phc index of ptp vclock.
354+
*
355+
* Returns converted timestamp, or 0 on error.
354356
*/
355-
void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
356-
int vclock_index);
357+
ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps,
358+
int vclock_index);
357359
#else
358360
static inline int ptp_get_vclocks_index(int pclock_index, int **vclock_index)
359361
{ return 0; }
360-
static inline void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
361-
int vclock_index)
362-
{ }
362+
static inline ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps,
363+
int vclock_index)
364+
{ return 0; }
363365

364366
#endif
365367

net/socket.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
830830
int empty = 1, false_tstamp = 0;
831831
struct skb_shared_hwtstamps *shhwtstamps =
832832
skb_hwtstamps(skb);
833+
ktime_t hwtstamp;
833834

834835
/* Race occurred between timestamp enabling and packet
835836
receiving. Fill in the current time for now. */
@@ -878,10 +879,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
878879
(sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
879880
!skb_is_swtx_tstamp(skb, false_tstamp)) {
880881
if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC)
881-
ptp_convert_timestamp(shhwtstamps, sk->sk_bind_phc);
882+
hwtstamp = ptp_convert_timestamp(shhwtstamps,
883+
sk->sk_bind_phc);
884+
else
885+
hwtstamp = shhwtstamps->hwtstamp;
882886

883-
if (ktime_to_timespec64_cond(shhwtstamps->hwtstamp,
884-
tss.ts + 2)) {
887+
if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
885888
empty = 0;
886889

887890
if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&

0 commit comments

Comments
 (0)