Subject: Re: [RFC][PATCH 1/1] net: support for hardware timestamping

From: Ingo Oeser <[email-masked]>
Date: Tue, 29 Jul 2008 19:30:19 +0200

Hi Octavian,

Octavian Purdila schrieb:
> On Tuesday 29 July 2008, Stephen Hemminger wrote:
> >
> > In my sky2 sample code, I took a different approach:
> >  1. Why have HW timestamps different than existing timestamps? If you
> >     just use existing timestamp, no socket API is needed.
> 
> I agree that is a much better approach if you are ok with the variance 
> introduced by synchronizing the HW timestamps with the CPU clock.

Just convert your hardware specific cookie you have into the nanoseconds
resolution timstamp in skb->tstamp just before calling netif_rx() 
or net_receive_skb().  

These functions will not touch it, as long as they never see a ZERO 
value there. A ZERO value in tstamp.tv64 means, we have no timestamp.

The difference to CPU clock doesn't matter. 
That compensation can be done by your driver or application at will.
For mainline, compensation in driver might be preferred.

As long as it is montonic increasing and related to time in any way, 
you could put anything there, I think :-)

The timestamp in nanoseconds will be submitted as CMSG().
see net/socket.c "put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof(ts), &ts);"

Enable it with this code fragment in user space:

	int one = 1;
	setsockopt(mysok, SOL_SOCKET, SO_TIMESTAMPNS, &one);

In the kernel the call chain is: raw_recvmsg() -> sock_recv_timestamp() -> __sock_recv_timestamp()
__sock_recv_timestamp() is:
void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
    struct sk_buff *skb)
{
    ktime_t kt = skb->tstamp;

    if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Check for nanosecond timestamps
        struct timeval tv;
        /* Race occurred between timestamp enabling and packet
           receiving.  Fill in the current time for now. */
        if (kt.tv64 == 0)
            kt = ktime_get_real();
        skb->tstamp = kt;
        tv = ktime_to_timeval(kt);
        put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, sizeof(tv), &tv);
    } else {
        struct timespec ts;
        /* Race occurred between timestamp enabling and packet
           receiving.  Fill in the current time for now. */
        if (kt.tv64 == 0)
            kt = ktime_get_real();
        skb->tstamp = kt;
        ts = ktime_to_timespec(kt);
        put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof(ts), &ts);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Put nanosecond timestamps into CMSG()
    }
}

> But if you want to precisely measure one-way delays, and if you have the hw 
> timestamp units synchronized across the nodes, then you need the hardware 
> timesetamp. 

Yes, no argument against that. Just your new user space ABI is simply not 
required for RX timestamps. It works out of the box already.

Best Regards

Ingo Oeser