Commit 56b17425 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

net: add rbnode to struct sk_buff

Yaogong replaces TCP out of order receive queue by an RB tree.

As netem already does a private skb->{next/prev/tstamp} union
with a 'struct rb_node', lets do this in a cleaner way.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Yaogong Wang <wygivan@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8ce0c825
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/rbtree.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/types.h> #include <asm/types.h>
...@@ -440,6 +441,7 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, ...@@ -440,6 +441,7 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1,
* @next: Next buffer in list * @next: Next buffer in list
* @prev: Previous buffer in list * @prev: Previous buffer in list
* @tstamp: Time we arrived/left * @tstamp: Time we arrived/left
* @rbnode: RB tree node, alternative to next/prev for netem/tcp
* @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
...@@ -504,6 +506,8 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, ...@@ -504,6 +506,8 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1,
*/ */
struct sk_buff { struct sk_buff {
union {
struct {
/* These two members must be first. */ /* These two members must be first. */
struct sk_buff *next; struct sk_buff *next;
struct sk_buff *prev; struct sk_buff *prev;
...@@ -512,7 +516,9 @@ struct sk_buff { ...@@ -512,7 +516,9 @@ struct sk_buff {
ktime_t tstamp; ktime_t tstamp;
struct skb_mstamp skb_mstamp; struct skb_mstamp skb_mstamp;
}; };
};
struct rb_node rbnode; /* used in netem & tcp stack */
};
struct sock *sk; struct sock *sk;
struct net_device *dev; struct net_device *dev;
......
...@@ -139,33 +139,20 @@ struct netem_sched_data { ...@@ -139,33 +139,20 @@ struct netem_sched_data {
/* Time stamp put into socket buffer control block /* Time stamp put into socket buffer control block
* Only valid when skbs are in our internal t(ime)fifo queue. * Only valid when skbs are in our internal t(ime)fifo queue.
*
* As skb->rbnode uses same storage than skb->next, skb->prev and skb->tstamp,
* and skb->next & skb->prev are scratch space for a qdisc,
* we save skb->tstamp value in skb->cb[] before destroying it.
*/ */
struct netem_skb_cb { struct netem_skb_cb {
psched_time_t time_to_send; psched_time_t time_to_send;
ktime_t tstamp_save; ktime_t tstamp_save;
}; };
/* Because space in skb->cb[] is tight, netem overloads skb->next/prev/tstamp
* to hold a rb_node structure.
*
* If struct sk_buff layout is changed, the following checks will complain.
*/
static struct rb_node *netem_rb_node(struct sk_buff *skb)
{
BUILD_BUG_ON(offsetof(struct sk_buff, next) != 0);
BUILD_BUG_ON(offsetof(struct sk_buff, prev) !=
offsetof(struct sk_buff, next) + sizeof(skb->next));
BUILD_BUG_ON(offsetof(struct sk_buff, tstamp) !=
offsetof(struct sk_buff, prev) + sizeof(skb->prev));
BUILD_BUG_ON(sizeof(struct rb_node) > sizeof(skb->next) +
sizeof(skb->prev) +
sizeof(skb->tstamp));
return (struct rb_node *)&skb->next;
}
static struct sk_buff *netem_rb_to_skb(struct rb_node *rb) static struct sk_buff *netem_rb_to_skb(struct rb_node *rb)
{ {
return (struct sk_buff *)rb; return container_of(rb, struct sk_buff, rbnode);
} }
static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb) static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb)
...@@ -403,8 +390,8 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) ...@@ -403,8 +390,8 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
else else
p = &parent->rb_left; p = &parent->rb_left;
} }
rb_link_node(netem_rb_node(nskb), parent, p); rb_link_node(&nskb->rbnode, parent, p);
rb_insert_color(netem_rb_node(nskb), &q->t_root); rb_insert_color(&nskb->rbnode, &q->t_root);
sch->q.qlen++; sch->q.qlen++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment