#include <net/checksum.h>
#include <linux/rcupdate.h>
#include <linux/dmaengine.h>
+#include <linux/hrtimer.h>
#define HAVE_ALLOC_SKB /* For the drivers to know */
#define HAVE_ALIGNABLE_SKB /* Ditto 8) */
#define SKB_DATAREF_SHIFT 16
#define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
-struct skb_timeval {
- u32 off_sec;
- u32 off_usec;
-};
-
enum {
SKB_FCLONE_UNAVAILABLE,
struct sk_buff *prev;
struct sock *sk;
- struct skb_timeval tstamp;
+ ktime_t tstamp;
struct net_device *dev;
int iif;
/* 4 byte hole on 64 bit*/
*/
static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
{
- stamp->tv_sec = skb->tstamp.off_sec;
- stamp->tv_usec = skb->tstamp.off_usec;
+ *stamp = ktime_to_timeval(skb->tstamp);
}
-/**
- * skb_set_timestamp - set timestamp of a skb
- * @skb: skb to set stamp of
- * @stamp: pointer to struct timeval to get stamp from
- *
- * Timestamps are stored in the skb as offsets to a base timestamp.
- * This function converts a struct timeval to an offset and stores
- * it in the skb.
- */
-static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
+static inline void __net_timestamp(struct sk_buff *skb)
{
- skb->tstamp.off_sec = stamp->tv_sec;
- skb->tstamp.off_usec = stamp->tv_usec;
+ skb->tstamp = ktime_get_real();
}
-extern void __net_timestamp(struct sk_buff *skb);
extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
struct sk_filter *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
- struct timeval sk_stamp;
+ ktime_t sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct page *sk_sndmsg_page;
static __inline__ void
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
{
- struct timeval stamp;
+ ktime_t kt = skb->tstamp;
- skb_get_timestamp(skb, &stamp);
if (sock_flag(sk, SOCK_RCVTSTAMP)) {
+ struct timeval tv;
/* Race occurred between timestamp enabling and packet
receiving. Fill in the current time for now. */
- if (stamp.tv_sec == 0)
- do_gettimeofday(&stamp);
- skb_set_timestamp(skb, &stamp);
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval),
- &stamp);
+ if (kt.tv64 == 0)
+ kt = ktime_get_real();
+ skb->tstamp = kt;
+ tv = ktime_to_timeval(kt);
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(tv), &tv);
} else
- sk->sk_stamp = stamp;
+ sk->sk_stamp = kt;
}
/**
return tv;
}
+EXPORT_SYMBOL(ns_to_timeval);
/*
* Convert jiffies to milliseconds and back.
unsigned int group = uloginfo->nlgroup;
ebt_ulog_buff_t *ub = &ulog_buffers[group];
spinlock_t *lock = &ub->lock;
+ ktime_t kt;
if ((uloginfo->cprange == 0) ||
(uloginfo->cprange > skb->len + ETH_HLEN))
/* Fill in the ulog data */
pm->version = EBT_ULOG_VERSION;
- do_gettimeofday(&pm->stamp);
+ kt = ktime_get_real();
+ pm->stamp = ktime_to_timeval(kt);
if (ub->qlen == 1)
- skb_set_timestamp(ub->skb, &pm->stamp);
+ ub->skb->tstamp = kt;
pm->data_len = copy_len;
pm->mark = skb->mark;
pm->hook = hooknr;
struct compat_timeval __user *ctv =
(struct compat_timeval __user*) userstamp;
int err = -ENOENT;
+ struct timeval tv;
if (!sock_flag(sk, SOCK_TIMESTAMP))
sock_enable_timestamp(sk);
- if (sk->sk_stamp.tv_sec == -1)
+ tv = ktime_to_timeval(sk->sk_stamp);
+ if (tv.tv_sec == -1)
return err;
- if (sk->sk_stamp.tv_sec == 0)
- do_gettimeofday(&sk->sk_stamp);
- if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
- put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
+ if (tv.tv_sec == 0) {
+ sk->sk_stamp = ktime_get_real();
+ tv = ktime_to_timeval(sk->sk_stamp);
+ }
+ err = 0;
+ if (put_user(tv.tv_sec, &ctv->tv_sec) ||
+ put_user(tv.tv_usec, &ctv->tv_usec))
err = -EFAULT;
return err;
}
atomic_dec(&netstamp_needed);
}
-void __net_timestamp(struct sk_buff *skb)
-{
- struct timeval tv;
-
- do_gettimeofday(&tv);
- skb_set_timestamp(skb, &tv);
-}
-EXPORT_SYMBOL(__net_timestamp);
-
static inline void net_timestamp(struct sk_buff *skb)
{
if (atomic_read(&netstamp_needed))
__net_timestamp(skb);
- else {
- skb->tstamp.off_sec = 0;
- skb->tstamp.off_usec = 0;
- }
+ else
+ skb->tstamp.tv64 = 0;
}
/*
if (netpoll_rx(skb))
return NET_RX_DROP;
- if (!skb->tstamp.off_sec)
+ if (!skb->tstamp.tv64)
net_timestamp(skb);
/*
if (skb->dev->poll && netpoll_rx(skb))
return NET_RX_DROP;
- if (!skb->tstamp.off_sec)
+ if (!skb->tstamp.tv64)
net_timestamp(skb);
if (!skb->iif)
sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
- sk->sk_stamp.tv_sec = -1L;
- sk->sk_stamp.tv_usec = -1L;
+ sk->sk_stamp = ktime_set(-1L, -1L);
atomic_set(&sk->sk_refcnt, 1);
}
int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
{
+ struct timeval tv;
if (!sock_flag(sk, SOCK_TIMESTAMP))
sock_enable_timestamp(sk);
- if (sk->sk_stamp.tv_sec == -1)
+ tv = ktime_to_timeval(sk->sk_stamp);
+ if (tv.tv_sec == -1)
return -ENOENT;
- if (sk->sk_stamp.tv_sec == 0)
- do_gettimeofday(&sk->sk_stamp);
- return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timeval)) ?
- -EFAULT : 0;
+ if (tv.tv_sec == 0) {
+ sk->sk_stamp = ktime_get_real();
+ tv = ktime_to_timeval(sk->sk_stamp);
+ }
+ return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0;
}
EXPORT_SYMBOL(sock_get_timestamp);
err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
if (err)
goto out_free;
- skb_get_timestamp(skb, &sk->sk_stamp);
+ sk->sk_stamp = skb->tstamp;
if (msg->msg_name)
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
spinlock_t lock;
atomic_t refcnt;
struct timer_list timer; /* when will this queue expire? */
- struct timeval stamp;
+ ktime_t stamp;
int iif;
unsigned int rid;
struct inet_peer *peer;
if (skb->dev)
qp->iif = skb->dev->ifindex;
skb->dev = NULL;
- skb_get_timestamp(skb, &qp->stamp);
+ qp->stamp = skb->tstamp;
qp->meat += skb->len;
atomic_add(skb->truesize, &ip_frag_mem);
if (offset == 0)
head->next = NULL;
head->dev = dev;
- skb_set_timestamp(head, &qp->stamp);
+ head->tstamp = qp->stamp;
iph = head->nh.iph;
iph->frag_off = 0;
return NULL;
}
-void ipfrag_init(void)
+void __init ipfrag_init(void)
{
ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
(jiffies ^ (jiffies >> 6)));
struct sk_buff *skb;
struct ipq_packet_msg *pmsg;
struct nlmsghdr *nlh;
+ struct timeval tv;
read_lock_bh(&queue_lock);
pmsg->packet_id = (unsigned long )entry;
pmsg->data_len = data_len;
- pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
- pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
+ tv = ktime_to_timeval(entry->skb->tstamp);
+ pmsg->timestamp_sec = tv.tv_sec;
+ pmsg->timestamp_usec = tv.tv_usec;
pmsg->mark = entry->skb->mark;
pmsg->hook = entry->info->hook;
pmsg->hw_protocol = entry->skb->protocol;
ulog_packet_msg_t *pm;
size_t size, copy_len;
struct nlmsghdr *nlh;
+ struct timeval tv;
/* ffs == find first bit set, necessary because userspace
* is already shifting groupnumber, but we need unshifted.
pm = NLMSG_DATA(nlh);
/* We might not have a timestamp, get one */
- if (skb->tstamp.off_sec == 0)
+ if (skb->tstamp.tv64 == 0)
__net_timestamp((struct sk_buff *)skb);
/* copy hook, prefix, timestamp, payload, etc. */
pm->data_len = copy_len;
- put_unaligned(skb->tstamp.off_sec, &pm->timestamp_sec);
- put_unaligned(skb->tstamp.off_usec, &pm->timestamp_usec);
+ tv = ktime_to_timeval(skb->tstamp);
+ put_unaligned(tv.tv_sec, &pm->timestamp_sec);
+ put_unaligned(tv.tv_usec, &pm->timestamp_usec);
put_unaligned(skb->mark, &pm->mark);
pm->hook = hooknum;
if (prefix != NULL)
ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
ipv6_addr_copy(&hao->addr, &tmp_addr);
- if (skb->tstamp.off_sec == 0)
+ if (skb->tstamp.tv64 == 0)
__net_timestamp(skb);
return 1;
struct sk_buff *skb;
struct ipq_packet_msg *pmsg;
struct nlmsghdr *nlh;
+ struct timeval tv;
read_lock_bh(&queue_lock);
pmsg->packet_id = (unsigned long )entry;
pmsg->data_len = data_len;
- pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
- pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
+ tv = ktime_to_timeval(entry->skb->tstamp);
+ pmsg->timestamp_sec = tv.tv_sec;
+ pmsg->timestamp_usec = tv.tv_usec;
pmsg->mark = entry->skb->mark;
pmsg->hook = entry->info->hook;
pmsg->hw_protocol = entry->skb->protocol;
struct sk_buff *fragments;
int len;
int meat;
- struct timeval stamp;
+ ktime_t stamp;
unsigned int csum;
__u8 last_in; /* has first/last segment arrived? */
#define COMPLETE 4
fq->fragments = skb;
skb->dev = NULL;
- skb_get_timestamp(skb, &fq->stamp);
+ fq->stamp = skb->tstamp;
fq->meat += skb->len;
atomic_add(skb->truesize, &nf_ct_frag6_mem);
head->next = NULL;
head->dev = dev;
- skb_set_timestamp(head, &fq->stamp);
+ head->tstamp = fq->stamp;
head->nh.ipv6h->payload_len = htons(payload_len);
/* Yes, and fold redundant checksum back. 8) */
int len;
int meat;
int iif;
- struct timeval stamp;
+ ktime_t stamp;
unsigned int csum;
__u8 last_in; /* has first/last segment arrived? */
#define COMPLETE 4
if (skb->dev)
fq->iif = skb->dev->ifindex;
skb->dev = NULL;
- skb_get_timestamp(skb, &fq->stamp);
+ fq->stamp = skb->tstamp;
fq->meat += skb->len;
atomic_add(skb->truesize, &ip6_frag_mem);
head->next = NULL;
head->dev = dev;
- skb_set_timestamp(head, &fq->stamp);
+ head->tstamp = fq->stamp;
head->nh.ipv6h->payload_len = htons(payload_len);
IP6CB(head)->nhoff = nhoff;
copied);
if (rc)
goto out_free;
- if (skb->tstamp.off_sec)
- skb_get_timestamp(skb, &sk->sk_stamp);
+ if (skb->tstamp.tv64)
+ sk->sk_stamp = skb->tstamp;
msg->msg_namelen = sizeof(*sipx);
NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
}
- if (skb->tstamp.off_sec) {
+ if (skb->tstamp.tv64) {
struct nfulnl_msg_packet_timestamp ts;
-
- ts.sec = cpu_to_be64(skb->tstamp.off_sec);
- ts.usec = cpu_to_be64(skb->tstamp.off_usec);
+ struct timeval tv = ktime_to_timeval(skb->tstamp);
+ ts.sec = cpu_to_be64(tv.tv_sec);
+ ts.usec = cpu_to_be64(tv.tv_usec);
NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
}
NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
}
- if (entskb->tstamp.off_sec) {
+ if (entskb->tstamp.tv64) {
struct nfqnl_msg_packet_timestamp ts;
-
- ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
- ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
+ struct timeval tv = ktime_to_timeval(entskb->tstamp);
+ ts.sec = cpu_to_be64(tv.tv_sec);
+ ts.usec = cpu_to_be64(tv.tv_usec);
NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
}
unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
unsigned short macoff, netoff;
struct sk_buff *copy_skb = NULL;
+ struct timeval tv;
if (skb->pkt_type == PACKET_LOOPBACK)
goto drop;
h->tp_snaplen = snaplen;
h->tp_mac = macoff;
h->tp_net = netoff;
- if (skb->tstamp.off_sec == 0) {
+ if (skb->tstamp.tv64 == 0) {
__net_timestamp(skb);
sock_enable_timestamp(sk);
}
- h->tp_sec = skb->tstamp.off_sec;
- h->tp_usec = skb->tstamp.off_usec;
+ tv = ktime_to_timeval(skb->tstamp);
+ h->tp_sec = tv.tv_sec;
+ h->tp_usec = tv.tv_usec;
sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
sll->sll_halen = 0;
dprintk("svc: recvfrom returned error %d\n", -err);
}
rqstp->rq_addrlen = sizeof(rqstp->rq_addr);
- if (skb->tstamp.off_sec == 0) {
- struct timeval tv;
-
- tv.tv_sec = xtime.tv_sec;
- tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
- skb_set_timestamp(skb, &tv);
+ if (skb->tstamp.tv64 == 0) {
+ skb->tstamp = ktime_get_real();
/* Don't enable netstamp, sunrpc doesn't
need that much accuracy */
}
- skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+ svsk->sk_sk->sk_stamp = skb->tstamp;
set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
/*