FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
session_debug.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 
17 #include <vnet/session/session.h>
18 
19 #if SESSION_DEBUG > 0
20 
22 
23 static clib_error_t *
24 show_session_dbg_clock_cycles_fn (vlib_main_t * vm, unformat_input_t * input,
25  vlib_cli_command_t * cmd)
26 {
27  u32 thread;
28 
30  return clib_error_return (0, "unknown input `%U'", format_unformat_error,
31  input);
32 
34  {
35  vlib_cli_output (vm, "Threads %u:\n", thread);
37 
38 #define _(sym, disp, type, str) \
39  if(disp) \
40  { \
41  if (!type) \
42  vlib_cli_output (vm, "\t %25s : %12lu ", str, \
43  sdm->counters[SESS_Q_##sym].u64); \
44  else \
45  vlib_cli_output (vm, "\t %25s : %12.3f ", str, \
46  sdm->counters[SESS_Q_##sym].f64); \
47  }
49 #undef _
50  }
51  return 0;
52 }
53 
54 
55 /* *INDENT-OFF* */
56 VLIB_CLI_COMMAND (show_session_dbg_clock_cycles_command, static) =
57 {
58  .path = "show session dbg clock_cycles",
59  .short_help = "show session dbg clock_cycles",
60  .function = show_session_dbg_clock_cycles_fn,
61 };
62 /* *INDENT-ON* */
63 
64 
65 static clib_error_t *
66 clear_session_dbg_clock_cycles_fn (vlib_main_t * vm, unformat_input_t * input,
67  vlib_cli_command_t * cmd)
68 {
69  session_dbg_evts_t *sde;
70  u32 thread;
71 
73  return clib_error_return (0, "unknown input `%U'", format_unformat_error,
74  input);
75 
77  {
78  sde = &session_dbg_main.wrk[thread];
79  clib_memset (sde, 0, sizeof (session_dbg_evts_t));
80  sde->last_time = vlib_time_now (vlib_mains[thread]);
81  sde->start_time = sde->last_time;
82  }
83 
84  return 0;
85 }
86 
87 
88 /* *INDENT-OFF* */
89 VLIB_CLI_COMMAND (clear_session_clock_cycles_command, static) =
90 {
91  .path = "clear session dbg clock_cycles",
92  .short_help = "clear session dbg clock_cycles",
93  .function = clear_session_dbg_clock_cycles_fn,
94 };
95 /* *INDENT-ON* */
96 
97 void
98 session_debug_init (void)
99 {
102  u32 num_threads, thread;
103 
104  num_threads = vtm->n_vlib_mains;
105 
106  vec_validate_aligned (sdm->wrk, num_threads - 1, CLIB_CACHE_LINE_BYTES);
107  for (thread = 0; thread < num_threads; thread++)
108  {
109  clib_memset (&sdm->wrk[thread], 0, sizeof (session_dbg_evts_t));
110  sdm->wrk[thread].start_time = vlib_time_now (vlib_mains[thread]);
111  }
112 }
113 #else
114 void
116 {
117 }
118 #endif
119 
120 void
122 {
124  u32 my_thread_index = vm->thread_index;
125  session_event_t _e, *e = &_e;
127  svm_msg_q_ring_t *ring;
128  session_t *s0;
129  svm_msg_q_msg_t *msg;
130  svm_msg_q_t *mq;
131  int i, index;
132 
133  mq = session_main_get_vpp_event_queue (my_thread_index);
134  sq = mq->q.shr;
135  index = sq->head;
136 
137  for (i = 0; i < sq->cursize; i++)
138  {
139  msg = (svm_msg_q_msg_t *) (&sq->data[0] + sq->elsize * index);
140  ring = svm_msg_q_ring (mq, msg->ring_index);
141  clib_memcpy_fast (e, svm_msg_q_msg_data (mq, msg), ring->elsize);
142 
143  switch (e->event_type)
144  {
145  case SESSION_IO_EVT_TX:
146  s0 = session_get_if_valid (e->session_index, my_thread_index);
147  fformat (stdout, "[%04d] TX session %d\n", i, s0->session_index);
148  break;
149 
151  s0 = session_get_from_handle (e->session_handle);
152  fformat (stdout, "[%04d] disconnect session %d\n", i,
153  s0->session_index);
154  break;
155 
157  s0 = session_get_if_valid (e->session_index, my_thread_index);
158  fformat (stdout, "[%04d] builtin_rx %d\n", i, s0->session_index);
159  break;
160 
162  fformat (stdout, "[%04d] RPC call %llx with %llx\n",
163  i, (u64) (uword) (e->rpc_args.fp),
164  (u64) (uword) (e->rpc_args.arg));
165  break;
166 
167  default:
168  fformat (stdout, "[%04d] unhandled event type %d\n",
169  i, e->event_type);
170  break;
171  }
172 
173  index++;
174 
175  if (index == sq->maxsize)
176  index = 0;
177  }
178 }
179 
180 static u8
181 session_node_cmp_event (session_event_t * e, svm_fifo_t * f)
182 {
183  session_t *s;
184  switch (e->event_type)
185  {
186  case SESSION_IO_EVT_RX:
187  case SESSION_IO_EVT_TX:
191  if (e->session_index == f->shr->master_session_index)
192  return 1;
193  break;
195  break;
197  s = session_get_from_handle (e->session_handle);
198  if (!s)
199  {
200  clib_warning ("session has event but doesn't exist!");
201  break;
202  }
203  if (s->rx_fifo == f || s->tx_fifo == f)
204  return 1;
205  break;
206  default:
207  break;
208  }
209  return 0;
210 }
211 
212 u8
214 {
218  int i, index, found = 0;
219  svm_msg_q_msg_t *msg;
220  svm_msg_q_ring_t *ring;
221  svm_msg_q_t *mq;
223 
224  ASSERT (e);
225  thread_index = f->master_thread_index;
227 
228  /*
229  * Search evt queue
230  */
231  mq = wrk->vpp_event_queue;
232  sq = mq->q.shr;
233  index = sq->head;
234  for (i = 0; i < sq->cursize; i++)
235  {
236  msg = (svm_msg_q_msg_t *) (&sq->data[0] + sq->elsize * index);
237  ring = svm_msg_q_ring (mq, msg->ring_index);
238  clib_memcpy_fast (e, svm_msg_q_msg_data (mq, msg), ring->elsize);
239  found = session_node_cmp_event (e, f);
240  if (found)
241  return 1;
242  index = (index + 1) % sq->maxsize;
243  }
244  /*
245  * Search pending events vector
246  */
247 
248  /* *INDENT-OFF* */
249  clib_llist_foreach (wrk->event_elts, evt_list,
251  elt, ({
252  found = session_node_cmp_event (&elt->evt, f);
253  if (found)
254  {
255  clib_memcpy_fast (e, &elt->evt, sizeof (*e));
256  goto done;
257  }
258  }));
259  /* *INDENT-ON* */
260 
261  /* *INDENT-OFF* */
262  clib_llist_foreach (wrk->event_elts, evt_list,
264  elt, ({
265  found = session_node_cmp_event (&elt->evt, f);
266  if (found)
267  {
268  clib_memcpy_fast (e, &elt->evt, sizeof (*e));
269  goto done;
270  }
271  }));
272  /* *INDENT-ON* */
273 
274 done:
275  return found;
276 }
277 
278 /*
279  * fd.io coding-style-patch-verification: ON
280  *
281  * Local Variables:
282  * eval: (c-set-style "gnu")
283  * End:
284  */
SESSION_CTRL_EVT_RPC
@ SESSION_CTRL_EVT_RPC
Definition: session_types.h:333
dump_thread_0_event_queue
void dump_thread_0_event_queue(void)
Definition: session_debug.c:121
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:495
session_::session_index
u32 session_index
Index in thread pool where session was allocated.
Definition: session_types.h:188
svm_msg_q_shr_queue_::elsize
u32 elsize
Definition: message_queue.h:36
f
vlib_frame_t * f
Definition: interface_output.c:1098
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
svm_msg_q_ring
svm_msg_q_ring_t * svm_msg_q_ring(svm_msg_q_t *mq, u32 ring_index)
Get message queue ring.
Definition: message_queue.c:30
svm_msg_q_msg_data
void * svm_msg_q_msg_data(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Get data for message in queue.
Definition: message_queue.c:287
session_::tx_fifo
svm_fifo_t * tx_fifo
Definition: session_types.h:179
session_
Definition: session_types.h:175
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
clib_llist_foreach
#define clib_llist_foreach(LP, name, H, E, body)
Walk list starting at head.
Definition: llist.h:293
vlib_cli_command_t::path
char * path
Definition: cli.h:96
thread
pthread_t thread[MAX_CONNS]
Definition: main.c:142
wrk
session_worker_t * wrk
Definition: application.c:490
SESSION_IO_EVT_RX
@ SESSION_IO_EVT_RX
Definition: session_types.h:328
session_node_lookup_fifo_event
u8 session_node_lookup_fifo_event(svm_fifo_t *f, session_event_t *e)
Definition: session_debug.c:213
session_dbg_main
session_dbg_main_t session_dbg_main
svm_msg_q_msg_t
Definition: message_queue.h:93
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
SESSION_IO_EVT_BUILTIN_TX
@ SESSION_IO_EVT_BUILTIN_TX
Definition: session_types.h:332
unformat_input_t
struct _unformat_input_t unformat_input_t
svm_msg_q_ring_
Definition: message_queue.h:58
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
session_worker_::new_head
clib_llist_index_t new_head
Head of list of elements.
Definition: session.h:131
svm_fifo_t
struct _svm_fifo svm_fifo_t
SESSION_CTRL_EVT_CLOSE
@ SESSION_CTRL_EVT_CLOSE
Definition: session_types.h:335
vlib_thread_main_t::n_vlib_mains
u32 n_vlib_mains
Definition: threads.h:262
svm_msg_q_shr_queue_::data
u8 data[0]
Definition: message_queue.h:38
session_::rx_fifo
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
Definition: session_types.h:178
SESSION_IO_EVT_BUILTIN_RX
@ SESSION_IO_EVT_BUILTIN_RX
Definition: session_types.h:331
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
svm_msg_q_shr_queue_::head
u32 head
Definition: message_queue.h:32
svm_msg_q_shr_queue_::maxsize
u32 maxsize
Definition: message_queue.h:35
session_evt_elt
Definition: session.h:64
session_main_get_vpp_event_queue
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
Definition: session.h:717
svm_msg_q_queue_::shr
svm_msg_q_shared_queue_t * shr
pointer to shared queue
Definition: message_queue.h:43
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
svm_msg_q_msg_t::ring_index
u32 ring_index
ring index, could be u8
Definition: message_queue.h:97
session_dbg_main_::wrk
session_dbg_evts_t * wrk
Definition: session_debug.h:92
session_node_cmp_event
static u8 session_node_cmp_event(session_event_t *e, svm_fifo_t *f)
Definition: session_debug.c:181
uword
u64 uword
Definition: types.h:112
SESSION_IO_EVT_TX_FLUSH
@ SESSION_IO_EVT_TX_FLUSH
Definition: session_types.h:330
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:215
session_debug_init
void session_debug_init(void)
Definition: session_debug.c:115
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
session_get_from_handle
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:357
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
SESSION_IO_EVT_TX
@ SESSION_IO_EVT_TX
Definition: session_types.h:329
session_dbg_main_
Definition: session_debug.h:90
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:58
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
svm_msg_q_
Definition: message_queue.h:72
session_worker_::vpp_event_queue
svm_msg_q_t * vpp_event_queue
vpp event message queue for worker
Definition: session.h:95
session_worker_::event_elts
session_evt_elt_t * event_elts
Pool of session event list elements.
Definition: session.h:122
svm_msg_q_shr_queue_
Definition: message_queue.h:28
index
u32 index
Definition: flow_types.api:221
session_dbg_evts_t
Definition: session_debug.h:81
u64
unsigned long u64
Definition: types.h:89
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
session_get_if_valid
static session_t * session_get_if_valid(u64 si, u32 thread_index)
Definition: session.h:344
u32
unsigned int u32
Definition: types.h:88
vlib_thread_main_t
Definition: threads.h:243
vlib_get_first_main
static vlib_main_t * vlib_get_first_main(void)
Definition: global_funcs.h:44
foreach_session_events
#define foreach_session_events
Definition: session_debug.h:41
svm_msg_q_ring_::elsize
u32 elsize
size of an element
Definition: message_queue.h:61
fformat
__clib_export word fformat(FILE *f, char *fmt,...)
Definition: format.c:466
elt
app_rx_mq_elt_t * elt
Definition: application.c:488
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
session_worker_::old_head
clib_llist_index_t old_head
Head of list of pending events.
Definition: session.h:134
session_dbg_evts_t::start_time
f64 start_time
Definition: session_debug.h:85
svm_msg_q_shr_queue_::cursize
volatile u32 cursize
Definition: message_queue.h:34
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
session.h
i
int i
Definition: flowhash_template.h:376
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
vlib_cli_command_t
Definition: cli.h:92
session_debug.h
vlib_get_thread_main
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
session_main_get_worker
static session_worker_t * session_main_get_worker(u32 thread_index)
Definition: session.h:703
session_dbg_evts_t::last_time
f64 last_time
Definition: session_debug.h:84
svm_msg_q_::q
svm_msg_q_queue_t q
queue for exchanging messages
Definition: message_queue.h:74
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
session_worker_
Definition: session.h:87