All of lore.kernel.org
 help / color / mirror / Atom feed
* CLOCK_MONOTONIC datagram timestamps by the kernel
@ 2007-02-28 10:18 John
  2007-02-28 13:37 ` John
  0 siblings, 1 reply; 39+ messages in thread
From: John @ 2007-02-28 10:18 UTC (permalink / raw)
  To: linux-net; +Cc: netdev, linux.kernel

Hello,

I know it's possible to have Linux timestamp incoming datagrams as soon 
as they are received, then for one to retrieve this timestamp later with 
an ioctl command or a recvmsg call.

As far as I understand, one can either do

   const int on = 1;
   setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof on);

then use recvmsg()

or not set the SO_TIMESTAMP socket option and just call

   ioctl(sock, SIOCGSTAMP, &tv);

after each datagram has been received.

SIOCGSTAMP
     Return a struct timeval with the receive timestamp of the last
packet passed to the user. This is useful for accurate round trip time
measurements. See setitimer(2) for a description of struct timeval.


As far as I understand, this timestamp is given by the CLOCK_REALTIME 
clock. However, I would like to obtain a timestamp given by the 
CLOCK_MONOTONIC clock.

Relevant parts of the code (I think):

net/core/dev.c

void net_enable_timestamp(void)
{
   atomic_inc(&netstamp_needed);
}

void __net_timestamp(struct sk_buff *skb)
{
   struct timeval tv;

   do_gettimeofday(&tv);
   skb_set_timestamp(skb, &tv);
}

static inline void net_timestamp(struct sk_buff *skb)
{
   if (atomic_read(&netstamp_needed))
     __net_timestamp(skb);
   else {
     skb->tstamp.off_sec = 0;
     skb->tstamp.off_usec = 0;
   }
}

do_gettimeofday() just calls __get_realtime_clock_ts()

Would it be possible to replace do_gettimeofday() by ktime_get_ts() with 
the appropriate division by 1000 to convert the struct timespec back 
into a struct timeval?

void __net_timestamp(struct sk_buff *skb)
{
   struct timespec now;
   struct timeval tv;

   ktime_get_ts(&ts);
   tv.tv_sec = now.tv_sec;
   tv->tv_usec = now.tv_nsec/1000;
   skb_set_timestamp(skb, &tv);
}

How many apps / drivers would this break?

Is there perhaps a different way to achieve this?

Regards.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 10:18 CLOCK_MONOTONIC datagram timestamps by the kernel John
@ 2007-02-28 13:37 ` John
  2007-02-28 13:55   ` Eric Dumazet
  2007-02-28 18:22   ` Stephen Hemminger
  0 siblings, 2 replies; 39+ messages in thread
From: John @ 2007-02-28 13:37 UTC (permalink / raw)
  To: linux-net; +Cc: netdev, linux.kernel

John wrote:

> I know it's possible to have Linux timestamp incoming datagrams as soon
> as they are received, then for one to retrieve this timestamp later with
> an ioctl command or a recvmsg call.

Has it ever been proposed to modify struct skb_timeval to hold 
nanosecond stamps instead of just microsecond stamps? Then make the 
improved precision somehow available to user space.

On a related note, the comment for skb_set_timestamp() states:

/**
  * skb_set_timestamp - set timestamp of a skb
  * @skb: skb to set stamp of
  * @stamp: pointer to struct timeval to get stamp from
  *
  * Timestamps are stored in the skb as offsets to a base timestamp.
  * This function converts a struct timeval to an offset and stores
  * it in the skb.
  */

But there is no mention of an offset in the code:

static inline void skb_set_timestamp(
   struct sk_buff *skb, const struct timeval *stamp)
{
   skb->tstamp.off_sec  = stamp->tv_sec;
   skb->tstamp.off_usec = stamp->tv_usec;
}

Likewise for skb_get_timestamp:

/**
  * skb_get_timestamp - get timestamp from a skb
  * @skb: skb to get stamp from
  * @stamp: pointer to struct timeval to store stamp in
  *
  * Timestamps are stored in the skb as offsets to a base timestamp.
  * This function converts the offset back to a struct timeval and stores
  * it in stamp.
  */

static inline void skb_get_timestamp(
   const struct sk_buff *skb, struct timeval *stamp)
{
   stamp->tv_sec  = skb->tstamp.off_sec;
   stamp->tv_usec = skb->tstamp.off_usec;
}

Are the comments related to code that has since been modified?

Regards.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 13:37 ` John
@ 2007-02-28 13:55   ` Eric Dumazet
  2007-02-28 14:23     ` John
  2007-02-28 18:22   ` Stephen Hemminger
  1 sibling, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-02-28 13:55 UTC (permalink / raw)
  To: John; +Cc: linux-net, netdev

On Wednesday 28 February 2007 14:37, John wrote:
> John wrote:
> > I know it's possible to have Linux timestamp incoming datagrams as soon
> > as they are received, then for one to retrieve this timestamp later with
> > an ioctl command or a recvmsg call.
>
> Has it ever been proposed to modify struct skb_timeval to hold
> nanosecond stamps instead of just microsecond stamps? Then make the
> improved precision somehow available to user space.

John, 

Most modern NICS are able to delay packet delivery, in order to reduce number 
of interrupts and benefit from better cache hits.

tg3 for example are able to delay up to 1024 us.

Then kernel is not realtime and some delays can occur between the hardware 
interrupt and the very moment we timestamp the packet. If CPU caches are 
cold, even the instruction fetches could easily add some us.

Enabling nanosecond stamps would be a lie to users, because real accuracy is 
not nanosecond, but in the order of 10 us (at least)

If you depend on a < 50 us precision, then linux might be the wrong OS for 
your application. Or maybe you need a NIC that is able to provide a timestamp 
in the packet itself (well... along with the packet...) , so that kernel 
latencies are not a problem.

Eric

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 13:55   ` Eric Dumazet
@ 2007-02-28 14:23     ` John
  2007-02-28 14:55       ` Eric Dumazet
  0 siblings, 1 reply; 39+ messages in thread
From: John @ 2007-02-28 14:23 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: linux-net, netdev, linux.kernel

Eric Dumazet wrote:

>> John wrote:
>> 
>>> I know it's possible to have Linux timestamp incoming datagrams as soon
>>> as they are received, then for one to retrieve this timestamp later with
>>> an ioctl command or a recvmsg call.
>> Has it ever been proposed to modify struct skb_timeval to hold
>> nanosecond stamps instead of just microsecond stamps? Then make the
>> improved precision somehow available to user space.
> 
> Most modern NICS are able to delay packet delivery, in order to reduce number 
> of interrupts and benefit from better cache hits.

You are referring to NAPI interrupt mitigation, right?

AFAIU, it is possible to disable this feature.

I'm dealing with 200-4000 packets per second. I don't think I'd save 
much with interrupt mitigation. Please correct any misconception.

> Then kernel is not realtime and some delays can occur between the hardware 
> interrupt and the very moment we timestamp the packet. If CPU caches are 
> cold, even the instruction fetches could easily add some us.

I've applied the real-time patch.
http://rt.wiki.kernel.org/index.php/Main_Page
This doesn't make Linux hard real-time, but the interrupt handlers can 
run with the highest priority (even kernel threads are preempted).

> Enabling nanosecond stamps would be a lie to users, because real accuracy is 
> not nanosecond, but in the order of 10 us (at least)

POSIX is moving to nanoseconds interfaces.
http://www.opengroup.org/onlinepubs/009695399/functions/clock_settime.html

struct timeval and struct timespec take as much space (64 bits).

If the hardware can indeed manage sub-microsecond accuracy, a struct 
timeval forces the kernel to discard valuable information.

> If you depend on a < 50 us precision, then linux might be the wrong OS for 
> your application. Or maybe you need a NIC that is able to provide a timestamp 
> in the packet itself (well... along with the packet...) , so that kernel 
> latencies are not a problem.

Does Linux support NICs that can do that?

Regards.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 14:23     ` John
@ 2007-02-28 14:55       ` Eric Dumazet
  2007-02-28 16:07         ` John
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-02-28 14:55 UTC (permalink / raw)
  To: John; +Cc: linux-net, netdev

On Wednesday 28 February 2007 15:23, John wrote:
> Eric Dumazet wrote:
> >> John wrote:
> >>> I know it's possible to have Linux timestamp incoming datagrams as soon
> >>> as they are received, then for one to retrieve this timestamp later
> >>> with an ioctl command or a recvmsg call.
> >>
> >> Has it ever been proposed to modify struct skb_timeval to hold
> >> nanosecond stamps instead of just microsecond stamps? Then make the
> >> improved precision somehow available to user space.
> >
> > Most modern NICS are able to delay packet delivery, in order to reduce
> > number of interrupts and benefit from better cache hits.
>
> You are referring to NAPI interrupt mitigation, right?

Nope; I am referring to hardware features. NAPI is software.

See ethtool -c eth0

# ethtool -c eth0
Coalesce parameters for eth0:
Adaptive RX: off  TX: off
stats-block-usecs: 1000000
sample-interval: 0
pkt-rate-low: 0
pkt-rate-high: 0

rx-usecs: 300
rx-frames: 60
rx-usecs-irq: 300
rx-frames-irq: 60

tx-usecs: 200
tx-frames: 53
tx-usecs-irq: 200
tx-frames-irq: 53

You can see on this setup, rx interrupts can be delayed up to 300 us (up to 60 
packets might be delayed)

>
> POSIX is moving to nanoseconds interfaces.
> http://www.opengroup.org/onlinepubs/009695399/functions/clock_settime.html

The fact that you are able to give nanosecond timestamps inside kernel is not 
sufficient. It is necessary of course, but not sufficient. This precision is 
OK to time locally generated events. The moment you ask a 'nanosecond' 
timestamp, it's usually long before/after the real event.

If you rely on nanosecond precision on network packets, then something is 
wrong with your algo. Even rt patches wont make sure your cpu caches are 
pre-filled, or that the routers/links between your machines are not busy.
A cache miss cost 40 ns for example. A typical interrupt handler or rx 
processing can trigger 100 cache misses, or not at all if cache is hot.

You said that rt gives highest priority to interrupt handlers :
If you have several nics, what will happen if you receive packets on both 
nics, or if the NIC interrupt happens in the same time than timer interrupt ? 
One timestamp will be wrong for sure.

For sure we could timestamp packets with nanosecond resolution, and eventually 
with MONOTONIC value too, but it will give you (and others) false confidence 
on the real precision. us timestamps are already wrong...

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 14:55       ` Eric Dumazet
@ 2007-02-28 16:07         ` John
  2007-03-01 10:03           ` Evgeniy Polyakov
  2007-03-01 11:30           ` Eric Dumazet
  0 siblings, 2 replies; 39+ messages in thread
From: John @ 2007-02-28 16:07 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: linux-net, netdev, linux.kernel

Eric Dumazet wrote:
> On Wednesday 28 February 2007 15:23, John wrote:
>> Eric Dumazet wrote:
>>>> John wrote:
>>>>> I know it's possible to have Linux timestamp incoming datagrams as soon
>>>>> as they are received, then for one to retrieve this timestamp later
>>>>> with an ioctl command or a recvmsg call.
>>>> Has it ever been proposed to modify struct skb_timeval to hold
>>>> nanosecond stamps instead of just microsecond stamps? Then make the
>>>> improved precision somehow available to user space.
>>> Most modern NICS are able to delay packet delivery, in order to reduce
>>> number of interrupts and benefit from better cache hits.
>>
>> You are referring to NAPI interrupt mitigation, right?
> 
> Nope; I am referring to hardware features. NAPI is software.
> 
> See ethtool -c eth0
> 
> # ethtool -c eth0
> Coalesce parameters for eth0:
> Adaptive RX: off  TX: off
> stats-block-usecs: 1000000
> sample-interval: 0
> pkt-rate-low: 0
> pkt-rate-high: 0
> 
> rx-usecs: 300
> rx-frames: 60
> rx-usecs-irq: 300
> rx-frames-irq: 60
> 
> tx-usecs: 200
> tx-frames: 53
> tx-usecs-irq: 200
> tx-frames-irq: 53
> 
> You can see on this setup, rx interrupts can be delayed up to 300 us (up to 60
> packets might be delayed)

One can disable interrupt mitigation. Your argument that it introduces 
latency therefore becomes irrelevant.

>> POSIX is moving to nanoseconds interfaces.
>> http://www.opengroup.org/onlinepubs/009695399/functions/clock_settime.html

You snipped too much. I also wrote:

struct timeval and struct timespec take as much space (64 bits).

If the hardware can indeed manage sub-microsecond accuracy, a struct
timeval forces the kernel to discard valuable information.

> The fact that you are able to give nanosecond timestamps inside kernel is not 
> sufficient. It is necessary of course, but not sufficient. This precision is 
> OK to time locally generated events. The moment you ask a 'nanosecond' 
> timestamp, it's usually long before/after the real event.
> 
> If you rely on nanosecond precision on network packets, then something is 
> wrong with your algo. Even rt patches wont make sure your cpu caches are 
> pre-filled, or that the routers/links between your machines are not busy.
> A cache miss cost 40 ns for example. A typical interrupt handler or rx 
> processing can trigger 100 cache misses, or not at all if cache is hot.

Consider an idle Linux 2.6.20-rt8 system, equipped with a single PCI-E 
gigabit Ethernet NIC, running on a modern CPU (e.g. Core 2 Duo E6700). 
All this system does is time stamp 1000 packets per second.

Are you claiming that this platform *cannot* handle most packets within 
less than 1 microsecond of their arrival?

If there are platforms that can achieve sub-microsecond precision, and 
if it is not more expensive to support nanosecond resolution (I said 
resolution not precision), then it makes sense to support nanosecond 
resolution in Linux. Right?

> You said that rt gives highest priority to interrupt handlers :
> If you have several nics, what will happen if you receive packets on both 
> nics, or if the NIC interrupt happens in the same time than timer interrupt ? 
> One timestamp will be wrong for sure.

Again, this is irrelevant. We are discussing whether it would make sense 
to support sub-microsecond resolution. If there is one platform that can 
achieve sub-microsecond precision, there is a need for sub-microsecond 
resolution. As long as we are changing the resolution, we might as well 
use something standard like struct timespec.

> For sure we could timestamp packets with nanosecond resolution, and eventually 
> with MONOTONIC value too, but it will give you (and others) false confidence 
> on the real precision. us timestamps are already wrong...

IMHO, this is not true for all platforms.

Regards.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 13:37 ` John
  2007-02-28 13:55   ` Eric Dumazet
@ 2007-02-28 18:22   ` Stephen Hemminger
  1 sibling, 0 replies; 39+ messages in thread
From: Stephen Hemminger @ 2007-02-28 18:22 UTC (permalink / raw)
  To: John; +Cc: linux-net, netdev, linux.kernel

On Wed, 28 Feb 2007 14:37:49 +0100
John <linux.kernel@free.fr> wrote:

> John wrote:
> 
> > I know it's possible to have Linux timestamp incoming datagrams as soon
> > as they are received, then for one to retrieve this timestamp later with
> > an ioctl command or a recvmsg call.
> 
> Has it ever been proposed to modify struct skb_timeval to hold 
> nanosecond stamps instead of just microsecond stamps? Then make the 
> improved precision somehow available to user space.
> 

I am playing with a couple of possible future changes.
1. Change skb timestamp to be a timespec instead of timeval, for ABI
   compatiablity the existing SO_TIMESTAMP has to stay microseconds,
   but add a new SO_TIMESPEC to get the nanosecond version.

   The change gets non trivial because of other uses of timestamp (like vegas)
   so I gave up for now.

2. Use hardware receive timestamp in Yukon2 to put actual receive time
   into skb timestamp.  Works, but still figuring out how to manage
   clock skew/resync.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 16:07         ` John
@ 2007-03-01 10:03           ` Evgeniy Polyakov
  2007-03-01 11:30           ` Eric Dumazet
  1 sibling, 0 replies; 39+ messages in thread
From: Evgeniy Polyakov @ 2007-03-01 10:03 UTC (permalink / raw)
  To: John; +Cc: Eric Dumazet, linux-net, netdev

On Wed, Feb 28, 2007 at 05:07:10PM +0100, John (linux.kernel@free.fr) wrote:
> Again, this is irrelevant. We are discussing whether it would make sense 
> to support sub-microsecond resolution. If there is one platform that can 
> achieve sub-microsecond precision, there is a need for sub-microsecond 
> resolution. As long as we are changing the resolution, we might as well 
> use something standard like struct timespec.

You can not blindly change skb timestamps to different entities - you
need to change all users (at least in kernel).
Exporting it to userspace must require new socket option and old one ust
be changed accordingly, but there is nothing wrong in having nanosecond
resolution in packet timestamp except that it might not be 100% correct
receiving time.

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-28 16:07         ` John
  2007-03-01 10:03           ` Evgeniy Polyakov
@ 2007-03-01 11:30           ` Eric Dumazet
  2007-03-01 15:54             ` Stephen Hemminger
                               ` (2 more replies)
  1 sibling, 3 replies; 39+ messages in thread
From: Eric Dumazet @ 2007-03-01 11:30 UTC (permalink / raw)
  To: John find; +Cc: linux-net, netdev, Stephen Hemminger

[-- Attachment #1: Type: text/plain, Size: 3766 bytes --]

On Wednesday 28 February 2007 17:07, John wrote:

>
> Consider an idle Linux 2.6.20-rt8 system, equipped with a single PCI-E
> gigabit Ethernet NIC, running on a modern CPU (e.g. Core 2 Duo E6700).
> All this system does is time stamp 1000 packets per second.
>
> Are you claiming that this platform *cannot* handle most packets within
> less than 1 microsecond of their arrival?

Yes I claim it.

You expect too much of this platform, unless "most" means 10 % for 
you ;)

If you replace "1 us" by "50 us", then yes, it probably can do it, if "most" 
means 99%, (not 99.999 %)

Anyway, if you want to play, you can apply this patch on top of 
linux-2.6.21-rc2  (nanosecond resolution infrastruture needs 2.6.21)
I let you do the adjustments for rt kernel.

I compiled it on my i386 machine, and tested it with a patched libpcap/tcpdump

[PATCH] NET : introduce nanosecond time infrastructure and SIOCGSTAMPNS

It appears some machines are *really* fast and that micro second resolution is 
a limiting factor.

This patch converts sk_buff timestamp to use new nanosecond infra (added in 
2.6.21), and introduces a new ioctl SIOCGSTAMPNS to let applications access 
nanosecond resolution (ie a timespec instead of timeval)


Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

 fs/compat_ioctl.c                       |   17 ++++++++
 include/asm-alpha/sockios.h             |    1 
 include/asm-arm26/sockios.h             |    3 +
 include/asm-avr32/sockios.h             |    3 +
 include/asm-cris/sockios.h              |    3 +
 include/asm-frv/sockios.h               |    3 +
 include/asm-h8300/sockios.h             |    3 +
 include/asm-i386/sockios.h              |    3 +
 include/asm-ia64/sockios.h              |    3 +
 include/asm-m32r/sockios.h              |    3 +
 include/asm-m68k/sockios.h              |    3 +
 include/asm-mips/sockios.h              |    3 +
 include/asm-parisc/sockios.h            |    3 +
 include/asm-powerpc/sockios.h           |    3 +
 include/asm-s390/sockios.h              |    3 +
 include/asm-sh/sockios.h                |    1 
 include/asm-sh64/sockios.h              |    1 
 include/asm-sparc/sockios.h             |    3 +
 include/asm-sparc64/sockios.h           |    3 +
 include/asm-v850/sockios.h              |    3 +
 include/asm-x86_64/sockios.h            |    3 +
 include/asm-xtensa/sockios.h            |    3 +
 include/linux/skbuff.h                  |   42 +++++++++++++++-------
 include/net/compat.h                    |    1 
 include/net/sock.h                      |   16 +++++---
 net/appletalk/ddp.c                     |    3 +
 net/atm/ioctl.c                         |    3 +
 net/ax25/af_ax25.c                      |    4 ++
 net/bridge/netfilter/ebt_ulog.c         |    2 -
 net/compat.c                            |   31 +++++++++++++---
 net/core/dev.c                          |   14 +++----
 net/core/skbuff.c                       |    4 +-
 net/core/sock.c                         |   28 +++++++++++---
 net/econet/af_econet.c                  |    4 +-
 net/ipv4/af_inet.c                      |    3 +
 net/ipv4/ip_fragment.c                  |    6 +--
 net/ipv4/tcp_output.c                   |    2 -
 net/ipv6/af_inet6.c                     |    3 +
 net/ipv6/netfilter/nf_conntrack_reasm.c |    6 +--
 net/ipv6/reassembly.c                   |    6 +--
 net/ipx/af_ipx.c                        |    2 -
 net/netrom/af_netrom.c                  |    5 ++
 net/packet/af_packet.c                  |    8 ++--
 net/rose/af_rose.c                      |    2 +
 net/sunrpc/svcsock.c                    |    9 ++--
 net/wanrouter/af_wanpipe.c              |    3 +
 net/x25/af_x25.c                        |   12 ++++++
 47 files changed, 216 insertions(+), 77 deletions(-)


[-- Attachment #2: net_nanosec_stamp.patch --]
[-- Type: text/plain, Size: 31832 bytes --]

--- linux-2.6.21-rc2/include/linux/skbuff.h	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/linux/skbuff.h	2007-03-01 13:15:07.000000000 +0100
@@ -156,9 +156,13 @@ struct skb_shared_info {
 #define SKB_DATAREF_SHIFT 16
 #define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
 
-struct skb_timeval {
+/*
+ * We use a special timespec like structure, because ABI constraints 
+ * make 'struct timespec' being 16 bytes on 64bit platforms.
+ */
+struct skb_timespec {
 	u32	off_sec;
-	u32	off_usec;
+	u32	off_nsec;
 };
 
 
@@ -186,7 +190,7 @@ enum {
  *	@next: Next buffer in list
  *	@prev: Previous buffer in list
  *	@sk: Socket we are owned by
- *	@tstamp: Time we arrived
+ *	@tstampns: Time we arrived
  *	@dev: Device we arrived on/are leaving by
  *	@input_dev: Device we arrived on
  *	@h: Transport layer header
@@ -233,7 +237,7 @@ struct sk_buff {
 	struct sk_buff		*prev;
 
 	struct sock		*sk;
-	struct skb_timeval	tstamp;
+	struct skb_timespec	tstampns;
 	struct net_device	*dev;
 	struct net_device	*input_dev;
 
@@ -1350,6 +1354,20 @@ extern void skb_init(void);
 extern void skb_add_mtu(int mtu);
 
 /**
+ *	skb_get_timestampns - get timestamp from a skb
+ *	@skb: skb to get stamp from
+ *	@stampns: pointer to struct timespec to store stamp in
+ *
+ *	Timestamps are stored in the skb as offsets to a base timestamp.
+ *	This function converts the offset back to a struct timespec and stores
+ *	it in stamp.
+ */
+static inline void skb_get_timestampns(const struct sk_buff *skb, struct timespec *stampns)
+{
+	stampns->tv_sec  = skb->tstampns.off_sec;
+	stampns->tv_nsec = skb->tstampns.off_nsec;
+}
+/**
  *	skb_get_timestamp - get timestamp from a skb
  *	@skb: skb to get stamp from
  *	@stamp: pointer to struct timeval to store stamp in
@@ -1360,23 +1378,23 @@ extern void skb_add_mtu(int mtu);
  */
 static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
 {
-	stamp->tv_sec  = skb->tstamp.off_sec;
-	stamp->tv_usec = skb->tstamp.off_usec;
+	stamp->tv_sec  = skb->tstampns.off_sec;
+	stamp->tv_usec = skb->tstampns.off_nsec/1000;
 }
 
 /**
- * 	skb_set_timestamp - set timestamp of a skb
+ * 	skb_set_timestampns - set timestamp of a skb
  *	@skb: skb to set stamp of
- *	@stamp: pointer to struct timeval to get stamp from
+ *	@stamp: pointer to struct timespec to get stamp from
  *
  *	Timestamps are stored in the skb as offsets to a base timestamp.
- *	This function converts a struct timeval to an offset and stores
+ *	This function converts a struct timespec to an offset and stores
  *	it in the skb.
  */
-static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
+static inline void skb_set_timestampns(struct sk_buff *skb, const struct timespec *stampns)
 {
-	skb->tstamp.off_sec  = stamp->tv_sec;
-	skb->tstamp.off_usec = stamp->tv_usec;
+	skb->tstampns.off_sec  = stampns->tv_sec;
+	skb->tstampns.off_nsec = stampns->tv_nsec;
 }
 
 extern void __net_timestamp(struct sk_buff *skb);
--- linux-2.6.21-rc2/include/net/sock.h	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/net/sock.h	2007-03-01 11:37:34.000000000 +0100
@@ -244,7 +244,7 @@ struct sock {
 	struct sk_filter      	*sk_filter;
 	void			*sk_protinfo;
 	struct timer_list	sk_timer;
-	struct timeval		sk_stamp;
+	struct timespec		sk_stampns;
 	struct socket		*sk_socket;
 	void			*sk_user_data;
 	struct page		*sk_sndmsg_page;
@@ -1307,19 +1307,22 @@ static inline int sock_intr_errno(long t
 static __inline__ void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
+	struct timespec stampns;
 	struct timeval stamp;
 
-	skb_get_timestamp(skb, &stamp);
+	skb_get_timestampns(skb, &stampns);
 	if (sock_flag(sk, SOCK_RCVTSTAMP)) {
 		/* Race occurred between timestamp enabling and packet
 		   receiving.  Fill in the current time for now. */
-		if (stamp.tv_sec == 0)
-			do_gettimeofday(&stamp);
-		skb_set_timestamp(skb, &stamp);
+		if (stampns.tv_sec == 0)
+			getnstimeofday(&stampns);
+		skb_set_timestampns(skb, &stampns);
+		stamp.tv_sec = stampns.tv_sec;
+		stamp.tv_usec = stampns.tv_nsec/1000;
 		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval),
 			 &stamp);
 	} else
-		sk->sk_stamp = stamp;
+		sk->sk_stampns = stampns;
 }
 
 /**
@@ -1350,6 +1353,7 @@ static inline void sk_eat_skb(struct soc
 
 extern void sock_enable_timestamp(struct sock *sk);
 extern int sock_get_timestamp(struct sock *, struct timeval __user *);
+extern int sock_get_timestampns(struct sock *, struct timespec __user *);
 
 /* 
  *	Enable debug/info messages 
--- linux-2.6.21-rc2/include/net/compat.h	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/net/compat.h	2007-02-28 20:54:35.000000000 +0100
@@ -25,6 +25,7 @@ struct compat_cmsghdr {
 };
 
 extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
+extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
 
 #else /* defined(CONFIG_COMPAT) */
 #define compat_msghdr	msghdr		/* to avoid compiler warnings */
--- linux-2.6.21-rc2/net/core/sock.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/core/sock.c	2007-02-28 21:16:43.000000000 +0100
@@ -1512,8 +1512,8 @@ void sock_init_data(struct socket *sock,
 	sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;
 	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;
 
-	sk->sk_stamp.tv_sec     = -1L;
-	sk->sk_stamp.tv_usec    = -1L;
+	sk->sk_stampns.tv_sec     = -1L;
+	sk->sk_stampns.tv_nsec    = -1L;
 
 	atomic_set(&sk->sk_refcnt, 1);
 }
@@ -1554,17 +1554,33 @@ EXPORT_SYMBOL(release_sock);
 
 int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
 {
+	struct timeval tstamp;
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
-	if (sk->sk_stamp.tv_sec == -1)
+	if (sk->sk_stampns.tv_sec == -1)
 		return -ENOENT;
-	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timeval)) ?
+	if (sk->sk_stampns.tv_sec == 0)
+		getnstimeofday(&sk->sk_stampns);
+	tstamp.tv_sec = sk->sk_stampns.tv_sec;
+	tstamp.tv_usec = sk->sk_stampns.tv_nsec/1000;
+	return copy_to_user(userstamp, &tstamp, sizeof(struct timeval)) ?
 		-EFAULT : 0;
 }
 EXPORT_SYMBOL(sock_get_timestamp);
 
+int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
+{
+	if (!sock_flag(sk, SOCK_TIMESTAMP))
+		sock_enable_timestamp(sk);
+	if (sk->sk_stampns.tv_sec == -1)
+		return -ENOENT;
+	if (sk->sk_stampns.tv_sec == 0)
+		getnstimeofday(&sk->sk_stampns);
+	return copy_to_user(userstamp, &sk->sk_stampns, sizeof(struct timespec)) ?
+		-EFAULT : 0;
+}
+EXPORT_SYMBOL(sock_get_timestampns);
+
 void sock_enable_timestamp(struct sock *sk)
 {
 	if (!sock_flag(sk, SOCK_TIMESTAMP)) {
--- linux-2.6.21-rc2/net/core/dev.c	2007-02-28 21:16:43.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/core/dev.c	2007-03-01 11:43:38.000000000 +0100
@@ -1036,10 +1036,10 @@ void net_disable_timestamp(void)
 
 void __net_timestamp(struct sk_buff *skb)
 {
-	struct timeval tv;
+	struct timespec ts;
 
-	do_gettimeofday(&tv);
-	skb_set_timestamp(skb, &tv);
+	getnstimeofday(&ts);
+	skb_set_timestampns(skb, &ts);
 }
 EXPORT_SYMBOL(__net_timestamp);
 
@@ -1048,8 +1048,8 @@ static inline void net_timestamp(struct 
 	if (atomic_read(&netstamp_needed))
 		__net_timestamp(skb);
 	else {
-		skb->tstamp.off_sec = 0;
-		skb->tstamp.off_usec = 0;
+		skb->tstampns.off_sec = 0;
+		skb->tstampns.off_nsec = 0;
 	}
 }
 
@@ -1580,7 +1580,7 @@ int netif_rx(struct sk_buff *skb)
 	if (netpoll_rx(skb))
 		return NET_RX_DROP;
 
-	if (!skb->tstamp.off_sec)
+	if (!skb->tstampns.off_sec)
 		net_timestamp(skb);
 
 	/*
@@ -1772,7 +1772,7 @@ int netif_receive_skb(struct sk_buff *sk
 	if (skb->dev->poll && netpoll_rx(skb))
 		return NET_RX_DROP;
 
-	if (!skb->tstamp.off_sec)
+	if (!skb->tstampns.off_sec)
 		net_timestamp(skb);
 
 	if (!skb->input_dev)
--- linux-2.6.21-rc2/net/core/skbuff.c	2007-03-01 11:41:01.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/core/skbuff.c	2007-03-01 11:41:25.000000000 +0100
@@ -449,7 +449,7 @@ struct sk_buff *skb_clone(struct sk_buff
 
 	n->next = n->prev = NULL;
 	n->sk = NULL;
-	C(tstamp);
+	C(tstampns);
 	C(dev);
 	C(h);
 	C(nh);
@@ -534,7 +534,7 @@ static void copy_skb_header(struct sk_bu
 	new->local_df	= old->local_df;
 	new->fclone	= SKB_FCLONE_UNAVAILABLE;
 	new->pkt_type	= old->pkt_type;
-	new->tstamp	= old->tstamp;
+	new->tstampns	= old->tstampns;
 	new->destructor = NULL;
 	new->mark	= old->mark;
 #ifdef CONFIG_NETFILTER
--- linux-2.6.21-rc2/net/ipv4/ip_fragment.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/ip_fragment.c	2007-03-01 11:45:09.000000000 +0100
@@ -92,7 +92,7 @@ struct ipq {
 	spinlock_t	lock;
 	atomic_t	refcnt;
 	struct timer_list timer;	/* when will this queue expire?		*/
-	struct timeval	stamp;
+	struct timespec	stampns;
 	int             iif;
 	unsigned int    rid;
 	struct inet_peer *peer;
@@ -592,7 +592,7 @@ static void ip_frag_queue(struct ipq *qp
 	if (skb->dev)
 		qp->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &qp->stamp);
+	skb_get_timestampns(skb, &qp->stampns);
 	qp->meat += skb->len;
 	atomic_add(skb->truesize, &ip_frag_mem);
 	if (offset == 0)
@@ -674,7 +674,7 @@ static struct sk_buff *ip_frag_reasm(str
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &qp->stamp);
+	skb_set_timestampns(head, &qp->stampns);
 
 	iph = head->nh.iph;
 	iph->frag_off = 0;
--- linux-2.6.21-rc2/net/ipv4/af_inet.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/af_inet.c	2007-02-28 20:54:35.000000000 +0100
@@ -755,6 +755,9 @@ int inet_ioctl(struct socket *sock, unsi
 		case SIOCGSTAMP:
 			err = sock_get_timestamp(sk, (struct timeval __user *)arg);
 			break;
+		case SIOCGSTAMPNS:
+			err = sock_get_timestampns(sk, (struct timespec __user *)arg);
+			break;
 		case SIOCADDRT:
 		case SIOCDELRT:
 		case SIOCRTMSG:
--- linux-2.6.21-rc2/net/ipv4/tcp_output.c	2007-03-01 11:45:09.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/tcp_output.c	2007-03-01 11:45:09.000000000 +0100
@@ -661,7 +661,7 @@ int tcp_fragment(struct sock *sk, struct
 	 * skbs, which it never sent before. --ANK
 	 */
 	TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
-	buff->tstamp = skb->tstamp;
+	buff->tstampns = skb->tstampns;
 
 	old_factor = tcp_skb_pcount(skb);
 
--- linux-2.6.21-rc2/net/ipv6/af_inet6.c	2007-03-01 12:34:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/af_inet6.c	2007-03-01 12:34:35.000000000 +0100
@@ -437,6 +437,9 @@ int inet6_ioctl(struct socket *sock, uns
 	case SIOCGSTAMP:
 		return sock_get_timestamp(sk, (struct timeval __user *)arg);
 
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *)arg);
+
 	case SIOCADDRT:
 	case SIOCDELRT:
 
--- linux-2.6.21-rc2/net/packet/af_packet.c	2007-02-28 21:23:12.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/packet/af_packet.c	2007-03-01 12:32:56.000000000 +0100
@@ -656,12 +656,12 @@ static int tpacket_rcv(struct sk_buff *s
 	h->tp_snaplen = snaplen;
 	h->tp_mac = macoff;
 	h->tp_net = netoff;
-	if (skb->tstamp.off_sec == 0) {
+	if (skb->tstampns.off_sec == 0) {
 		__net_timestamp(skb);
 		sock_enable_timestamp(sk);
 	}
-	h->tp_sec = skb->tstamp.off_sec;
-	h->tp_usec = skb->tstamp.off_usec;
+	h->tp_sec = skb->tstampns.off_sec;
+	h->tp_usec = skb->tstampns.off_nsec/1000;
 
 	sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
 	sll->sll_halen = 0;
@@ -1543,6 +1543,8 @@ static int packet_ioctl(struct socket *s
 		}
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, (struct timeval __user *)arg);
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, (struct timespec __user *)arg);
 
 #ifdef CONFIG_INET
 		case SIOCADDRT:
--- linux-2.6.21-rc2/net/sunrpc/svcsock.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/sunrpc/svcsock.c	2007-03-01 13:15:07.000000000 +0100
@@ -806,15 +806,14 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 		dprintk("svc: recvfrom returned error %d\n", -err);
 	}
 	if (skb->tstamp.off_sec == 0) {
-		struct timeval tv;
+		struct timespec ts;
 
-		tv.tv_sec = xtime.tv_sec;
-		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
-		skb_set_timestamp(skb, &tv);
+		ts = current_kernel_time();
+		skb_set_timestampns(skb, &ts);
 		/* Don't enable netstamp, sunrpc doesn't
 		   need that much accuracy */
 	}
-	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+	skb_get_timestampns(skb, &svsk->sk_sk->sk_stampns);
 	set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
 
 	/*
--- linux-2.6.21-rc2/net/compat.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/compat.c	2007-03-01 12:56:02.000000000 +0100
@@ -545,20 +545,41 @@ int compat_sock_get_timestamp(struct soc
 	struct compat_timeval __user *ctv =
 			(struct compat_timeval __user*) userstamp;
 	int err = -ENOENT;
+	long usec;
 
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
-	if (sk->sk_stamp.tv_sec == -1)
+	if (sk->sk_stampns.tv_sec == -1)
 		return err;
-	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
-			put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+	if (sk->sk_stampns.tv_sec == 0)
+		getnstimeofday(&sk->sk_stampns);
+	usec = sk->sk_stampns.tv_nsec / 1000;
+	if (put_user(sk->sk_stampns.tv_sec, &ctv->tv_sec) ||
+			put_user(usec, &ctv->tv_usec))
 		err = -EFAULT;
 	return err;
 }
 EXPORT_SYMBOL(compat_sock_get_timestamp);
 
+int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
+{
+	struct compat_timespec __user *ctv =
+			(struct compat_timespec __user*) userstamp;
+	int err = -ENOENT;
+
+	if (!sock_flag(sk, SOCK_TIMESTAMP))
+		sock_enable_timestamp(sk);
+	if (sk->sk_stampns.tv_sec == -1)
+		return err;
+	if (sk->sk_stampns.tv_sec == 0)
+		getnstimeofday(&sk->sk_stampns);
+	if (put_user(sk->sk_stampns.tv_sec, &ctv->tv_sec) ||
+			put_user(sk->sk_stampns.tv_nsec, &ctv->tv_nsec))
+		err = -EFAULT;
+	return err;
+}
+EXPORT_SYMBOL(compat_sock_get_timestampns);
+
 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
 				char __user *optval, int __user *optlen)
 {
--- linux-2.6.21-rc2/fs/compat_ioctl.c	2007-03-01 13:01:27.000000000 +0100
+++ linux-2.6.21-rc2-ed/fs/compat_ioctl.c	2007-03-01 13:01:27.000000000 +0100
@@ -265,6 +265,22 @@ static int do_siocgstamp(unsigned int fd
 	}
 	return err;
 }
+static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct compat_timespec __user *up = compat_ptr(arg);
+	struct timespec ktv;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
+	set_fs(old_fs);
+	if(!err) {
+		err = put_user(ktv.tv_sec, &up->tv_sec);
+		err |= __put_user(ktv.tv_nsec, &up->tv_nsec);
+	}
+	return err;
+}
 
 struct ifmap32 {
 	compat_ulong_t mem_start;
@@ -2437,6 +2453,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc)
 /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
 HANDLE_IOCTL(SIOCRTMSG, ret_einval)
 HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
+HANDLE_IOCTL(SIOCGSTAMPNS, do_siocgstampns)
 #endif
 #ifdef CONFIG_BLOCK
 HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
--- linux-2.6.21-rc2/net/appletalk/ddp.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/appletalk/ddp.c	2007-03-01 12:56:02.000000000 +0100
@@ -1768,6 +1768,9 @@ static int atalk_ioctl(struct socket *so
 		case SIOCGSTAMP:
 			rc = sock_get_timestamp(sk, argp);
 			break;
+		case SIOCGSTAMPNS:
+			rc = sock_get_timestampns(sk, argp);
+			break;
 		/* Routing */
 		case SIOCADDRT:
 		case SIOCDELRT:
--- linux-2.6.21-rc2/net/ax25/af_ax25.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ax25/af_ax25.c	2007-03-01 12:56:02.000000000 +0100
@@ -1711,6 +1711,10 @@ static int ax25_ioctl(struct socket *soc
 		res = sock_get_timestamp(sk, argp);
 		break;
 
+	case SIOCGSTAMPNS:
+		res = sock_get_timestampns(sk, argp);
+		break;
+
 	case SIOCAX25ADDUID:	/* Add a uid to the uid/call map table */
 	case SIOCAX25DELUID:	/* Delete a uid from the uid/call map table */
 	case SIOCAX25GETUID: {
--- linux-2.6.21-rc2/net/atm/ioctl.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/atm/ioctl.c	2007-03-01 12:56:02.000000000 +0100
@@ -82,6 +82,9 @@ int vcc_ioctl(struct socket *sock, unsig
 		case SIOCGSTAMP: /* borrowed from IP */
 			error = sock_get_timestamp(sk, argp);
 			goto done;
+		case SIOCGSTAMPNS: /* borrowed from IP */
+			error = sock_get_timestampns(sk, argp);
+			goto done;
 		case ATM_SETSC:
 			printk(KERN_WARNING "ATM_SETSC is obsolete\n");
 			error = 0;
--- linux-2.6.21-rc2/net/econet/af_econet.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/econet/af_econet.c	2007-03-01 12:56:02.000000000 +0100
@@ -162,7 +162,7 @@ static int econet_recvmsg(struct kiocb *
 	err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
 	if (err)
 		goto out_free;
-	skb_get_timestamp(skb, &sk->sk_stamp);
+	skb_get_timestampns(skb, &sk->sk_stampns);
 
 	if (msg->msg_name)
 		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
@@ -726,6 +726,8 @@ static int econet_ioctl(struct socket *s
 	switch(cmd) {
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, argp);
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, argp);
 
 		case SIOCSIFADDR:
 		case SIOCGIFADDR:
--- linux-2.6.21-rc2/net/ipx/af_ipx.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipx/af_ipx.c	2007-03-01 11:34:07.000000000 +0100
@@ -1808,7 +1808,7 @@ static int ipx_recvmsg(struct kiocb *ioc
 	if (rc)
 		goto out_free;
 	if (skb->tstamp.off_sec)
-		skb_get_timestamp(skb, &sk->sk_stamp);
+		skb_get_timestampns(skb, &sk->sk_stampns);
 
 	msg->msg_namelen = sizeof(*sipx);
 
--- linux-2.6.21-rc2/net/netrom/af_netrom.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/netrom/af_netrom.c	2007-03-01 12:56:02.000000000 +0100
@@ -1208,6 +1208,11 @@ static int nr_ioctl(struct socket *sock,
 		ret = sock_get_timestamp(sk, argp);
 		release_sock(sk);
 		return ret;
+	case SIOCGSTAMPNS:
+		lock_sock(sk);
+		ret = sock_get_timestampns(sk, argp);
+		release_sock(sk);
+		return ret;
 
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
--- linux-2.6.21-rc2/net/rose/af_rose.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/rose/af_rose.c	2007-03-01 12:56:02.000000000 +0100
@@ -1271,6 +1271,8 @@ static int rose_ioctl(struct socket *soc
 
 	case SIOCGSTAMP:
 		return sock_get_timestamp(sk, (struct timeval __user *) argp);
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *) argp);
 
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
--- linux-2.6.21-rc2/net/wanrouter/af_wanpipe.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/wanrouter/af_wanpipe.c	2007-03-01 12:56:02.000000000 +0100
@@ -1770,6 +1770,9 @@ static int wanpipe_ioctl(struct socket *
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, (struct timeval __user *)arg);
 
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, (struct timespec __user *)arg);
+
 		case SIOC_WANPIPE_CHECK_TX:
 
 			return atomic_read(&sk->sk_wmem_alloc);
--- linux-2.6.21-rc2/net/x25/af_x25.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/x25/af_x25.c	2007-03-01 12:56:02.000000000 +0100
@@ -1280,6 +1280,12 @@ static int x25_ioctl(struct socket *sock
 				rc = sock_get_timestamp(sk,
 						(struct timeval __user *)argp);
 			break;
+		case SIOCGSTAMP:
+			rc = -EINVAL;
+			if (sk)
+				rc = sock_get_timestampns(sk,
+						(struct timespec __user *)argp);
+			break;
 		case SIOCGIFADDR:
 		case SIOCSIFADDR:
 		case SIOCGIFDSTADDR:
@@ -1521,6 +1527,12 @@ static int compat_x25_ioctl(struct socke
 			rc = compat_sock_get_timestamp(sk,
 					(struct timeval __user*)argp);
 		break;
+	case SIOCGSTAMP:
+		rc = -EINVAL;
+		if (sk)
+			rc = compat_sock_get_timestampns(sk,
+					(struct timespec __user*)argp);
+		break;
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
 	case SIOCGIFDSTADDR:
--- linux-2.6.21-rc2/net/bridge/netfilter/ebt_ulog.c	2007-03-01 13:09:56.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/bridge/netfilter/ebt_ulog.c	2007-03-01 13:09:56.000000000 +0100
@@ -166,7 +166,7 @@ static void ebt_ulog_packet(unsigned int
 	pm->version = EBT_ULOG_VERSION;
 	do_gettimeofday(&pm->stamp);
 	if (ub->qlen == 1)
-		skb_set_timestamp(ub->skb, &pm->stamp);
+		skb_set_timestampus(ub->skb, &pm->stamp);
 	pm->data_len = copy_len;
 	pm->mark = skb->mark;
 	pm->hook = hooknr;
--- linux-2.6.21-rc2/net/ipv6/netfilter/nf_conntrack_reasm.c	2007-03-01 13:09:56.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/netfilter/nf_conntrack_reasm.c	2007-03-01 13:15:07.000000000 +0100
@@ -82,7 +82,7 @@ struct nf_ct_frag6_queue
 	struct sk_buff		*fragments;
 	int			len;
 	int			meat;
-	struct timeval		stamp;
+	struct timespec		stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -542,7 +542,7 @@ static int nf_ct_frag6_queue(struct nf_c
 		fq->fragments = skb;
 
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	skb_get_timestampns(skb, &fq->stamp);
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &nf_ct_frag6_mem);
 
@@ -648,7 +648,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_que
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	skb_set_timestampns(head, &fq->stamp);
 	head->nh.ipv6h->payload_len = htons(payload_len);
 
 	/* Yes, and fold redundant checksum back. 8) */
--- linux-2.6.21-rc2/net/ipv6/reassembly.c	2007-03-01 13:15:07.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/reassembly.c	2007-03-01 13:15:07.000000000 +0100
@@ -88,7 +88,7 @@ struct frag_queue
 	int			len;
 	int			meat;
 	int			iif;
-	struct timeval		stamp;
+	struct timespec		stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -562,7 +562,7 @@ static void ip6_frag_queue(struct frag_q
 	if (skb->dev)
 		fq->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	skb_get_timestampns(skb, &fq->stamp);
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &ip6_frag_mem);
 
@@ -663,7 +663,7 @@ static int ip6_frag_reasm(struct frag_qu
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	skb_set_timestampns(head, &fq->stamp);
 	head->nh.ipv6h->payload_len = htons(payload_len);
 	IP6CB(head)->nhoff = nhoff;
 
--- linux-2.6.21-rc2/include/asm-i386/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-i386/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-x86_64/sockios.h	2007-02-28 21:19:22.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-x86_64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-alpha/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-alpha/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -11,5 +11,6 @@
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
 #define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_ALPHA_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-arm26/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-arm26/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-avr32/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-avr32/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ASM_AVR32_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-cris/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-cris/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-frv/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-frv/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,7 +7,8 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_SOCKIOS__ */
 
--- linux-2.6.21-rc2/include/asm-h8300/sockios.h	2007-03-01 11:53:45.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-h8300/sockios.h	2007-03-01 11:53:45.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ARCH_H8300_SOCKIOS__ */
--- linux-2.6.21-rc2/include/asm-ia64/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-ia64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -14,6 +14,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_IA64_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-m32r/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-m32r/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif  /* _ASM_M32R_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-m68k/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-m68k/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ARCH_M68K_SOCKIOS__ */
--- linux-2.6.21-rc2/include/asm-mips/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-mips/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -20,6 +20,7 @@
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906			/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-parisc/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-parisc/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-powerpc/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-powerpc/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -14,6 +14,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif	/* _ASM_POWERPC_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-s390/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-s390/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -15,6 +15,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-sh/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sh/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -10,4 +10,5 @@
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
 #define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#define SIOCGSTAMPNS	_IOR('s', 101, struct timespec) /* Get stamp - linux-specific */
 #endif /* __ASM_SH_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-sh64/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sh64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -21,4 +21,5 @@
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
 #define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#define SIOCGSTAMPNS	_IOR('s', 101, struct timespec) /* Get stamp - linux-specific */
 #endif /* __ASM_SH64_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-sparc/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sparc/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,7 +7,8 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* !(_ASM_SPARC_SOCKIOS_H) */
 
--- linux-2.6.21-rc2/include/asm-sparc64/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sparc64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,7 +7,8 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* !(_ASM_SPARC64_SOCKIOS_H) */
 
--- linux-2.6.21-rc2/include/asm-v850/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-v850/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __V850_SOCKIOS_H__ */
--- linux-2.6.21-rc2/include/asm-xtensa/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-xtensa/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -25,6 +25,7 @@
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif	/* _XTENSA_SOCKIOS_H */

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 11:30           ` Eric Dumazet
@ 2007-03-01 15:54             ` Stephen Hemminger
  2007-03-01 16:13               ` Eric Dumazet
  2007-03-02 14:38               ` [PATCH] NET : convert network timestamps to ktime_t Eric Dumazet
  2007-03-01 18:53             ` CLOCK_MONOTONIC datagram timestamps by the kernel Stephen Hemminger
  2007-03-02  9:26             ` John
  2 siblings, 2 replies; 39+ messages in thread
From: Stephen Hemminger @ 2007-03-01 15:54 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: John find, linux-net, netdev

Eric Dumazet wrote:
> On Wednesday 28 February 2007 17:07, John wrote:
>
>   
>> Consider an idle Linux 2.6.20-rt8 system, equipped with a single PCI-E
>> gigabit Ethernet NIC, running on a modern CPU (e.g. Core 2 Duo E6700).
>> All this system does is time stamp 1000 packets per second.
>>
>> Are you claiming that this platform *cannot* handle most packets within
>> less than 1 microsecond of their arrival?
>>     
>
> Yes I claim it.
>
> You expect too much of this platform, unless "most" means 10 % for 
> you ;)
>
> If you replace "1 us" by "50 us", then yes, it probably can do it, if "most" 
> means 99%, (not 99.999 %)
>
> Anyway, if you want to play, you can apply this patch on top of 
> linux-2.6.21-rc2  (nanosecond resolution infrastruture needs 2.6.21)
> I let you do the adjustments for rt kernel.
>
>   
I like it except changing stamp to stampns all over the place is 
unnecessary, just change the
type.

> I compiled it on my i386 machine, and tested it with a patched libpcap/tcpdump
>
>   
I assume old tcpdump works as expected.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 15:54             ` Stephen Hemminger
@ 2007-03-01 16:13               ` Eric Dumazet
  2007-03-02 14:38               ` [PATCH] NET : convert network timestamps to ktime_t Eric Dumazet
  1 sibling, 0 replies; 39+ messages in thread
From: Eric Dumazet @ 2007-03-01 16:13 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: John find, linux-net, netdev

On Thursday 01 March 2007 16:54, Stephen Hemminger wrote:
>
> I like it except changing stamp to stampns all over the place is
> unnecessary, just change the
> type.

Well... After seeing the compat code using casts, I felt some external users 
could try to cast it as well and not detect the new type...

>
> I assume old tcpdump works as expected.

Yes, of course...

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 11:30           ` Eric Dumazet
  2007-03-01 15:54             ` Stephen Hemminger
@ 2007-03-01 18:53             ` Stephen Hemminger
  2007-03-01 23:14               ` Eric Dumazet
  2007-03-02  9:26             ` John
  2 siblings, 1 reply; 39+ messages in thread
From: Stephen Hemminger @ 2007-03-01 18:53 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: John find, linux-net, netdev

On Thu, 1 Mar 2007 12:30:50 +0100
Eric Dumazet <dada1@cosmosbay.com> wrote:

> On Wednesday 28 February 2007 17:07, John wrote:
> 
> >
> > Consider an idle Linux 2.6.20-rt8 system, equipped with a single PCI-E
> > gigabit Ethernet NIC, running on a modern CPU (e.g. Core 2 Duo E6700).
> > All this system does is time stamp 1000 packets per second.
> >
> > Are you claiming that this platform *cannot* handle most packets within
> > less than 1 microsecond of their arrival?
> 
> Yes I claim it.
> 
> You expect too much of this platform, unless "most" means 10 % for 
> you ;)
> 
> If you replace "1 us" by "50 us", then yes, it probably can do it, if "most" 
> means 99%, (not 99.999 %)
> 
> Anyway, if you want to play, you can apply this patch on top of 
> linux-2.6.21-rc2  (nanosecond resolution infrastruture needs 2.6.21)
> I let you do the adjustments for rt kernel.
> 
> I compiled it on my i386 machine, and tested it with a patched libpcap/tcpdump
> 
> [PATCH] NET : introduce nanosecond time infrastructure and SIOCGSTAMPNS
> 
> It appears some machines are *really* fast and that micro second resolution is 
> a limiting factor.
> 
> This patch converts sk_buff timestamp to use new nanosecond infra (added in 
> 2.6.21), and introduces a new ioctl SIOCGSTAMPNS to let applications access 
> nanosecond resolution (ie a timespec instead of timeval)
> 
> 
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
>

You probably want to add a SO_TIMESTAMPNS setsockopt() value like existing SO_TIMESTAMP

Also use NSEC_PER_USEC rather than hardcoded 1000.


-- 
Stephen Hemminger <shemminger@linux-foundation.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 18:53             ` CLOCK_MONOTONIC datagram timestamps by the kernel Stephen Hemminger
@ 2007-03-01 23:14               ` Eric Dumazet
  2007-03-01 23:34                 ` Stephen Hemminger
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-01 23:14 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: John find, linux-net, netdev

Stephen Hemminger a écrit :

> 
> You probably want to add a SO_TIMESTAMPNS setsockopt() value like existing SO_TIMESTAMP

You mean an alias like this ?

#define SO_TIMESTAMPNS SO_TIMESTAMP

Or should we really use another value ?

> 
> Also use NSEC_PER_USEC rather than hardcoded 1000.
> 
> 

Yes I will resubmit a patch including your suggestions (I discovered some 
missing bits after a make allyesconfig)

Thank you


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 23:14               ` Eric Dumazet
@ 2007-03-01 23:34                 ` Stephen Hemminger
  2007-03-02  0:56                   ` Eric Dumazet
  0 siblings, 1 reply; 39+ messages in thread
From: Stephen Hemminger @ 2007-03-01 23:34 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: John find, linux-net, netdev

On Fri, 02 Mar 2007 00:14:37 +0100
Eric Dumazet <dada1@cosmosbay.com> wrote:

> Stephen Hemminger a écrit :
> 
> > 
> > You probably want to add a SO_TIMESTAMPNS setsockopt() value like existing SO_TIMESTAMP
> 
> You mean an alias like this ?
> 
> #define SO_TIMESTAMPNS SO_TIMESTAMP
> 
> Or should we really use another value ?

Another value since if someone turns on SO_TIMESTAMP they want usec (timeval)
and SO_TIMESTAMPNS would be for nanosecond values. Trying to set both
flags would be not allowed.

- original -

     If the SO_TIMESTAMP option is enabled on a SOCK_DGRAM socket, the
     recvmsg(2) call will return a timestamp corresponding to when the data-
     gram was received.  The msg_control field in the msghdr structure points
     to a buffer that contains a cmsghdr structure followed by a struct
     timeval.  The cmsghdr fields have the following values:

     cmsg_len = sizeof(struct timeval)
     cmsg_level = SOL_SOCKET
     cmsg_type = SCM_TIMESTAMP

- add -
     If the SO_TIMESTAMPNS option is enabled on a SOCK_DGRAM socket,
...
     cmsg_len = sizeof(struct timespec)
     cmsg_level = SOL_SOCKET
     cmsg_type = SCM_TIMESTAMPNS
-- 
Stephen Hemminger <shemminger@linux-foundation.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 23:34                 ` Stephen Hemminger
@ 2007-03-02  0:56                   ` Eric Dumazet
  0 siblings, 0 replies; 39+ messages in thread
From: Eric Dumazet @ 2007-03-02  0:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: John find, linux-net, netdev

[-- Attachment #1: Type: text/plain, Size: 5336 bytes --]

Stephen Hemminger a écrit :
> Another value since if someone turns on SO_TIMESTAMP they want usec (timeval)
> and SO_TIMESTAMPNS would be for nanosecond values. Trying to set both
> flags would be not allowed.
> 
> - original -
> 
>      If the SO_TIMESTAMP option is enabled on a SOCK_DGRAM socket, the
>      recvmsg(2) call will return a timestamp corresponding to when the data-
>      gram was received.  The msg_control field in the msghdr structure points
>      to a buffer that contains a cmsghdr structure followed by a struct
>      timeval.  The cmsghdr fields have the following values:
> 
>      cmsg_len = sizeof(struct timeval)
>      cmsg_level = SOL_SOCKET
>      cmsg_type = SCM_TIMESTAMP
> 
> - add -
>      If the SO_TIMESTAMPNS option is enabled on a SOCK_DGRAM socket,
> ...
>      cmsg_len = sizeof(struct timespec)
>      cmsg_level = SOL_SOCKET
>      cmsg_type = SCM_TIMESTAMPNS

I got it now, thank you :)

Here is the second version of the patch.

[NET] : introduce nanosecond time infrastructure for packet timestamping

It appears some machines are *really* fast and that micro second resolution is
a limiting factor.

This patch converts sk_buff timestamp to use new nanosecond infra (added in
2.6.21), and introduces a new ioctl SIOCGSTAMPNS to let applications access
nanosecond resolution (ie a timespec instead of timeval)

SO_TIMESTAMPNS is also introduced so that a recvmsg() on SOCK_DGRAM socket may 
  transfer a struct timespec (cmsg_type = SCM_TIMESTAMPNS). SO_TIMESTAMP and 
SO_TIMESTAMPNS are mutually exclusive.


Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

  fs/compat_ioctl.c                       |   17 +++++++++
  include/asm-alpha/socket.h              |    2 +
  include/asm-alpha/sockios.h             |    1
  include/asm-arm/socket.h                |    2 +
  include/asm-arm26/socket.h              |    2 +
  include/asm-arm26/sockios.h             |    3 +
  include/asm-avr32/socket.h              |    2 +
  include/asm-avr32/sockios.h             |    3 +
  include/asm-cris/sockios.h              |    3 +
  include/asm-frv/socket.h                |    2 +
  include/asm-frv/sockios.h               |    3 +
  include/asm-h8300/socket.h              |    2 +
  include/asm-h8300/sockios.h             |    3 +
  include/asm-i386/socket.h               |    2 +
  include/asm-i386/sockios.h              |    3 +
  include/asm-ia64/socket.h               |    2 +
  include/asm-ia64/sockios.h              |    3 +
  include/asm-m32r/socket.h               |    2 +
  include/asm-m32r/sockios.h              |    3 +
  include/asm-m68k/socket.h               |    2 +
  include/asm-m68k/sockios.h              |    3 +
  include/asm-mips/socket.h               |    2 +
  include/asm-mips/sockios.h              |    3 +
  include/asm-parisc/socket.h             |    2 +
  include/asm-parisc/sockios.h            |    3 +
  include/asm-powerpc/socket.h            |    2 +
  include/asm-powerpc/sockios.h           |    3 +
  include/asm-s390/socket.h               |    2 -
  include/asm-s390/sockios.h              |    3 +
  include/asm-sh/socket.h                 |    2 -
  include/asm-sh/sockios.h                |    1
  include/asm-sh64/sockios.h              |    1
  include/asm-sparc/socket.h              |    2 +
  include/asm-sparc/sockios.h             |    3 +
  include/asm-sparc64/socket.h            |    2 +
  include/asm-sparc64/sockios.h           |    3 +
  include/asm-v850/socket.h               |    2 +
  include/asm-v850/sockios.h              |    3 +
  include/asm-x86_64/socket.h             |    2 +
  include/asm-x86_64/sockios.h            |    3 +
  include/asm-xtensa/socket.h             |    2 +
  include/asm-xtensa/sockios.h            |    3 +
  include/linux/skbuff.h                  |   38 ++++++++++++++++------
  include/net/compat.h                    |    1
  include/net/sock.h                      |   31 ++++++++++++-----
  net/appletalk/ddp.c                     |    3 +
  net/atm/ioctl.c                         |    3 +
  net/ax25/af_ax25.c                      |    4 ++
  net/bridge/netfilter/ebt_ulog.c         |    7 ++--
  net/compat.c                            |   33 +++++++++++++++++--
  net/core/dev.c                          |    8 ++--
  net/core/sock.c                         |   36 +++++++++++++++++++-
  net/econet/af_econet.c                  |    5 ++
  net/ipv4/af_inet.c                      |    3 +
  net/ipv4/ip_fragment.c                  |    6 +--
  net/ipv4/netfilter/ip_queue.c           |    2 -
  net/ipv4/netfilter/ipt_ULOG.c           |    2 -
  net/ipv6/af_inet6.c                     |    3 +
  net/ipv6/netfilter/ip6_queue.c          |    2 -
  net/ipv6/netfilter/nf_conntrack_reasm.c |    6 +--
  net/ipv6/reassembly.c                   |    6 +--
  net/ipx/af_ipx.c                        |    2 -
  net/netfilter/nfnetlink_log.c           |    2 -
  net/netfilter/nfnetlink_queue.c         |    2 -
  net/netrom/af_netrom.c                  |    5 ++
  net/packet/af_packet.c                  |    4 +-
  net/rose/af_rose.c                      |    2 +
  net/sunrpc/svcsock.c                    |    9 ++---
  net/wanrouter/af_wanpipe.c              |    3 +
  net/x25/af_x25.c                        |   12 ++++++
  70 files changed, 280 insertions(+), 74 deletions(-)


[-- Attachment #2: net_nanosec_stamp.patch --]
[-- Type: text/plain, Size: 42389 bytes --]

--- linux-2.6.21-rc2/include/linux/skbuff.h	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/linux/skbuff.h	2007-03-01 23:53:23.000000000 +0100
@@ -156,9 +156,13 @@ struct skb_shared_info {
 #define SKB_DATAREF_SHIFT 16
 #define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
 
-struct skb_timeval {
+/*
+ * We use a special timespec like structure, because ABI constraints 
+ * make 'struct timespec' being 16 bytes on 64bit platforms.
+ */
+struct skb_timespec {
 	u32	off_sec;
-	u32	off_usec;
+	u32	off_nsec;
 };
 
 
@@ -233,7 +237,7 @@ struct sk_buff {
 	struct sk_buff		*prev;
 
 	struct sock		*sk;
-	struct skb_timeval	tstamp;
+	struct skb_timespec	tstamp;
 	struct net_device	*dev;
 	struct net_device	*input_dev;
 
@@ -1350,6 +1354,20 @@ extern void skb_init(void);
 extern void skb_add_mtu(int mtu);
 
 /**
+ *	skb_get_timestampns - get timestamp from a skb
+ *	@skb: skb to get stamp from
+ *	@stampns: pointer to struct timespec to store stamp in
+ *
+ *	Timestamps are stored in the skb as offsets to a base timestamp.
+ *	This function converts the offset back to a struct timespec and stores
+ *	it in stamp.
+ */
+static inline void skb_get_timestampns(const struct sk_buff *skb, struct timespec *stampns)
+{
+	stampns->tv_sec  = skb->tstamp.off_sec;
+	stampns->tv_nsec = skb->tstamp.off_nsec;
+}
+/**
  *	skb_get_timestamp - get timestamp from a skb
  *	@skb: skb to get stamp from
  *	@stamp: pointer to struct timeval to store stamp in
@@ -1361,22 +1379,22 @@ extern void skb_add_mtu(int mtu);
 static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
 {
 	stamp->tv_sec  = skb->tstamp.off_sec;
-	stamp->tv_usec = skb->tstamp.off_usec;
+	stamp->tv_usec = skb->tstamp.off_nsec / NSEC_PER_USEC;
 }
 
 /**
- * 	skb_set_timestamp - set timestamp of a skb
+ * 	skb_set_timestampns - set timestamp of a skb
  *	@skb: skb to set stamp of
- *	@stamp: pointer to struct timeval to get stamp from
+ *	@stamp: pointer to struct timespec to get stamp from
  *
  *	Timestamps are stored in the skb as offsets to a base timestamp.
- *	This function converts a struct timeval to an offset and stores
+ *	This function converts a struct timespec to an offset and stores
  *	it in the skb.
  */
-static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
+static inline void skb_set_timestampns(struct sk_buff *skb, const struct timespec *stampns)
 {
-	skb->tstamp.off_sec  = stamp->tv_sec;
-	skb->tstamp.off_usec = stamp->tv_usec;
+	skb->tstamp.off_sec  = stampns->tv_sec;
+	skb->tstamp.off_nsec = stampns->tv_nsec;
 }
 
 extern void __net_timestamp(struct sk_buff *skb);
--- linux-2.6.21-rc2/include/net/sock.h	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/net/sock.h	2007-03-02 02:37:09.000000000 +0100
@@ -244,7 +244,7 @@ struct sock {
 	struct sk_filter      	*sk_filter;
 	void			*sk_protinfo;
 	struct timer_list	sk_timer;
-	struct timeval		sk_stamp;
+	struct timespec		sk_stamp;
 	struct socket		*sk_socket;
 	void			*sk_user_data;
 	struct page		*sk_sndmsg_page;
@@ -390,6 +390,7 @@ enum sock_flags {
 	SOCK_USE_WRITE_QUEUE, /* whether to call sk->sk_write_space in sock_wfree */
 	SOCK_DBG, /* %SO_DEBUG setting */
 	SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */
+	SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */
 	SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
 	SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
 };
@@ -1307,19 +1308,30 @@ static inline int sock_intr_errno(long t
 static __inline__ void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
-	struct timeval stamp;
+	struct timespec ts;
+	struct timeval tv;
 
-	skb_get_timestamp(skb, &stamp);
+	skb_get_timestampns(skb, &ts);
 	if (sock_flag(sk, SOCK_RCVTSTAMP)) {
 		/* Race occurred between timestamp enabling and packet
 		   receiving.  Fill in the current time for now. */
-		if (stamp.tv_sec == 0)
-			do_gettimeofday(&stamp);
-		skb_set_timestamp(skb, &stamp);
-		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval),
-			 &stamp);
+		if (ts.tv_sec == 0)
+			getnstimeofday(&ts);
+		skb_set_timestampns(skb, &ts);
+		tv.tv_sec = ts.tv_sec;
+		tv.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+		put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, sizeof(struct timeval),
+			 &tv);
+	} else if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+		/* Race occurred between timestamp enabling and packet
+		   receiving.  Fill in the current time for now. */
+		if (ts.tv_sec == 0)
+			getnstimeofday(&ts);
+		skb_set_timestampns(skb, &ts);
+		put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof(struct timespec),
+			 &ts);
 	} else
-		sk->sk_stamp = stamp;
+		sk->sk_stamp = ts;
 }
 
 /**
@@ -1350,6 +1362,7 @@ static inline void sk_eat_skb(struct soc
 
 extern void sock_enable_timestamp(struct sock *sk);
 extern int sock_get_timestamp(struct sock *, struct timeval __user *);
+extern int sock_get_timestampns(struct sock *, struct timespec __user *);
 
 /* 
  *	Enable debug/info messages 
--- linux-2.6.21-rc2/include/net/compat.h	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/net/compat.h	2007-02-28 20:54:35.000000000 +0100
@@ -25,6 +25,7 @@ struct compat_cmsghdr {
 };
 
 extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
+extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
 
 #else /* defined(CONFIG_COMPAT) */
 #define compat_msghdr	msghdr		/* to avoid compiler warnings */
--- linux-2.6.21-rc2/net/core/sock.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/core/sock.c	2007-03-02 02:38:39.000000000 +0100
@@ -524,12 +524,22 @@ set_rcvbuf:
 
 		case SO_TIMESTAMP:
 			if (valbool)  {
+				sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
 				sock_set_flag(sk, SOCK_RCVTSTAMP);
 				sock_enable_timestamp(sk);
 			} else
 				sock_reset_flag(sk, SOCK_RCVTSTAMP);
 			break;
 
+		case SO_TIMESTAMPNS:
+			if (valbool)  {
+				sock_reset_flag(sk, SOCK_RCVTSTAMP);
+				sock_set_flag(sk, SOCK_RCVTSTAMPNS);
+				sock_enable_timestamp(sk);
+			} else
+				sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
+			break;
+
 		case SO_RCVLOWAT:
 			if (val < 0)
 				val = INT_MAX;
@@ -722,6 +732,10 @@ int sock_getsockopt(struct socket *sock,
 			v.val = sock_flag(sk, SOCK_RCVTSTAMP);
 			break;
 
+		case SO_TIMESTAMPNS:
+			v.val = sock_flag(sk, SOCK_RCVTSTAMPNS);
+			break;
+
 		case SO_RCVTIMEO:
 			lv=sizeof(struct timeval);
 			if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) {
@@ -1513,7 +1527,7 @@ void sock_init_data(struct socket *sock,
 	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;
 
 	sk->sk_stamp.tv_sec     = -1L;
-	sk->sk_stamp.tv_usec    = -1L;
+	sk->sk_stamp.tv_nsec    = -1L;
 
 	atomic_set(&sk->sk_refcnt, 1);
 }
@@ -1554,17 +1568,33 @@ EXPORT_SYMBOL(release_sock);
 
 int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
 {
+	struct timeval tstamp;
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
 	if (sk->sk_stamp.tv_sec == -1)
 		return -ENOENT;
 	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timeval)) ?
+		getnstimeofday(&sk->sk_stamp);
+	tstamp.tv_sec = sk->sk_stamp.tv_sec;
+	tstamp.tv_usec = sk->sk_stamp.tv_nsec / NSEC_PER_USEC;
+	return copy_to_user(userstamp, &tstamp, sizeof(struct timeval)) ?
 		-EFAULT : 0;
 }
 EXPORT_SYMBOL(sock_get_timestamp);
 
+int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
+{
+	if (!sock_flag(sk, SOCK_TIMESTAMP))
+		sock_enable_timestamp(sk);
+	if (sk->sk_stamp.tv_sec == -1)
+		return -ENOENT;
+	if (sk->sk_stamp.tv_sec == 0)
+		getnstimeofday(&sk->sk_stamp);
+	return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timespec)) ?
+		-EFAULT : 0;
+}
+EXPORT_SYMBOL(sock_get_timestampns);
+
 void sock_enable_timestamp(struct sock *sk)
 {
 	if (!sock_flag(sk, SOCK_TIMESTAMP)) {
--- linux-2.6.21-rc2/net/core/dev.c	2007-02-28 21:16:43.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/core/dev.c	2007-03-01 23:53:23.000000000 +0100
@@ -1036,10 +1036,10 @@ void net_disable_timestamp(void)
 
 void __net_timestamp(struct sk_buff *skb)
 {
-	struct timeval tv;
+	struct timespec ts;
 
-	do_gettimeofday(&tv);
-	skb_set_timestamp(skb, &tv);
+	getnstimeofday(&ts);
+	skb_set_timestampns(skb, &ts);
 }
 EXPORT_SYMBOL(__net_timestamp);
 
@@ -1049,7 +1049,7 @@ static inline void net_timestamp(struct 
 		__net_timestamp(skb);
 	else {
 		skb->tstamp.off_sec = 0;
-		skb->tstamp.off_usec = 0;
+		skb->tstamp.off_nsec = 0;
 	}
 }
 
--- linux-2.6.21-rc2/net/ipv4/ip_fragment.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/ip_fragment.c	2007-03-01 23:53:23.000000000 +0100
@@ -92,7 +92,7 @@ struct ipq {
 	spinlock_t	lock;
 	atomic_t	refcnt;
 	struct timer_list timer;	/* when will this queue expire?		*/
-	struct timeval	stamp;
+	struct timespec	stamp;
 	int             iif;
 	unsigned int    rid;
 	struct inet_peer *peer;
@@ -592,7 +592,7 @@ static void ip_frag_queue(struct ipq *qp
 	if (skb->dev)
 		qp->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &qp->stamp);
+	skb_get_timestampns(skb, &qp->stamp);
 	qp->meat += skb->len;
 	atomic_add(skb->truesize, &ip_frag_mem);
 	if (offset == 0)
@@ -674,7 +674,7 @@ static struct sk_buff *ip_frag_reasm(str
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &qp->stamp);
+	skb_set_timestampns(head, &qp->stamp);
 
 	iph = head->nh.iph;
 	iph->frag_off = 0;
--- linux-2.6.21-rc2/net/ipv4/af_inet.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/af_inet.c	2007-02-28 20:54:35.000000000 +0100
@@ -755,6 +755,9 @@ int inet_ioctl(struct socket *sock, unsi
 		case SIOCGSTAMP:
 			err = sock_get_timestamp(sk, (struct timeval __user *)arg);
 			break;
+		case SIOCGSTAMPNS:
+			err = sock_get_timestampns(sk, (struct timespec __user *)arg);
+			break;
 		case SIOCADDRT:
 		case SIOCDELRT:
 		case SIOCRTMSG:
--- linux-2.6.21-rc2/net/ipv6/af_inet6.c	2007-03-01 12:34:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/af_inet6.c	2007-03-01 12:34:35.000000000 +0100
@@ -437,6 +437,9 @@ int inet6_ioctl(struct socket *sock, uns
 	case SIOCGSTAMP:
 		return sock_get_timestamp(sk, (struct timeval __user *)arg);
 
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *)arg);
+
 	case SIOCADDRT:
 	case SIOCDELRT:
 
--- linux-2.6.21-rc2/net/packet/af_packet.c	2007-02-28 21:23:12.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/packet/af_packet.c	2007-03-01 23:53:23.000000000 +0100
@@ -661,7 +661,7 @@ static int tpacket_rcv(struct sk_buff *s
 		sock_enable_timestamp(sk);
 	}
 	h->tp_sec = skb->tstamp.off_sec;
-	h->tp_usec = skb->tstamp.off_usec;
+	h->tp_usec = skb->tstamp.off_nsec / NSEC_PER_USEC;
 
 	sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
 	sll->sll_halen = 0;
@@ -1543,6 +1543,8 @@ static int packet_ioctl(struct socket *s
 		}
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, (struct timeval __user *)arg);
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, (struct timespec __user *)arg);
 
 #ifdef CONFIG_INET
 		case SIOCADDRT:
--- linux-2.6.21-rc2/net/sunrpc/svcsock.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/sunrpc/svcsock.c	2007-03-01 23:53:23.000000000 +0100
@@ -806,15 +806,14 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 		dprintk("svc: recvfrom returned error %d\n", -err);
 	}
 	if (skb->tstamp.off_sec == 0) {
-		struct timeval tv;
+		struct timespec ts;
 
-		tv.tv_sec = xtime.tv_sec;
-		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
-		skb_set_timestamp(skb, &tv);
+		ts = current_kernel_time();
+		skb_set_timestampns(skb, &ts);
 		/* Don't enable netstamp, sunrpc doesn't
 		   need that much accuracy */
 	}
-	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+	skb_get_timestampns(skb, &svsk->sk_sk->sk_stamp);
 	set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
 
 	/*
--- linux-2.6.21-rc2/net/compat.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/compat.c	2007-03-02 02:10:08.000000000 +0100
@@ -215,6 +215,7 @@ Efault:
 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
 {
 	struct compat_timeval ctv;
+	struct compat_timespec cts;
 	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
 	struct compat_cmsghdr cmhdr;
 	int cmlen;
@@ -231,6 +232,13 @@ int put_cmsg_compat(struct msghdr *kmsg,
 		data = &ctv;
 		len = sizeof(struct compat_timeval);
 	}
+	if (level == SOL_SOCKET && type == SO_TIMESTAMPNS) {
+		struct timespec *ts = (struct timespec *)data;
+		cts.tv_sec = ts->tv_sec;
+		cts.tv_nsec = ts->tv_nsec;
+		data = &cts;
+		len = sizeof(struct compat_timespec);
+	}
 
 	cmlen = CMSG_COMPAT_LEN(len);
 	if(kmsg->msg_controllen < cmlen) {
@@ -545,20 +553,41 @@ int compat_sock_get_timestamp(struct soc
 	struct compat_timeval __user *ctv =
 			(struct compat_timeval __user*) userstamp;
 	int err = -ENOENT;
+	long usec;
 
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
 	if (sk->sk_stamp.tv_sec == -1)
 		return err;
 	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
+		getnstimeofday(&sk->sk_stamp);
+	usec = sk->sk_stamp.tv_nsec / NSEC_PER_USEC;
 	if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
-			put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+			put_user(usec, &ctv->tv_usec))
 		err = -EFAULT;
 	return err;
 }
 EXPORT_SYMBOL(compat_sock_get_timestamp);
 
+int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
+{
+	struct compat_timespec __user *ctv =
+			(struct compat_timespec __user*) userstamp;
+	int err = -ENOENT;
+
+	if (!sock_flag(sk, SOCK_TIMESTAMP))
+		sock_enable_timestamp(sk);
+	if (sk->sk_stamp.tv_sec == -1)
+		return err;
+	if (sk->sk_stamp.tv_sec == 0)
+		getnstimeofday(&sk->sk_stamp);
+	if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
+			put_user(sk->sk_stamp.tv_nsec, &ctv->tv_nsec))
+		err = -EFAULT;
+	return err;
+}
+EXPORT_SYMBOL(compat_sock_get_timestampns);
+
 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
 				char __user *optval, int __user *optlen)
 {
--- linux-2.6.21-rc2/fs/compat_ioctl.c	2007-03-01 13:01:27.000000000 +0100
+++ linux-2.6.21-rc2-ed/fs/compat_ioctl.c	2007-03-01 13:01:27.000000000 +0100
@@ -265,6 +265,22 @@ static int do_siocgstamp(unsigned int fd
 	}
 	return err;
 }
+static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct compat_timespec __user *up = compat_ptr(arg);
+	struct timespec ktv;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
+	set_fs(old_fs);
+	if(!err) {
+		err = put_user(ktv.tv_sec, &up->tv_sec);
+		err |= __put_user(ktv.tv_nsec, &up->tv_nsec);
+	}
+	return err;
+}
 
 struct ifmap32 {
 	compat_ulong_t mem_start;
@@ -2437,6 +2453,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc)
 /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
 HANDLE_IOCTL(SIOCRTMSG, ret_einval)
 HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
+HANDLE_IOCTL(SIOCGSTAMPNS, do_siocgstampns)
 #endif
 #ifdef CONFIG_BLOCK
 HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
--- linux-2.6.21-rc2/net/appletalk/ddp.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/appletalk/ddp.c	2007-03-01 12:56:02.000000000 +0100
@@ -1768,6 +1768,9 @@ static int atalk_ioctl(struct socket *so
 		case SIOCGSTAMP:
 			rc = sock_get_timestamp(sk, argp);
 			break;
+		case SIOCGSTAMPNS:
+			rc = sock_get_timestampns(sk, argp);
+			break;
 		/* Routing */
 		case SIOCADDRT:
 		case SIOCDELRT:
--- linux-2.6.21-rc2/net/ax25/af_ax25.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ax25/af_ax25.c	2007-03-01 12:56:02.000000000 +0100
@@ -1711,6 +1711,10 @@ static int ax25_ioctl(struct socket *soc
 		res = sock_get_timestamp(sk, argp);
 		break;
 
+	case SIOCGSTAMPNS:
+		res = sock_get_timestampns(sk, argp);
+		break;
+
 	case SIOCAX25ADDUID:	/* Add a uid to the uid/call map table */
 	case SIOCAX25DELUID:	/* Delete a uid from the uid/call map table */
 	case SIOCAX25GETUID: {
--- linux-2.6.21-rc2/net/atm/ioctl.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/atm/ioctl.c	2007-03-01 12:56:02.000000000 +0100
@@ -82,6 +82,9 @@ int vcc_ioctl(struct socket *sock, unsig
 		case SIOCGSTAMP: /* borrowed from IP */
 			error = sock_get_timestamp(sk, argp);
 			goto done;
+		case SIOCGSTAMPNS: /* borrowed from IP */
+			error = sock_get_timestampns(sk, argp);
+			goto done;
 		case ATM_SETSC:
 			printk(KERN_WARNING "ATM_SETSC is obsolete\n");
 			error = 0;
--- linux-2.6.21-rc2/net/econet/af_econet.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/econet/af_econet.c	2007-03-01 23:53:23.000000000 +0100
@@ -162,7 +162,7 @@ static int econet_recvmsg(struct kiocb *
 	err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
 	if (err)
 		goto out_free;
-	skb_get_timestamp(skb, &sk->sk_stamp);
+	skb_get_timestampns(skb, &sk->sk_stamp);
 
 	if (msg->msg_name)
 		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
@@ -727,6 +727,9 @@ static int econet_ioctl(struct socket *s
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, argp);
 
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, argp);
+
 		case SIOCSIFADDR:
 		case SIOCGIFADDR:
 			return ec_dev_ioctl(sock, cmd, argp);
--- linux-2.6.21-rc2/net/ipx/af_ipx.c	2007-02-28 20:54:35.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipx/af_ipx.c	2007-03-01 23:53:23.000000000 +0100
@@ -1808,7 +1808,7 @@ static int ipx_recvmsg(struct kiocb *ioc
 	if (rc)
 		goto out_free;
 	if (skb->tstamp.off_sec)
-		skb_get_timestamp(skb, &sk->sk_stamp);
+		skb_get_timestampns(skb, &sk->sk_stamp);
 
 	msg->msg_namelen = sizeof(*sipx);
 
--- linux-2.6.21-rc2/net/netrom/af_netrom.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/netrom/af_netrom.c	2007-03-01 12:56:02.000000000 +0100
@@ -1208,6 +1208,11 @@ static int nr_ioctl(struct socket *sock,
 		ret = sock_get_timestamp(sk, argp);
 		release_sock(sk);
 		return ret;
+	case SIOCGSTAMPNS:
+		lock_sock(sk);
+		ret = sock_get_timestampns(sk, argp);
+		release_sock(sk);
+		return ret;
 
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
--- linux-2.6.21-rc2/net/rose/af_rose.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/rose/af_rose.c	2007-03-01 12:56:02.000000000 +0100
@@ -1271,6 +1271,8 @@ static int rose_ioctl(struct socket *soc
 
 	case SIOCGSTAMP:
 		return sock_get_timestamp(sk, (struct timeval __user *) argp);
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *) argp);
 
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
--- linux-2.6.21-rc2/net/wanrouter/af_wanpipe.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/wanrouter/af_wanpipe.c	2007-03-01 12:56:02.000000000 +0100
@@ -1770,6 +1770,9 @@ static int wanpipe_ioctl(struct socket *
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, (struct timeval __user *)arg);
 
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, (struct timespec __user *)arg);
+
 		case SIOC_WANPIPE_CHECK_TX:
 
 			return atomic_read(&sk->sk_wmem_alloc);
--- linux-2.6.21-rc2/net/x25/af_x25.c	2007-03-01 12:56:02.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/x25/af_x25.c	2007-03-02 00:58:10.000000000 +0100
@@ -1280,6 +1280,12 @@ static int x25_ioctl(struct socket *sock
 				rc = sock_get_timestamp(sk,
 						(struct timeval __user *)argp);
 			break;
+		case SIOCGSTAMPNS:
+			rc = -EINVAL;
+			if (sk)
+				rc = sock_get_timestampns(sk,
+						(struct timespec __user *)argp);
+			break;
 		case SIOCGIFADDR:
 		case SIOCSIFADDR:
 		case SIOCGIFDSTADDR:
@@ -1521,6 +1527,12 @@ static int compat_x25_ioctl(struct socke
 			rc = compat_sock_get_timestamp(sk,
 					(struct timeval __user*)argp);
 		break;
+	case SIOCGSTAMPNS:
+		rc = -EINVAL;
+		if (sk)
+			rc = compat_sock_get_timestampns(sk,
+					(struct timespec __user*)argp);
+		break;
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
 	case SIOCGIFDSTADDR:
--- linux-2.6.21-rc2/net/bridge/netfilter/ebt_ulog.c	2007-03-01 13:09:56.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/bridge/netfilter/ebt_ulog.c	2007-03-01 23:53:23.000000000 +0100
@@ -130,6 +130,7 @@ static void ebt_ulog_packet(unsigned int
 	unsigned int group = uloginfo->nlgroup;
 	ebt_ulog_buff_t *ub = &ulog_buffers[group];
 	spinlock_t *lock = &ub->lock;
+	struct timespec ts;
 
 	if ((uloginfo->cprange == 0) ||
 	    (uloginfo->cprange > skb->len + ETH_HLEN))
@@ -164,9 +165,11 @@ static void ebt_ulog_packet(unsigned int
 
 	/* Fill in the ulog data */
 	pm->version = EBT_ULOG_VERSION;
-	do_gettimeofday(&pm->stamp);
+	getnstimeofday(&ts);
+	pm->stamp.tv_sec = ts.tv_sec;
+	pm->stamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 	if (ub->qlen == 1)
-		skb_set_timestamp(ub->skb, &pm->stamp);
+		skb_set_timestampns(ub->skb, &ts);
 	pm->data_len = copy_len;
 	pm->mark = skb->mark;
 	pm->hook = hooknr;
--- linux-2.6.21-rc2/net/ipv4/netfilter/ipt_ULOG.c	2007-03-02 00:37:08.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/netfilter/ipt_ULOG.c	2007-03-02 00:37:08.000000000 +0100
@@ -237,7 +237,7 @@ static void ipt_ulog_packet(unsigned int
 	/* copy hook, prefix, timestamp, payload, etc. */
 	pm->data_len = copy_len;
 	pm->timestamp_sec = skb->tstamp.off_sec;
-	pm->timestamp_usec = skb->tstamp.off_usec;
+	pm->timestamp_usec = skb->tstamp.off_nsec / NSEC_PER_USEC;
 	pm->mark = skb->mark;
 	pm->hook = hooknum;
 	if (prefix != NULL)
--- linux-2.6.21-rc2/net/ipv4/netfilter/ip_queue.c	2007-03-02 00:38:53.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv4/netfilter/ip_queue.c	2007-03-02 00:38:53.000000000 +0100
@@ -242,7 +242,7 @@ ipq_build_packet_message(struct ipq_queu
 	pmsg->packet_id       = (unsigned long )entry;
 	pmsg->data_len        = data_len;
 	pmsg->timestamp_sec   = entry->skb->tstamp.off_sec;
-	pmsg->timestamp_usec  = entry->skb->tstamp.off_usec;
+	pmsg->timestamp_usec  = entry->skb->tstamp.off_nsec / NSEC_PER_USEC;
 	pmsg->mark            = entry->skb->mark;
 	pmsg->hook            = entry->info->hook;
 	pmsg->hw_protocol     = entry->skb->protocol;
--- linux-2.6.21-rc2/net/ipv6/netfilter/ip6_queue.c	2007-03-02 00:40:37.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/netfilter/ip6_queue.c	2007-03-02 00:40:37.000000000 +0100
@@ -240,7 +240,7 @@ ipq_build_packet_message(struct ipq_queu
 	pmsg->packet_id       = (unsigned long )entry;
 	pmsg->data_len        = data_len;
 	pmsg->timestamp_sec   = entry->skb->tstamp.off_sec;
-	pmsg->timestamp_usec  = entry->skb->tstamp.off_usec;
+	pmsg->timestamp_usec  = entry->skb->tstamp.off_nsec / NSEC_PER_USEC;
 	pmsg->mark            = entry->skb->mark;
 	pmsg->hook            = entry->info->hook;
 	pmsg->hw_protocol     = entry->skb->protocol;
--- linux-2.6.21-rc2/net/netfilter/nfnetlink_queue.c	2007-02-28 05:59:12.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/netfilter/nfnetlink_queue.c	2007-03-02 00:44:08.000000000 +0100
@@ -499,7 +499,7 @@ nfqnl_build_packet_message(struct nfqnl_
 		struct nfqnl_msg_packet_timestamp ts;
 
 		ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
+		ts.usec = cpu_to_be64(entskb->tstamp.off_nsec / NSEC_PER_USEC);
 
 		NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
 	}
--- linux-2.6.21-rc2/net/netfilter/nfnetlink_log.c	2007-03-02 00:44:45.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/netfilter/nfnetlink_log.c	2007-03-02 00:47:08.000000000 +0100
@@ -514,7 +514,7 @@ __build_packet_message(struct nfulnl_ins
 		struct nfulnl_msg_packet_timestamp ts;
 
 		ts.sec = cpu_to_be64(skb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(skb->tstamp.off_usec);
+		ts.usec = cpu_to_be64(skb->tstamp.off_nsec / NSEC_PER_USEC);
 
 		NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
 	}
--- linux-2.6.21-rc2/net/ipv6/netfilter/nf_conntrack_reasm.c	2007-03-01 13:09:56.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/netfilter/nf_conntrack_reasm.c	2007-03-01 13:15:07.000000000 +0100
@@ -82,7 +82,7 @@ struct nf_ct_frag6_queue
 	struct sk_buff		*fragments;
 	int			len;
 	int			meat;
-	struct timeval		stamp;
+	struct timespec		stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -542,7 +542,7 @@ static int nf_ct_frag6_queue(struct nf_c
 		fq->fragments = skb;
 
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	skb_get_timestampns(skb, &fq->stamp);
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &nf_ct_frag6_mem);
 
@@ -648,7 +648,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_que
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	skb_set_timestampns(head, &fq->stamp);
 	head->nh.ipv6h->payload_len = htons(payload_len);
 
 	/* Yes, and fold redundant checksum back. 8) */
--- linux-2.6.21-rc2/net/ipv6/reassembly.c	2007-03-01 13:15:07.000000000 +0100
+++ linux-2.6.21-rc2-ed/net/ipv6/reassembly.c	2007-03-01 13:15:07.000000000 +0100
@@ -88,7 +88,7 @@ struct frag_queue
 	int			len;
 	int			meat;
 	int			iif;
-	struct timeval		stamp;
+	struct timespec		stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -562,7 +562,7 @@ static void ip6_frag_queue(struct frag_q
 	if (skb->dev)
 		fq->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	skb_get_timestampns(skb, &fq->stamp);
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &ip6_frag_mem);
 
@@ -663,7 +663,7 @@ static int ip6_frag_reasm(struct frag_qu
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	skb_set_timestampns(head, &fq->stamp);
 	head->nh.ipv6h->payload_len = htons(payload_len);
 	IP6CB(head)->nhoff = nhoff;
 
--- linux-2.6.21-rc2/include/asm-i386/socket.h	2007-03-02 02:10:08.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-i386/socket.h	2007-03-02 02:10:08.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-i386/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-i386/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-x86_64/socket.h	2007-03-02 02:35:28.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-x86_64/socket.h	2007-03-02 02:35:28.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-x86_64/sockios.h	2007-02-28 21:19:22.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-x86_64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-alpha/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-alpha/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -52,6 +52,8 @@
 
 #define SO_PEERSEC		30
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		19
--- linux-2.6.21-rc2/include/asm-alpha/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-alpha/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -11,5 +11,6 @@
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
 #define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_ALPHA_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-arm/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-arm/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-arm26/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-arm26/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-arm26/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-arm26/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-avr32/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-avr32/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* __ASM_AVR32_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-avr32/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-avr32/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ASM_AVR32_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-cris/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-cris/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-frv/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-frv/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,6 +49,8 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
 
--- linux-2.6.21-rc2/include/asm-frv/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-frv/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,7 +7,8 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_SOCKIOS__ */
 
--- linux-2.6.21-rc2/include/asm-h8300/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-h8300/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-h8300/sockios.h	2007-03-01 11:53:45.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-h8300/sockios.h	2007-03-01 11:53:45.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ARCH_H8300_SOCKIOS__ */
--- linux-2.6.21-rc2/include/asm-ia64/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-ia64/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -58,5 +58,7 @@
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_IA64_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-ia64/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-ia64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -14,6 +14,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_IA64_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-m32r/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-m32r/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_M32R_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-m32r/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-m32r/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif  /* _ASM_M32R_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-m68k/socket.h	2007-03-02 02:26:19.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-m68k/socket.h	2007-03-02 02:26:19.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-m68k/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-m68k/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ARCH_M68K_SOCKIOS__ */
--- linux-2.6.21-rc2/include/asm-mips/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-mips/socket.h	2007-03-02 02:33:47.000000000 +0100
@@ -70,6 +70,8 @@ To add: #define SO_REUSEPORT 0x0200	/* A
 #define SO_SNDBUFFORCE		31
 #define SO_RCVBUFFORCE		33
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #ifdef __KERNEL__
 
--- linux-2.6.21-rc2/include/asm-mips/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-mips/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -20,6 +20,7 @@
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906			/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-parisc/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-parisc/socket.h	2007-03-02 02:33:47.000000000 +0100
@@ -33,6 +33,8 @@
 #define SO_PEERCRED	0x4011
 #define SO_TIMESTAMP	0x4012
 #define SCM_TIMESTAMP	SO_TIMESTAMP
+#define SO_TIMESTAMPNS	0x4013
+#define SCM_TIMESTAMPNS	SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x4016
--- linux-2.6.21-rc2/include/asm-parisc/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-parisc/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-powerpc/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-powerpc/socket.h	2007-03-02 02:33:47.000000000 +0100
@@ -56,5 +56,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif	/* _ASM_POWERPC_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-powerpc/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-powerpc/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -14,6 +14,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif	/* _ASM_POWERPC_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-s390/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-s390/socket.h	2007-02-28 05:59:12.000000000 +0100
@@ -57,7 +57,5 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
-#define SO_TIMESTAMPNS		35
-#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-s390/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-s390/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -15,6 +15,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
--- linux-2.6.21-rc2/include/asm-sh/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sh/socket.h	2007-02-28 05:59:12.000000000 +0100
@@ -49,7 +49,5 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
-#define SO_TIMESTAMPNS		35
-#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* __ASM_SH_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-sh/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sh/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -10,4 +10,5 @@
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
 #define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#define SIOCGSTAMPNS	_IOR('s', 101, struct timespec) /* Get stamp - linux-specific */
 #endif /* __ASM_SH_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-sh64/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sh64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -21,4 +21,5 @@
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
 #define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#define SIOCGSTAMPNS	_IOR('s', 101, struct timespec) /* Get stamp - linux-specific */
 #endif /* __ASM_SH64_SOCKIOS_H */
--- linux-2.6.21-rc2/include/asm-sparc/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sparc/socket.h	2007-03-02 02:33:47.000000000 +0100
@@ -49,6 +49,8 @@
 
 #define SO_PEERSEC		0x001e
 #define SO_PASSSEC		0x001f
+#define SO_TIMESTAMPNS		0x0020
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
--- linux-2.6.21-rc2/include/asm-sparc/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sparc/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,7 +7,8 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* !(_ASM_SPARC_SOCKIOS_H) */
 
--- linux-2.6.21-rc2/include/asm-sparc64/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sparc64/socket.h	2007-03-02 02:33:47.000000000 +0100
@@ -49,6 +49,8 @@
 
 #define SO_PEERSEC		0x001e
 #define SO_PASSSEC		0x001f
+#define SO_TIMESTAMPNS		0x0020
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
--- linux-2.6.21-rc2/include/asm-sparc64/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-sparc64/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,7 +7,8 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* !(_ASM_SPARC64_SOCKIOS_H) */
 
--- linux-2.6.21-rc2/include/asm-v850/socket.h	2007-03-02 02:33:47.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-v850/socket.h	2007-03-02 02:33:47.000000000 +0100
@@ -49,5 +49,7 @@
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* __V850_SOCKET_H__ */
--- linux-2.6.21-rc2/include/asm-v850/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-v850/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -7,6 +7,7 @@
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __V850_SOCKIOS_H__ */
--- linux-2.6.21-rc2/include/asm-xtensa/socket.h	2007-03-02 02:35:28.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-xtensa/socket.h	2007-03-02 02:35:28.000000000 +0100
@@ -60,5 +60,7 @@
 #define SO_ACCEPTCONN		30
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif	/* _XTENSA_SOCKET_H */
--- linux-2.6.21-rc2/include/asm-xtensa/sockios.h	2007-03-01 11:11:33.000000000 +0100
+++ linux-2.6.21-rc2-ed/include/asm-xtensa/sockios.h	2007-03-01 11:11:33.000000000 +0100
@@ -25,6 +25,7 @@
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif	/* _XTENSA_SOCKIOS_H */

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-01 11:30           ` Eric Dumazet
  2007-03-01 15:54             ` Stephen Hemminger
  2007-03-01 18:53             ` CLOCK_MONOTONIC datagram timestamps by the kernel Stephen Hemminger
@ 2007-03-02  9:26             ` John
  2007-03-02 10:11               ` Eric Dumazet
  2 siblings, 1 reply; 39+ messages in thread
From: John @ 2007-03-02  9:26 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: linux-net, netdev, Stephen Hemminger, linux.kernel

Eric Dumazet wrote:

> John wrote:
> 
>> Consider an idle Linux 2.6.20-rt8 system, equipped with a single PCI-E
>> gigabit Ethernet NIC, running on a modern CPU (e.g. Core 2 Duo E6700).
>> All this system does is time stamp 1000 packets per second.
>>
>> Are you claiming that this platform *cannot* handle most packets within
>> less than 1 microsecond of their arrival?
> 
> Yes I claim it. You expect too much of this platform, unless "most" means
> 10 % for you ;)

By "most" I meant more than 50%.

Has someone tried to measure interrupt latency in Linux? I'd like to 
plot the distribution of network IRQ to interrupt handler latencies.

> If you replace "1 us" by "50 us", then yes, it probably can do it, if "most" 
> means 99%, (not 99.999 %)

I think we need cold, hard numbers at this point :-)

> Anyway, if you want to play, you can apply this patch on top of 
> linux-2.6.21-rc2  (nanosecond resolution infrastructure needs 2.6.21)
> I let you do the adjustments for rt kernel.

Why does it require 2.6.21?

> This patch converts sk_buff timestamp to use new nanosecond infra
> (added in 2.6.21)

Is this mentioned somewhere in the 2.6.21-rc1 ChangeLog?
http://kernel.org/pub/linux/kernel/v2.6/testing/ChangeLog-2.6.21-rc1

Regards.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-03-02  9:26             ` John
@ 2007-03-02 10:11               ` Eric Dumazet
  0 siblings, 0 replies; 39+ messages in thread
From: Eric Dumazet @ 2007-03-02 10:11 UTC (permalink / raw)
  To: John; +Cc: netdev, Stephen Hemminger

On Friday 02 March 2007 10:26, John wrote:
> Eric Dumazet wrote:

> > Anyway, if you want to play, you can apply this patch on top of
> > linux-2.6.21-rc2  (nanosecond resolution infrastructure needs 2.6.21)
> > I let you do the adjustments for rt kernel.
>
> Why does it require 2.6.21?

Well, this patch was done on top of the latest kernel for obvious practical 
reasons, but you probably can adapt it on the kernel of your choice.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH] NET : convert network timestamps to ktime_t
  2007-03-01 15:54             ` Stephen Hemminger
  2007-03-01 16:13               ` Eric Dumazet
@ 2007-03-02 14:38               ` Eric Dumazet
  2007-03-02 16:27                 ` Stephen Hemminger
                                   ` (2 more replies)
  1 sibling, 3 replies; 39+ messages in thread
From: Eric Dumazet @ 2007-03-02 14:38 UTC (permalink / raw)
  To: David Miller; +Cc: Stephen Hemminger, John find, netdev

[-- Attachment #1: Type: text/plain, Size: 2216 bytes --]

We currently use a special structure (struct skb_timeval) and plain 'struct 
timeval' to store packet timestamps in sk_buffs and struct sock.

This has some drawbacks :
- Fixed resolution of micro second.
- Waste of space on 64bit platforms where sizeof(struct timeval)=16

I suggest using ktime_t that is a nice abstraction of high resolution time 
services, currently capable of nanosecond resolution.

As sizeof(ktime_t) is 8 bytes, using ktime_t in 'struct sock' permits a 8 byte 
shrink of this structure on 64bit architectures. Some other structures also 
benefit from this size reduction (struct ipq in ipv4/ip_fragment.c, struct 
frag_queue in ipv6/reassembly.c, ...)


Once this ktime infrastructure adopted, we can more easily provide nanosecond 
resolution on top of it. (ioctl SIOCGSTAMPNS and/or 
SO_TIMESTAMPNS/SCM_TIMESTAMPNS)

Note : this patch includes a bug correction in compat_sock_get_timestamp() 
where a "err = 0;" was missing (so this syscall returned -ENOENT instead of 
0)

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
CC: Stephen Hemminger <shemminger@linux-foundation.org>
CC: John find <linux.kernel@free.fr>

 include/linux/skbuff.h                  |   26 ++++------------------
 include/net/sock.h                      |   18 +++++++--------
 net/bridge/netfilter/ebt_ulog.c         |    6 +++--
 net/compat.c                            |   15 ++++++++----
 net/core/dev.c                          |   19 +++-------------
 net/core/sock.c                         |   16 +++++++------
 net/econet/af_econet.c                  |    2 -
 net/ipv4/ip_fragment.c                  |    6 ++---
 net/ipv4/netfilter/ip_queue.c           |    6 +++--
 net/ipv4/netfilter/ipt_ULOG.c           |    8 ++++--
 net/ipv6/exthdrs.c                      |    2 -
 net/ipv6/netfilter/ip6_queue.c          |    6 +++--
 net/ipv6/netfilter/nf_conntrack_reasm.c |    6 ++---
 net/ipv6/reassembly.c                   |    6 ++---
 net/ipx/af_ipx.c                        |    4 +--
 net/netfilter/nfnetlink_log.c           |    8 +++---
 net/netfilter/nfnetlink_queue.c         |    8 +++---
 net/packet/af_packet.c                  |    8 ++++--
 18 files changed, 80 insertions(+), 90 deletions(-)

[-- Attachment #2: net_stamp_ktime.patch --]
[-- Type: text/plain, Size: 15906 bytes --]

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4ff3940..24dcbb3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -27,6 +27,7 @@ #include <linux/textsearch.h>
 #include <net/checksum.h>
 #include <linux/rcupdate.h>
 #include <linux/dmaengine.h>
+#include <linux/hrtimer.h>
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
@@ -156,11 +157,6 @@ struct skb_shared_info {
 #define SKB_DATAREF_SHIFT 16
 #define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
 
-struct skb_timeval {
-	u32	off_sec;
-	u32	off_usec;
-};
-
 
 enum {
 	SKB_FCLONE_UNAVAILABLE,
@@ -233,7 +229,7 @@ struct sk_buff {
 	struct sk_buff		*prev;
 
 	struct sock		*sk;
-	struct skb_timeval	tstamp;
+	ktime_t			tstamp;
 	struct net_device	*dev;
 	struct net_device	*input_dev;
 
@@ -1360,26 +1356,14 @@ extern void skb_add_mtu(int mtu);
  */
 static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
 {
-	stamp->tv_sec  = skb->tstamp.off_sec;
-	stamp->tv_usec = skb->tstamp.off_usec;
+	*stamp = ktime_to_timeval(skb->tstamp);
 }
 
-/**
- * 	skb_set_timestamp - set timestamp of a skb
- *	@skb: skb to set stamp of
- *	@stamp: pointer to struct timeval to get stamp from
- *
- *	Timestamps are stored in the skb as offsets to a base timestamp.
- *	This function converts a struct timeval to an offset and stores
- *	it in the skb.
- */
-static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
+static inline void __net_timestamp(struct sk_buff *skb)
 {
-	skb->tstamp.off_sec  = stamp->tv_sec;
-	skb->tstamp.off_usec = stamp->tv_usec;
+	skb->tstamp = ktime_get_real();
 }
 
-extern void __net_timestamp(struct sk_buff *skb);
 
 extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
diff --git a/include/net/sock.h b/include/net/sock.h
index 2c7d60c..19f6540 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -244,7 +244,7 @@ #define sk_prot			__sk_common.skc_prot
 	struct sk_filter      	*sk_filter;
 	void			*sk_protinfo;
 	struct timer_list	sk_timer;
-	struct timeval		sk_stamp;
+	ktime_t			sk_stamp;
 	struct socket		*sk_socket;
 	void			*sk_user_data;
 	struct page		*sk_sndmsg_page;
@@ -1307,19 +1307,19 @@ static inline int sock_intr_errno(long t
 static __inline__ void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
-	struct timeval stamp;
+	ktime_t kt = skb->tstamp;
 
-	skb_get_timestamp(skb, &stamp);
 	if (sock_flag(sk, SOCK_RCVTSTAMP)) {
+		struct timeval tv;
 		/* Race occurred between timestamp enabling and packet
 		   receiving.  Fill in the current time for now. */
-		if (stamp.tv_sec == 0)
-			do_gettimeofday(&stamp);
-		skb_set_timestamp(skb, &stamp);
-		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval),
-			 &stamp);
+		if (kt.tv64 == 0)
+			kt = ktime_get_real();
+		skb->tstamp = kt;
+		tv = ktime_to_timeval(kt);
+		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(tv), &tv);
 	} else
-		sk->sk_stamp = stamp;
+		sk->sk_stamp = kt;
 }
 
 /**
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 8e15cc4..259f5c3 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -130,6 +130,7 @@ static void ebt_ulog_packet(unsigned int
 	unsigned int group = uloginfo->nlgroup;
 	ebt_ulog_buff_t *ub = &ulog_buffers[group];
 	spinlock_t *lock = &ub->lock;
+	ktime_t kt;
 
 	if ((uloginfo->cprange == 0) ||
 	    (uloginfo->cprange > skb->len + ETH_HLEN))
@@ -164,9 +165,10 @@ static void ebt_ulog_packet(unsigned int
 
 	/* Fill in the ulog data */
 	pm->version = EBT_ULOG_VERSION;
-	do_gettimeofday(&pm->stamp);
+	kt = ktime_get_real();
+	pm->stamp = ktime_to_timeval(kt);
 	if (ub->qlen == 1)
-		skb_set_timestamp(ub->skb, &pm->stamp);
+		ub->skb->tstamp = kt;
 	pm->data_len = copy_len;
 	pm->mark = skb->mark;
 	pm->hook = hooknr;
diff --git a/net/compat.c b/net/compat.c
index 1f32866..17c2710 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -545,15 +545,20 @@ int compat_sock_get_timestamp(struct soc
 	struct compat_timeval __user *ctv =
 			(struct compat_timeval __user*) userstamp;
 	int err = -ENOENT;
+	struct timeval tv;
 
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
-	if (sk->sk_stamp.tv_sec == -1)
+	tv = ktime_to_timeval(sk->sk_stamp);
+	if (tv.tv_sec == -1)
 		return err;
-	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
-			put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+	if (tv.tv_sec == 0) {
+		sk->sk_stamp = ktime_get_real();
+		tv = ktime_to_timeval(sk->sk_stamp);
+	}
+	err = 0;
+	if (put_user(tv.tv_sec, &ctv->tv_sec) ||
+			put_user(tv.tv_usec, &ctv->tv_usec))
 		err = -EFAULT;
 	return err;
 }
diff --git a/net/core/dev.c b/net/core/dev.c
index cf71614..833ca92 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1034,23 +1034,12 @@ void net_disable_timestamp(void)
 	atomic_dec(&netstamp_needed);
 }
 
-void __net_timestamp(struct sk_buff *skb)
-{
-	struct timeval tv;
-
-	do_gettimeofday(&tv);
-	skb_set_timestamp(skb, &tv);
-}
-EXPORT_SYMBOL(__net_timestamp);
-
 static inline void net_timestamp(struct sk_buff *skb)
 {
 	if (atomic_read(&netstamp_needed))
 		__net_timestamp(skb);
-	else {
-		skb->tstamp.off_sec = 0;
-		skb->tstamp.off_usec = 0;
-	}
+	else
+		skb->tstamp.tv64 = 0;
 }
 
 /*
@@ -1580,7 +1569,7 @@ int netif_rx(struct sk_buff *skb)
 	if (netpoll_rx(skb))
 		return NET_RX_DROP;
 
-	if (!skb->tstamp.off_sec)
+	if (!skb->tstamp.tv64)
 		net_timestamp(skb);
 
 	/*
@@ -1772,7 +1761,7 @@ int netif_receive_skb(struct sk_buff *sk
 	if (skb->dev->poll && netpoll_rx(skb))
 		return NET_RX_DROP;
 
-	if (!skb->tstamp.off_sec)
+	if (!skb->tstamp.tv64)
 		net_timestamp(skb);
 
 	if (!skb->input_dev)
diff --git a/net/core/sock.c b/net/core/sock.c
index e9986ac..5c50693 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1512,8 +1512,7 @@ #endif
 	sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;
 	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;
 
-	sk->sk_stamp.tv_sec     = -1L;
-	sk->sk_stamp.tv_usec    = -1L;
+	sk->sk_stamp = ktime_set(-1L, -1L);
 
 	atomic_set(&sk->sk_refcnt, 1);
 }
@@ -1554,14 +1553,17 @@ EXPORT_SYMBOL(release_sock);
 
 int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
 {
+	struct timeval tv;
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
-	if (sk->sk_stamp.tv_sec == -1)
+	tv = ktime_to_timeval(sk->sk_stamp);
+	if (tv.tv_sec == -1)
 		return -ENOENT;
-	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timeval)) ?
-		-EFAULT : 0;
+	if (tv.tv_sec == 0) {
+		sk->sk_stamp = ktime_get_real();
+		tv = ktime_to_timeval(sk->sk_stamp);
+	}
+	return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0;
 }
 EXPORT_SYMBOL(sock_get_timestamp);
 
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index bc12e36..f573edd 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -162,7 +162,7 @@ static int econet_recvmsg(struct kiocb *
 	err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
 	if (err)
 		goto out_free;
-	skb_get_timestamp(skb, &sk->sk_stamp);
+	sk->sk_stamp = skb->tstamp;
 
 	if (msg->msg_name)
 		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b6f0553..08ff3ff 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -92,7 +92,7 @@ #define LAST_IN			1
 	spinlock_t	lock;
 	atomic_t	refcnt;
 	struct timer_list timer;	/* when will this queue expire?		*/
-	struct timeval	stamp;
+	ktime_t		stamp;
 	int             iif;
 	unsigned int    rid;
 	struct inet_peer *peer;
@@ -592,7 +592,7 @@ static void ip_frag_queue(struct ipq *qp
 	if (skb->dev)
 		qp->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &qp->stamp);
+	qp->stamp = skb->tstamp;
 	qp->meat += skb->len;
 	atomic_add(skb->truesize, &ip_frag_mem);
 	if (offset == 0)
@@ -674,7 +674,7 @@ static struct sk_buff *ip_frag_reasm(str
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &qp->stamp);
+	head->tstamp = qp->stamp;
 
 	iph = head->nh.iph;
 	iph->frag_off = 0;
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index a14798a..5842f1a 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -197,6 +197,7 @@ ipq_build_packet_message(struct ipq_queu
 	struct sk_buff *skb;
 	struct ipq_packet_msg *pmsg;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 
 	read_lock_bh(&queue_lock);
 
@@ -241,8 +242,9 @@ ipq_build_packet_message(struct ipq_queu
 
 	pmsg->packet_id       = (unsigned long )entry;
 	pmsg->data_len        = data_len;
-	pmsg->timestamp_sec   = entry->skb->tstamp.off_sec;
-	pmsg->timestamp_usec  = entry->skb->tstamp.off_usec;
+	tv = ktime_to_timeval(entry->skb->tstamp);
+	pmsg->timestamp_sec   = tv.tv_sec;
+	pmsg->timestamp_usec  = tv.tv_usec;
 	pmsg->mark            = entry->skb->mark;
 	pmsg->hook            = entry->info->hook;
 	pmsg->hw_protocol     = entry->skb->protocol;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index a26404d..e78c9d7 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -186,6 +186,7 @@ static void ipt_ulog_packet(unsigned int
 	ulog_packet_msg_t *pm;
 	size_t size, copy_len;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 
 	/* ffs == find first bit set, necessary because userspace
 	 * is already shifting groupnumber, but we need unshifted.
@@ -231,13 +232,14 @@ static void ipt_ulog_packet(unsigned int
 	pm = NLMSG_DATA(nlh);
 
 	/* We might not have a timestamp, get one */
-	if (skb->tstamp.off_sec == 0)
+	if (skb->tstamp.tv64 == 0)
 		__net_timestamp((struct sk_buff *)skb);
 
 	/* copy hook, prefix, timestamp, payload, etc. */
 	pm->data_len = copy_len;
-	pm->timestamp_sec = skb->tstamp.off_sec;
-	pm->timestamp_usec = skb->tstamp.off_usec;
+	tv = ktime_to_timeval(skb->tstamp);
+	pm->timestamp_sec = tv.tv_sec;
+	pm->timestamp_usec = tv.tv_usec;
 	pm->mark = skb->mark;
 	pm->hook = hooknum;
 	if (prefix != NULL)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 28e0c65..0dc0ca0 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -255,7 +255,7 @@ static int ipv6_dest_hao(struct sk_buff 
 	ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
 	ipv6_addr_copy(&hao->addr, &tmp_addr);
 
-	if (skb->tstamp.off_sec == 0)
+	if (skb->tstamp.tv64 == 0)
 		__net_timestamp(skb);
 
 	return 1;
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index fdb30a5..66a2c41 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -195,6 +195,7 @@ ipq_build_packet_message(struct ipq_queu
 	struct sk_buff *skb;
 	struct ipq_packet_msg *pmsg;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 
 	read_lock_bh(&queue_lock);
 
@@ -239,8 +240,9 @@ ipq_build_packet_message(struct ipq_queu
 
 	pmsg->packet_id       = (unsigned long )entry;
 	pmsg->data_len        = data_len;
-	pmsg->timestamp_sec   = entry->skb->tstamp.off_sec;
-	pmsg->timestamp_usec  = entry->skb->tstamp.off_usec;
+	tv = ktime_to_timeval(entry->skb->tstamp);
+	pmsg->timestamp_sec   = tv.tv_sec;
+	pmsg->timestamp_usec  = tv.tv_usec;
 	pmsg->mark            = entry->skb->mark;
 	pmsg->hook            = entry->info->hook;
 	pmsg->hw_protocol     = entry->skb->protocol;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 15ab1e3..c311b9a 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -82,7 +82,7 @@ struct nf_ct_frag6_queue
 	struct sk_buff		*fragments;
 	int			len;
 	int			meat;
-	struct timeval		stamp;
+	ktime_t			stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -542,7 +542,7 @@ static int nf_ct_frag6_queue(struct nf_c
 		fq->fragments = skb;
 
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	fq->stamp = skb->tstamp;
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &nf_ct_frag6_mem);
 
@@ -648,7 +648,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_que
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	head->tstamp = fq->stamp;
 	head->nh.ipv6h->payload_len = htons(payload_len);
 
 	/* Yes, and fold redundant checksum back. 8) */
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 7034c54..1dde449 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -88,7 +88,7 @@ struct frag_queue
 	int			len;
 	int			meat;
 	int			iif;
-	struct timeval		stamp;
+	ktime_t			stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -562,7 +562,7 @@ static void ip6_frag_queue(struct frag_q
 	if (skb->dev)
 		fq->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	fq->stamp = skb->tstamp;
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &ip6_frag_mem);
 
@@ -663,7 +663,7 @@ static int ip6_frag_reasm(struct frag_qu
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	head->tstamp = fq->stamp;
 	head->nh.ipv6h->payload_len = htons(payload_len);
 	IP6CB(head)->nhoff = nhoff;
 
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index cac35a7..6c6c0a3 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1807,8 +1807,8 @@ #endif	/* CONFIG_IPX_INTERN */
 				     copied);
 	if (rc)
 		goto out_free;
-	if (skb->tstamp.off_sec)
-		skb_get_timestamp(skb, &sk->sk_stamp);
+	if (skb->tstamp.tv64)
+		sk->sk_stamp = skb->tstamp;
 
 	msg->msg_namelen = sizeof(*sipx);
 
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index b8eab0d..2f7872e 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -510,11 +510,11 @@ #endif
 		NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
 	}
 
-	if (skb->tstamp.off_sec) {
+	if (skb->tstamp.tv64) {
 		struct nfulnl_msg_packet_timestamp ts;
-
-		ts.sec = cpu_to_be64(skb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(skb->tstamp.off_usec);
+		struct timeval tv = ktime_to_timeval(skb->tstamp);
+		ts.sec = cpu_to_be64(tv.tv_sec);
+		ts.usec = cpu_to_be64(tv.tv_usec);
 
 		NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
 	}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index d9ce4a7..cfbee39 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -495,11 +495,11 @@ #endif
 		NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
 	}
 
-	if (entskb->tstamp.off_sec) {
+	if (entskb->tstamp.tv64) {
 		struct nfqnl_msg_packet_timestamp ts;
-
-		ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
+		struct timeval tv = ktime_to_timeval(entskb->tstamp);
+		ts.sec = cpu_to_be64(tv.tv_sec);
+		ts.usec = cpu_to_be64(tv.tv_usec);
 
 		NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
 	}
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 28d47e8..f9866a8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -582,6 +582,7 @@ static int tpacket_rcv(struct sk_buff *s
 	unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
 	unsigned short macoff, netoff;
 	struct sk_buff *copy_skb = NULL;
+	struct timeval tv;
 
 	if (skb->pkt_type == PACKET_LOOPBACK)
 		goto drop;
@@ -656,12 +657,13 @@ static int tpacket_rcv(struct sk_buff *s
 	h->tp_snaplen = snaplen;
 	h->tp_mac = macoff;
 	h->tp_net = netoff;
-	if (skb->tstamp.off_sec == 0) {
+	if (skb->tstamp.tv64 == 0) {
 		__net_timestamp(skb);
 		sock_enable_timestamp(sk);
 	}
-	h->tp_sec = skb->tstamp.off_sec;
-	h->tp_usec = skb->tstamp.off_usec;
+	tv = ktime_to_timeval(skb->tstamp);
+	h->tp_sec = tv.tv_sec;
+	h->tp_usec = tv.tv_usec;
 
 	sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
 	sll->sll_halen = 0;

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-02 14:38               ` [PATCH] NET : convert network timestamps to ktime_t Eric Dumazet
@ 2007-03-02 16:27                 ` Stephen Hemminger
  2007-03-02 21:02                 ` Stephen Hemminger
  2007-03-08 14:17                 ` [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution Eric Dumazet
  2 siblings, 0 replies; 39+ messages in thread
From: Stephen Hemminger @ 2007-03-02 16:27 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, John find, netdev

On Fri, 2 Mar 2007 15:38:41 +0100
Eric Dumazet <dada1@cosmosbay.com> wrote:

> We currently use a special structure (struct skb_timeval) and plain 'struct 
> timeval' to store packet timestamps in sk_buffs and struct sock.
> 
> This has some drawbacks :
> - Fixed resolution of micro second.
> - Waste of space on 64bit platforms where sizeof(struct timeval)=16
> 
> I suggest using ktime_t that is a nice abstraction of high resolution time 
> services, currently capable of nanosecond resolution.
> 
> As sizeof(ktime_t) is 8 bytes, using ktime_t in 'struct sock' permits a 8 byte 
> shrink of this structure on 64bit architectures. Some other structures also 
> benefit from this size reduction (struct ipq in ipv4/ip_fragment.c, struct 
> frag_queue in ipv6/reassembly.c, ...)

This is even better. Also comparing ktime_t's is easier if some code needs
to do that.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-02 14:38               ` [PATCH] NET : convert network timestamps to ktime_t Eric Dumazet
  2007-03-02 16:27                 ` Stephen Hemminger
@ 2007-03-02 21:02                 ` Stephen Hemminger
  2007-03-02 22:46                   ` Eric Dumazet
  2007-03-08 14:17                 ` [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution Eric Dumazet
  2 siblings, 1 reply; 39+ messages in thread
From: Stephen Hemminger @ 2007-03-02 21:02 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, John find, netdev

On Fri, 2 Mar 2007 15:38:41 +0100
Eric Dumazet <dada1@cosmosbay.com> wrote:

> We currently use a special structure (struct skb_timeval) and plain 'struct 
> timeval' to store packet timestamps in sk_buffs and struct sock.
> 
> This has some drawbacks :
> - Fixed resolution of micro second.
> - Waste of space on 64bit platforms where sizeof(struct timeval)=16
> 
> I suggest using ktime_t that is a nice abstraction of high resolution time 
> services, currently capable of nanosecond resolution.
> 
> As sizeof(ktime_t) is 8 bytes, using ktime_t in 'struct sock' permits a 8 byte 
> shrink of this structure on 64bit architectures. Some other structures also 
> benefit from this size reduction (struct ipq in ipv4/ip_fragment.c, struct 
> frag_queue in ipv6/reassembly.c, ...)
> 
> 

You missed a couple of spots.

--- tcp-2.6.orig/net/sunrpc/svcsock.c	2007-03-02 12:50:45.000000000 -0800
+++ tcp-2.6/net/sunrpc/svcsock.c	2007-03-02 12:58:28.000000000 -0800
@@ -805,16 +805,9 @@
 		/* possibly an icmp error */
 		dprintk("svc: recvfrom returned error %d\n", -err);
 	}
-	if (skb->tstamp.off_sec == 0) {
-		struct timeval tv;
 
-		tv.tv_sec = xtime.tv_sec;
-		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
-		skb_set_timestamp(skb, &tv);
-		/* Don't enable netstamp, sunrpc doesn't
-		   need that much accuracy */
-	}
-	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+	svsk->sk_sk->sk_stamp = (skb->tstamp.tv64 != 0) ? skb->tstamp
+		: ktime_get_real();
 	set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
 
 	/*
--- tcp-2.6.orig/kernel/time.c	2007-03-02 12:59:55.000000000 -0800
+++ tcp-2.6/kernel/time.c	2007-03-02 13:00:08.000000000 -0800
@@ -469,6 +469,8 @@
 
 	return tv;
 }
+EXPORT_SYMBOL(ns_to_timeval);
+
 
 /*
  * Convert jiffies to milliseconds and back.



-- 
Stephen Hemminger <shemminger@linux-foundation.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-02 21:02                 ` Stephen Hemminger
@ 2007-03-02 22:46                   ` Eric Dumazet
  2007-03-05  0:19                     ` David Miller
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-02 22:46 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, John find, netdev

Stephen Hemminger a écrit :
> On Fri, 2 Mar 2007 15:38:41 +0100
> Eric Dumazet <dada1@cosmosbay.com> wrote:
> 
>> We currently use a special structure (struct skb_timeval) and plain 'struct 
>> timeval' to store packet timestamps in sk_buffs and struct sock.
>>
>> This has some drawbacks :
>> - Fixed resolution of micro second.
>> - Waste of space on 64bit platforms where sizeof(struct timeval)=16
>>
>> I suggest using ktime_t that is a nice abstraction of high resolution time 
>> services, currently capable of nanosecond resolution.
>>
>> As sizeof(ktime_t) is 8 bytes, using ktime_t in 'struct sock' permits a 8 byte 
>> shrink of this structure on 64bit architectures. Some other structures also 
>> benefit from this size reduction (struct ipq in ipv4/ip_fragment.c, struct 
>> frag_queue in ipv6/reassembly.c, ...)
>>
>>
> 
> You missed a couple of spots.

Arg yes...

> 
> --- tcp-2.6.orig/net/sunrpc/svcsock.c	2007-03-02 12:50:45.000000000 -0800
> +++ tcp-2.6/net/sunrpc/svcsock.c	2007-03-02 12:58:28.000000000 -0800
> @@ -805,16 +805,9 @@
>  		/* possibly an icmp error */
>  		dprintk("svc: recvfrom returned error %d\n", -err);
>  	}
> -	if (skb->tstamp.off_sec == 0) {
> -		struct timeval tv;
>  
> -		tv.tv_sec = xtime.tv_sec;
> -		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
> -		skb_set_timestamp(skb, &tv);
> -		/* Don't enable netstamp, sunrpc doesn't
> -		   need that much accuracy */
> -	}
> -	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
> +	svsk->sk_sk->sk_stamp = (skb->tstamp.tv64 != 0) ? skb->tstamp
> +		: ktime_get_real();

Well, if we want to stay in the spirit of old code, we probably want to use 
current_kernel_time() (+ timespec_to_ktime()), because its less expensive.

And also setting the skb tstamp, no ?



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-02 22:46                   ` Eric Dumazet
@ 2007-03-05  0:19                     ` David Miller
  2007-03-05  6:56                       ` Eric Dumazet
  0 siblings, 1 reply; 39+ messages in thread
From: David Miller @ 2007-03-05  0:19 UTC (permalink / raw)
  To: dada1; +Cc: shemminger, linux.kernel, netdev

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Fri, 02 Mar 2007 23:46:14 +0100

> Stephen Hemminger a écrit :
> > You missed a couple of spots.
> 
> Arg yes...
 ...
> > -	}
> > -	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
> > +	svsk->sk_sk->sk_stamp = (skb->tstamp.tv64 != 0) ? skb->tstamp
> > +		: ktime_get_real();
> 
> Well, if we want to stay in the spirit of old code, we probably want to use 
> current_kernel_time() (+ timespec_to_ktime()), because its less expensive.
> 
> And also setting the skb tstamp, no ?

Can you guys cook up an integrated patch with all the missing cases
fixed up as desired, so I can add this to net-2.6.22, thanks?

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-05  0:19                     ` David Miller
@ 2007-03-05  6:56                       ` Eric Dumazet
  2007-03-05  7:40                         ` Eric Dumazet
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-05  6:56 UTC (permalink / raw)
  To: David Miller; +Cc: shemminger, linux.kernel, netdev

David Miller a écrit :
> From: Eric Dumazet <dada1@cosmosbay.com>
> Date: Fri, 02 Mar 2007 23:46:14 +0100
> 
>> Stephen Hemminger a écrit :
>>> You missed a couple of spots.
>> Arg yes...
>  ...
>>> -	}
>>> -	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
>>> +	svsk->sk_sk->sk_stamp = (skb->tstamp.tv64 != 0) ? skb->tstamp
>>> +		: ktime_get_real();
>> Well, if we want to stay in the spirit of old code, we probably want to use 
>> current_kernel_time() (+ timespec_to_ktime()), because its less expensive.
>>
>> And also setting the skb tstamp, no ?
> 
> Can you guys cook up an integrated patch with all the missing cases
> fixed up as desired, so I can add this to net-2.6.22, thanks?

Yes, I will send the patch against net-2.6.22 this morning.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH] NET : convert network timestamps to ktime_t
  2007-03-05  6:56                       ` Eric Dumazet
@ 2007-03-05  7:40                         ` Eric Dumazet
  2007-03-05  8:00                           ` David Miller
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-05  7:40 UTC (permalink / raw)
  To: David Miller; +Cc: shemminger, linux.kernel, netdev

[-- Attachment #1: Type: text/plain, Size: 2521 bytes --]

Hi David

Here is the second version of this patch, including missing bits spoted by 
Stephen. This is against net-2.6.22

Thank you

[PATCH] NET : convert network timestamps to ktime_t

We currently use a special structure (struct skb_timeval) and plain 'struct
timeval' to store packet timestamps in sk_buffs and struct sock.

This has some drawbacks :
- Fixed resolution of micro second.
- Waste of space on 64bit platforms where sizeof(struct timeval)=16

I suggest using ktime_t that is a nice abstraction of high resolution time
services, currently capable of nanosecond resolution.

As sizeof(ktime_t) is 8 bytes, using ktime_t in 'struct sock' permits a 8 byte
shrink of this structure on 64bit architectures. Some other structures also
benefit from this size reduction (struct ipq in ipv4/ip_fragment.c, struct
frag_queue in ipv6/reassembly.c, ...)


Once this ktime infrastructure adopted, we can more easily provide nanosecond
resolution on top of it. (ioctl SIOCGSTAMPNS and/or
SO_TIMESTAMPNS/SCM_TIMESTAMPNS)

Note : this patch includes a bug correction in compat_sock_get_timestamp()
where a "err = 0;" was missing (so this syscall returned -ENOENT instead of
0)

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
CC: Stephen Hemminger <shemminger@linux-foundation.org>
CC: John find <linux.kernel@free.fr>

  include/linux/skbuff.h                  |   26 ++++------------------
  include/net/sock.h                      |   18 +++++++--------
  kernel/time.c                           |    1
  net/bridge/netfilter/ebt_ulog.c         |    6 +++--
  net/compat.c                            |   15 ++++++++----
  net/core/dev.c                          |   19 +++-------------
  net/core/sock.c                         |   16 +++++++------
  net/econet/af_econet.c                  |    2 -
  net/ipv4/ip_fragment.c                  |    8 +++---
  net/ipv4/netfilter/ip_queue.c           |    6 +++--
  net/ipv4/netfilter/ipt_ULOG.c           |    8 ++++--
  net/ipv6/exthdrs.c                      |    2 -
  net/ipv6/netfilter/ip6_queue.c          |    6 +++--
  net/ipv6/netfilter/nf_conntrack_reasm.c |    6 ++---
  net/ipv6/reassembly.c                   |    6 ++---
  net/ipx/af_ipx.c                        |    4 +--
  net/netfilter/nfnetlink_log.c           |    8 +++---
  net/netfilter/nfnetlink_queue.c         |    8 +++---
  net/packet/af_packet.c                  |    8 ++++--
  net/sunrpc/svcsock.c                    |   10 ++------
  20 files changed, 85 insertions(+), 98 deletions(-)

[-- Attachment #2: net_stamp_ktime_2.patch --]
[-- Type: text/plain, Size: 17194 bytes --]

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4ff3940..24dcbb3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -27,6 +27,7 @@ #include <linux/textsearch.h>
 #include <net/checksum.h>
 #include <linux/rcupdate.h>
 #include <linux/dmaengine.h>
+#include <linux/hrtimer.h>
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
@@ -156,11 +157,6 @@ struct skb_shared_info {
 #define SKB_DATAREF_SHIFT 16
 #define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
 
-struct skb_timeval {
-	u32	off_sec;
-	u32	off_usec;
-};
-
 
 enum {
 	SKB_FCLONE_UNAVAILABLE,
@@ -233,7 +229,7 @@ struct sk_buff {
 	struct sk_buff		*prev;
 
 	struct sock		*sk;
-	struct skb_timeval	tstamp;
+	ktime_t			tstamp;
 	struct net_device	*dev;
 	struct net_device	*input_dev;
 
@@ -1360,26 +1356,14 @@ extern void skb_add_mtu(int mtu);
  */
 static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
 {
-	stamp->tv_sec  = skb->tstamp.off_sec;
-	stamp->tv_usec = skb->tstamp.off_usec;
+	*stamp = ktime_to_timeval(skb->tstamp);
 }
 
-/**
- * 	skb_set_timestamp - set timestamp of a skb
- *	@skb: skb to set stamp of
- *	@stamp: pointer to struct timeval to get stamp from
- *
- *	Timestamps are stored in the skb as offsets to a base timestamp.
- *	This function converts a struct timeval to an offset and stores
- *	it in the skb.
- */
-static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
+static inline void __net_timestamp(struct sk_buff *skb)
 {
-	skb->tstamp.off_sec  = stamp->tv_sec;
-	skb->tstamp.off_usec = stamp->tv_usec;
+	skb->tstamp = ktime_get_real();
 }
 
-extern void __net_timestamp(struct sk_buff *skb);
 
 extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
diff --git a/include/net/sock.h b/include/net/sock.h
index f352d22..59af9fc 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -244,7 +244,7 @@ #define sk_prot			__sk_common.skc_prot
 	struct sk_filter      	*sk_filter;
 	void			*sk_protinfo;
 	struct timer_list	sk_timer;
-	struct timeval		sk_stamp;
+	ktime_t			sk_stamp;
 	struct socket		*sk_socket;
 	void			*sk_user_data;
 	struct page		*sk_sndmsg_page;
@@ -1307,19 +1307,19 @@ static inline int sock_intr_errno(long t
 static __inline__ void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
-	struct timeval stamp;
+	ktime_t kt = skb->tstamp;
 
-	skb_get_timestamp(skb, &stamp);
 	if (sock_flag(sk, SOCK_RCVTSTAMP)) {
+		struct timeval tv;
 		/* Race occurred between timestamp enabling and packet
 		   receiving.  Fill in the current time for now. */
-		if (stamp.tv_sec == 0)
-			do_gettimeofday(&stamp);
-		skb_set_timestamp(skb, &stamp);
-		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval),
-			 &stamp);
+		if (kt.tv64 == 0)
+			kt = ktime_get_real();
+		skb->tstamp = kt;
+		tv = ktime_to_timeval(kt);
+		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(tv), &tv);
 	} else
-		sk->sk_stamp = stamp;
+		sk->sk_stamp = kt;
 }
 
 /**
diff --git a/kernel/time.c b/kernel/time.c
index c6c80ea..ec5b10c 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -469,6 +469,7 @@ struct timeval ns_to_timeval(const s64 n
 
 	return tv;
 }
+EXPORT_SYMBOL(ns_to_timeval);
 
 /*
  * Convert jiffies to milliseconds and back.
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 8e15cc4..259f5c3 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -130,6 +130,7 @@ static void ebt_ulog_packet(unsigned int
 	unsigned int group = uloginfo->nlgroup;
 	ebt_ulog_buff_t *ub = &ulog_buffers[group];
 	spinlock_t *lock = &ub->lock;
+	ktime_t kt;
 
 	if ((uloginfo->cprange == 0) ||
 	    (uloginfo->cprange > skb->len + ETH_HLEN))
@@ -164,9 +165,10 @@ static void ebt_ulog_packet(unsigned int
 
 	/* Fill in the ulog data */
 	pm->version = EBT_ULOG_VERSION;
-	do_gettimeofday(&pm->stamp);
+	kt = ktime_get_real();
+	pm->stamp = ktime_to_timeval(kt);
 	if (ub->qlen == 1)
-		skb_set_timestamp(ub->skb, &pm->stamp);
+		ub->skb->tstamp = kt;
 	pm->data_len = copy_len;
 	pm->mark = skb->mark;
 	pm->hook = hooknr;
diff --git a/net/compat.c b/net/compat.c
index 1f32866..17c2710 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -545,15 +545,20 @@ int compat_sock_get_timestamp(struct soc
 	struct compat_timeval __user *ctv =
 			(struct compat_timeval __user*) userstamp;
 	int err = -ENOENT;
+	struct timeval tv;
 
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
-	if (sk->sk_stamp.tv_sec == -1)
+	tv = ktime_to_timeval(sk->sk_stamp);
+	if (tv.tv_sec == -1)
 		return err;
-	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
-			put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+	if (tv.tv_sec == 0) {
+		sk->sk_stamp = ktime_get_real();
+		tv = ktime_to_timeval(sk->sk_stamp);
+	}
+	err = 0;
+	if (put_user(tv.tv_sec, &ctv->tv_sec) ||
+			put_user(tv.tv_usec, &ctv->tv_usec))
 		err = -EFAULT;
 	return err;
 }
diff --git a/net/core/dev.c b/net/core/dev.c
index cf71614..833ca92 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1034,23 +1034,12 @@ void net_disable_timestamp(void)
 	atomic_dec(&netstamp_needed);
 }
 
-void __net_timestamp(struct sk_buff *skb)
-{
-	struct timeval tv;
-
-	do_gettimeofday(&tv);
-	skb_set_timestamp(skb, &tv);
-}
-EXPORT_SYMBOL(__net_timestamp);
-
 static inline void net_timestamp(struct sk_buff *skb)
 {
 	if (atomic_read(&netstamp_needed))
 		__net_timestamp(skb);
-	else {
-		skb->tstamp.off_sec = 0;
-		skb->tstamp.off_usec = 0;
-	}
+	else
+		skb->tstamp.tv64 = 0;
 }
 
 /*
@@ -1580,7 +1569,7 @@ int netif_rx(struct sk_buff *skb)
 	if (netpoll_rx(skb))
 		return NET_RX_DROP;
 
-	if (!skb->tstamp.off_sec)
+	if (!skb->tstamp.tv64)
 		net_timestamp(skb);
 
 	/*
@@ -1772,7 +1761,7 @@ int netif_receive_skb(struct sk_buff *sk
 	if (skb->dev->poll && netpoll_rx(skb))
 		return NET_RX_DROP;
 
-	if (!skb->tstamp.off_sec)
+	if (!skb->tstamp.tv64)
 		net_timestamp(skb);
 
 	if (!skb->input_dev)
diff --git a/net/core/sock.c b/net/core/sock.c
index 16ef004..95062a7 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1512,8 +1512,7 @@ #endif
 	sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;
 	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;
 
-	sk->sk_stamp.tv_sec     = -1L;
-	sk->sk_stamp.tv_usec    = -1L;
+	sk->sk_stamp = ktime_set(-1L, -1L);
 
 	atomic_set(&sk->sk_refcnt, 1);
 }
@@ -1554,14 +1553,17 @@ EXPORT_SYMBOL(release_sock);
 
 int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
 {
+	struct timeval tv;
 	if (!sock_flag(sk, SOCK_TIMESTAMP))
 		sock_enable_timestamp(sk);
-	if (sk->sk_stamp.tv_sec == -1)
+	tv = ktime_to_timeval(sk->sk_stamp);
+	if (tv.tv_sec == -1)
 		return -ENOENT;
-	if (sk->sk_stamp.tv_sec == 0)
-		do_gettimeofday(&sk->sk_stamp);
-	return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timeval)) ?
-		-EFAULT : 0;
+	if (tv.tv_sec == 0) {
+		sk->sk_stamp = ktime_get_real();
+		tv = ktime_to_timeval(sk->sk_stamp);
+	}
+	return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0;
 }
 EXPORT_SYMBOL(sock_get_timestamp);
 
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index bc12e36..f573edd 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -162,7 +162,7 @@ static int econet_recvmsg(struct kiocb *
 	err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
 	if (err)
 		goto out_free;
-	skb_get_timestamp(skb, &sk->sk_stamp);
+	sk->sk_stamp = skb->tstamp;
 
 	if (msg->msg_name)
 		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b6f0553..e10be7d 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -92,7 +92,7 @@ #define LAST_IN			1
 	spinlock_t	lock;
 	atomic_t	refcnt;
 	struct timer_list timer;	/* when will this queue expire?		*/
-	struct timeval	stamp;
+	ktime_t		stamp;
 	int             iif;
 	unsigned int    rid;
 	struct inet_peer *peer;
@@ -592,7 +592,7 @@ static void ip_frag_queue(struct ipq *qp
 	if (skb->dev)
 		qp->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &qp->stamp);
+	qp->stamp = skb->tstamp;
 	qp->meat += skb->len;
 	atomic_add(skb->truesize, &ip_frag_mem);
 	if (offset == 0)
@@ -674,7 +674,7 @@ static struct sk_buff *ip_frag_reasm(str
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &qp->stamp);
+	head->tstamp = qp->stamp;
 
 	iph = head->nh.iph;
 	iph->frag_off = 0;
@@ -734,7 +734,7 @@ struct sk_buff *ip_defrag(struct sk_buff
 	return NULL;
 }
 
-void ipfrag_init(void)
+void __init ipfrag_init(void)
 {
 	ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
 				 (jiffies ^ (jiffies >> 6)));
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index a14798a..5842f1a 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -197,6 +197,7 @@ ipq_build_packet_message(struct ipq_queu
 	struct sk_buff *skb;
 	struct ipq_packet_msg *pmsg;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 
 	read_lock_bh(&queue_lock);
 
@@ -241,8 +242,9 @@ ipq_build_packet_message(struct ipq_queu
 
 	pmsg->packet_id       = (unsigned long )entry;
 	pmsg->data_len        = data_len;
-	pmsg->timestamp_sec   = entry->skb->tstamp.off_sec;
-	pmsg->timestamp_usec  = entry->skb->tstamp.off_usec;
+	tv = ktime_to_timeval(entry->skb->tstamp);
+	pmsg->timestamp_sec   = tv.tv_sec;
+	pmsg->timestamp_usec  = tv.tv_usec;
 	pmsg->mark            = entry->skb->mark;
 	pmsg->hook            = entry->info->hook;
 	pmsg->hw_protocol     = entry->skb->protocol;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index a26404d..e78c9d7 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -186,6 +186,7 @@ static void ipt_ulog_packet(unsigned int
 	ulog_packet_msg_t *pm;
 	size_t size, copy_len;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 
 	/* ffs == find first bit set, necessary because userspace
 	 * is already shifting groupnumber, but we need unshifted.
@@ -231,13 +232,14 @@ static void ipt_ulog_packet(unsigned int
 	pm = NLMSG_DATA(nlh);
 
 	/* We might not have a timestamp, get one */
-	if (skb->tstamp.off_sec == 0)
+	if (skb->tstamp.tv64 == 0)
 		__net_timestamp((struct sk_buff *)skb);
 
 	/* copy hook, prefix, timestamp, payload, etc. */
 	pm->data_len = copy_len;
-	pm->timestamp_sec = skb->tstamp.off_sec;
-	pm->timestamp_usec = skb->tstamp.off_usec;
+	tv = ktime_to_timeval(skb->tstamp);
+	pm->timestamp_sec = tv.tv_sec;
+	pm->timestamp_usec = tv.tv_usec;
 	pm->mark = skb->mark;
 	pm->hook = hooknum;
 	if (prefix != NULL)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 28e0c65..0dc0ca0 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -255,7 +255,7 @@ static int ipv6_dest_hao(struct sk_buff 
 	ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
 	ipv6_addr_copy(&hao->addr, &tmp_addr);
 
-	if (skb->tstamp.off_sec == 0)
+	if (skb->tstamp.tv64 == 0)
 		__net_timestamp(skb);
 
 	return 1;
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index fdb30a5..66a2c41 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -195,6 +195,7 @@ ipq_build_packet_message(struct ipq_queu
 	struct sk_buff *skb;
 	struct ipq_packet_msg *pmsg;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 
 	read_lock_bh(&queue_lock);
 
@@ -239,8 +240,9 @@ ipq_build_packet_message(struct ipq_queu
 
 	pmsg->packet_id       = (unsigned long )entry;
 	pmsg->data_len        = data_len;
-	pmsg->timestamp_sec   = entry->skb->tstamp.off_sec;
-	pmsg->timestamp_usec  = entry->skb->tstamp.off_usec;
+	tv = ktime_to_timeval(entry->skb->tstamp);
+	pmsg->timestamp_sec   = tv.tv_sec;
+	pmsg->timestamp_usec  = tv.tv_usec;
 	pmsg->mark            = entry->skb->mark;
 	pmsg->hook            = entry->info->hook;
 	pmsg->hw_protocol     = entry->skb->protocol;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 15ab1e3..c311b9a 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -82,7 +82,7 @@ struct nf_ct_frag6_queue
 	struct sk_buff		*fragments;
 	int			len;
 	int			meat;
-	struct timeval		stamp;
+	ktime_t			stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -542,7 +542,7 @@ static int nf_ct_frag6_queue(struct nf_c
 		fq->fragments = skb;
 
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	fq->stamp = skb->tstamp;
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &nf_ct_frag6_mem);
 
@@ -648,7 +648,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_que
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	head->tstamp = fq->stamp;
 	head->nh.ipv6h->payload_len = htons(payload_len);
 
 	/* Yes, and fold redundant checksum back. 8) */
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 7034c54..1dde449 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -88,7 +88,7 @@ struct frag_queue
 	int			len;
 	int			meat;
 	int			iif;
-	struct timeval		stamp;
+	ktime_t			stamp;
 	unsigned int		csum;
 	__u8			last_in;	/* has first/last segment arrived? */
 #define COMPLETE		4
@@ -562,7 +562,7 @@ static void ip6_frag_queue(struct frag_q
 	if (skb->dev)
 		fq->iif = skb->dev->ifindex;
 	skb->dev = NULL;
-	skb_get_timestamp(skb, &fq->stamp);
+	fq->stamp = skb->tstamp;
 	fq->meat += skb->len;
 	atomic_add(skb->truesize, &ip6_frag_mem);
 
@@ -663,7 +663,7 @@ static int ip6_frag_reasm(struct frag_qu
 
 	head->next = NULL;
 	head->dev = dev;
-	skb_set_timestamp(head, &fq->stamp);
+	head->tstamp = fq->stamp;
 	head->nh.ipv6h->payload_len = htons(payload_len);
 	IP6CB(head)->nhoff = nhoff;
 
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index cac35a7..6c6c0a3 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1807,8 +1807,8 @@ #endif	/* CONFIG_IPX_INTERN */
 				     copied);
 	if (rc)
 		goto out_free;
-	if (skb->tstamp.off_sec)
-		skb_get_timestamp(skb, &sk->sk_stamp);
+	if (skb->tstamp.tv64)
+		sk->sk_stamp = skb->tstamp;
 
 	msg->msg_namelen = sizeof(*sipx);
 
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index b8eab0d..2f7872e 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -510,11 +510,11 @@ #endif
 		NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
 	}
 
-	if (skb->tstamp.off_sec) {
+	if (skb->tstamp.tv64) {
 		struct nfulnl_msg_packet_timestamp ts;
-
-		ts.sec = cpu_to_be64(skb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(skb->tstamp.off_usec);
+		struct timeval tv = ktime_to_timeval(skb->tstamp);
+		ts.sec = cpu_to_be64(tv.tv_sec);
+		ts.usec = cpu_to_be64(tv.tv_usec);
 
 		NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
 	}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index d9ce4a7..cfbee39 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -495,11 +495,11 @@ #endif
 		NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
 	}
 
-	if (entskb->tstamp.off_sec) {
+	if (entskb->tstamp.tv64) {
 		struct nfqnl_msg_packet_timestamp ts;
-
-		ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
+		struct timeval tv = ktime_to_timeval(entskb->tstamp);
+		ts.sec = cpu_to_be64(tv.tv_sec);
+		ts.usec = cpu_to_be64(tv.tv_usec);
 
 		NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
 	}
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 28d47e8..f9866a8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -582,6 +582,7 @@ static int tpacket_rcv(struct sk_buff *s
 	unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
 	unsigned short macoff, netoff;
 	struct sk_buff *copy_skb = NULL;
+	struct timeval tv;
 
 	if (skb->pkt_type == PACKET_LOOPBACK)
 		goto drop;
@@ -656,12 +657,13 @@ static int tpacket_rcv(struct sk_buff *s
 	h->tp_snaplen = snaplen;
 	h->tp_mac = macoff;
 	h->tp_net = netoff;
-	if (skb->tstamp.off_sec == 0) {
+	if (skb->tstamp.tv64 == 0) {
 		__net_timestamp(skb);
 		sock_enable_timestamp(sk);
 	}
-	h->tp_sec = skb->tstamp.off_sec;
-	h->tp_usec = skb->tstamp.off_usec;
+	tv = ktime_to_timeval(skb->tstamp);
+	h->tp_sec = tv.tv_sec;
+	h->tp_usec = tv.tv_usec;
 
 	sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
 	sll->sll_halen = 0;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 63ae947..a90e57a 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -805,16 +805,12 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 		/* possibly an icmp error */
 		dprintk("svc: recvfrom returned error %d\n", -err);
 	}
-	if (skb->tstamp.off_sec == 0) {
-		struct timeval tv;
-
-		tv.tv_sec = xtime.tv_sec;
-		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
-		skb_set_timestamp(skb, &tv);
+	if (skb->tstamp.tv64 == 0) {
+		skb->tstamp = ktime_get_real();
 		/* Don't enable netstamp, sunrpc doesn't
 		   need that much accuracy */
 	}
-	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+	svsk->sk_sk->sk_stamp = skb->tstamp;
 	set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
 
 	/*

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-05  7:40                         ` Eric Dumazet
@ 2007-03-05  8:00                           ` David Miller
  2007-03-05  8:21                             ` Eric Dumazet
  0 siblings, 1 reply; 39+ messages in thread
From: David Miller @ 2007-03-05  8:00 UTC (permalink / raw)
  To: dada1; +Cc: shemminger, linux.kernel, netdev

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Mon, 05 Mar 2007 08:40:03 +0100

> Here is the second version of this patch, including missing bits spoted by 
> Stephen. This is against net-2.6.22

Applied, thanks a lot.

> Note : this patch includes a bug correction in compat_sock_get_timestamp()
> where a "err = 0;" was missing (so this syscall returned -ENOENT instead of
> 0)

Grrr, good spotting.  Eric can you send me a version of just this bug
fix against 2.6.21?  I'll push that to Linus and 2.6.x-stable.

I guess most applications don't even bother to check the getsockopt()
return value. :-)

Thanks a lot!

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-05  8:00                           ` David Miller
@ 2007-03-05  8:21                             ` Eric Dumazet
  2007-03-05  8:49                               ` David Miller
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-05  8:21 UTC (permalink / raw)
  To: David Miller; +Cc: shemminger, linux.kernel, netdev

David Miller a écrit :
> From: Eric Dumazet <dada1@cosmosbay.com>
> Date: Mon, 05 Mar 2007 08:40:03 +0100
> 
>> Here is the second version of this patch, including missing bits spoted by 
>> Stephen. This is against net-2.6.22
> 
> Applied, thanks a lot.
> 
>> Note : this patch includes a bug correction in compat_sock_get_timestamp()
>> where a "err = 0;" was missing (so this syscall returned -ENOENT instead of
>> 0)
> 
> Grrr, good spotting.  Eric can you send me a version of just this bug
> fix against 2.6.21?  I'll push that to Linus and 2.6.x-stable.

Yes I will do it. But, are your sure its really used ?

I dont know very much this compat stuff, but I found 
compat_sock_get_timestamp() only called from net/x25/af_x25.c

I wonder how a 32 bit task on x86_64 can enter this compat code on other sockets ?


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : convert network timestamps to ktime_t
  2007-03-05  8:21                             ` Eric Dumazet
@ 2007-03-05  8:49                               ` David Miller
  0 siblings, 0 replies; 39+ messages in thread
From: David Miller @ 2007-03-05  8:49 UTC (permalink / raw)
  To: dada1; +Cc: shemminger, linux.kernel, netdev

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Mon, 05 Mar 2007 09:21:30 +0100

> I dont know very much this compat stuff, but I found 
> compat_sock_get_timestamp() only called from net/x25/af_x25.c

Good point, I thought for some reason that this function
was used for all SO_TIMESTAMP handling, but looking again
I see that the main stuff is handled in put_cmsg() compat
code.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution
  2007-03-02 14:38               ` [PATCH] NET : convert network timestamps to ktime_t Eric Dumazet
  2007-03-02 16:27                 ` Stephen Hemminger
  2007-03-02 21:02                 ` Stephen Hemminger
@ 2007-03-08 14:17                 ` Eric Dumazet
  2007-03-08 16:28                   ` Patrick McHardy
                                     ` (2 more replies)
  2 siblings, 3 replies; 39+ messages in thread
From: Eric Dumazet @ 2007-03-08 14:17 UTC (permalink / raw)
  To: David Miller; +Cc: Stephen Hemminger, netdev

[-- Attachment #1: Type: text/plain, Size: 2235 bytes --]

Hi David

This patch is for net-2.6.22 git tree.

A separate patch will follow for  SO_TIMESTAMPNS / SCM_TIMESTAMPNS support.

Thank you

[PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec 
resolution

Now network timestamps use ktime_t infrastructure, we can add a new ioctl() 
SIOCGSTAMPNS  command to get timestamps in 'struct timespec'.
User programs can thus access to nanosecond resolution.

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
CC: Stephen Hemminger <shemminger@linux-foundation.org>

 fs/compat_ioctl.c             |   18 ++++++++++++++++++
 include/asm-alpha/sockios.h   |    3 ++-
 include/asm-arm/sockios.h     |    3 ++-
 include/asm-arm26/sockios.h   |    3 ++-
 include/asm-avr32/sockios.h   |    3 ++-
 include/asm-cris/sockios.h    |    3 ++-
 include/asm-frv/sockios.h     |    3 ++-
 include/asm-h8300/sockios.h   |    3 ++-
 include/asm-i386/sockios.h    |    3 ++-
 include/asm-ia64/sockios.h    |    3 ++-
 include/asm-m32r/sockios.h    |    3 ++-
 include/asm-m68k/sockios.h    |    3 ++-
 include/asm-mips/sockios.h    |    3 ++-
 include/asm-parisc/sockios.h  |    3 ++-
 include/asm-powerpc/sockios.h |    3 ++-
 include/asm-s390/sockios.h    |    3 ++-
 include/asm-sh/sockios.h      |    3 ++-
 include/asm-sh64/sockios.h    |    3 ++-
 include/asm-sparc/sockios.h   |    3 ++-
 include/asm-sparc64/sockios.h |    3 ++-
 include/asm-v850/sockios.h    |    3 ++-
 include/asm-x86_64/sockios.h  |    3 ++-
 include/asm-xtensa/sockios.h  |    3 ++-
 include/net/compat.h          |    1 +
 include/net/sock.h            |    1 +
 net/appletalk/ddp.c           |    3 +++
 net/atm/ioctl.c               |    3 +++
 net/ax25/af_ax25.c            |    4 ++++
 net/compat.c                  |   24 ++++++++++++++++++++++++
 net/core/sock.c               |   16 ++++++++++++++++
 net/econet/af_econet.c        |    3 +++
 net/ipv4/af_inet.c            |    3 +++
 net/ipv6/af_inet6.c           |    3 +++
 net/netrom/af_netrom.c        |    6 ++++++
 net/packet/af_packet.c        |    2 ++
 net/rose/af_rose.c            |    3 +++
 net/wanrouter/af_wanpipe.c    |    3 +++
 net/x25/af_x25.c              |   12 ++++++++++++
 38 files changed, 149 insertions(+), 22 deletions(-)

[-- Attachment #2: SIOCGSTAMPNS.patch --]
[-- Type: text/plain, Size: 19596 bytes --]

diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index c81c958..e9e5965 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -266,6 +266,23 @@ static int do_siocgstamp(unsigned int fd
 	return err;
 }
 
+static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct compat_timespec __user *up = compat_ptr(arg);
+	struct timespec kts;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&kts);
+	set_fs(old_fs);
+	if (!err) {
+		err = put_user(kts.tv_sec, &up->tv_sec);
+		err |= __put_user(kts.tv_nsec, &up->tv_nsec);
+	}
+	return err;
+}
+
 struct ifmap32 {
 	compat_ulong_t mem_start;
 	compat_ulong_t mem_end;
@@ -2437,6 +2454,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc)
 /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
 HANDLE_IOCTL(SIOCRTMSG, ret_einval)
 HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
+HANDLE_IOCTL(SIOCGSTAMPNS, do_siocgstampns)
 #endif
 #ifdef CONFIG_BLOCK
 HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
diff --git a/include/asm-alpha/sockios.h b/include/asm-alpha/sockios.h
index e4961a7..7932c7a 100644
--- a/include/asm-alpha/sockios.h
+++ b/include/asm-alpha/sockios.h
@@ -10,6 +10,7 @@ #define SIOCATMARK	_IOR('s', 7, int)
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_ALPHA_SOCKIOS_H */
diff --git a/include/asm-arm/sockios.h b/include/asm-arm/sockios.h
index 77c3408..a2588a2 100644
--- a/include/asm-arm/sockios.h
+++ b/include/asm-arm/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-arm26/sockios.h b/include/asm-arm26/sockios.h
index 77c3408..a2588a2 100644
--- a/include/asm-arm26/sockios.h
+++ b/include/asm-arm26/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-avr32/sockios.h b/include/asm-avr32/sockios.h
index 84f3d65..0802d74 100644
--- a/include/asm-avr32/sockios.h
+++ b/include/asm-avr32/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ASM_AVR32_SOCKIOS_H */
diff --git a/include/asm-cris/sockios.h b/include/asm-cris/sockios.h
index 6c4012f..cfe7bfe 100644
--- a/include/asm-cris/sockios.h
+++ b/include/asm-cris/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-frv/sockios.h b/include/asm-frv/sockios.h
index 8a6e4b2..5dbdd13 100644
--- a/include/asm-frv/sockios.h
+++ b/include/asm-frv/sockios.h
@@ -7,7 +7,8 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_SOCKIOS__ */
 
diff --git a/include/asm-h8300/sockios.h b/include/asm-h8300/sockios.h
index d005d95..e9c7ec8 100644
--- a/include/asm-h8300/sockios.h
+++ b/include/asm-h8300/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ARCH_H8300_SOCKIOS__ */
diff --git a/include/asm-i386/sockios.h b/include/asm-i386/sockios.h
index 6b747f8..ff528c7 100644
--- a/include/asm-i386/sockios.h
+++ b/include/asm-i386/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-ia64/sockios.h b/include/asm-ia64/sockios.h
index cf94857..15c9246 100644
--- a/include/asm-ia64/sockios.h
+++ b/include/asm-ia64/sockios.h
@@ -14,6 +14,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_IA64_SOCKIOS_H */
diff --git a/include/asm-m32r/sockios.h b/include/asm-m32r/sockios.h
index f89962e..6c1fb9b 100644
--- a/include/asm-m32r/sockios.h
+++ b/include/asm-m32r/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif  /* _ASM_M32R_SOCKIOS_H */
diff --git a/include/asm-m68k/sockios.h b/include/asm-m68k/sockios.h
index 9b9ed97..c04a239 100644
--- a/include/asm-m68k/sockios.h
+++ b/include/asm-m68k/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __ARCH_M68K_SOCKIOS__ */
diff --git a/include/asm-mips/sockios.h b/include/asm-mips/sockios.h
index 87a50bf..ed1a5f7 100644
--- a/include/asm-mips/sockios.h
+++ b/include/asm-mips/sockios.h
@@ -20,6 +20,7 @@ #define SIOCATMARK	_IOR('s', 7, int)
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* _ASM_SOCKIOS_H */
diff --git a/include/asm-parisc/sockios.h b/include/asm-parisc/sockios.h
index aace496..dabfbc7 100644
--- a/include/asm-parisc/sockios.h
+++ b/include/asm-parisc/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-powerpc/sockios.h b/include/asm-powerpc/sockios.h
index 590078d..55cef76 100644
--- a/include/asm-powerpc/sockios.h
+++ b/include/asm-powerpc/sockios.h
@@ -14,6 +14,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif	/* _ASM_POWERPC_SOCKIOS_H */
diff --git a/include/asm-s390/sockios.h b/include/asm-s390/sockios.h
index 412aeb4..f4fc16c 100644
--- a/include/asm-s390/sockios.h
+++ b/include/asm-s390/sockios.h
@@ -15,6 +15,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-sh/sockios.h b/include/asm-sh/sockios.h
index 08a71df..cf8b96b 100644
--- a/include/asm-sh/sockios.h
+++ b/include/asm-sh/sockios.h
@@ -9,5 +9,6 @@ #define SIOCATMARK	_IOR('s', 7, int)
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp (timeval) */
+#define SIOCGSTAMPNS	_IOR('s', 101, struct timespec) /* Get stamp (timespec) */
 #endif /* __ASM_SH_SOCKIOS_H */
diff --git a/include/asm-sh64/sockios.h b/include/asm-sh64/sockios.h
index 1ae23ae..419e76f 100644
--- a/include/asm-sh64/sockios.h
+++ b/include/asm-sh64/sockios.h
@@ -20,5 +20,6 @@ #define SIOCATMARK	_IOR('s', 7, int)
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp (timeval) */
+#define SIOCGSTAMPNS	_IOR('s', 101, struct timespec) /* Get stamp (timespec) */
 #endif /* __ASM_SH64_SOCKIOS_H */
diff --git a/include/asm-sparc/sockios.h b/include/asm-sparc/sockios.h
index 0c01b59..990ea74 100644
--- a/include/asm-sparc/sockios.h
+++ b/include/asm-sparc/sockios.h
@@ -7,7 +7,8 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* !(_ASM_SPARC_SOCKIOS_H) */
 
diff --git a/include/asm-sparc64/sockios.h b/include/asm-sparc64/sockios.h
index 6735bab..c7d9900 100644
--- a/include/asm-sparc64/sockios.h
+++ b/include/asm-sparc64/sockios.h
@@ -7,7 +7,8 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* !(_ASM_SPARC64_SOCKIOS_H) */
 
diff --git a/include/asm-v850/sockios.h b/include/asm-v850/sockios.h
index cf4874c..823e106 100644
--- a/include/asm-v850/sockios.h
+++ b/include/asm-v850/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif /* __V850_SOCKIOS_H__ */
diff --git a/include/asm-x86_64/sockios.h b/include/asm-x86_64/sockios.h
index 2eefd10..d726ba2 100644
--- a/include/asm-x86_64/sockios.h
+++ b/include/asm-x86_64/sockios.h
@@ -7,6 +7,7 @@ #define SIOCSPGRP	0x8902
 #define FIOGETOWN	0x8903
 #define SIOCGPGRP	0x8904
 #define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif
diff --git a/include/asm-xtensa/sockios.h b/include/asm-xtensa/sockios.h
index 20d2ba1..efe0af3 100644
--- a/include/asm-xtensa/sockios.h
+++ b/include/asm-xtensa/sockios.h
@@ -25,6 +25,7 @@ #define SIOCATMARK	_IOR('s', 7, int)
 #define SIOCSPGRP	_IOW('s', 8, pid_t)
 #define SIOCGPGRP	_IOR('s', 9, pid_t)
 
-#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
 
 #endif	/* _XTENSA_SOCKIOS_H */
diff --git a/include/net/compat.h b/include/net/compat.h
index 9859b60..406db24 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -25,6 +25,7 @@ struct compat_cmsghdr {
 };
 
 extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
+extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
 
 #else /* defined(CONFIG_COMPAT) */
 #define compat_msghdr	msghdr		/* to avoid compiler warnings */
diff --git a/include/net/sock.h b/include/net/sock.h
index 2974bac..d093e49 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1329,6 +1329,7 @@ #endif
 
 extern void sock_enable_timestamp(struct sock *sk);
 extern int sock_get_timestamp(struct sock *, struct timeval __user *);
+extern int sock_get_timestampns(struct sock *, struct timespec __user *);
 
 /* 
  *	Enable debug/info messages 
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 113c175..53247be 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1768,6 +1768,9 @@ static int atalk_ioctl(struct socket *so
 		case SIOCGSTAMP:
 			rc = sock_get_timestamp(sk, argp);
 			break;
+		case SIOCGSTAMPNS:
+			rc = sock_get_timestampns(sk, argp);
+			break;
 		/* Routing */
 		case SIOCADDRT:
 		case SIOCDELRT:
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 8ccee45..7afd8e7 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -82,6 +82,9 @@ int vcc_ioctl(struct socket *sock, unsig
 		case SIOCGSTAMP: /* borrowed from IP */
 			error = sock_get_timestamp(sk, argp);
 			goto done;
+		case SIOCGSTAMPNS: /* borrowed from IP */
+			error = sock_get_timestampns(sk, argp);
+			goto done;
 		case ATM_SETSC:
 			printk(KERN_WARNING "ATM_SETSC is obsolete\n");
 			error = 0;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 1c07c6a..62605dc 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1711,6 +1711,10 @@ static int ax25_ioctl(struct socket *soc
 		res = sock_get_timestamp(sk, argp);
 		break;
 
+	case SIOCGSTAMPNS:
+		res = sock_get_timestampns(sk, argp);
+		break;
+
 	case SIOCAX25ADDUID:	/* Add a uid to the uid/call map table */
 	case SIOCAX25DELUID:	/* Delete a uid from the uid/call map table */
 	case SIOCAX25GETUID: {
diff --git a/net/compat.c b/net/compat.c
index 17c2710..2fc6d9b 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -564,6 +564,30 @@ int compat_sock_get_timestamp(struct soc
 }
 EXPORT_SYMBOL(compat_sock_get_timestamp);
 
+int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
+{
+	struct compat_timespec __user *ctv =
+			(struct compat_timespec __user*) userstamp;
+	int err = -ENOENT;
+	struct timespec ts;
+
+	if (!sock_flag(sk, SOCK_TIMESTAMP))
+		sock_enable_timestamp(sk);
+	ts = ktime_to_timespec(sk->sk_stamp);
+	if (ts.tv_sec == -1)
+		return err;
+	if (ts.tv_sec == 0) {
+		sk->sk_stamp = ktime_get_real();
+		ts = ktime_to_timespec(sk->sk_stamp);
+	}
+	err = 0;
+	if (put_user(ts.tv_sec, &ctv->tv_sec) ||
+			put_user(ts.tv_nsec, &ctv->tv_nsec))
+		err = -EFAULT;
+	return err;
+}
+EXPORT_SYMBOL(compat_sock_get_timestampns);
+
 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
 				char __user *optval, int __user *optlen)
 {
diff --git a/net/core/sock.c b/net/core/sock.c
index 6c92ec4..c1fc8cc 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1567,6 +1567,22 @@ int sock_get_timestamp(struct sock *sk, 
 }
 EXPORT_SYMBOL(sock_get_timestamp);
 
+int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
+{
+	struct timespec ts;
+	if (!sock_flag(sk, SOCK_TIMESTAMP))
+		sock_enable_timestamp(sk);
+	ts = ktime_to_timespec(sk->sk_stamp);
+	if (ts.tv_sec == -1)
+		return -ENOENT;
+	if (ts.tv_sec == 0) {
+		sk->sk_stamp = ktime_get_real();
+		ts = ktime_to_timespec(sk->sk_stamp);
+	}
+	return copy_to_user(userstamp, &ts, sizeof(ts)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL(sock_get_timestampns);
+
 void sock_enable_timestamp(struct sock *sk)
 {
 	if (!sock_flag(sk, SOCK_TIMESTAMP)) {
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index f573edd..487f879 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -727,6 +727,9 @@ static int econet_ioctl(struct socket *s
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, argp);
 
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, argp);
+
 		case SIOCSIFADDR:
 		case SIOCGIFADDR:
 			return ec_dev_ioctl(sock, cmd, argp);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index cf358c8..df41856 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -755,6 +755,9 @@ int inet_ioctl(struct socket *sock, unsi
 		case SIOCGSTAMP:
 			err = sock_get_timestamp(sk, (struct timeval __user *)arg);
 			break;
+		case SIOCGSTAMPNS:
+			err = sock_get_timestampns(sk, (struct timespec __user *)arg);
+			break;
 		case SIOCADDRT:
 		case SIOCDELRT:
 		case SIOCRTMSG:
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index fed3758..2ff0704 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -443,6 +443,9 @@ int inet6_ioctl(struct socket *sock, uns
 	case SIOCGSTAMP:
 		return sock_get_timestamp(sk, (struct timeval __user *)arg);
 
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *)arg);
+
 	case SIOCADDRT:
 	case SIOCDELRT:
 
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index bf9837d..a54e7ef 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1209,6 +1209,12 @@ static int nr_ioctl(struct socket *sock,
 		release_sock(sk);
 		return ret;
 
+	case SIOCGSTAMPNS:
+		lock_sock(sk);
+		ret = sock_get_timestampns(sk, argp);
+		release_sock(sk);
+		return ret;
+
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
 	case SIOCGIFDSTADDR:
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index f9866a8..6f8c72d 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1545,6 +1545,8 @@ static int packet_ioctl(struct socket *s
 		}
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, (struct timeval __user *)arg);
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, (struct timespec __user *)arg);
 
 #ifdef CONFIG_INET
 		case SIOCADDRT:
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 8c34f1c..8fa7e47 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1272,6 +1272,9 @@ static int rose_ioctl(struct socket *soc
 	case SIOCGSTAMP:
 		return sock_get_timestamp(sk, (struct timeval __user *) argp);
 
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *) argp);
+
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
 	case SIOCGIFDSTADDR:
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 41d7e32..02c09e7 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -1770,6 +1770,9 @@ static int wanpipe_ioctl(struct socket *
 		case SIOCGSTAMP:
 			return sock_get_timestamp(sk, (struct timeval __user *)arg);
 
+		case SIOCGSTAMPNS:
+			return sock_get_timestampns(sk, (struct timespec __user *)arg);
+
 		case SIOC_WANPIPE_CHECK_TX:
 
 			return atomic_read(&sk->sk_wmem_alloc);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index e62ba41..a198843 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1280,6 +1280,12 @@ static int x25_ioctl(struct socket *sock
 				rc = sock_get_timestamp(sk,
 						(struct timeval __user *)argp);
 			break;
+		case SIOCGSTAMPNS:
+			rc = -EINVAL;
+			if (sk)
+				rc = sock_get_timestampns(sk,
+						(struct timespec __user *)argp);
+			break;
 		case SIOCGIFADDR:
 		case SIOCSIFADDR:
 		case SIOCGIFDSTADDR:
@@ -1521,6 +1527,12 @@ static int compat_x25_ioctl(struct socke
 			rc = compat_sock_get_timestamp(sk,
 					(struct timeval __user*)argp);
 		break;
+	case SIOCGSTAMPNS:
+		rc = -EINVAL;
+		if (sk)
+			rc = compat_sock_get_timestampns(sk,
+					(struct timespec __user*)argp);
+		break;
 	case SIOCGIFADDR:
 	case SIOCSIFADDR:
 	case SIOCGIFDSTADDR:

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution
  2007-03-08 14:17                 ` [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution Eric Dumazet
@ 2007-03-08 16:28                   ` Patrick McHardy
  2007-03-08 16:42                     ` Eric Dumazet
  2007-03-09  4:39                   ` David Miller
  2007-03-09 18:39                   ` [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support Eric Dumazet
  2 siblings, 1 reply; 39+ messages in thread
From: Patrick McHardy @ 2007-03-08 16:28 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, Stephen Hemminger, netdev

Eric Dumazet wrote:
> --- a/include/asm-mips/sockios.h
> +++ b/include/asm-mips/sockios.h
> @@ -20,6 +20,7 @@ #define SIOCATMARK	_IOR('s', 7, int)
>  #define SIOCSPGRP	_IOW('s', 8, pid_t)
>  #define SIOCGPGRP	_IOR('s', 9, pid_t)
>  
> -#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
> +#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
> +#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */


You might want to CC linux-arch or the architecture maintainers.
Last time I changed something in this area I got complaints
because it affected syscall emulation for non-Linux binaries
or something like that.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution
  2007-03-08 16:28                   ` Patrick McHardy
@ 2007-03-08 16:42                     ` Eric Dumazet
  2007-03-08 16:45                       ` Patrick McHardy
  0 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-08 16:42 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: David Miller, Stephen Hemminger, netdev

On Thursday 08 March 2007 17:28, Patrick McHardy wrote:
> Eric Dumazet wrote:
> > --- a/include/asm-mips/sockios.h
> > +++ b/include/asm-mips/sockios.h
> > @@ -20,6 +20,7 @@ #define SIOCATMARK	_IOR('s', 7, int)
> >  #define SIOCSPGRP	_IOW('s', 8, pid_t)
> >  #define SIOCGPGRP	_IOR('s', 9, pid_t)
> >
> > -#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
> > +#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
> > +#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
>
> You might want to CC linux-arch or the architecture maintainers.
> Last time I changed something in this area I got complaints
> because it affected syscall emulation for non-Linux binaries
> or something like that.

I really dont see how this change could break syscall emulation for non-Linux 
binaries. SIOCGSTAMP{NS} is linux specific.

Could you please give the context of your past problems ?

Thank you

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution
  2007-03-08 16:42                     ` Eric Dumazet
@ 2007-03-08 16:45                       ` Patrick McHardy
  0 siblings, 0 replies; 39+ messages in thread
From: Patrick McHardy @ 2007-03-08 16:45 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, Stephen Hemminger, netdev

Eric Dumazet wrote:
> On Thursday 08 March 2007 17:28, Patrick McHardy wrote:
>>>--- a/include/asm-mips/sockios.h
>>>+++ b/include/asm-mips/sockios.h
>>>@@ -20,6 +20,7 @@ #define SIOCATMARK	_IOR('s', 7, int)
>>> #define SIOCSPGRP	_IOW('s', 8, pid_t)
>>> #define SIOCGPGRP	_IOR('s', 9, pid_t)
>>>
>>>-#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
>>>+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
>>>+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
>>
>>You might want to CC linux-arch or the architecture maintainers.
>>Last time I changed something in this area I got complaints
>>because it affected syscall emulation for non-Linux binaries
>>or something like that.
> 
> 
> I really dont see how this change could break syscall emulation for non-Linux 
> binaries. SIOCGSTAMP{NS} is linux specific.
> 
> Could you please give the context of your past problems ?


It was when I added the SO_SNDBUFFORCE/SO_RCVBUFFORCE setsockopt
options. IIRC the values I chose where already used differently
for non-Linux MIPS binaries.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution
  2007-03-08 14:17                 ` [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution Eric Dumazet
  2007-03-08 16:28                   ` Patrick McHardy
@ 2007-03-09  4:39                   ` David Miller
  2007-03-09 18:39                   ` [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support Eric Dumazet
  2 siblings, 0 replies; 39+ messages in thread
From: David Miller @ 2007-03-09  4:39 UTC (permalink / raw)
  To: dada1; +Cc: shemminger, netdev, linux-arch

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Thu, 8 Mar 2007 15:17:57 +0100

> [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec 
> resolution
> 
> Now network timestamps use ktime_t infrastructure, we can add a new ioctl() 
> SIOCGSTAMPNS  command to get timestamps in 'struct timespec'.
> User programs can thus access to nanosecond resolution.
> 
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
> CC: Stephen Hemminger <shemminger@linux-foundation.org>

Applied, thanks Eric.

This patch points out a potential compat layer problem which sh64.  It
defines the SIOCGSTAMP (and not SIOCGSTAMPNS) ioctls as not constants,
but rather constant values that depend upon the size of the structure
passed in.

But the compat bridges for these timestamp ioctls simply match on the
native ioctl value and then pass it in unchanged to the real handler.
That won't work for sh64 compat layer for 32-bit sh applications.

That's what they get for being different :-)

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support
  2007-03-08 14:17                 ` [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution Eric Dumazet
  2007-03-08 16:28                   ` Patrick McHardy
  2007-03-09  4:39                   ` David Miller
@ 2007-03-09 18:39                   ` Eric Dumazet
  2007-03-09 22:17                     ` David Miller
  2 siblings, 1 reply; 39+ messages in thread
From: Eric Dumazet @ 2007-03-09 18:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-arch

[-- Attachment #1: Type: text/plain, Size: 784 bytes --]

Hi David

This patch is against net-2.6.22 git tree.

Thank you

[PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support

Now that network timestamps use ktime_t infrastructure, we can add a new 
SOL_SOCKET sockopt  SO_TIMESTAMPNS.

This command is similar to SO_TIMESTAMP, but permits transmission of 
a 'timespec struct' instead of a 'timeval struct' control message. 
(nanosecond resolution instead of microsecond)

Control message is labelled SCM_TIMESTAMPNS instead of SCM_TIMESTAMP

A socket cannot mix SO_TIMESTAMP and SO_TIMESTAMPNS : the two modes are 
mutually exclusive.

sock_recv_timestamp() became too big to be fully inlined so I added a 
__sock_recv_timestamp() helper function.

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
CC: linux-arch@vger.kernel.org


[-- Attachment #2: SCM_TIMESTAMPNS.patch --]
[-- Type: text/plain, Size: 12346 bytes --]

diff --git a/include/net/sock.h b/include/net/sock.h
index 5124657..390c047 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -390,6 +390,7 @@ enum sock_flags {
 	SOCK_USE_WRITE_QUEUE, /* whether to call sk->sk_write_space in sock_wfree */
 	SOCK_DBG, /* %SO_DEBUG setting */
 	SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */
+	SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */
 	SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
 	SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
 };
@@ -1283,21 +1284,17 @@ static inline int sock_intr_errno(long t
 	return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR;
 }
 
+extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
+	struct sk_buff *skb);
+
 static __inline__ void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
 	ktime_t kt = skb->tstamp;
 
-	if (sock_flag(sk, SOCK_RCVTSTAMP)) {
-		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, SO_TIMESTAMP, sizeof(tv), &tv);
-	} else
+	if (sock_flag(sk, SOCK_RCVTSTAMP))
+		__sock_recv_timestamp(msg, sk, skb);
+	else
 		sk->sk_stamp = kt;
 }
 
diff --git a/net/compat.c b/net/compat.c
index 0e40756..9a0f5f2 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -215,6 +215,7 @@ Efault:
 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
 {
 	struct compat_timeval ctv;
+	struct compat_timespec cts;
 	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
 	struct compat_cmsghdr cmhdr;
 	int cmlen;
@@ -229,7 +230,14 @@ int put_cmsg_compat(struct msghdr *kmsg,
 		ctv.tv_sec = tv->tv_sec;
 		ctv.tv_usec = tv->tv_usec;
 		data = &ctv;
-		len = sizeof(struct compat_timeval);
+		len = sizeof(ctv);
+	}
+	if (level == SOL_SOCKET && type == SO_TIMESTAMPNS) {
+		struct timespec *ts = (struct timespec *)data;
+		cts.tv_sec = ts->tv_sec;
+		cts.tv_nsec = ts->tv_nsec;
+		data = &cts;
+		len = sizeof(cts);
 	}
 
 	cmlen = CMSG_COMPAT_LEN(len);
diff --git a/net/core/sock.c b/net/core/sock.c
index a016661..d4c89f8 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -521,11 +521,18 @@ #endif
 		break;
 
 	case SO_TIMESTAMP:
+	case SO_TIMESTAMPNS:
 		if (valbool)  {
+			if (optname == SO_TIMESTAMP)
+				sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
+			else
+				sock_set_flag(sk, SOCK_RCVTSTAMPNS);
 			sock_set_flag(sk, SOCK_RCVTSTAMP);
 			sock_enable_timestamp(sk);
-		} else
+		} else {
 			sock_reset_flag(sk, SOCK_RCVTSTAMP);
+			sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
+		}
 		break;
 
 	case SO_RCVLOWAT:
@@ -715,7 +722,12 @@ int sock_getsockopt(struct socket *sock,
 		break;
 
 	case SO_TIMESTAMP:
-		v.val = sock_flag(sk, SOCK_RCVTSTAMP);
+		v.val = sock_flag(sk, SOCK_RCVTSTAMP) &&
+				!sock_flag(sk, SOCK_RCVTSTAMPNS);
+		break;
+
+	case SO_TIMESTAMPNS:
+		v.val = sock_flag(sk, SOCK_RCVTSTAMPNS);
 		break;
 
 	case SO_RCVTIMEO:
diff --git a/net/socket.c b/net/socket.c
index 724b9cd..15e4327 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -585,6 +585,35 @@ int kernel_sendmsg(struct socket *sock, 
 	return result;
 }
 
+/*
+ * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
+ */
+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)) {
+		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);
+	}
+}
+
 static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 				 struct msghdr *msg, size_t size, int flags)
 {
diff --git a/include/asm-alpha/socket.h b/include/asm-alpha/socket.h
index d22ab97..1fede7f 100644
--- a/include/asm-alpha/socket.h
+++ b/include/asm-alpha/socket.h
@@ -52,6 +52,8 @@ #define SCM_TIMESTAMP		SO_TIMESTAMP
 
 #define SO_PEERSEC		30
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		19
diff --git a/include/asm-arm/socket.h b/include/asm-arm/socket.h
index 19f7df7..65a1a64 100644
--- a/include/asm-arm/socket.h
+++ b/include/asm-arm/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-arm26/socket.h b/include/asm-arm26/socket.h
index 19f7df7..65a1a64 100644
--- a/include/asm-arm26/socket.h
+++ b/include/asm-arm26/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-avr32/socket.h b/include/asm-avr32/socket.h
index 543229d..a0d0507 100644
--- a/include/asm-avr32/socket.h
+++ b/include/asm-avr32/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* __ASM_AVR32_SOCKET_H */
diff --git a/include/asm-cris/socket.h b/include/asm-cris/socket.h
index 01cfdf1..5b18dfd 100644
--- a/include/asm-cris/socket.h
+++ b/include/asm-cris/socket.h
@@ -51,6 +51,8 @@ #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
 
diff --git a/include/asm-frv/socket.h b/include/asm-frv/socket.h
index 31db18f..a823bef 100644
--- a/include/asm-frv/socket.h
+++ b/include/asm-frv/socket.h
@@ -49,6 +49,8 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
 
diff --git a/include/asm-h8300/socket.h b/include/asm-h8300/socket.h
index ebc830f..39911d8 100644
--- a/include/asm-h8300/socket.h
+++ b/include/asm-h8300/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-i386/socket.h b/include/asm-i386/socket.h
index 5755d57..99ca648 100644
--- a/include/asm-i386/socket.h
+++ b/include/asm-i386/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-ia64/socket.h b/include/asm-ia64/socket.h
index d638ef3..9e42ce4 100644
--- a/include/asm-ia64/socket.h
+++ b/include/asm-ia64/socket.h
@@ -58,5 +58,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_IA64_SOCKET_H */
diff --git a/include/asm-m32r/socket.h b/include/asm-m32r/socket.h
index acdf748..793d5d3 100644
--- a/include/asm-m32r/socket.h
+++ b/include/asm-m32r/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_M32R_SOCKET_H */
diff --git a/include/asm-m68k/socket.h b/include/asm-m68k/socket.h
index a5966ec..6d21b90 100644
--- a/include/asm-m68k/socket.h
+++ b/include/asm-m68k/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h
index 36ebe4e..9594568 100644
--- a/include/asm-mips/socket.h
+++ b/include/asm-mips/socket.h
@@ -70,6 +70,8 @@ #define SO_PEERSEC		30
 #define SO_SNDBUFFORCE		31
 #define SO_RCVBUFFORCE		33
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-parisc/socket.h b/include/asm-parisc/socket.h
index ce2eae1..99e868f 100644
--- a/include/asm-parisc/socket.h
+++ b/include/asm-parisc/socket.h
@@ -33,6 +33,8 @@ #define SO_PASSCRED	0x4010
 #define SO_PEERCRED	0x4011
 #define SO_TIMESTAMP	0x4012
 #define SCM_TIMESTAMP	SO_TIMESTAMP
+#define SO_TIMESTAMPNS	0x4013
+#define SCM_TIMESTAMPNS	SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x4016
diff --git a/include/asm-powerpc/socket.h b/include/asm-powerpc/socket.h
index c8b1da5..403e9fd 100644
--- a/include/asm-powerpc/socket.h
+++ b/include/asm-powerpc/socket.h
@@ -56,5 +56,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif	/* _ASM_POWERPC_SOCKET_H */
diff --git a/include/asm-s390/socket.h b/include/asm-s390/socket.h
index 1778a49..1161ebe 100644
--- a/include/asm-s390/socket.h
+++ b/include/asm-s390/socket.h
@@ -57,5 +57,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-sh/socket.h b/include/asm-sh/socket.h
index ca70362..c48d6fc 100644
--- a/include/asm-sh/socket.h
+++ b/include/asm-sh/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* __ASM_SH_SOCKET_H */
diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h
index f6c4e5b..d77768e 100644
--- a/include/asm-sparc/socket.h
+++ b/include/asm-sparc/socket.h
@@ -49,6 +49,8 @@ #define SCM_TIMESTAMP		SO_TIMESTAMP
 
 #define SO_PEERSEC		0x001e
 #define SO_PASSSEC		0x001f
+#define SO_TIMESTAMPNS		0x0020
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
diff --git a/include/asm-sparc64/socket.h b/include/asm-sparc64/socket.h
index 754d46a..1bd9f52 100644
--- a/include/asm-sparc64/socket.h
+++ b/include/asm-sparc64/socket.h
@@ -49,6 +49,8 @@ #define SCM_TIMESTAMP		SO_TIMESTAMP
 
 #define SO_PEERSEC		0x001e
 #define SO_PASSSEC		0x001f
+#define SO_TIMESTAMPNS		0x0020
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
diff --git a/include/asm-v850/socket.h b/include/asm-v850/socket.h
index 0dfe55a..a4c2493 100644
--- a/include/asm-v850/socket.h
+++ b/include/asm-v850/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* __V850_SOCKET_H__ */
diff --git a/include/asm-x86_64/socket.h b/include/asm-x86_64/socket.h
index b467026..90af60c 100644
--- a/include/asm-x86_64/socket.h
+++ b/include/asm-x86_64/socket.h
@@ -49,5 +49,7 @@ #define SO_ACCEPTCONN		30
 
 #define SO_PEERSEC             31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif /* _ASM_SOCKET_H */
diff --git a/include/asm-xtensa/socket.h b/include/asm-xtensa/socket.h
index 971d231..1f5aeac 100644
--- a/include/asm-xtensa/socket.h
+++ b/include/asm-xtensa/socket.h
@@ -60,5 +60,7 @@ #define SCM_TIMESTAMP		SO_TIMESTAMP
 #define SO_ACCEPTCONN		30
 #define SO_PEERSEC		31
 #define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
 
 #endif	/* _XTENSA_SOCKET_H */

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support
  2007-03-09 18:39                   ` [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support Eric Dumazet
@ 2007-03-09 22:17                     ` David Miller
  0 siblings, 0 replies; 39+ messages in thread
From: David Miller @ 2007-03-09 22:17 UTC (permalink / raw)
  To: dada1; +Cc: netdev, linux-arch

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Fri, 9 Mar 2007 19:39:42 +0100

> [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support
> 
> Now that network timestamps use ktime_t infrastructure, we can add a new 
> SOL_SOCKET sockopt  SO_TIMESTAMPNS.
> 
> This command is similar to SO_TIMESTAMP, but permits transmission of 
> a 'timespec struct' instead of a 'timeval struct' control message. 
> (nanosecond resolution instead of microsecond)
> 
> Control message is labelled SCM_TIMESTAMPNS instead of SCM_TIMESTAMP
> 
> A socket cannot mix SO_TIMESTAMP and SO_TIMESTAMPNS : the two modes are 
> mutually exclusive.
> 
> sock_recv_timestamp() became too big to be fully inlined so I added a 
> __sock_recv_timestamp() helper function.
> 
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
> CC: linux-arch@vger.kernel.org
> 

Applied, thanks for following up on all of this nanosecond
timestamp work.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-26 14:17     ` John
@ 2007-02-28 11:23       ` John
  0 siblings, 0 replies; 39+ messages in thread
From: John @ 2007-02-28 11:23 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andi Kleen, johnstul, mingo, zippel, tglx, akpm, jbohac, linux.kernel

John wrote:

> Andi Kleen wrote:
> 
>> John wrote:
>>
>>> My app expects a stream of UDP datagrams containing compressed video.
>>> These datagrams have been time stamped by the source using a high
>>> resolution clock.
>>
>> Why do you need another time stamp then?
> 
> Source and receiver do not share a common clock. Thus, I have to monitor
> clock skew. If I simply use the time stamps produced by the source, my
> buffer will eventually underflow or overflow.
> 
> As far as I have seen, clock skew is on the order of ±10^-5, i.e. when
> the source thinks 100000 seconds have elapsed, the receiver thinks
> 100001 seconds have elapsed.

I've considered running NTP to synchronize the clocks, but I'm afraid it 
wouldn't help, for several reasons:

1) The 40.5 MHz clock used to timestamp datagrams at the source is 
located on a PCI board. I have read access to a 32-bit counter that is 
incremented every cycle (somewhat like the TSC on x86).

2) Source and receiver are inside a VPN, and do not have access to the 
Internet. I don't think I can keep NTP happy if it can't talk to any NTP 
servers.

(I'm not snipping the rest of the message in case someone is willing
to comment.)

>>> The video stream is played out in real-time. I buffer several packets,
>>> then repeatedly arm a one-shot timer (with TIMER_ABSTIME set) to wait
>>> until it's time to send the oldest packet.
>>>
>>> AFAIU, if I use the CLOCK_REALTIME clock in my app, and if the 
>>> sysadmin changes the date, hell will break loose in my app.
>>
>> Only if your app cannot handle time going backwards.
> 
> My app cannot handle time going backwards.
> 
> The algorithm looks like:
> 
> /* Start transmission, record start date */
> NEXT_DEADLINE = now;
> 
> while ( 1 )
> {
>   send(oldest_packet);
>   recv_available_packets();
>   /* compute next deadline */
>   NEXT_DEADLINE += time_to_wait_until_next_packet();
>   sleep_until(NEXT_DEADLINE);
> }
> 
> If the clock changes under me, I'm toast.
> 
>>> I suppose that if I change sock_get_timestamp() in core/sock.c to
>>> call __get_realtime_clock_ts() instead of do_gettimeofday() I'll
>>> break 50 billion applications (ping? traceroute?) that expect a
>>> struct timeval?
>>
>> Not that many, but some probably.
> 
> Another option would be to change sock_get_timestamp() to call
> ktime_get_ts() instead of do_gettimeofday() and convert ns to us.
> 
> i.e. I still return a struct timeval, but using CLOCK_MONOTONIC.
> 
>> Letting the kernel do the time stamping is usually quite useless
>> anyways. You can as well do it in your application when you receive
>> it. After all you're interested in when you can read the packet in
>> your app, not when the driver processes it.
> 
> I use clock_nanosleep() to sleep until it's time to send the next
> packet. I check for packets when I wake up. I need the kernel to time
> stamp the packets because I was sleeping when they reached the system.
> 
> I try to do it this way because I read this:
> 
> http://rt.wiki.kernel.org/index.php/High_resolution_timers
> 
> "Note that (clock_)nanosleep functions do not suffer from this problem
> as the wakeup function at timer expiry is executed in the context of the
> high resolution timer interrupt. If an application is not using
> asynchronous signal handlers, it is recommended to use the
> clock_nanosleep() function with the TIMER_ABSTIME flag set instead of
> waiting for the periodic timer signal delivery. The application has to
> maintain the absolute expiry time for the next interval itself, but this
> is a lightweight operation of adding and normalizing two struct timespec
> values. The benefit is significantly lower maximum latencies (~50us) and
> less OS overhead in general."


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-26 12:20   ` Andi Kleen
@ 2007-02-26 14:17     ` John
  2007-02-28 11:23       ` John
  0 siblings, 1 reply; 39+ messages in thread
From: John @ 2007-02-26 14:17 UTC (permalink / raw)
  To: Andi Kleen
  Cc: linux-kernel, johnstul, mingo, zippel, tglx, akpm, jbohac, linux.kernel

Andi Kleen wrote:

> John wrote:
> 
>> My app expects a stream of UDP datagrams containing compressed video.
>> These datagrams have been time stamped by the source using a high
>> resolution clock.
> 
> Why do you need another time stamp then?

Source and receiver do not share a common clock. Thus, I have to monitor 
clock skew. If I simply use the time stamps produced by the source, my 
buffer will eventually underflow or overflow.

As far as I have seen, clock skew is on the order of ±10^-5, i.e. when 
the source thinks 100000 seconds have elapsed, the receiver thinks 
100001 seconds have elapsed.

>> The video stream is played out in real-time. I buffer several packets,
>> then repeatedly arm a one-shot timer (with TIMER_ABSTIME set) to wait
>> until it's time to send the oldest packet.
>>
>> AFAIU, if I use the CLOCK_REALTIME clock in my app, and if the sysadmin 
>> changes the date, hell will break loose in my app.
> 
> Only if your app cannot handle time going backwards.

My app cannot handle time going backwards.

The algorithm looks like:

/* Start transmission, record start date */
NEXT_DEADLINE = now;

while ( 1 )
{
   send(oldest_packet);
   recv_available_packets();
   /* compute next deadline */
   NEXT_DEADLINE += time_to_wait_until_next_packet();
   sleep_until(NEXT_DEADLINE);
}

If the clock changes under me, I'm toast.

>> I suppose that if I change sock_get_timestamp() in core/sock.c to call 
>> __get_realtime_clock_ts() instead of do_gettimeofday() I'll break 50 
>> billion applications (ping? traceroute?) that expect a struct timeval?
> 
> Not that many, but some probably.

Another option would be to change sock_get_timestamp() to call 
ktime_get_ts() instead of do_gettimeofday() and convert ns to us.

i.e. I still return a struct timeval, but using CLOCK_MONOTONIC.

> Letting the kernel do the time stamping is usually quite useless anyways. 
> You can as well do it in your application when you receive it. After all
> you're interested in when you can read the packet in your app, 
> not when the driver processes it.

I use clock_nanosleep() to sleep until it's time to send the next 
packet. I check for packets when I wake up. I need the kernel to time 
stamp the packets because I was sleeping when they reached the system.

I try to do it this way because I read this:

http://rt.wiki.kernel.org/index.php/High_resolution_timers

"Note that (clock_)nanosleep functions do not suffer from this problem 
as the wakeup function at timer expiry is executed in the context of the 
high resolution timer interrupt. If an application is not using 
asynchronous signal handlers, it is recommended to use the 
clock_nanosleep() function with the TIMER_ABSTIME flag set instead of 
waiting for the periodic timer signal delivery. The application has to 
maintain the absolute expiry time for the next interval itself, but this 
is a lightweight operation of adding and normalizing two struct timespec 
values. The benefit is significantly lower maximum latencies (~50us) and 
less OS overhead in general."

Regards.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-26 10:26 ` John
@ 2007-02-26 12:20   ` Andi Kleen
  2007-02-26 14:17     ` John
  0 siblings, 1 reply; 39+ messages in thread
From: Andi Kleen @ 2007-02-26 12:20 UTC (permalink / raw)
  To: John; +Cc: linux-kernel, johnstul, mingo, zippel, tglx, akpm, jbohac


Mr Anonymous,

> 
> My app expects a stream of UDP datagrams containing compressed video.
> These datagrams have been time stamped by the source using a high 
> resolution clock.

Why do you need another time stamp them? 
> 
> The video stream is played out in real-time. I buffer several packets, 
> then repeatedly arm a one-shot timer (with TIMER_ABSTIME set) to wait 
> until it's time to send the oldest packet.
> 
> AFAIU, if I use the CLOCK_REALTIME clock in my app, and if the sysadmin 
> changes the date, hell will break loose in my app.

Only if your app cannot handle time going backwards.

> I suppose that if I change sock_get_timestamp() in core/sock.c to call 
> __get_realtime_clock_ts() instead of do_gettimeofday() I'll break 50 
> billion applications (ping? traceroute?) that expect a struct timeval?

Not that many, but some probably. 

Letting the kernel do the time stamping is usually quite useless anyways. 
You can as well do it in your application when you receive it. After all
you're interested in when you can read the packet in your app, 
not when the driver processes it.

The kernel time stamping is mainly for sniffing applications that want
to know exactly what's going on on the wire. But even then it's fairly
arbitary because it can be a long time between the packet arriving 
on the PHY and being processed by the driver.

-Andi

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CLOCK_MONOTONIC datagram timestamps by the kernel
  2007-02-25 21:29 John
@ 2007-02-26 10:26 ` John
  2007-02-26 12:20   ` Andi Kleen
  0 siblings, 1 reply; 39+ messages in thread
From: John @ 2007-02-26 10:26 UTC (permalink / raw)
  To: linux-kernel
  Cc: johnstul, mingo, zippel, tglx, akpm, ak, jbohac, linux.kernel

John wrote:

> It is possible to ask Linux to timestamp incoming datagrams when they
> are received, then to retrieve this timestamp with an ioctl command or
> a recvmsg call (which would save one round trip to kernel space).
> 
> SIOCGSTAMP
>     Return a struct timeval with the receive timestamp of the last
> packet passed to the user. This is useful for accurate round trip time
> measurements. See setitimer(2) for a description of struct timeval.
> 
> As far as I understand, this timestamp is given by the CLOCK_REALTIME
> clock. I would like to get the timestamp given by a different clock:
> the CLOCK_MONOTONIC clock.
> 
> In other words, I would like the kernel to do the equivalent of
> 
>   struct timespec spec;
>   clock_gettime(CLOCK_MONOTONIC, &spec)
> 
> for each datagram the system receives, as soon as it is received.
> 
> Is there a way to achieve that?
> 
> Is there a different ioctl perhaps? (I don't think so.)

I've been reading the following documents:

Clocks and Timers
http://www.opengroup.org/onlinepubs/009695399/xrat/xsh_chap02.html#tag_03_02_08_18

Rationale for the Monotonic Clock
http://www.opengroup.org/onlinepubs/009695399/xrat/xsh_chap02.html#tag_03_02_08_19

"For those applications that use time services to achieve realtime 
behavior, changing the value of the clock on which these services rely 
may cause erroneous timing behavior. For these applications, it is 
necessary to have a monotonic clock which cannot run backwards, and 
which has a maximum clock jump that is required to be documented by the 
implementation. Additionally, it is desirable (but not required by IEEE 
Std 1003.1-2001) that the monotonic clock increases its value uniformly. 
This clock should not be affected by changes to the system time; for 
example, to synchronize the clock with an external source or to account 
for leap seconds. Such changes would cause errors in the measurement of 
time intervals for those time services that use the absolute value of 
the clock."

clock and timer functions
http://www.opengroup.org/onlinepubs/009695399/functions/clock_settime.html

"If the value of the CLOCK_REALTIME clock is set via clock_settime(), 
the new value of the clock shall be used to determine the time of 
expiration for absolute time services based upon the CLOCK_REALTIME 
clock. This applies to the time at which armed absolute timers expire. 
If the absolute time requested at the invocation of such a time service 
is before the new value of the clock, the time service shall expire 
immediately as if the clock had reached the requested time normally."

"The effect of setting a clock via clock_settime() on armed per-process 
timers associated with a clock other than CLOCK_REALTIME is 
implementation-defined."


Here's some background on what I'm trying to do:

My app expects a stream of UDP datagrams containing compressed video.
These datagrams have been time stamped by the source using a high 
resolution clock.

The video stream is played out in real-time. I buffer several packets, 
then repeatedly arm a one-shot timer (with TIMER_ABSTIME set) to wait 
until it's time to send the oldest packet.

AFAIU, if I use the CLOCK_REALTIME clock in my app, and if the sysadmin 
changes the date, hell will break loose in my app. Hence my need for 
CLOCK_MONOTONIC.


On a related note, I see that do_gettimeofday() in kernel/timer.c 
actually gets a struct timespec from __get_realtime_clock_ts() then 
throws bits away in the ns to us conversion. The integer division is 
also a waste of cycles in my case, as I want the result in ns.

I suppose that if I change sock_get_timestamp() in core/sock.c to call 
__get_realtime_clock_ts() instead of do_gettimeofday() I'll break 50 
billion applications (ping? traceroute?) that expect a struct timeval?

Anyway, thanks for reading this far.

Regards.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* CLOCK_MONOTONIC datagram timestamps by the kernel
@ 2007-02-25 21:29 John
  2007-02-26 10:26 ` John
  0 siblings, 1 reply; 39+ messages in thread
From: John @ 2007-02-25 21:29 UTC (permalink / raw)
  To: linux-kernel; +Cc: johnstul, mingo, zippel, tglx, linux.kernel, akpm

Hello,

It is possible to ask Linux to timestamp incoming datagrams when they
are received, then to retrieve this timestamp with an ioctl command or
a recvmsg call (which would save one round trip to kernel space).

SIOCGSTAMP
     Return a struct timeval with the receive timestamp of the last
packet passed to the user. This is useful for accurate round trip time
measurements. See setitimer(2) for a description of struct timeval.

As far as I understand, this timestamp is given by the CLOCK_REALTIME
clock. I would like to get the timestamp given by a different clock: the
CLOCK_MONOTONIC clock.

In other words, I would like the kernel to do the equivalent of

   struct timespec spec;
   clock_gettime(CLOCK_MONOTONIC, &spec)

for each datagram the system receives, as soon as it is received.

Is there a way to achieve that?

Is there a different ioctl perhaps? (I don't think so.)

Regards.

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2007-03-09 22:17 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-28 10:18 CLOCK_MONOTONIC datagram timestamps by the kernel John
2007-02-28 13:37 ` John
2007-02-28 13:55   ` Eric Dumazet
2007-02-28 14:23     ` John
2007-02-28 14:55       ` Eric Dumazet
2007-02-28 16:07         ` John
2007-03-01 10:03           ` Evgeniy Polyakov
2007-03-01 11:30           ` Eric Dumazet
2007-03-01 15:54             ` Stephen Hemminger
2007-03-01 16:13               ` Eric Dumazet
2007-03-02 14:38               ` [PATCH] NET : convert network timestamps to ktime_t Eric Dumazet
2007-03-02 16:27                 ` Stephen Hemminger
2007-03-02 21:02                 ` Stephen Hemminger
2007-03-02 22:46                   ` Eric Dumazet
2007-03-05  0:19                     ` David Miller
2007-03-05  6:56                       ` Eric Dumazet
2007-03-05  7:40                         ` Eric Dumazet
2007-03-05  8:00                           ` David Miller
2007-03-05  8:21                             ` Eric Dumazet
2007-03-05  8:49                               ` David Miller
2007-03-08 14:17                 ` [PATCH] NET : Introduce SIOCGSTAMPNS ioctl to get timestamps with nanosec resolution Eric Dumazet
2007-03-08 16:28                   ` Patrick McHardy
2007-03-08 16:42                     ` Eric Dumazet
2007-03-08 16:45                       ` Patrick McHardy
2007-03-09  4:39                   ` David Miller
2007-03-09 18:39                   ` [PATCH] NET : Adding SO_TIMESTAMPNS / SCM_TIMESTAMPNS support Eric Dumazet
2007-03-09 22:17                     ` David Miller
2007-03-01 18:53             ` CLOCK_MONOTONIC datagram timestamps by the kernel Stephen Hemminger
2007-03-01 23:14               ` Eric Dumazet
2007-03-01 23:34                 ` Stephen Hemminger
2007-03-02  0:56                   ` Eric Dumazet
2007-03-02  9:26             ` John
2007-03-02 10:11               ` Eric Dumazet
2007-02-28 18:22   ` Stephen Hemminger
  -- strict thread matches above, loose matches on Subject: below --
2007-02-25 21:29 John
2007-02-26 10:26 ` John
2007-02-26 12:20   ` Andi Kleen
2007-02-26 14:17     ` John
2007-02-28 11:23       ` John

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.