FD.io VPP  v17.10-9-gd594711
Vector Packet Processing
node_unserialize.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 #include <vlib/vlib.h>
16 
17 #include <vppinfra/serialize.h>
18 
19 /* serialized representation of state strings */
20 
21 #define foreach_state_string_code \
22 _(STATE_DONE, "done") \
23 _(STATE_DISABLED, "disabled") \
24 _(STATE_TIME_WAIT, "time wait") \
25 _(STATE_EVENT_WAIT, "event wait") \
26 _(STATE_ANY_WAIT, "any wait") \
27 _(STATE_POLLING, "polling") \
28 _(STATE_INTERRUPT_WAIT, "interrupt wait") \
29 _(STATE_INTERNAL, "internal")
30 
31 typedef enum
32 {
33 #define _(a,b) a,
35 #undef _
37 
38 static char *state_strings[] = {
39 #define _(a,b) b,
41 #undef _
42 };
43 
44 vlib_node_t ***
46 {
47  serialize_main_t _sm, *sm = &_sm;
48  u32 nnodes, nnexts;
49  u32 nstat_vms;
50  vlib_node_t *node;
51  vlib_node_t **nodes;
52  vlib_node_t ***nodes_by_thread = 0;
53  int i, j, k;
54  u64 l, v, c, d;
55  state_string_enum_t state_code;
56  int stats_present;
57 
58  serialize_open_vector (sm, vector);
59 
61 
62  vec_validate (nodes_by_thread, nstat_vms - 1);
63  _vec_len (nodes_by_thread) = 0;
64 
65  for (i = 0; i < nstat_vms; i++)
66  {
68 
69  nodes = 0;
70  vec_validate (nodes, nnodes - 1);
71  vec_add1 (nodes_by_thread, nodes);
72 
73  for (j = 0; j < nnodes; j++)
74  {
75  node = 0;
76  vec_validate (node, 0);
77  nodes[j] = node;
78 
79  unserialize_cstring (sm, (char **) &(node->name));
81  node->state_string = (u8 *) state_strings[state_code];
82 
85  if (nnexts > 0)
86  vec_validate (node->next_nodes, nnexts - 1);
87  for (k = 0; k < nnexts; k++)
88  node->next_nodes[k] =
90 
91  stats_present = unserialize_likely_small_unsigned_integer (sm);
92 
93  if (stats_present)
94  {
95  /* total clocks */
96  unserialize_integer (sm, &l, 8);
97  node->stats_total.clocks = l;
98  node->stats_last_clear.clocks = 0;
99 
100  /* Total calls */
101  unserialize_integer (sm, &c, 8);
102  node->stats_total.calls = c;
103 
104  /* Total vectors */
105  unserialize_integer (sm, &v, 8);
106  node->stats_total.vectors = v;
107 
108  /* Total suspends */
109  unserialize_integer (sm, &d, 8);
110  node->stats_total.suspends = d;
111  }
112  }
113  }
114  return nodes_by_thread;
115 }
116 
117 #if TEST_CODE
118 
119 static clib_error_t *
120 test_node_serialize_command_fn (vlib_main_t * vm,
121  unformat_input_t * input,
122  vlib_cli_command_t * cmd)
123 {
124  vlib_node_main_t *nm = &vm->node_main;
125  u8 *vector = 0;
126  vlib_node_t ***nodes_by_thread;
127  vlib_node_t **nodes;
128  vlib_node_t *node;
129  vlib_node_t *next_node;
130  int i, j, k;
131  u32 max_threads = (u32) ~ 0;
132  int include_nexts = 0;
133  int include_stats = 0;
134 
136  {
137  if (unformat (input, "max-threads %d", &max_threads))
138  ;
139  else if (unformat (input, "stats"))
140  include_stats = 1;
141  else if (unformat (input, "nexts"))
142  include_nexts = 1;
143  else
144  break;
145  }
146 
147  /*
148  * Keep the number of memcpy ops to a minimum (e.g. 1).
149  * The current size of the serialized vector is
150  * slightly under 4K.
151  */
152  vec_validate (vector, 16383);
153  vec_reset_length (vector);
154 
155  vector = vlib_node_serialize (nm, vector, max_threads,
156  include_nexts, include_stats);
157 
158  vlib_cli_output (vm, "result vector %d bytes", vec_len (vector));
159 
160  nodes_by_thread = vlib_node_unserialize (vector);
161 
162  vec_free (vector);
163 
164  for (i = 0; i < vec_len (nodes_by_thread); i++)
165  {
166  nodes = nodes_by_thread[i];
167 
168  vlib_cli_output (vm, "thread %d", i);
169 
170  for (j = 0; j < vec_len (nodes); j++)
171  {
172  node = nodes[j];
173 
174  vlib_cli_output (vm, "[%d] %s state %s", j, node->name,
175  node->state_string);
176 
178  (vm, " clocks %lld calls %lld suspends"
179  " %lld vectors %lld",
180  node->stats_total.clocks,
181  node->stats_total.calls,
182  node->stats_total.suspends, node->stats_total.vectors);
183 
184  for (k = 0; k < vec_len (node->next_nodes); k++)
185  {
186  if (node->next_nodes[k] != ~0)
187  {
188  next_node = nodes[node->next_nodes[k]];
189  vlib_cli_output (vm, " [%d] %s", k, next_node->name);
190  }
191  }
192  }
193  }
194 
195  for (j = 0; j < vec_len (nodes_by_thread); j++)
196  {
197  nodes = nodes_by_thread[j];
198 
199  for (i = 0; i < vec_len (nodes); i++)
200  {
201  vec_free (nodes[i]->name);
202  vec_free (nodes[i]->next_nodes);
203  vec_free (nodes[i]);
204  }
205  vec_free (nodes);
206  }
207  vec_free (nodes_by_thread);
208 
209  return 0;
210 }
211 
212 /* *INDENT-OFF* */
213 VLIB_CLI_COMMAND (test_node_serialize_node, static) = {
214  .path = "test node serialize",
215  .short_help = "test node serialize [max-threads NN] nexts stats",
216  .function = test_node_serialize_command_fn,
217 };
218 /* *INDENT-ON* */
219 #endif
220 
221 /*
222  * fd.io coding-style-patch-verification: ON
223  *
224  * Local Variables:
225  * eval: (c-set-style "gnu")
226  * End:
227  */
u32 * next_nodes
Definition: node.h:288
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:432
u8 * state_string
Definition: node.h:322
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
Definition: serialize.h:254
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
state_string_enum_t
u8 * vlib_node_serialize(vlib_node_main_t *nm, u8 *vector, u32 max_threads, int include_nexts, int include_stats)
vlib_node_t *** vlib_node_unserialize(u8 *vector)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
vlib_node_stats_t stats_last_clear
Definition: node.h:231
unsigned long u64
Definition: types.h:89
#define foreach_state_string_code
vlib_node_stats_t stats_total
Definition: node.h:227
#define v
Definition: acl.c:323
struct _unformat_input_t unformat_input_t
void unserialize_cstring(serialize_main_t *m, char **s)
Definition: serialize.c:178
u8 * name
Definition: node.h:221
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
svmdb_client_t * c
void serialize_open_vector(serialize_main_t *m, u8 *vector)
Definition: serialize.c:908
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
Definition: serialize.h:201
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
unsigned int u32
Definition: types.h:88
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
vlib_node_main_t node_main
Definition: main.h:129
vlib_node_type_t type
Definition: node.h:234
static char * state_strings[]
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
state_string_enum_t
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169