FD.io VPP  v16.09
Vector Packet Processing
cj.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * cj.c
4  *
5  * Copyright (c) 2013 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <stdio.h>
21 #include <vlib/vlib.h>
22 
23 #include <vlib/unix/cj.h>
24 
26 
27 void
28 cj_log (u32 type, void *data0, void *data1)
29 {
30  u64 new_tail;
31  cj_main_t *cjm = &cj_main;
32  cj_record_t *r;
33 
34  if (cjm->enable == 0)
35  return;
36 
37  new_tail = __sync_add_and_fetch (&cjm->tail, 1);
38 
39  r = (cj_record_t *) & (cjm->records[new_tail & (cjm->num_records - 1)]);
40  r->time = vlib_time_now (cjm->vlib_main);
41  r->cpu = os_get_cpu_number ();
42  r->type = type;
43  r->data[0] = pointer_to_uword (data0);
44  r->data[1] = pointer_to_uword (data1);
45 }
46 
47 void
48 cj_stop (void)
49 {
50  cj_main_t *cjm = &cj_main;
51 
52  cjm->enable = 0;
53 }
54 
55 
58 {
59  cj_main_t *cjm = &cj_main;
60 
61  cjm->vlib_main = vm;
62  return 0;
63 }
64 
66 
67 static clib_error_t *
69 {
70  cj_main_t *cjm = &cj_main;
71  int matched = 0;
72  int enable = 0;
73 
75  {
76  if (unformat (input, "records %d", &cjm->num_records))
77  matched = 1;
78  else if (unformat (input, "on"))
79  enable = 1;
80  else
81  return clib_error_return (0, "cj_config: unknown input '%U'",
82  format_unformat_error, input);
83  }
84 
85  if (matched == 0)
86  return 0;
87 
88  cjm->num_records = max_pow2 (cjm->num_records);
89  vec_validate (cjm->records, cjm->num_records - 1);
90  memset (cjm->records, 0xff, cjm->num_records * sizeof (cj_record_t));
91  cjm->tail = ~0;
92  cjm->enable = enable;
93 
94  return 0;
95 }
96 
98 
99 void
100 cj_enable_disable (int is_enable)
101 {
102  cj_main_t *cjm = &cj_main;
103 
104  if (cjm->num_records)
105  cjm->enable = is_enable;
106  else
107  vlib_cli_output (cjm->vlib_main, "CJ not configured...");
108 }
109 
110 static inline void
112 {
113  fprintf (stderr, "[%d]: %10.6f T%02d %llx %llx\n",
114  r->cpu, r->time, r->type, (long long unsigned int) r->data[0],
115  (long long unsigned int) r->data[1]);
116 }
117 
118 static void
119 cj_dump_internal (u8 filter0_enable, u64 filter0,
120  u8 filter1_enable, u64 filter1)
121 {
122  cj_main_t *cjm = &cj_main;
123  cj_record_t *r;
124  u32 i, index;
125 
126  if (cjm->num_records == 0)
127  {
128  fprintf (stderr, "CJ not configured...\n");
129  return;
130  }
131 
132  if (cjm->tail == (u64) ~ 0)
133  {
134  fprintf (stderr, "No data collected...\n");
135  return;
136  }
137 
138  /* Has the trace wrapped? */
139  index = (cjm->tail + 1) & (cjm->num_records - 1);
140  r = &(cjm->records[index]);
141 
142  if (r->cpu != (u32) ~ 0)
143  {
144  /* Yes, dump from tail + 1 to the end */
145  for (i = index; i < cjm->num_records; i++)
146  {
147  if (filter0_enable && (r->data[0] != filter0))
148  goto skip;
149  if (filter1_enable && (r->data[1] != filter1))
150  goto skip;
151  cj_dump_one_record (r);
152  skip:
153  r++;
154  }
155  }
156  /* dump from the beginning through the final tail */
157  r = cjm->records;
158  for (i = 0; i <= cjm->tail; i++)
159  {
160  if (filter0_enable && (r->data[0] != filter0))
161  goto skip2;
162  if (filter1_enable && (r->data[1] != filter1))
163  goto skip2;
164  cj_dump_one_record (r);
165  skip2:
166  r++;
167  }
168 }
169 
170 void
171 cj_dump (void)
172 {
173  cj_dump_internal (0, 0, 0, 0);
174 }
175 
176 void
178 {
179  cj_dump_internal (1 /* enable f0 */ , filter0, 0, 0);
180 }
181 
182 void
184 {
185  cj_dump_internal (0, 0, 1 /* enable f1 */ , filter1);
186 }
187 
188 void
189 cj_dump_filter_data12 (u64 filter0, u64 filter1)
190 {
191  cj_dump_internal (1, filter0, 1, filter1);
192 }
193 
194 static clib_error_t *
196  unformat_input_t * input, vlib_cli_command_t * cmd)
197 {
198  int is_enable = -1;
199  int is_dump = -1;
200 
202  {
203  if (unformat (input, "enable") || unformat (input, "on"))
204  is_enable = 1;
205  else if (unformat (input, "disable") || unformat (input, "off"))
206  is_enable = 0;
207  else if (unformat (input, "dump"))
208  is_dump = 1;
209  else
210  return clib_error_return (0, "unknown input `%U'",
211  format_unformat_error, input);
212  }
213 
214  if (is_enable >= 0)
215  cj_enable_disable (is_enable);
216 
217  if (is_dump > 0)
218  cj_dump ();
219 
220  return 0;
221 }
222 
223 /* *INDENT-OFF* */
224 VLIB_CLI_COMMAND (cj_command,static) = {
225  .path = "cj",
226  .short_help = "cj",
227  .function = cj_command_fn,
228 };
229 /* *INDENT-ON* */
230 
231 
232 /*
233  * fd.io coding-style-patch-verification: ON
234  *
235  * Local Variables:
236  * eval: (c-set-style "gnu")
237  * End:
238  */
void cj_dump_filter_data12(u64 filter0, u64 filter1)
Definition: cj.c:189
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
u32 cpu
Definition: cj.h:26
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
Definition: cj.h:31
static clib_error_t * cj_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cj.c:195
volatile u32 enable
Definition: cj.h:36
volatile u64 tail
Definition: cj.h:33
void cj_dump_filter_data1(u64 filter1)
Definition: cj.c:183
void cj_stop(void)
Definition: cj.c:48
void cj_enable_disable(int is_enable)
Definition: cj.c:100
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
f64 time
Definition: cj.h:25
unsigned long u64
Definition: types.h:89
void cj_log(u32 type, void *data0, void *data1)
Definition: cj.c:28
static uword pointer_to_uword(const void *p)
Definition: types.h:131
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
cj_main_t cj_main
Definition: cj.c:25
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:118
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
vlib_main_t * vlib_main
Definition: cj.h:38
static void cj_dump_one_record(cj_record_t *r)
Definition: cj.c:111
static uword max_pow2(uword x)
Definition: clib.h:257
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void cj_dump_filter_data0(u64 filter0)
Definition: cj.c:177
clib_error_t * cj_init(vlib_main_t *vm)
Definition: cj.c:57
u64 data[2]
Definition: cj.h:28
Definition: cj.h:23
u32 type
Definition: cj.h:27
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
unsigned char u8
Definition: types.h:56
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static void cj_dump_internal(u8 filter0_enable, u64 filter0, u8 filter1_enable, u64 filter1)
Definition: cj.c:119
u32 num_records
Definition: cj.h:35
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
cj_record_t * records
Definition: cj.h:34
void cj_dump(void)
Definition: cj.c:171
static clib_error_t * cj_config(vlib_main_t *vm, unformat_input_t *input)
Definition: cj.c:68