Do lazy gettimeofday for network packets
Subsystems (11)
PATCH 1/1 Do lazy gettimeofday for network packets
This adds lazy network timestamping to 2.6.5. skb->stamp is only filled in when there is a consumer of network timestamps active in the system.
On normal x86 machines (with TSC based gettimeofday) it doesn't seem to make benchmarks significantly faster, but they use a bit less CPU.
It also cleans up some duplicated code in the various socket protocols, overall it deletes nearly as much code as it adds.
The problems reported for earlier versions have been fixed.
Please consider applying,
-Andi
include/net/sock.h renamed from include/net/sock.h-T +28 -5
@@ -382,6 +382,7 @@SOCK_LINGER ,SOCK_DESTROY ,SOCK_BROADCAST , + SOCK_TIMESTAMP, };static inline void sock_set_flag (struct sock *sk,enum sock_flags flag)
@@ -1023,11 +1024,33 @@static __inline__void sock_recv_timestamp (struct msghdr *msg,struct sock *sk,struct sk_buff *skb) { -if (sk->sk_rcvtstamp) -put_cmsg (msg,SOL_SOCKET ,SO_TIMESTAMP ,sizeof (skb->stamp), &skb->stamp); -else - sk->sk_stamp = skb->stamp; -} +struct timeval *stamp = &skb->stamp; +if (sk->sk_rcvtstamp) { +/* Race occurred between timestamp enabling and packet +receiving. Fill in the current time for now. */ +if (stamp->tv_sec ==0 ) +do_gettimeofday (stamp); +put_cmsg (msg,SOL_SOCKET ,SO_TIMESTAMP ,sizeof (struct timeval ), + stamp); + }else + sk->sk_stamp = *stamp; +} + +extern atomic_t netstamp_needed; +extern void sock_enable_timestamp (struct sock *sk); +extern void sock_disable_timestamp (struct sock *sk); + +static inline void net_timestamp (struct timeval *stamp) +{ +if (atomic_read (&netstamp_needed)) +do_gettimeofday (stamp); +else { + stamp->tv_sec =0 ; + stamp->tv_usec =0 ; + } +} + +extern int sock_get_timestamp (struct sock *,struct timeval *);/* * Enable debug/info messages
include/net/neighbour.h renamed from include/net/neighbour.h-T +2 -0
@@ -281,6 +281,8 @@return neigh_create (tbl, pkey, dev); } +#define LOCALLY_ENQUEUED -2 +#endif #endif
net/core/sock.c renamed from net/core/sock.c-T +41 -1
68 lines not on this page · raw message
net/core/dev.c renamed from net/core/dev.c-T +4 -4
@@ -1125,7 +1125,7 @@void dev_queue_xmit_nit (struct sk_buff *skb,struct net_device *dev) {struct packet_type *ptype; -do_gettimeofday (&skb->stamp); +net_timestamp (&skb->stamp);rcu_read_lock ();list_for_each_entry_rcu (ptype, &ptype_all, list) {
@@ -1546,9 +1546,9 @@ return NET_RX_DROP; }#endif - +if (!skb->stamp.tv_sec) -do_gettimeofday (&skb->stamp); +net_timestamp (&skb->stamp);/* * The code is rearranged so that the path is the most
@@ -1710,7 +1710,7 @@#endif if (!skb->stamp.tv_sec) -do_gettimeofday (&skb->stamp); +net_timestamp (&skb->stamp);skb_bond (skb);
net/core/neighbour.c renamed from net/core/neighbour.c-T +1 -1
@@ -1094,7 +1094,7 @@kfree_skb (skb);return ; } - skb->stamp.tv_sec =0 ; + skb->stamp.tv_sec =LOCALLY_ENQUEUED ; skb->stamp.tv_usec = now + sched_next;spin_lock (&tbl->proxy_queue.lock);
net/ipv4/af_inet.c renamed from net/ipv4/af_inet.c-T +1 -5
@@ -843,11 +843,7 @@switch (cmd) {case SIOCGSTAMP : -if (!sk->sk_stamp.tv_sec) - err = -ENOENT ; -else if (copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval ))) - err = -EFAULT ; + err =sock_get_timestamp (sk, (struct timeval *)arg);break ;case SIOCADDRT :case SIOCDELRT :
net/ipv4/arp.c renamed from net/ipv4/arp.c-T +1 -1
@@ -860,7 +860,7 @@if (n)neigh_release (n); -if (skb->stamp.tv_sec ==0 || +if (skb->stamp.tv_sec ==LOCALLY_ENQUEUED || skb->pkt_type ==PACKET_HOST || in_dev->arp_parms->proxy_delay ==0 ) {arp_send (ARPOP_REPLY ,ETH_P_ARP ,sip,dev,tip,sha,dev->dev_addr,sha);
net/sunrpc/svcsock.c renamed from net/sunrpc/svcsock.c-T +6 -0
@@ -591,6 +591,12 @@/* possibly an icmp error */ dprintk ("svc: recvfrom returned error %d\n" , -err); } +if (skb->stamp.tv_sec ==0 ) { + skb->stamp.tv_sec = xtime.tv_sec; + skb->stamp.tv_usec = xtime.tv_nsec *1000 ; +/* Don't enable netstamp, sunrpc doesn't +need that much accuracy */ + } svsk->sk_sk->sk_stamp = skb->stamp;set_bit (SK_DATA , &svsk->sk_flags);/* there may be more data... */
net/rose/af_rose.c renamed from net/rose/af_rose.c-T +2 -6
@@ -1269,12 +1269,8 @@ }case SIOCGSTAMP : -if (sk !=NULL ) { -if (!sk->sk_stamp.tv_sec) -return -ENOENT ; -return copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval )) ? -EFAULT :0 ; - } +if (sk !=NULL ) +return sock_get_timestamp (sk, (struct timeval *)arg);return -EINVAL ;case SIOCGIFADDR :
net/irda/af_irda.c renamed from net/irda/af_irda.c-T +2 -8
@@ -1796,14 +1796,8 @@ }case SIOCGSTAMP : -if (sk !=NULL ) { -if (!sk->sk_stamp.tv_sec) -return -ENOENT ; -if (copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval ))) -return -EFAULT ; -return 0 ; - } +if (sk !=NULL ) +return sock_get_timestamp (sk, (struct timeval *)arg);return -EINVAL ;case SIOCGIFADDR :
net/ipx/af_ipx.c renamed from net/ipx/af_ipx.c-T +4 -10
@@ -1797,7 +1797,8 @@ copied);if (rc) goto out_free; - sk->sk_stamp = skb->stamp; +if (skb->stamp.tv_sec) + sk->sk_stamp = skb->stamp; msg->msg_namelen =sizeof (*sipx);
@@ -1870,15 +1871,8 @@break ;case SIOCGSTAMP : rc = -EINVAL ; -if (sk) { - rc = -ENOENT ; -if (!sk->sk_stamp.tv_sec) -break ; - rc = -EFAULT ; -if (!copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval ))) - rc =0 ; - } +if (sk) + rc =sock_get_timestamp (sk, (struct timeval *)arg);break ;case SIOCGIFDSTADDR :case SIOCSIFDSTADDR :
net/atm/ioctl.c renamed from net/atm/ioctl.c-T +2 -6
@@ -76,12 +76,8 @@ goto done; }case SIOCGSTAMP :/* borrowed from IP */ -if (!vcc->sk->sk_stamp.tv_sec) { - error = -ENOENT ; - goto done; - } - error =copy_to_user ((void *)arg, &vcc->sk->sk_stamp, -sizeof (struct timeval )) ? -EFAULT :0 ; + error =sock_get_timestamp (vcc->sk, (struct timeval *) + arg); goto done;case ATM_SETSC :printk (KERN_WARNING "ATM_SETSC is obsolete\n" );
net/ax25/af_ax25.c renamed from net/ax25/af_ax25.c-T +1 -6
@@ -1694,12 +1694,7 @@case SIOCGSTAMP :if (sk !=NULL ) { -if (!sk->sk_stamp.tv_sec) { - res = -ENOENT ; -break ; - } - res =copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval )) ? -EFAULT :0 ; + res =sock_get_timestamp (sk, (struct timeval *)arg);break ; } res = -EINVAL ;
net/ipv6/af_inet6.c renamed from net/ipv6/af_inet6.c-T +1 -7
@@ -474,13 +474,7 @@switch (cmd) {case SIOCGSTAMP : -if (!sk->sk_stamp.tv_sec) -return -ENOENT ; - err =copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval )); -if (err) -return -EFAULT ; -return 0 ; +return sock_get_timestamp (sk, (struct timeval *)arg);case SIOCADDRT :case SIOCDELRT :
net/ipv6/ndisc.c renamed from net/ipv6/ndisc.c-T +1 -1
@@ -761,7 +761,7 @@if (ipv6_chk_acast_addr (dev, &msg->target) || (idev->cnf.forwarding &&pneigh_lookup (&nd_tbl, &msg->target, dev,0 ))) { -if (skb->stamp.tv_sec !=0 && +if (skb->stamp.tv_sec !=LOCALLY_ENQUEUED && skb->pkt_type !=PACKET_HOST && inc !=0 && idev->nd_parms->proxy_delay !=0 ) {
net/rxrpc/transport.c renamed from net/rxrpc/transport.c-T +5 -0
@@ -341,6 +341,11 @@ msg->trans = trans; msg->state =RXRPC_MSG_RECEIVED ; msg->stamp = pkt->stamp; +if (msg->stamp.tv_sec ==0 ) { +do_gettimeofday (&msg->stamp); +if (pkt->sk) +sock_enable_timestamp (pkt->sk); + } msg->seq =ntohl (msg->hdr.seq);/* attach the packet */
net/sctp/input.c renamed from net/sctp/input.c-T +6 -0
@@ -175,6 +175,12 @@ rcvr = asoc ? &asoc->base : &ep->base; sk = rcvr->sk; +/* SCTP seems to always need a timestamp right now (FIXME) */ +if (skb->stamp.tv_sec ==0 ) { +do_gettimeofday (&skb->stamp); +sock_enable_timestamp (sk); + } +if (!xfrm_policy_check (sk,XFRM_POLICY_IN , skb, family)) goto discard_release;
net/x25/af_x25.c renamed from net/x25/af_x25.c-T +3 -7
@@ -1206,14 +1206,10 @@ }case SIOCGSTAMP : -if (sk) { - rc = -ENOENT ; -if (!sk->sk_stamp.tv_sec) -break ; - rc =copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval )) ? -EFAULT :0 ; - } rc = -EINVAL ; +if (sk) + rc =sock_get_timestamp (sk, + (struct timeval *)arg);break ;case SIOCGIFADDR :case SIOCSIFADDR :
net/wanrouter/af_wanpipe.c renamed from net/wanrouter/af_wanpipe.c-T +1 -7
@@ -1765,13 +1765,7 @@switch (cmd) {case SIOCGSTAMP : -if (!sk->sk_stamp.tv_sec) -return -ENOENT ; - err = -EFAULT ; -if (!copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval ))) - err =0 ; -return err; +return sock_get_timestamp (sk, (struct timeval *)arg);case SIOC_WANPIPE_CHECK_TX :
net/packet/af_packet.c renamed from net/packet/af_packet.c-T +6 -7
@@ -606,6 +606,10 @@ h->tp_snaplen = snaplen; h->tp_mac = macoff; h->tp_net = netoff; +if (skb->stamp.tv_sec ==0 ) { +do_gettimeofday (&skb->stamp); +sock_enable_timestamp (sk); + } h->tp_sec = skb->stamp.tv_sec; h->tp_usec = skb->stamp.tv_usec;
@@ -1442,13 +1446,8 @@return put_user (amount, (int *)arg); }case SIOCGSTAMP : -if (!sk->sk_stamp.tv_sec) -return -ENOENT ; -if (copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval ))) -return -EFAULT ; -break ; - +return sock_get_timestamp (sk, (struct timeval *)arg); +#ifdef CONFIG_INET case SIOCADDRT :case SIOCDELRT :
net/netrom/af_netrom.c renamed from net/netrom/af_netrom.c-T +4 -10
@@ -1200,17 +1200,11 @@ }case SIOCGSTAMP : -if (sk !=NULL ) { -if (!sk->sk_stamp.tv_sec) { -release_sock (sk); -return -ENOENT ; - } - ret =copy_to_user ((void *)arg, &sk->sk_stamp,sizeof (struct timeval )) ? -EFAULT :0 ; -release_sock (sk); -return ret; - } + ret = -EINVAL ; +if (sk !=NULL ) + ret =sock_get_timestamp (sk, (struct timeval *)arg);release_sock (sk); -return -EINVAL ; +return ret;case SIOCGIFADDR :case SIOCSIFADDR :
net/appletalk/ddp.c renamed from net/appletalk/ddp.c-T +1 -7
@@ -1795,13 +1795,7 @@break ; }case SIOCGSTAMP : -if (!sk) -break ; - rc = -ENOENT ; -if (!sk->sk_stamp.tv_sec) -break ; - rc =copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval )) ? -EFAULT :0 ; + rc =sock_get_timestamp (sk, (struct timeval *)arg);break ;/* Routing */ case SIOCADDRT :
net/econet/af_econet.c renamed from net/econet/af_econet.c-T +2 -4
@@ -665,10 +665,8 @@switch (cmd) {case SIOCGSTAMP : -if (!sk->sk_stamp.tv_sec) -return -ENOENT ; -return copy_to_user ((void *)arg, &sk->sk_stamp, -sizeof (struct timeval )) ? -EFAULT :0 ; +return sock_get_timestamp (sk,(struct timeval *)arg); +case SIOCSIFADDR :case SIOCGIFADDR :return ec_dev_ioctl (sock, cmd, (void *)arg);
Quoted 2 lines · On Fri, 9 Apr 2004 17:35:54 +0200 Andi Kleen <[email protected]> wrote:
This adds lazy network timestamping to 2.6.5.
skb->stampis only filled in when there is a consumer of network timestamps active in the system.
Ok, let's give this a try, I'll apply this.
Thanks Andi.