mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
net: add rb_to_skb() and other rb tree helpers
Geeralize private netem_rb_to_skb()
TCP rtx queue will soon be converted to rb-tree,
so we will need skb_rbtree_walk() helpers.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 18a4c0eab2)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
791521e2e3
commit
b475cf3bf1
@@ -2988,6 +2988,12 @@ static inline int __skb_grow_rcsum(struct sk_buff *skb, unsigned int len)
|
||||
|
||||
#define rb_to_skb(rb) rb_entry_safe(rb, struct sk_buff, rbnode)
|
||||
|
||||
#define rb_to_skb(rb) rb_entry_safe(rb, struct sk_buff, rbnode)
|
||||
#define skb_rb_first(root) rb_to_skb(rb_first(root))
|
||||
#define skb_rb_last(root) rb_to_skb(rb_last(root))
|
||||
#define skb_rb_next(skb) rb_to_skb(rb_next(&(skb)->rbnode))
|
||||
#define skb_rb_prev(skb) rb_to_skb(rb_prev(&(skb)->rbnode))
|
||||
|
||||
#define skb_queue_walk(queue, skb) \
|
||||
for (skb = (queue)->next; \
|
||||
skb != (struct sk_buff *)(queue); \
|
||||
@@ -3002,6 +3008,18 @@ static inline int __skb_grow_rcsum(struct sk_buff *skb, unsigned int len)
|
||||
for (; skb != (struct sk_buff *)(queue); \
|
||||
skb = skb->next)
|
||||
|
||||
#define skb_rbtree_walk(skb, root) \
|
||||
for (skb = skb_rb_first(root); skb != NULL; \
|
||||
skb = skb_rb_next(skb))
|
||||
|
||||
#define skb_rbtree_walk_from(skb) \
|
||||
for (; skb != NULL; \
|
||||
skb = skb_rb_next(skb))
|
||||
|
||||
#define skb_rbtree_walk_from_safe(skb, tmp) \
|
||||
for (; tmp = skb ? skb_rb_next(skb) : NULL, (skb != NULL); \
|
||||
skb = tmp)
|
||||
|
||||
#define skb_queue_walk_from_safe(queue, skb, tmp) \
|
||||
for (tmp = skb->next; \
|
||||
skb != (struct sk_buff *)(queue); \
|
||||
|
||||
@@ -4406,7 +4406,7 @@ static void tcp_ofo_queue(struct sock *sk)
|
||||
|
||||
p = rb_first(&tp->out_of_order_queue);
|
||||
while (p) {
|
||||
skb = rb_entry(p, struct sk_buff, rbnode);
|
||||
skb = rb_to_skb(p);
|
||||
if (after(TCP_SKB_CB(skb)->seq, tp->rcv_nxt))
|
||||
break;
|
||||
|
||||
@@ -4470,7 +4470,7 @@ static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb,
|
||||
static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct rb_node **p, *q, *parent;
|
||||
struct rb_node **p, *parent;
|
||||
struct sk_buff *skb1;
|
||||
u32 seq, end_seq;
|
||||
bool fragstolen;
|
||||
@@ -4529,7 +4529,7 @@ coalesce_done:
|
||||
parent = NULL;
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
skb1 = rb_entry(parent, struct sk_buff, rbnode);
|
||||
skb1 = rb_to_skb(parent);
|
||||
if (before(seq, TCP_SKB_CB(skb1)->seq)) {
|
||||
p = &parent->rb_left;
|
||||
continue;
|
||||
@@ -4574,9 +4574,7 @@ insert:
|
||||
|
||||
merge_right:
|
||||
/* Remove other segments covered by skb. */
|
||||
while ((q = rb_next(&skb->rbnode)) != NULL) {
|
||||
skb1 = rb_entry(q, struct sk_buff, rbnode);
|
||||
|
||||
while ((skb1 = skb_rb_next(skb)) != NULL) {
|
||||
if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
|
||||
break;
|
||||
if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
|
||||
@@ -4591,7 +4589,7 @@ merge_right:
|
||||
tcp_drop(sk, skb1);
|
||||
}
|
||||
/* If there is no skb after us, we are the last_skb ! */
|
||||
if (!q)
|
||||
if (!skb1)
|
||||
tp->ooo_last_skb = skb;
|
||||
|
||||
add_sack:
|
||||
@@ -4792,7 +4790,7 @@ static struct sk_buff *tcp_skb_next(struct sk_buff *skb, struct sk_buff_head *li
|
||||
if (list)
|
||||
return !skb_queue_is_last(list, skb) ? skb->next : NULL;
|
||||
|
||||
return rb_entry_safe(rb_next(&skb->rbnode), struct sk_buff, rbnode);
|
||||
return skb_rb_next(skb);
|
||||
}
|
||||
|
||||
static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
|
||||
@@ -4821,7 +4819,7 @@ static void tcp_rbtree_insert(struct rb_root *root, struct sk_buff *skb)
|
||||
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
skb1 = rb_entry(parent, struct sk_buff, rbnode);
|
||||
skb1 = rb_to_skb(parent);
|
||||
if (before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb1)->seq))
|
||||
p = &parent->rb_left;
|
||||
else
|
||||
@@ -4941,19 +4939,12 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
u32 range_truesize, sum_tiny = 0;
|
||||
struct sk_buff *skb, *head;
|
||||
struct rb_node *p;
|
||||
u32 start, end;
|
||||
|
||||
p = rb_first(&tp->out_of_order_queue);
|
||||
skb = rb_entry_safe(p, struct sk_buff, rbnode);
|
||||
skb = skb_rb_first(&tp->out_of_order_queue);
|
||||
new_range:
|
||||
if (!skb) {
|
||||
p = rb_last(&tp->out_of_order_queue);
|
||||
/* Note: This is possible p is NULL here. We do not
|
||||
* use rb_entry_safe(), as ooo_last_skb is valid only
|
||||
* if rbtree is not empty.
|
||||
*/
|
||||
tp->ooo_last_skb = rb_entry(p, struct sk_buff, rbnode);
|
||||
tp->ooo_last_skb = skb_rb_last(&tp->out_of_order_queue);
|
||||
return;
|
||||
}
|
||||
start = TCP_SKB_CB(skb)->seq;
|
||||
@@ -4961,7 +4952,7 @@ new_range:
|
||||
range_truesize = skb->truesize;
|
||||
|
||||
for (head = skb;;) {
|
||||
skb = tcp_skb_next(skb, NULL);
|
||||
skb = skb_rb_next(skb);
|
||||
|
||||
/* Range is terminated when we see a gap or when
|
||||
* we are at the queue end.
|
||||
@@ -5017,7 +5008,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
|
||||
prev = rb_prev(node);
|
||||
rb_erase(node, &tp->out_of_order_queue);
|
||||
goal -= rb_to_skb(node)->truesize;
|
||||
tcp_drop(sk, rb_entry(node, struct sk_buff, rbnode));
|
||||
tcp_drop(sk, rb_to_skb(node));
|
||||
if (!prev || goal <= 0) {
|
||||
sk_mem_reclaim(sk);
|
||||
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
|
||||
@@ -5027,7 +5018,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
|
||||
}
|
||||
node = prev;
|
||||
} while (node);
|
||||
tp->ooo_last_skb = rb_entry(prev, struct sk_buff, rbnode);
|
||||
tp->ooo_last_skb = rb_to_skb(prev);
|
||||
|
||||
/* Reset SACK state. A conforming SACK implementation will
|
||||
* do the same at a timeout based retransmit. When a connection
|
||||
|
||||
Reference in New Issue
Block a user