FD.io VPP  v20.05-21-gb1500e9ff
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 {
125  u32 my_thread_index = vm->thread_index;
126  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 = smm->wrk[my_thread_index].vpp_event_queue;
134  index = mq->q->head;
135 
136  for (i = 0; i < mq->q->cursize; i++)
137  {
138  msg = (svm_msg_q_msg_t *) (&mq->q->data[0] + mq->q->elsize * index);
139  ring = svm_msg_q_ring (mq, msg->ring_index);
140  clib_memcpy_fast (e, svm_msg_q_msg_data (mq, msg), ring->elsize);
141 
142  switch (e->event_type)
143  {
144  case SESSION_IO_EVT_TX:
145  s0 = session_get_if_valid (e->session_index, my_thread_index);
146  fformat (stdout, "[%04d] TX session %d\n", i, s0->session_index);
147  break;
148 
150  s0 = session_get_from_handle (e->session_handle);
151  fformat (stdout, "[%04d] disconnect session %d\n", i,
152  s0->session_index);
153  break;
154 
156  s0 = session_get_if_valid (e->session_index, my_thread_index);
157  fformat (stdout, "[%04d] builtin_rx %d\n", i, s0->session_index);
158  break;
159 
161  fformat (stdout, "[%04d] RPC call %llx with %llx\n",
162  i, (u64) (uword) (e->rpc_args.fp),
163  (u64) (uword) (e->rpc_args.arg));
164  break;
165 
166  default:
167  fformat (stdout, "[%04d] unhandled event type %d\n",
168  i, e->event_type);
169  break;
170  }
171 
172  index++;
173 
174  if (index == mq->q->maxsize)
175  index = 0;
176  }
177 }
178 
179 static u8
180 session_node_cmp_event (session_event_t * e, svm_fifo_t * f)
181 {
182  session_t *s;
183  switch (e->event_type)
184  {
185  case SESSION_IO_EVT_RX:
186  case SESSION_IO_EVT_TX:
190  if (e->session_index == f->master_session_index)
191  return 1;
192  break;
194  break;
196  s = session_get_from_handle (e->session_handle);
197  if (!s)
198  {
199  clib_warning ("session has event but doesn't exist!");
200  break;
201  }
202  if (s->rx_fifo == f || s->tx_fifo == f)
203  return 1;
204  break;
205  default:
206  break;
207  }
208  return 0;
209 }
210 
211 u8
212 session_node_lookup_fifo_event (svm_fifo_t * f, session_event_t * e)
213 {
214  session_evt_elt_t *elt;
215  session_worker_t *wrk;
216  int i, index, found = 0;
217  svm_msg_q_msg_t *msg;
218  svm_msg_q_ring_t *ring;
219  svm_msg_q_t *mq;
220  u8 thread_index;
221 
222  ASSERT (e);
223  thread_index = f->master_thread_index;
224  wrk = session_main_get_worker (thread_index);
225 
226  /*
227  * Search evt queue
228  */
229  mq = wrk->vpp_event_queue;
230  index = mq->q->head;
231  for (i = 0; i < mq->q->cursize; i++)
232  {
233  msg = (svm_msg_q_msg_t *) (&mq->q->data[0] + mq->q->elsize * index);
234  ring = svm_msg_q_ring (mq, msg->ring_index);
235  clib_memcpy_fast (e, svm_msg_q_msg_data (mq, msg), ring->elsize);
236  found = session_node_cmp_event (e, f);
237  if (found)
238  return 1;
239  index = (index + 1) % mq->q->maxsize;
240  }
241  /*
242  * Search pending events vector
243  */
244 
245  /* *INDENT-OFF* */
246  clib_llist_foreach (wrk->event_elts, evt_list,
248  elt, ({
249  found = session_node_cmp_event (&elt->evt, f);
250  if (found)
251  {
252  clib_memcpy_fast (e, &elt->evt, sizeof (*e));
253  goto done;
254  }
255  }));
256  /* *INDENT-ON* */
257 
258  /* *INDENT-OFF* */
259  clib_llist_foreach (wrk->event_elts, evt_list,
260  pool_elt_at_index (wrk->event_elts, wrk->old_head),
261  elt, ({
262  found = session_node_cmp_event (&elt->evt, f);
263  if (found)
264  {
265  clib_memcpy_fast (e, &elt->evt, sizeof (*e));
266  goto done;
267  }
268  }));
269  /* *INDENT-ON* */
270 
271 done:
272  return found;
273 }
274 
275 /*
276  * fd.io coding-style-patch-verification: ON
277  *
278  * Local Variables:
279  * eval: (c-set-style "gnu")
280  * End:
281  */
vlib_main_t vlib_global_main
Definition: main.c:1999
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:80
svm_fifo_t * tx_fifo
u32 session_index
Index in thread pool where session was allocated.
unsigned long u64
Definition: types.h:89
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:291
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
session_worker_t * wrk
Worker contexts.
Definition: session.h:143
static session_t * session_get_if_valid(u64 si, u32 thread_index)
Definition: session.h:308
u32 thread_index
Definition: main.h:218
session_dbg_main_t session_dbg_main
session_evt_elt_t * event_elts
Pool of session event list elements.
Definition: session.h:101
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:518
vlib_main_t ** vlib_mains
Definition: buffer.c:332
#define clib_llist_foreach(LP, name, H, E, body)
Walk list starting at head.
Definition: llist.h:255
unsigned char u8
Definition: types.h:56
static session_worker_t * session_main_get_worker(u32 thread_index)
Definition: session.h:619
clib_llist_index_t new_head
Head of list of elements.
Definition: session.h:110
#define clib_error_return(e, args...)
Definition: error.h:99
pthread_t thread[MAX_CONNS]
Definition: main.c:142
unsigned int u32
Definition: types.h:88
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:321
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:28
u8 session_node_lookup_fifo_event(svm_fifo_t *f, session_event_t *e)
word fformat(FILE *f, char *fmt,...)
Definition: format.c:462
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define clib_warning(format, args...)
Definition: error.h:59
svm_queue_t * q
queue for exchanging messages
Definition: message_queue.h:39
session_dbg_evts_t * wrk
Definition: session_debug.h:92
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
u32 ring_index
ring index, could be u8
Definition: message_queue.h:62
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
#define foreach_session_events
Definition: session_debug.h:41
void dump_thread_0_event_queue(void)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void session_debug_init(void)
u64 uword
Definition: types.h:112
u32 elsize
size of an element
Definition: message_queue.h:33
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:32
static session_main_t * vnet_get_session_main()
Definition: session.h:613
#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:171