FD.io VPP  v21.06
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 
33  for (thread = 0; thread < vec_len (session_dbg_main.wrk); thread++)
34  {
35  vlib_cli_output (vm, "Threads %u:\n", thread);
36  session_dbg_evts_t *sdm = &session_dbg_main.wrk[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 
76  for (thread = 0; thread < vec_len (session_dbg_main.wrk); thread++)
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;
226  wrk = session_main_get_worker (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  */
static u8 session_node_cmp_event(session_event_t *e, svm_fifo_t *f)
void * svm_msg_q_msg_data(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Get data for message in queue.
svm_msg_q_t * vpp_event_queue
vpp event message queue for worker
Definition: session.h:95
svm_fifo_t * tx_fifo
u32 thread_index
u32 session_index
Index in thread pool where session was allocated.
session_worker_t * wrk
Definition: application.c:490
unsigned long u64
Definition: types.h:89
svm_msg_q_shared_queue_t * shr
pointer to shared queue
Definition: message_queue.h:43
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
Definition: session.h:716
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:325
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
static session_t * session_get_if_valid(u64 si, u32 thread_index)
Definition: session.h:343
u32 thread_index
Definition: main.h:213
session_dbg_main_t session_dbg_main
session_evt_elt_t * event_elts
Pool of session event list elements.
Definition: session.h:122
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:535
#define clib_llist_foreach(LP, name, H, E, body)
Walk list starting at head.
Definition: llist.h:293
unsigned char u8
Definition: types.h:56
unsigned int u32
Definition: types.h:88
__clib_export word fformat(FILE *f, char *fmt,...)
Definition: format.c:466
vlib_frame_t * f
static session_worker_t * session_main_get_worker(u32 thread_index)
Definition: session.h:702
clib_llist_index_t new_head
Head of list of elements.
Definition: session.h:131
#define clib_error_return(e, args...)
Definition: error.h:99
pthread_t thread[MAX_CONNS]
Definition: main.c:142
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:356
struct _unformat_input_t unformat_input_t
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_queue_t q
queue for exchanging messages
Definition: message_queue.h:74
u8 session_node_lookup_fifo_event(svm_fifo_t *f, session_event_t *e)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
u32 index
Definition: flow_types.api:221
#define clib_warning(format, args...)
Definition: error.h:59
session_dbg_evts_t * wrk
Definition: session_debug.h:92
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
static vlib_main_t * vlib_get_first_main(void)
Definition: global_funcs.h:44
u32 ring_index
ring index, could be u8
Definition: message_queue.h:97
volatile u32 cursize
Definition: message_queue.h:34
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
#define foreach_session_events
Definition: session_debug.h:41
app_rx_mq_elt_t * elt
Definition: application.c:488
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
void dump_thread_0_event_queue(void)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_llist_index_t old_head
Head of list of pending events.
Definition: session.h:134
void session_debug_init(void)
u64 uword
Definition: types.h:112
u32 elsize
size of an element
Definition: message_queue.h:61
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
struct _svm_fifo svm_fifo_t
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163