LCOV - code coverage report
Current view: top level - vnet/session - session_debug.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 2 73 2.7 %
Date: 2023-10-26 01:39:38 Functions: 1 4 25.0 %

          Line data    Source code
       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             : 
      16             : #include <vnet/session/session_debug.h>
      17             : #include <vnet/session/session.h>
      18             : 
      19             : #if SESSION_DEBUG > 0
      20             : 
      21             : session_dbg_main_t session_dbg_main;
      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             : 
      29             :   if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
      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             :     }
      48             :       foreach_session_events
      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             : static_always_inline f64
      65             : session_dbg_time_now (u32 thread)
      66             : {
      67             :   vlib_main_t *vm = vlib_get_main_by_index (thread);
      68             : 
      69             :   return clib_time_now (&vm->clib_time) + vm->time_offset;
      70             : }
      71             : 
      72             : static clib_error_t *
      73             : clear_session_dbg_clock_cycles_fn (vlib_main_t * vm, unformat_input_t * input,
      74             :                                    vlib_cli_command_t * cmd)
      75             : {
      76             :   session_dbg_evts_t *sde;
      77             :   u32 thread;
      78             : 
      79             :   if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
      80             :     return clib_error_return (0, "unknown input `%U'", format_unformat_error,
      81             :                               input);
      82             : 
      83             :   for (thread = 0; thread < vec_len (session_dbg_main.wrk); thread++)
      84             :     {
      85             :       sde = &session_dbg_main.wrk[thread];
      86             :       clib_memset (sde, 0, sizeof (session_dbg_evts_t));
      87             :       sde->last_time = session_dbg_time_now (thread);
      88             :       sde->start_time = sde->last_time;
      89             :     }
      90             : 
      91             :   return 0;
      92             : }
      93             : 
      94             : 
      95             : /* *INDENT-OFF* */
      96             : VLIB_CLI_COMMAND (clear_session_clock_cycles_command, static) =
      97             : {
      98             :   .path = "clear session dbg clock_cycles",
      99             :   .short_help = "clear session dbg clock_cycles",
     100             :   .function = clear_session_dbg_clock_cycles_fn,
     101             : };
     102             : /* *INDENT-ON* */
     103             : 
     104             : void
     105             : session_debug_init (void)
     106             : {
     107             :   vlib_thread_main_t *vtm = vlib_get_thread_main ();
     108             :   session_dbg_main_t *sdm = &session_dbg_main;
     109             :   u32 num_threads, thread;
     110             : 
     111             :   num_threads = vtm->n_vlib_mains;
     112             : 
     113             :   vec_validate_aligned (sdm->wrk, num_threads - 1, CLIB_CACHE_LINE_BYTES);
     114             :   for (thread = 0; thread < num_threads; thread++)
     115             :     {
     116             :       clib_memset (&sdm->wrk[thread], 0, sizeof (session_dbg_evts_t));
     117             :       sdm->wrk[thread].start_time = session_dbg_time_now (thread);
     118             :     }
     119             : }
     120             : 
     121             : static const char *session_evt_grp_str[] = {
     122             : #define _(sym, str) str,
     123             :   foreach_session_evt_grp
     124             : #undef _
     125             : };
     126             : 
     127             : static void
     128             : session_debug_show_groups (vlib_main_t *vm)
     129             : {
     130             :   session_dbg_main_t *sdm = &session_dbg_main;
     131             :   int i = 0;
     132             : 
     133             :   vlib_cli_output (vm, "%-10s%-30s%-10s", "Index", "Group", "Level");
     134             : 
     135             :   for (i = 0; i < SESSION_EVT_N_GRP; i++)
     136             :     vlib_cli_output (vm, "%-10d%-30s%-10d", i, session_evt_grp_str[i],
     137             :                      sdm->grp_dbg_lvl[i]);
     138             : }
     139             : 
     140             : static clib_error_t *
     141             : session_debug_fn (vlib_main_t *vm, unformat_input_t *input,
     142             :                   vlib_cli_command_t *cmd)
     143             : {
     144             :   session_dbg_main_t *sdm = &session_dbg_main;
     145             :   u32 group, level = ~0;
     146             :   clib_error_t *error = 0;
     147             :   u8 is_show = 0;
     148             :   uword *bitmap = 0;
     149             : 
     150             :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     151             :     {
     152             :       if (unformat (input, "show"))
     153             :         is_show = 1;
     154             :       else if (unformat (input, "group %U", unformat_bitmap_list, &bitmap))
     155             :         ;
     156             :       else if (unformat (input, "level %d", &level))
     157             :         ;
     158             :       else
     159             :         {
     160             :           error = clib_error_return (0, "unknown input `%U'",
     161             :                                      format_unformat_error, input);
     162             :           goto done;
     163             :         }
     164             :     }
     165             : 
     166             :   if (is_show)
     167             :     {
     168             :       session_debug_show_groups (vm);
     169             :       goto done;
     170             :     }
     171             :   if (level == ~0)
     172             :     {
     173             :       vlib_cli_output (vm, "level must be entered");
     174             :       goto done;
     175             :     }
     176             : 
     177             :   group = clib_bitmap_last_set (bitmap);
     178             :   if (group == ~0)
     179             :     {
     180             :       vlib_cli_output (vm, "group must be entered");
     181             :       goto done;
     182             :     }
     183             :   if (group >= SESSION_EVT_N_GRP)
     184             :     {
     185             :       vlib_cli_output (vm, "group out of bounds");
     186             :       goto done;
     187             :     }
     188             :   clib_bitmap_foreach (group, bitmap)
     189             :     sdm->grp_dbg_lvl[group] = level;
     190             : 
     191             : done:
     192             : 
     193             :   clib_bitmap_free (bitmap);
     194             :   return error;
     195             : }
     196             : 
     197             : VLIB_CLI_COMMAND (session_debug_command, static) = {
     198             :   .path = "session debug",
     199             :   .short_help = "session debug {show | debug group <list> level <n>}",
     200             :   .function = session_debug_fn,
     201             :   .is_mp_safe = 1,
     202             : };
     203             : 
     204             : #else
     205             : void
     206          49 : session_debug_init (void)
     207             : {
     208          49 : }
     209             : #endif /* SESSION_DEBUG */
     210             : 
     211             : void
     212           0 : dump_thread_0_event_queue (void)
     213             : {
     214           0 :   vlib_main_t *vm = vlib_get_first_main ();
     215           0 :   u32 my_thread_index = vm->thread_index;
     216           0 :   session_event_t _e, *e = &_e;
     217             :   svm_msg_q_shared_queue_t *sq;
     218             :   svm_msg_q_ring_t *ring;
     219             :   session_t *s0;
     220             :   svm_msg_q_msg_t *msg;
     221             :   svm_msg_q_t *mq;
     222             :   int i, index;
     223             : 
     224           0 :   mq = session_main_get_vpp_event_queue (my_thread_index);
     225           0 :   sq = mq->q.shr;
     226           0 :   index = sq->head;
     227             : 
     228           0 :   for (i = 0; i < sq->cursize; i++)
     229             :     {
     230           0 :       msg = (svm_msg_q_msg_t *) (&sq->data[0] + sq->elsize * index);
     231           0 :       ring = svm_msg_q_ring (mq, msg->ring_index);
     232           0 :       clib_memcpy_fast (e, svm_msg_q_msg_data (mq, msg), ring->elsize);
     233             : 
     234           0 :       switch (e->event_type)
     235             :         {
     236           0 :         case SESSION_IO_EVT_TX:
     237           0 :           s0 = session_get_if_valid (e->session_index, my_thread_index);
     238           0 :           if (!s0)
     239           0 :             break;
     240           0 :           fformat (stdout, "[%04d] TX session %d\n", i, s0->session_index);
     241           0 :           break;
     242             : 
     243           0 :         case SESSION_CTRL_EVT_CLOSE:
     244           0 :           s0 = session_get_from_handle (e->session_handle);
     245           0 :           fformat (stdout, "[%04d] disconnect session %d\n", i,
     246             :                    s0->session_index);
     247           0 :           break;
     248             : 
     249           0 :         case SESSION_IO_EVT_BUILTIN_RX:
     250           0 :           s0 = session_get_if_valid (e->session_index, my_thread_index);
     251           0 :           if (!s0)
     252           0 :             break;
     253           0 :           fformat (stdout, "[%04d] builtin_rx %d\n", i, s0->session_index);
     254           0 :           break;
     255             : 
     256           0 :         case SESSION_CTRL_EVT_RPC:
     257           0 :           fformat (stdout, "[%04d] RPC call %llx with %llx\n",
     258           0 :                    i, (u64) (uword) (e->rpc_args.fp),
     259           0 :                    (u64) (uword) (e->rpc_args.arg));
     260           0 :           break;
     261             : 
     262           0 :         default:
     263           0 :           fformat (stdout, "[%04d] unhandled event type %d\n",
     264           0 :                    i, e->event_type);
     265           0 :           break;
     266             :         }
     267             : 
     268           0 :       index++;
     269             : 
     270           0 :       if (index == sq->maxsize)
     271           0 :         index = 0;
     272             :     }
     273           0 : }
     274             : 
     275             : static u8
     276           0 : session_node_cmp_event (session_event_t * e, svm_fifo_t * f)
     277             : {
     278           0 :   switch (e->event_type)
     279             :     {
     280           0 :     case SESSION_IO_EVT_RX:
     281             :     case SESSION_IO_EVT_TX:
     282             :     case SESSION_IO_EVT_BUILTIN_RX:
     283             :     case SESSION_IO_EVT_TX_MAIN:
     284             :     case SESSION_IO_EVT_TX_FLUSH:
     285           0 :       if (e->session_index == f->shr->master_session_index)
     286           0 :         return 1;
     287           0 :       break;
     288           0 :     case SESSION_CTRL_EVT_CLOSE:
     289             :     case SESSION_CTRL_EVT_RPC:
     290           0 :       break;
     291           0 :     default:
     292           0 :       break;
     293             :     }
     294           0 :   return 0;
     295             : }
     296             : 
     297             : u8
     298           0 : session_node_lookup_fifo_event (svm_fifo_t * f, session_event_t * e)
     299             : {
     300             :   svm_msg_q_shared_queue_t *sq;
     301             :   session_evt_elt_t *elt;
     302             :   session_worker_t *wrk;
     303           0 :   int i, index, found = 0;
     304             :   svm_msg_q_msg_t *msg;
     305             :   svm_msg_q_t *mq;
     306             :   u8 thread_index;
     307             : 
     308           0 :   ASSERT (e);
     309           0 :   thread_index = f->master_thread_index;
     310           0 :   wrk = session_main_get_worker (thread_index);
     311             : 
     312             :   /*
     313             :    * Search evt queue
     314             :    */
     315           0 :   mq = wrk->vpp_event_queue;
     316           0 :   sq = mq->q.shr;
     317           0 :   index = sq->head;
     318           0 :   for (i = 0; i < sq->cursize; i++)
     319             :     {
     320           0 :       msg = (svm_msg_q_msg_t *) (&sq->data[0] + sq->elsize * index);
     321           0 :       clib_memcpy_fast (e, svm_msg_q_msg_data (mq, msg), sizeof (*e));
     322           0 :       found = session_node_cmp_event (e, f);
     323           0 :       if (found)
     324           0 :         return 1;
     325           0 :       index = (index + 1) % sq->maxsize;
     326             :     }
     327             :   /*
     328             :    * Search pending events vector
     329             :    */
     330             : 
     331             :   /* *INDENT-OFF* */
     332           0 :   clib_llist_foreach (wrk->event_elts, evt_list,
     333             :                       pool_elt_at_index (wrk->event_elts, wrk->new_head),
     334             :                       elt, ({
     335             :     found = session_node_cmp_event (&elt->evt, f);
     336             :     if (found)
     337             :       {
     338             :         clib_memcpy_fast (e, &elt->evt, sizeof (*e));
     339             :         goto done;
     340             :       }
     341             :   }));
     342             :   /* *INDENT-ON* */
     343             : 
     344             :   /* *INDENT-OFF* */
     345           0 :   clib_llist_foreach (wrk->event_elts, evt_list,
     346             :                       pool_elt_at_index (wrk->event_elts, wrk->old_head),
     347             :                       elt, ({
     348             :     found = session_node_cmp_event (&elt->evt, f);
     349             :     if (found)
     350             :       {
     351             :         clib_memcpy_fast (e, &elt->evt, sizeof (*e));
     352             :         goto done;
     353             :       }
     354             :   }));
     355             :   /* *INDENT-ON* */
     356             : 
     357           0 : done:
     358           0 :   return found;
     359             : }
     360             : 
     361             : /*
     362             :  * fd.io coding-style-patch-verification: ON
     363             :  *
     364             :  * Local Variables:
     365             :  * eval: (c-set-style "gnu")
     366             :  * End:
     367             :  */

Generated by: LCOV version 1.14