* CLOCK_MONOTONIC datagram timestamps by the kernel @ 2007-02-25 21:29 John 2007-02-26 10:26 ` John 0 siblings, 1 reply; 22+ 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] 22+ messages in thread
* Re: CLOCK_MONOTONIC datagram timestamps by the kernel 2007-02-25 21:29 CLOCK_MONOTONIC datagram timestamps by the kernel John @ 2007-02-26 10:26 ` John 2007-02-26 12:20 ` Andi Kleen 0 siblings, 1 reply; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread
* CLOCK_MONOTONIC datagram timestamps by the kernel @ 2007-02-28 10:18 John 2007-02-28 13:37 ` John 0 siblings, 1 reply; 22+ 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] 22+ messages in thread
* Re: CLOCK_MONOTONIC datagram timestamps by the kernel 2007-02-28 10:18 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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-01 18:53 ` Stephen Hemminger 2007-03-02 9:26 ` John 2 siblings, 1 reply; 22+ 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] 22+ 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 0 siblings, 0 replies; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread
* Re: CLOCK_MONOTONIC datagram timestamps by the kernel 2007-03-01 18:53 ` Stephen Hemminger @ 2007-03-01 23:14 ` Eric Dumazet 2007-03-01 23:34 ` Stephen Hemminger 0 siblings, 1 reply; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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-02 9:26 ` John 2007-03-02 10:11 ` Eric Dumazet 2 siblings, 1 reply; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread
end of thread, other threads:[~2007-03-02 10:11 UTC | newest] Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-02-25 21:29 CLOCK_MONOTONIC datagram timestamps by the kernel 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 2007-02-28 10:18 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-01 18:53 ` 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
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.