FD.io VPP  v17.07.01-10-g3be13f0
Vector Packet Processing
buffer_serialize.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * buffer.c: allocate/free network buffers.
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vlib/vlib.h>
41 
42 static void
44 {
45  vlib_main_t *vm;
47  uword n, n_bytes_to_write;
49 
50  n_bytes_to_write = s->current_buffer_index;
51  sm =
54  vm = sm->vlib_main;
55 
56  ASSERT (sm->tx.max_n_data_bytes_per_chain > 0);
58  || sm->tx.n_total_data_bytes + n_bytes_to_write >
59  sm->tx.max_n_data_bytes_per_chain)
60  {
62 
63  last = vlib_get_buffer (vm, sm->last_buffer);
64  last->current_length = n_bytes_to_write;
65 
66  vlib_set_next_frame_buffer (vm, &p->node_runtime, sm->tx.next_index,
67  sm->first_buffer);
68 
69  sm->first_buffer = sm->last_buffer = ~0;
70  sm->tx.n_total_data_bytes = 0;
71  }
72 
73  else if (n_bytes_to_write == 0 && s->n_buffer_bytes == 0)
74  {
75  ASSERT (sm->first_buffer == ~0);
76  ASSERT (sm->last_buffer == ~0);
77  n =
79  sm->tx.free_list_index);
80  if (n != 1)
81  serialize_error (m,
83  ("vlib_buffer_alloc_from_free_list fails"));
84  sm->last_buffer = sm->first_buffer;
85  s->n_buffer_bytes =
86  vlib_buffer_free_list_buffer_size (vm, sm->tx.free_list_index);
87  }
88 
89  if (n_bytes_to_write > 0)
90  {
91  vlib_buffer_t *prev = vlib_get_buffer (vm, sm->last_buffer);
92  n =
94  sm->tx.free_list_index);
95  if (n != 1)
96  serialize_error (m,
98  ("vlib_buffer_alloc_from_free_list fails"));
99  sm->tx.n_total_data_bytes += n_bytes_to_write;
100  prev->current_length = n_bytes_to_write;
101  prev->next_buffer = sm->last_buffer;
103  }
104 
105  if (sm->last_buffer != ~0)
106  {
107  last = vlib_get_buffer (vm, sm->last_buffer);
108  s->buffer = vlib_buffer_get_current (last);
109  s->current_buffer_index = 0;
111  }
112 }
113 
114 static void
116 {
117  vlib_main_t *vm;
120 
121  sm =
124  vm = sm->vlib_main;
125 
127  return;
128 
129  if (sm->last_buffer != ~0)
130  {
131  last = vlib_get_buffer (vm, sm->last_buffer);
132 
133  if (last->flags & VLIB_BUFFER_NEXT_PRESENT)
134  sm->last_buffer = last->next_buffer;
135  else
136  {
137  vlib_buffer_free (vm, &sm->first_buffer, /* count */ 1);
138  sm->first_buffer = sm->last_buffer = ~0;
139  }
140  }
141 
142  if (sm->last_buffer == ~0)
143  {
144  while (clib_fifo_elts (sm->rx.buffer_fifo) == 0)
145  {
146  sm->rx.ready_one_time_event =
148  ~0);
149  vlib_process_wait_for_one_time_event (vm, /* no event data */ 0,
150  sm->rx.ready_one_time_event);
151  }
152 
153  clib_fifo_sub1 (sm->rx.buffer_fifo, sm->first_buffer);
154  sm->last_buffer = sm->first_buffer;
155  }
156 
157  ASSERT (sm->last_buffer != ~0);
158 
159  last = vlib_get_buffer (vm, sm->last_buffer);
160  s->current_buffer_index = 0;
161  s->buffer = vlib_buffer_get_current (last);
162  s->n_buffer_bytes = last->current_length;
163 }
164 
165 static void
167  vlib_main_t * vm,
168  vlib_serialize_buffer_main_t * sm, uword is_read)
169 {
170  /* Initialize serialize main but save overflow buffer for re-use between calls. */
171  {
172  u8 *save = m->stream.overflow_buffer;
173  memset (m, 0, sizeof (m[0]));
174  m->stream.overflow_buffer = save;
175  if (save)
176  _vec_len (save) = 0;
177  }
178 
179  sm->first_buffer = sm->last_buffer = ~0;
180  if (is_read)
181  clib_fifo_reset (sm->rx.buffer_fifo);
182  else
183  sm->tx.n_total_data_bytes = 0;
184  sm->vlib_main = vm;
187 }
188 
189 void
192 {
193  serialize_open_vlib_helper (m, vm, sm, /* is_read */ 0);
194 }
195 
196 void
199 {
200  serialize_open_vlib_helper (m, vm, sm, /* is_read */ 1);
201 }
202 
203 u32
205 {
210  serialize_stream_t *s = &m->stream;
211 
212  last = vlib_get_buffer (sm->vlib_main, sm->last_buffer);
214 
215  if (vec_len (s->overflow_buffer) > 0)
216  {
217  sm->last_buffer
218  = vlib_buffer_add_data (sm->vlib_main, sm->tx.free_list_index,
219  sm->last_buffer == ~0 ? 0 : sm->last_buffer,
220  s->overflow_buffer,
221  vec_len (s->overflow_buffer));
222  _vec_len (s->overflow_buffer) = 0;
223  }
224 
225  return sm->first_buffer;
226 }
227 
228 void
230 {
234  if (sm->first_buffer != ~0)
236  clib_fifo_reset (sm->rx.buffer_fifo);
237  if (m->stream.overflow_buffer)
238  _vec_len (m->stream.overflow_buffer) = 0;
239 }
240 
241 /** @endcond */
242 /*
243  * fd.io coding-style-patch-verification: ON
244  *
245  * Local Variables:
246  * eval: (c-set-style "gnu")
247  * End:
248  */
static void serialize_open_vlib_helper(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm, uword is_read)
u32 serialize_close_vlib_buffer(serialize_main_t *m)
vlib_node_runtime_t node_runtime
Definition: node.h:499
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:290
static uword clib_fifo_elts(void *v)
Definition: fifo.h:66
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
Definition: node_funcs.h:399
static uword vlib_current_process(vlib_main_t *vm)
Definition: node_funcs.h:426
serialize_main_header_t header
Definition: serialize.h:146
static void serialize_error(serialize_main_header_t *m, clib_error_t *error)
Definition: serialize.h:107
struct vlib_main_t * vlib_main
Definition: buffer.h:429
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
static void vlib_serialize_rx(serialize_main_header_t *m, serialize_stream_t *s)
void unserialize_open_vlib_buffer(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
#define VLIB_BUFFER_NEXT_PRESENT
Definition: buffer.h:87
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:67
static uword serialize_stream_is_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:87
void unserialize_close_vlib_buffer(serialize_main_t *m)
#define clib_error_create(args...)
Definition: error.h:96
static uword pointer_to_uword(const void *p)
Definition: types.h:131
void serialize_open_vlib_buffer(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
struct vlib_serialize_buffer_main_t::@26::@29 rx
#define clib_fifo_sub1(f, e)
Definition: fifo.h:224
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:71
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:188
static u32 vlib_buffer_free_list_buffer_size(vlib_main_t *vm, u32 free_list_index)
Definition: buffer_funcs.h:399
static void clib_fifo_reset(void *v)
Definition: fifo.h:88
#define uword_to_pointer(u, type)
Definition: types.h:136
serialize_stream_t stream
Definition: serialize.h:147
u32 current_buffer_index
Definition: serialize.h:62
static void vlib_serialize_tx(serialize_main_header_t *m, serialize_stream_t *s)
static vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
Definition: node_funcs.h:413
static uword vlib_process_wait_for_one_time_event(vlib_main_t *vm, uword **data_vector, uword with_type_index)
Definition: node_funcs.h:640
static uword vlib_process_create_one_time_event(vlib_main_t *vm, uword node_index, uword with_type_opaque)
Definition: node_funcs.h:741
serialize_data_function_t * data_function
Definition: serialize.h:97
static u32 vlib_buffer_alloc_from_free_list(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 free_list_index)
Allocate buffers from specific freelist into supplied array.
Definition: buffer_funcs.h:269
uword data_function_opaque
Definition: serialize.h:74
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:109
u32 vlib_buffer_add_data(vlib_main_t *vm, u32 free_list_index, u32 buffer_index, void *data, u32 n_data_bytes)
u64 uword
Definition: types.h:112
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
struct vlib_serialize_buffer_main_t::@26::@28 tx
static void vlib_buffer_free_one(vlib_main_t *vm, u32 buffer_index)
Free one buffer Shorthand to free a single buffer chain.
Definition: buffer_funcs.h:331
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:74
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57