net: add skb_mstamp infrastructure
ktime_get() is too expensive on some cases, and we'd like to get usec resolution timestamps in TCP stack. This patch adds a light weight facility using a combination of local_clock() and jiffies samples. Instead of : u64 t0, t1; t0 = ktime_get(); // stuff t1 = ktime_get(); delta_us = ktime_us_delta(t1, t0); use : struct skb_mstamp t0, t1; skb_mstamp_get(&t0); // stuff skb_mstamp_get(&t1); delta_us = skb_mstamp_us_delta(&t1, &t0); Note : local_clock() might have a (bounded) drift between cpus. Do not use this infra in place of ktime_get() without understanding the issues. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Stephen Hemminger <stephen@networkplumber.org> Cc: Yuchung Cheng <ycheng@google.com> Cc: Neal Cardwell <ncardwell@google.com> Cc: Larry Brakmo <brakmo@google.com> Cc: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
20d8435a1c
commit
363ec39235
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/hrtimer.h>
|
#include <linux/hrtimer.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/netdev_features.h>
|
#include <linux/netdev_features.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
#include <net/flow_keys.h>
|
#include <net/flow_keys.h>
|
||||||
|
|
||||||
/* A. Checksumming of received packets by device.
|
/* A. Checksumming of received packets by device.
|
||||||
|
@ -356,11 +357,62 @@ typedef unsigned int sk_buff_data_t;
|
||||||
typedef unsigned char *sk_buff_data_t;
|
typedef unsigned char *sk_buff_data_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct skb_mstamp - multi resolution time stamps
|
||||||
|
* @stamp_us: timestamp in us resolution
|
||||||
|
* @stamp_jiffies: timestamp in jiffies
|
||||||
|
*/
|
||||||
|
struct skb_mstamp {
|
||||||
|
union {
|
||||||
|
u64 v64;
|
||||||
|
struct {
|
||||||
|
u32 stamp_us;
|
||||||
|
u32 stamp_jiffies;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* skb_mstamp_get - get current timestamp
|
||||||
|
* @cl: place to store timestamps
|
||||||
|
*/
|
||||||
|
static inline void skb_mstamp_get(struct skb_mstamp *cl)
|
||||||
|
{
|
||||||
|
u64 val = local_clock();
|
||||||
|
|
||||||
|
do_div(val, NSEC_PER_USEC);
|
||||||
|
cl->stamp_us = (u32)val;
|
||||||
|
cl->stamp_jiffies = (u32)jiffies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* skb_mstamp_delta - compute the difference in usec between two skb_mstamp
|
||||||
|
* @t1: pointer to newest sample
|
||||||
|
* @t0: pointer to oldest sample
|
||||||
|
*/
|
||||||
|
static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1,
|
||||||
|
const struct skb_mstamp *t0)
|
||||||
|
{
|
||||||
|
s32 delta_us = t1->stamp_us - t0->stamp_us;
|
||||||
|
u32 delta_jiffies = t1->stamp_jiffies - t0->stamp_jiffies;
|
||||||
|
|
||||||
|
/* If delta_us is negative, this might be because interval is too big,
|
||||||
|
* or local_clock() drift is too big : fallback using jiffies.
|
||||||
|
*/
|
||||||
|
if (delta_us <= 0 ||
|
||||||
|
delta_jiffies >= (INT_MAX / (USEC_PER_SEC / HZ)))
|
||||||
|
|
||||||
|
delta_us = jiffies_to_usecs(delta_jiffies);
|
||||||
|
|
||||||
|
return delta_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct sk_buff - socket buffer
|
* struct sk_buff - socket buffer
|
||||||
* @next: Next buffer in list
|
* @next: Next buffer in list
|
||||||
* @prev: Previous buffer in list
|
* @prev: Previous buffer in list
|
||||||
* @tstamp: Time we arrived
|
* @tstamp: Time we arrived/left
|
||||||
* @sk: Socket we are owned by
|
* @sk: Socket we are owned by
|
||||||
* @dev: Device we arrived on/are leaving by
|
* @dev: Device we arrived on/are leaving by
|
||||||
* @cb: Control buffer. Free for use by every layer. Put private vars here
|
* @cb: Control buffer. Free for use by every layer. Put private vars here
|
||||||
|
@ -429,7 +481,10 @@ struct sk_buff {
|
||||||
struct sk_buff *next;
|
struct sk_buff *next;
|
||||||
struct sk_buff *prev;
|
struct sk_buff *prev;
|
||||||
|
|
||||||
ktime_t tstamp;
|
union {
|
||||||
|
ktime_t tstamp;
|
||||||
|
struct skb_mstamp skb_mstamp;
|
||||||
|
};
|
||||||
|
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
Loading…
Reference in New Issue