Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  *  Definitions for the 'struct skb_array' datastructure.
0004  *
0005  *  Author:
0006  *      Michael S. Tsirkin <mst@redhat.com>
0007  *
0008  *  Copyright (C) 2016 Red Hat, Inc.
0009  *
0010  *  Limited-size FIFO of skbs. Can be used more or less whenever
0011  *  sk_buff_head can be used, except you need to know the queue size in
0012  *  advance.
0013  *  Implemented as a type-safe wrapper around ptr_ring.
0014  */
0015 
0016 #ifndef _LINUX_SKB_ARRAY_H
0017 #define _LINUX_SKB_ARRAY_H 1
0018 
0019 #ifdef __KERNEL__
0020 #include <linux/ptr_ring.h>
0021 #include <linux/skbuff.h>
0022 #include <linux/if_vlan.h>
0023 #endif
0024 
0025 struct skb_array {
0026     struct ptr_ring ring;
0027 };
0028 
0029 /* Might be slightly faster than skb_array_full below, but callers invoking
0030  * this in a loop must use a compiler barrier, for example cpu_relax().
0031  */
0032 static inline bool __skb_array_full(struct skb_array *a)
0033 {
0034     return __ptr_ring_full(&a->ring);
0035 }
0036 
0037 static inline bool skb_array_full(struct skb_array *a)
0038 {
0039     return ptr_ring_full(&a->ring);
0040 }
0041 
0042 static inline int skb_array_produce(struct skb_array *a, struct sk_buff *skb)
0043 {
0044     return ptr_ring_produce(&a->ring, skb);
0045 }
0046 
0047 static inline int skb_array_produce_irq(struct skb_array *a, struct sk_buff *skb)
0048 {
0049     return ptr_ring_produce_irq(&a->ring, skb);
0050 }
0051 
0052 static inline int skb_array_produce_bh(struct skb_array *a, struct sk_buff *skb)
0053 {
0054     return ptr_ring_produce_bh(&a->ring, skb);
0055 }
0056 
0057 static inline int skb_array_produce_any(struct skb_array *a, struct sk_buff *skb)
0058 {
0059     return ptr_ring_produce_any(&a->ring, skb);
0060 }
0061 
0062 /* Might be slightly faster than skb_array_empty below, but only safe if the
0063  * array is never resized. Also, callers invoking this in a loop must take care
0064  * to use a compiler barrier, for example cpu_relax().
0065  */
0066 static inline bool __skb_array_empty(struct skb_array *a)
0067 {
0068     return __ptr_ring_empty(&a->ring);
0069 }
0070 
0071 static inline struct sk_buff *__skb_array_peek(struct skb_array *a)
0072 {
0073     return __ptr_ring_peek(&a->ring);
0074 }
0075 
0076 static inline bool skb_array_empty(struct skb_array *a)
0077 {
0078     return ptr_ring_empty(&a->ring);
0079 }
0080 
0081 static inline bool skb_array_empty_bh(struct skb_array *a)
0082 {
0083     return ptr_ring_empty_bh(&a->ring);
0084 }
0085 
0086 static inline bool skb_array_empty_irq(struct skb_array *a)
0087 {
0088     return ptr_ring_empty_irq(&a->ring);
0089 }
0090 
0091 static inline bool skb_array_empty_any(struct skb_array *a)
0092 {
0093     return ptr_ring_empty_any(&a->ring);
0094 }
0095 
0096 static inline struct sk_buff *__skb_array_consume(struct skb_array *a)
0097 {
0098     return __ptr_ring_consume(&a->ring);
0099 }
0100 
0101 static inline struct sk_buff *skb_array_consume(struct skb_array *a)
0102 {
0103     return ptr_ring_consume(&a->ring);
0104 }
0105 
0106 static inline int skb_array_consume_batched(struct skb_array *a,
0107                         struct sk_buff **array, int n)
0108 {
0109     return ptr_ring_consume_batched(&a->ring, (void **)array, n);
0110 }
0111 
0112 static inline struct sk_buff *skb_array_consume_irq(struct skb_array *a)
0113 {
0114     return ptr_ring_consume_irq(&a->ring);
0115 }
0116 
0117 static inline int skb_array_consume_batched_irq(struct skb_array *a,
0118                         struct sk_buff **array, int n)
0119 {
0120     return ptr_ring_consume_batched_irq(&a->ring, (void **)array, n);
0121 }
0122 
0123 static inline struct sk_buff *skb_array_consume_any(struct skb_array *a)
0124 {
0125     return ptr_ring_consume_any(&a->ring);
0126 }
0127 
0128 static inline int skb_array_consume_batched_any(struct skb_array *a,
0129                         struct sk_buff **array, int n)
0130 {
0131     return ptr_ring_consume_batched_any(&a->ring, (void **)array, n);
0132 }
0133 
0134 
0135 static inline struct sk_buff *skb_array_consume_bh(struct skb_array *a)
0136 {
0137     return ptr_ring_consume_bh(&a->ring);
0138 }
0139 
0140 static inline int skb_array_consume_batched_bh(struct skb_array *a,
0141                            struct sk_buff **array, int n)
0142 {
0143     return ptr_ring_consume_batched_bh(&a->ring, (void **)array, n);
0144 }
0145 
0146 static inline int __skb_array_len_with_tag(struct sk_buff *skb)
0147 {
0148     if (likely(skb)) {
0149         int len = skb->len;
0150 
0151         if (skb_vlan_tag_present(skb))
0152             len += VLAN_HLEN;
0153 
0154         return len;
0155     } else {
0156         return 0;
0157     }
0158 }
0159 
0160 static inline int skb_array_peek_len(struct skb_array *a)
0161 {
0162     return PTR_RING_PEEK_CALL(&a->ring, __skb_array_len_with_tag);
0163 }
0164 
0165 static inline int skb_array_peek_len_irq(struct skb_array *a)
0166 {
0167     return PTR_RING_PEEK_CALL_IRQ(&a->ring, __skb_array_len_with_tag);
0168 }
0169 
0170 static inline int skb_array_peek_len_bh(struct skb_array *a)
0171 {
0172     return PTR_RING_PEEK_CALL_BH(&a->ring, __skb_array_len_with_tag);
0173 }
0174 
0175 static inline int skb_array_peek_len_any(struct skb_array *a)
0176 {
0177     return PTR_RING_PEEK_CALL_ANY(&a->ring, __skb_array_len_with_tag);
0178 }
0179 
0180 static inline int skb_array_init(struct skb_array *a, int size, gfp_t gfp)
0181 {
0182     return ptr_ring_init(&a->ring, size, gfp);
0183 }
0184 
0185 static void __skb_array_destroy_skb(void *ptr)
0186 {
0187     kfree_skb(ptr);
0188 }
0189 
0190 static inline void skb_array_unconsume(struct skb_array *a,
0191                        struct sk_buff **skbs, int n)
0192 {
0193     ptr_ring_unconsume(&a->ring, (void **)skbs, n, __skb_array_destroy_skb);
0194 }
0195 
0196 static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp)
0197 {
0198     return ptr_ring_resize(&a->ring, size, gfp, __skb_array_destroy_skb);
0199 }
0200 
0201 static inline int skb_array_resize_multiple(struct skb_array **rings,
0202                         int nrings, unsigned int size,
0203                         gfp_t gfp)
0204 {
0205     BUILD_BUG_ON(offsetof(struct skb_array, ring));
0206     return ptr_ring_resize_multiple((struct ptr_ring **)rings,
0207                     nrings, size, gfp,
0208                     __skb_array_destroy_skb);
0209 }
0210 
0211 static inline void skb_array_cleanup(struct skb_array *a)
0212 {
0213     ptr_ring_cleanup(&a->ring, __skb_array_destroy_skb);
0214 }
0215 
0216 #endif /* _LINUX_SKB_ARRAY_H  */