Commit 5be5726e authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'timestamp-for-jens' of...

Merge branch 'timestamp-for-jens' of https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next into for-6.17/io_uring

Pull networking side timestamp prep patch from Jakub.

* 'timestamp-for-jens' of https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next:
  net: timestamp: add helper returning skb's tx tstamp
parents cb9ccfb4 2410251c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2677,6 +2677,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
			     struct sk_buff *skb);

bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk);
int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
			 struct timespec64 *ts);

static inline void
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
{
+46 −0
Original line number Diff line number Diff line
@@ -843,6 +843,52 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
		 sizeof(ts_pktinfo), &ts_pktinfo);
}

bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk)
{
	const struct sock_exterr_skb *serr = SKB_EXT_ERR(skb);
	u32 tsflags = READ_ONCE(sk->sk_tsflags);

	if (serr->ee.ee_errno != ENOMSG ||
	   serr->ee.ee_origin != SO_EE_ORIGIN_TIMESTAMPING)
		return false;

	/* software time stamp available and wanted */
	if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) && skb->tstamp)
		return true;
	/* hardware time stamps available and wanted */
	return (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
		skb_hwtstamps(skb)->hwtstamp;
}

int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk,
			  struct timespec64 *ts)
{
	u32 tsflags = READ_ONCE(sk->sk_tsflags);
	ktime_t hwtstamp;
	int if_index = 0;

	if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
	    ktime_to_timespec64_cond(skb->tstamp, ts))
		return SOF_TIMESTAMPING_TX_SOFTWARE;

	if (!(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) ||
	    skb_is_swtx_tstamp(skb, false))
		return -ENOENT;

	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV)
		hwtstamp = get_timestamp(sk, skb, &if_index);
	else
		hwtstamp = skb_hwtstamps(skb)->hwtstamp;

	if (tsflags & SOF_TIMESTAMPING_BIND_PHC)
		hwtstamp = ptp_convert_timestamp(&hwtstamp,
						READ_ONCE(sk->sk_bind_phc));
	if (!ktime_to_timespec64_cond(hwtstamp, ts))
		return -ENOENT;

	return SOF_TIMESTAMPING_TX_HARDWARE;
}

/*
 * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
 */