FD.io VPP  v16.06
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 cj_stop(void)
48 {
49  cj_main_t * cjm = &cj_main;
50 
51  cjm->enable = 0;
52 }
53 
54 
56 {
57  cj_main_t * cjm = &cj_main;
58 
59  cjm->vlib_main = vm;
60  return 0;
61 }
63 
64 static clib_error_t *
66 {
67  cj_main_t * cjm = &cj_main;
68  int matched = 0;
69  int enable = 0;
70 
72  {
73  if (unformat (input, "records %d", &cjm->num_records))
74  matched = 1;
75  else if (unformat (input, "on"))
76  enable = 1;
77  else
78  return clib_error_return (0, "cj_config: unknown input '%U'",
79  format_unformat_error, input);
80  }
81 
82  if (matched == 0)
83  return 0;
84 
85  cjm->num_records = max_pow2 (cjm->num_records);
86  vec_validate (cjm->records, cjm->num_records-1);
87  memset (cjm->records, 0xff, cjm->num_records * sizeof (cj_record_t));
88  cjm->tail = ~0;
89  cjm->enable = enable;
90 
91  return 0;
92 }
93 
95 
96 void cj_enable_disable (int is_enable)
97 {
98  cj_main_t * cjm = &cj_main;
99 
100  if (cjm->num_records)
101  cjm->enable = is_enable;
102  else
103  vlib_cli_output (cjm->vlib_main, "CJ not configured...");
104 }
105 
106 static inline void cj_dump_one_record (cj_record_t * r)
107 {
108  fprintf (stderr, "[%d]: %10.6f T%02d %llx %llx\n",
109  r->cpu, r->time, r->type, (long long unsigned int) r->data[0],
110  (long long unsigned int) r->data[1]);
111 }
112 
113 static void cj_dump_internal (u8 filter0_enable, u64 filter0,
114  u8 filter1_enable, u64 filter1)
115 {
116  cj_main_t * cjm = &cj_main;
117  cj_record_t * r;
118  u32 i, index;
119 
120  if (cjm->num_records == 0)
121  {
122  fprintf (stderr, "CJ not configured...\n");
123  return;
124  }
125 
126  if (cjm->tail == (u64)~0)
127  {
128  fprintf (stderr, "No data collected...\n");
129  return;
130  }
131 
132  /* Has the trace wrapped? */
133  index = (cjm->tail+1) & (cjm->num_records - 1);
134  r = &(cjm->records[index]);
135 
136  if (r->cpu != (u32)~0)
137  {
138  /* Yes, dump from tail + 1 to the end */
139  for (i = index; i < cjm->num_records; i++)
140  {
141  if (filter0_enable && (r->data[0] != filter0))
142  goto skip;
143  if (filter1_enable && (r->data[1] != filter1))
144  goto skip;
145  cj_dump_one_record (r);
146  skip:
147  r++;
148  }
149  }
150  /* dump from the beginning through the final tail */
151  r = cjm->records;
152  for (i = 0; i <= cjm->tail; i++)
153  {
154  if (filter0_enable && (r->data[0] != filter0))
155  goto skip2;
156  if (filter1_enable && (r->data[1] != filter1))
157  goto skip2;
158  cj_dump_one_record (r);
159  skip2:
160  r++;
161  }
162 }
163 
164 void cj_dump (void)
165 {
166  cj_dump_internal (0, 0, 0, 0);
167 }
168 
169 void cj_dump_filter_data0 (u64 filter0)
170 {
171  cj_dump_internal (1/* enable f0 */, filter0, 0, 0);
172 }
173 
174 void cj_dump_filter_data1 (u64 filter1)
175 {
176  cj_dump_internal (0, 0, 1 /* enable f1 */, filter1);
177 }
178 
179 void cj_dump_filter_data12 (u64 filter0, u64 filter1)
180 {
181  cj_dump_internal (1, filter0, 1, filter1);
182 }
183 
184 static clib_error_t *
186  unformat_input_t * input,
187  vlib_cli_command_t * cmd)
188 {
189  int is_enable = -1;
190  int is_dump = -1;
191 
192  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
193  if (unformat (input, "enable") || unformat (input, "on"))
194  is_enable = 1;
195  else if (unformat (input, "disable") || unformat (input, "off"))
196  is_enable = 0;
197  else if (unformat (input, "dump"))
198  is_dump = 1;
199  else
200  return clib_error_return (0, "unknown input `%U'",
201  format_unformat_error, input);
202  }
203 
204  if (is_enable >= 0)
205  cj_enable_disable (is_enable);
206 
207  if (is_dump > 0)
208  cj_dump ();
209 
210  return 0;
211 }
212 
213 VLIB_CLI_COMMAND (cj_command,static) = {
214  .path = "cj",
215  .short_help = "cj",
216  .function = cj_command_fn,
217 };
218 
void cj_dump_filter_data12(u64 filter0, u64 filter1)
Definition: cj.c:179
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
u32 cpu
Definition: cj.h:25
always_inline uword max_pow2(uword x)
Definition: clib.h:245
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
Definition: cj.h:30
static clib_error_t * cj_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cj.c:185
volatile u32 enable
Definition: cj.h:34
volatile u64 tail
Definition: cj.h:31
void cj_dump_filter_data1(u64 filter1)
Definition: cj.c:174
void cj_stop(void)
Definition: cj.c:47
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
void cj_enable_disable(int is_enable)
Definition: cj.c:96
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
f64 time
Definition: cj.h:24
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:206
cj_main_t cj_main
Definition: cj.c:25
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:116
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:538
vlib_main_t * vlib_main
Definition: cj.h:36
static void cj_dump_one_record(cj_record_t *r)
Definition: cj.c:106
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
void cj_dump_filter_data0(u64 filter0)
Definition: cj.c:169
clib_error_t * cj_init(vlib_main_t *vm)
Definition: cj.c:55
u64 data[2]
Definition: cj.h:27
Definition: cj.h:23
u32 type
Definition: cj.h:26
unsigned char u8
Definition: types.h:56
static void cj_dump_internal(u8 filter0_enable, u64 filter0, u8 filter1_enable, u64 filter1)
Definition: cj.c:113
always_inline f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
u32 num_records
Definition: cj.h:33
#define clib_error_return(e, args...)
Definition: error.h:112
struct _unformat_input_t unformat_input_t
cj_record_t * records
Definition: cj.h:32
void cj_dump(void)
Definition: cj.c:164
static clib_error_t * cj_config(vlib_main_t *vm, unformat_input_t *input)
Definition: cj.c:65