diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2007-04-19 19:16:32 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:23:34 -0400 |
commit | b7aa0bf70c4afb9e38be25f5c0922498d0f8684c (patch) | |
tree | 4bc9d61031f4eb40d73887d6bde09e7d6bf2b259 /net/ipv4 | |
parent | 3927f2e8f9afa3424bb51ca81f7abac01ffd0005 (diff) |
[NET]: convert network timestamps to ktime_t
We currently use a special structure (struct skb_timeval) and plain
'struct timeval' to store packet timestamps in sk_buffs and struct
sock.
This has some drawbacks :
- Fixed resolution of micro second.
- Waste of space on 64bit platforms where sizeof(struct timeval)=16
I suggest using ktime_t that is a nice abstraction of high resolution
time services, currently capable of nanosecond resolution.
As sizeof(ktime_t) is 8 bytes, using ktime_t in 'struct sock' permits
a 8 byte shrink of this structure on 64bit architectures. Some other
structures also benefit from this size reduction (struct ipq in
ipv4/ip_fragment.c, struct frag_queue in ipv6/reassembly.c, ...)
Once this ktime infrastructure adopted, we can more easily provide
nanosecond resolution on top of it. (ioctl SIOCGSTAMPNS and/or
SO_TIMESTAMPNS/SCM_TIMESTAMPNS)
Note : this patch includes a bug correction in
compat_sock_get_timestamp() where a "err = 0;" was missing (so this
syscall returned -ENOENT instead of 0)
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
CC: Stephen Hemminger <shemminger@linux-foundation.org>
CC: John find <linux.kernel@free.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ip_fragment.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 8 |
3 files changed, 13 insertions, 9 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index b6f055380373..e10be7d7752d 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -92,7 +92,7 @@ struct ipq { | |||
92 | spinlock_t lock; | 92 | spinlock_t lock; |
93 | atomic_t refcnt; | 93 | atomic_t refcnt; |
94 | struct timer_list timer; /* when will this queue expire? */ | 94 | struct timer_list timer; /* when will this queue expire? */ |
95 | struct timeval stamp; | 95 | ktime_t stamp; |
96 | int iif; | 96 | int iif; |
97 | unsigned int rid; | 97 | unsigned int rid; |
98 | struct inet_peer *peer; | 98 | struct inet_peer *peer; |
@@ -592,7 +592,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb) | |||
592 | if (skb->dev) | 592 | if (skb->dev) |
593 | qp->iif = skb->dev->ifindex; | 593 | qp->iif = skb->dev->ifindex; |
594 | skb->dev = NULL; | 594 | skb->dev = NULL; |
595 | skb_get_timestamp(skb, &qp->stamp); | 595 | qp->stamp = skb->tstamp; |
596 | qp->meat += skb->len; | 596 | qp->meat += skb->len; |
597 | atomic_add(skb->truesize, &ip_frag_mem); | 597 | atomic_add(skb->truesize, &ip_frag_mem); |
598 | if (offset == 0) | 598 | if (offset == 0) |
@@ -674,7 +674,7 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev) | |||
674 | 674 | ||
675 | head->next = NULL; | 675 | head->next = NULL; |
676 | head->dev = dev; | 676 | head->dev = dev; |
677 | skb_set_timestamp(head, &qp->stamp); | 677 | head->tstamp = qp->stamp; |
678 | 678 | ||
679 | iph = head->nh.iph; | 679 | iph = head->nh.iph; |
680 | iph->frag_off = 0; | 680 | iph->frag_off = 0; |
@@ -734,7 +734,7 @@ struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user) | |||
734 | return NULL; | 734 | return NULL; |
735 | } | 735 | } |
736 | 736 | ||
737 | void ipfrag_init(void) | 737 | void __init ipfrag_init(void) |
738 | { | 738 | { |
739 | ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^ | 739 | ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^ |
740 | (jiffies ^ (jiffies >> 6))); | 740 | (jiffies ^ (jiffies >> 6))); |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index a14798a850d7..5842f1aa973a 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -197,6 +197,7 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp) | |||
197 | struct sk_buff *skb; | 197 | struct sk_buff *skb; |
198 | struct ipq_packet_msg *pmsg; | 198 | struct ipq_packet_msg *pmsg; |
199 | struct nlmsghdr *nlh; | 199 | struct nlmsghdr *nlh; |
200 | struct timeval tv; | ||
200 | 201 | ||
201 | read_lock_bh(&queue_lock); | 202 | read_lock_bh(&queue_lock); |
202 | 203 | ||
@@ -241,8 +242,9 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp) | |||
241 | 242 | ||
242 | pmsg->packet_id = (unsigned long )entry; | 243 | pmsg->packet_id = (unsigned long )entry; |
243 | pmsg->data_len = data_len; | 244 | pmsg->data_len = data_len; |
244 | pmsg->timestamp_sec = entry->skb->tstamp.off_sec; | 245 | tv = ktime_to_timeval(entry->skb->tstamp); |
245 | pmsg->timestamp_usec = entry->skb->tstamp.off_usec; | 246 | pmsg->timestamp_sec = tv.tv_sec; |
247 | pmsg->timestamp_usec = tv.tv_usec; | ||
246 | pmsg->mark = entry->skb->mark; | 248 | pmsg->mark = entry->skb->mark; |
247 | pmsg->hook = entry->info->hook; | 249 | pmsg->hook = entry->info->hook; |
248 | pmsg->hw_protocol = entry->skb->protocol; | 250 | pmsg->hw_protocol = entry->skb->protocol; |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 9acc018766f2..9718b666a380 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -187,6 +187,7 @@ static void ipt_ulog_packet(unsigned int hooknum, | |||
187 | ulog_packet_msg_t *pm; | 187 | ulog_packet_msg_t *pm; |
188 | size_t size, copy_len; | 188 | size_t size, copy_len; |
189 | struct nlmsghdr *nlh; | 189 | struct nlmsghdr *nlh; |
190 | struct timeval tv; | ||
190 | 191 | ||
191 | /* ffs == find first bit set, necessary because userspace | 192 | /* ffs == find first bit set, necessary because userspace |
192 | * is already shifting groupnumber, but we need unshifted. | 193 | * is already shifting groupnumber, but we need unshifted. |
@@ -232,13 +233,14 @@ static void ipt_ulog_packet(unsigned int hooknum, | |||
232 | pm = NLMSG_DATA(nlh); | 233 | pm = NLMSG_DATA(nlh); |
233 | 234 | ||
234 | /* We might not have a timestamp, get one */ | 235 | /* We might not have a timestamp, get one */ |
235 | if (skb->tstamp.off_sec == 0) | 236 | if (skb->tstamp.tv64 == 0) |
236 | __net_timestamp((struct sk_buff *)skb); | 237 | __net_timestamp((struct sk_buff *)skb); |
237 | 238 | ||
238 | /* copy hook, prefix, timestamp, payload, etc. */ | 239 | /* copy hook, prefix, timestamp, payload, etc. */ |
239 | pm->data_len = copy_len; | 240 | pm->data_len = copy_len; |
240 | put_unaligned(skb->tstamp.off_sec, &pm->timestamp_sec); | 241 | tv = ktime_to_timeval(skb->tstamp); |
241 | put_unaligned(skb->tstamp.off_usec, &pm->timestamp_usec); | 242 | put_unaligned(tv.tv_sec, &pm->timestamp_sec); |
243 | put_unaligned(tv.tv_usec, &pm->timestamp_usec); | ||
242 | put_unaligned(skb->mark, &pm->mark); | 244 | put_unaligned(skb->mark, &pm->mark); |
243 | pm->hook = hooknum; | 245 | pm->hook = hooknum; |
244 | if (prefix != NULL) | 246 | if (prefix != NULL) |