Skip to content

Commit ad69f35

Browse files
mstsirkindavem330
authored andcommitted
skb_array: array based FIFO for skbs
A simple array based FIFO of pointers. Intended for net stack so uses skbs for type safety. Implemented as a set of wrappers around ptr_ring. Signed-off-by: Michael S. Tsirkin <[email protected]> Acked-by: Jesper Dangaard Brouer <[email protected]> Tested-by: Jesper Dangaard Brouer <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9fb6bc5 commit ad69f35

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

include/linux/skb_array.h

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Definitions for the 'struct skb_array' datastructure.
3+
*
4+
* Author:
5+
* Michael S. Tsirkin <[email protected]>
6+
*
7+
* Copyright (C) 2016 Red Hat, Inc.
8+
*
9+
* This program is free software; you can redistribute it and/or modify it
10+
* under the terms of the GNU General Public License as published by the
11+
* Free Software Foundation; either version 2 of the License, or (at your
12+
* option) any later version.
13+
*
14+
* Limited-size FIFO of skbs. Can be used more or less whenever
15+
* sk_buff_head can be used, except you need to know the queue size in
16+
* advance.
17+
* Implemented as a type-safe wrapper around ptr_ring.
18+
*/
19+
20+
#ifndef _LINUX_SKB_ARRAY_H
21+
#define _LINUX_SKB_ARRAY_H 1
22+
23+
#ifdef __KERNEL__
24+
#include <linux/ptr_ring.h>
25+
#include <linux/skbuff.h>
26+
#include <linux/if_vlan.h>
27+
#endif
28+
29+
struct skb_array {
30+
struct ptr_ring ring;
31+
};
32+
33+
/* Might be slightly faster than skb_array_full below, but callers invoking
34+
* this in a loop must use a compiler barrier, for example cpu_relax().
35+
*/
36+
static inline bool __skb_array_full(struct skb_array *a)
37+
{
38+
return __ptr_ring_full(&a->ring);
39+
}
40+
41+
static inline bool skb_array_full(struct skb_array *a)
42+
{
43+
return ptr_ring_full(&a->ring);
44+
}
45+
46+
static inline int skb_array_produce(struct skb_array *a, struct sk_buff *skb)
47+
{
48+
return ptr_ring_produce(&a->ring, skb);
49+
}
50+
51+
static inline int skb_array_produce_irq(struct skb_array *a, struct sk_buff *skb)
52+
{
53+
return ptr_ring_produce_irq(&a->ring, skb);
54+
}
55+
56+
static inline int skb_array_produce_bh(struct skb_array *a, struct sk_buff *skb)
57+
{
58+
return ptr_ring_produce_bh(&a->ring, skb);
59+
}
60+
61+
static inline int skb_array_produce_any(struct skb_array *a, struct sk_buff *skb)
62+
{
63+
return ptr_ring_produce_any(&a->ring, skb);
64+
}
65+
66+
/* Might be slightly faster than skb_array_empty below, but callers invoking
67+
* this in a loop must take care to use a compiler barrier, for example
68+
* cpu_relax().
69+
*/
70+
static inline bool __skb_array_empty(struct skb_array *a)
71+
{
72+
return !__ptr_ring_peek(&a->ring);
73+
}
74+
75+
static inline bool skb_array_empty(struct skb_array *a)
76+
{
77+
return ptr_ring_empty(&a->ring);
78+
}
79+
80+
static inline struct sk_buff *skb_array_consume(struct skb_array *a)
81+
{
82+
return ptr_ring_consume(&a->ring);
83+
}
84+
85+
static inline struct sk_buff *skb_array_consume_irq(struct skb_array *a)
86+
{
87+
return ptr_ring_consume_irq(&a->ring);
88+
}
89+
90+
static inline struct sk_buff *skb_array_consume_any(struct skb_array *a)
91+
{
92+
return ptr_ring_consume_any(&a->ring);
93+
}
94+
95+
static inline struct sk_buff *skb_array_consume_bh(struct skb_array *a)
96+
{
97+
return ptr_ring_consume_bh(&a->ring);
98+
}
99+
100+
static inline int __skb_array_len_with_tag(struct sk_buff *skb)
101+
{
102+
if (likely(skb)) {
103+
int len = skb->len;
104+
105+
if (skb_vlan_tag_present(skb))
106+
len += VLAN_HLEN;
107+
108+
return len;
109+
} else {
110+
return 0;
111+
}
112+
}
113+
114+
static inline int skb_array_peek_len(struct skb_array *a)
115+
{
116+
return PTR_RING_PEEK_CALL(&a->ring, __skb_array_len_with_tag);
117+
}
118+
119+
static inline int skb_array_peek_len_irq(struct skb_array *a)
120+
{
121+
return PTR_RING_PEEK_CALL_IRQ(&a->ring, __skb_array_len_with_tag);
122+
}
123+
124+
static inline int skb_array_peek_len_bh(struct skb_array *a)
125+
{
126+
return PTR_RING_PEEK_CALL_BH(&a->ring, __skb_array_len_with_tag);
127+
}
128+
129+
static inline int skb_array_peek_len_any(struct skb_array *a)
130+
{
131+
return PTR_RING_PEEK_CALL_ANY(&a->ring, __skb_array_len_with_tag);
132+
}
133+
134+
static inline int skb_array_init(struct skb_array *a, int size, gfp_t gfp)
135+
{
136+
return ptr_ring_init(&a->ring, size, gfp);
137+
}
138+
139+
static inline void skb_array_cleanup(struct skb_array *a)
140+
{
141+
ptr_ring_cleanup(&a->ring);
142+
}
143+
144+
#endif /* _LINUX_SKB_ARRAY_H */

0 commit comments

Comments
 (0)