FD.io VPP  v21.01.1
Vector Packet Processing
virtio_buffering.h
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2020 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #ifndef _VNET_DEVICES_VIRTIO_VIRTIO_BUFFERING_H_
19 #define _VNET_DEVICES_VIRTIO_VIRTIO_BUFFERING_H_
20 
21 #define VIRTIO_BUFFERING_DEFAULT_SIZE 1024
22 #define VIRTIO_BUFFERING_TIMEOUT 1e-5
23 
24 typedef struct
25 {
35 
38  u32 node_index, u16 size)
39 {
40  if (*buffering)
41  return clib_error_return (0, "buffering: already initialized");
42 
43  if (!is_pow2 (size))
44  return clib_error_return (0, "buffering: size must be power of 2");
45 
46  if (size > 32768)
47  return clib_error_return (0, "buffering: size must be 32768 or lower");
48 
49  if (size == 0)
51 
52  virtio_vring_buffering_t *b_temp = 0;
53  b_temp =
56  if (!b_temp)
57  return clib_error_return (0, "buffering: memory allocation failed");
58 
59  clib_memset (b_temp, 0, sizeof (virtio_vring_buffering_t));
60 
61  b_temp->node_index = node_index;
62  b_temp->free_size = size;
63  b_temp->size = size;
64 
66  b_temp->is_enable = 1;
67 
68  *buffering = b_temp;
69  return 0;
70 }
71 
74  virtio_vring_buffering_t * buffering)
75 {
76  u16 n_buffers = buffering->size - buffering->free_size;
77  if (n_buffers)
78  {
79  vlib_buffer_free_from_ring (vm, buffering->buffers, buffering->front,
80  buffering->size, n_buffers);
81  buffering->free_size += n_buffers;
82  }
83 }
84 
87  virtio_vring_buffering_t * buffering)
88 {
89  if (buffering)
90  {
92  vec_free (buffering->buffers);
93  clib_mem_free (buffering);
94  }
95 }
96 
99 {
100  if (buffering)
101  return buffering->is_enable;
102 
103  return 0;
104 }
105 
108  u8 is_enable)
109 {
110  if (buffering)
111  buffering->is_enable = is_enable;
112 }
113 
116  virtio_vring_buffering_t * buffering,
117  f64 timeout_expire)
118 {
119  if (buffering)
120  buffering->timeout_ts = vlib_time_now (vm) + timeout_expire;
121 }
122 
125  virtio_vring_buffering_t * buffering)
126 {
127  if (buffering && (buffering->timeout_ts < vlib_time_now (vm)))
128  return 1;
129  return 0;
130 }
131 
134 {
135  if (buffering->size == buffering->free_size)
136  return 1;
137  return 0;
138 }
139 
142 {
143  if (buffering->free_size == 0)
144  return 1;
145  return 0;
146 }
147 
150 {
151  return (buffering->size - buffering->free_size);
152 }
153 
156  u32 * bi, u16 n_store)
157 {
158  u16 mask, n_s = 0, i = 0;
159 
160  if (!virtio_vring_buffering_is_enable (buffering)
161  || virtio_vring_buffering_is_full (buffering))
162  return 0;
163 
164  mask = buffering->size - 1;
165  n_s = clib_min (n_store, buffering->free_size);
166 
167  while (i < n_s)
168  {
169  buffering->buffers[buffering->back] = bi[i];
170  buffering->back = (buffering->back + 1) & mask;
171  buffering->free_size--;
172  i++;
173  }
174  return n_s;
175 }
176 
179 {
180  u32 bi = ~0;
181  u16 mask = buffering->size - 1;
182  if (virtio_vring_buffering_is_empty (buffering))
183  return bi;
184 
185  bi = buffering->buffers[buffering->front];
186  buffering->buffers[buffering->front] = ~0;
187  buffering->front = (buffering->front + 1) & mask;
188  buffering->free_size++;
189  return bi;
190 }
191 
194 {
195  u32 bi = ~0;
196  u16 mask = buffering->size - 1;
197  if (virtio_vring_buffering_is_empty (buffering))
198  return bi;
199 
200  buffering->back = (buffering->back - 1) & mask;
201  bi = buffering->buffers[buffering->back];
202  buffering->buffers[buffering->back] = ~0;
203  buffering->free_size++;
204  return bi;
205 }
206 
210  buffering)
211 {
212  if (buffering && virtio_vring_buffering_is_timeout (vm, buffering)
213  && virtio_vring_n_buffers (buffering))
214  {
215  vlib_frame_t *f = vlib_get_frame_to_node (vm, buffering->node_index);
216  u32 *f_to = vlib_frame_vector_args (f);
217  f_to[f->n_vectors] = virtio_vring_buffering_read_from_back (buffering);
218  f->n_vectors++;
219  vlib_put_frame_to_node (vm, buffering->node_index, f);
220  virtio_vring_buffering_set_timeout (vm, buffering,
222  }
223 }
224 
226 virtio_vring_buffering_format (u8 * s, va_list * args)
227 {
228  virtio_vring_buffering_t *buffering =
229  va_arg (*args, virtio_vring_buffering_t *);
230  u32 indent = format_get_indent (s);
231 
232  if (!buffering)
233  return s;
234 
235  indent += 2;
236 
237  if (buffering->is_enable)
238  s = format (s, "packet-buffering: enable\n");
239  else
240  s = format (s, "packet-buffering: disable\n");
241  s =
242  format (s,
243  "%Usize %u n_buffers %u front %u back %u",
244  format_white_space, indent, buffering->size,
245  virtio_vring_n_buffers (buffering), buffering->front,
246  buffering->back);
247 
248  return s;
249 }
250 
251 #endif /* _VNET_DEVICES_VIRTIO_VIRTIO_BUFFERING_H_ */
252 
253 /*
254  * fd.io coding-style-patch-verification: ON
255  *
256  * Local Variables:
257  * eval: (c-set-style "gnu")
258  * End:
259  */
static_always_inline u8 virtio_vring_buffering_is_full(virtio_vring_buffering_t *buffering)
static_always_inline u16 virtio_vring_n_buffers(virtio_vring_buffering_t *buffering)
#define clib_min(x, y)
Definition: clib.h:328
#define VIRTIO_BUFFERING_DEFAULT_SIZE
static_always_inline u8 virtio_vring_buffering_is_timeout(vlib_main_t *vm, virtio_vring_buffering_t *buffering)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:334
static u32 format_get_indent(u8 *s)
Definition: format.h:72
vlib_main_t * vm
Definition: in2out_ed.c:1580
static_always_inline u32 virtio_vring_buffering_read_from_front(virtio_vring_buffering_t *buffering)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:520
u16 mask
Definition: flow_types.api:52
static_always_inline void virtio_vring_buffering_set_timeout(vlib_main_t *vm, virtio_vring_buffering_t *buffering, f64 timeout_expire)
unsigned char u8
Definition: types.h:56
double f64
Definition: types.h:142
#define static_always_inline
Definition: clib.h:109
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
description fragment has unexpected format
Definition: map.api:433
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:182
#define clib_error_return(e, args...)
Definition: error.h:99
static_always_inline void virtio_vring_buffering_buffers_free(vlib_main_t *vm, virtio_vring_buffering_t *buffering)
static_always_inline u32 virtio_vring_buffering_read_from_back(virtio_vring_buffering_t *buffering)
unsigned int u32
Definition: types.h:88
static void vlib_buffer_free_from_ring(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring.
Definition: buffer_funcs.h:984
static_always_inline u8 virtio_vring_buffering_is_enable(virtio_vring_buffering_t *buffering)
unsigned short u16
Definition: types.h:57
u32 size
Definition: vhost_user.h:106
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:216
u16 n_vectors
Definition: node.h:397
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define VIRTIO_BUFFERING_TIMEOUT
static_always_inline void virtio_vring_buffering_schedule_node_on_dispatcher(vlib_main_t *vm, virtio_vring_buffering_t *buffering)
static void clib_mem_free(void *p)
Definition: mem.h:311
static void * clib_mem_alloc(uword size)
Definition: mem.h:253
static_always_inline u8 virtio_vring_buffering_is_empty(virtio_vring_buffering_t *buffering)
static uword is_pow2(uword x)
Definition: clib.h:253
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
static_always_inline u16 virtio_vring_buffering_store_packets(virtio_vring_buffering_t *buffering, u32 *bi, u16 n_store)
static_always_inline clib_error_t * virtio_vring_buffering_init(virtio_vring_buffering_t **buffering, u32 node_index, u16 size)
static_always_inline u8 * virtio_vring_buffering_format(u8 *s, va_list *args)
static_always_inline void virtio_vring_buffering_set_is_enable(virtio_vring_buffering_t *buffering, u8 is_enable)
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
static_always_inline void virtio_vring_buffering_free(vlib_main_t *vm, virtio_vring_buffering_t *buffering)