7b284166503b8d7b658482a7e10558ab818a8a5f
[vpp.git] / src / vcl / vcl_debug.h
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this
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 #ifndef SRC_VCL_VCL_DEBUG_H_
17 #define SRC_VCL_VCL_DEBUG_H_
18
19 #include <vppinfra/elog.h>
20
21 #define VCL_ELOG        0
22 #define VCL_DBG_ON      1
23
24 #define VDBG(_lvl, _fmt, _args...)                                      \
25   if (VCL_DBG_ON && vcm->debug > _lvl)                                  \
26     clib_warning ("vcl<w%d>: " _fmt, __vcl_worker_index, ##_args)
27
28 #define foreach_vcl_dbg_evt                                             \
29   _(INIT, "vcl init track")                                             \
30   _(TIMEOUT, "vcl timeout")                                             \
31   _(DETACH, "vcl detach")                                               \
32   _(SESSION_INIT, "init session track")                                 \
33   _(SESSION_TIMEOUT, "session timeout")                                 \
34   _(CREATE, "session create")                                           \
35   _(CLOSE, "session close")                                             \
36   _(BIND, "session bind")                                               \
37   _(UNBIND, "session unbind")                                           \
38   _(ACCEPT, "session accept")                                           \
39   _(EPOLL_CREATE, "epoll session create")                               \
40   _(EPOLL_CTLADD, "epoll ctl add")                                      \
41   _(EPOLL_CTLDEL, "epoll ctl del")                                      \
42
43 typedef enum vcl_dbg_evt_
44 {
45 #define _(sym, str) VCL_EVT_##sym,
46   foreach_vcl_dbg_evt
47 #undef _
48 } vcl_dbg_evt_e;
49
50 #if VCL_ELOG
51
52 #define VCL_DECLARE_ETD(_s, _e, _size)                                  \
53   struct { u32 data[_size]; } * ed;                                     \
54   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track)            \
55
56 #define VCL_EVT_INIT_HANDLER(_vcm, ...)                                 \
57 {                                                                       \
58   _vcm->elog_track.name = (char *) format (0, "P:%d:C:%d%c", getpid (), \
59                                           _vcm->my_client_index, 0);    \
60   elog_track_register (&_vcm->elog_main, &_vcm->elog_track);            \
61   ELOG_TYPE_DECLARE (e) =                                               \
62   {                                                                     \
63         .format = "connect_vpp:rv:%d",                                  \
64         .format_args = "i4",                                            \
65   };                                                                    \
66   struct { u32 data; } *ed;                                             \
67   ed = ELOG_TRACK_DATA (&_vcm->elog_main, e, _vcm->elog_track);         \
68   ed->data = (u32) rv;                                                  \
69 }
70
71 #define VCL_EVT_SESSION_INIT_HANDLER(_s, _s_index, ...)                 \
72 {                                                                       \
73   _s->elog_track.name = (char *) format (0, "CI:%d:S:%d%c",             \
74                                          vcm->my_client_index,          \
75                                          _s_index, 0);                  \
76   elog_track_register (&vcm->elog_main, &_s->elog_track);               \
77 }
78
79 #define VCL_EVT_BIND_HANDLER(_s, ...)                                   \
80 {                                                                       \
81   if (_s->lcl_addr.is_ip4)                                              \
82     {                                                                   \
83       ELOG_TYPE_DECLARE (_e) =                                          \
84       {                                                                 \
85         .format = "bind local:%s:%d.%d.%d.%d:%d ",                      \
86         .format_args = "t1i1i1i1i1i2",                                  \
87         .n_enum_strings = 2,                                            \
88         .enum_strings = {"TCP", "UDP",},                                \
89       };                                                                \
90       CLIB_PACKED (struct {                                             \
91         u8 proto;                                                       \
92         u8 addr[4];                                                     \
93         u16 port;                                                       \
94       }) *ed;                                                           \
95       ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);       \
96       ed->proto = _s->proto;                                            \
97       ed->addr[0] = _s->lcl_addr.ip46.ip4.as_u8[0];                     \
98       ed->addr[1] = _s->lcl_addr.ip46.ip4.as_u8[1];                     \
99       ed->addr[2] = _s->lcl_addr.ip46.ip4.as_u8[2];                     \
100       ed->addr[3] = _s->lcl_addr.ip46.ip4.as_u8[3];                     \
101       ed->port = clib_net_to_host_u16 (_s->lcl_port);                   \
102     }                                                                   \
103   else                                                                  \
104     {                                                                   \
105       /* TBD */                                                         \
106     }                                                                   \
107 }
108
109 #define VCL_EVT_ACCEPT_HANDLER(_s, _ls, _s_idx, ...)                    \
110 {                                                                       \
111   VCL_EVT_SESSION_INIT_HANDLER (_s, _s_idx);                            \
112   ELOG_TYPE_DECLARE (_e) =                                              \
113   {                                                                     \
114     .format = "accept: listen_handle:%x from_handle:%x",                \
115     .format_args = "i8i8",                                              \
116   };                                                                    \
117   struct { u64 handle[2];  } *ed;                                       \
118   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);           \
119   ed->handle[0] = _ls->vpp_handle;                                      \
120   ed->handle[1] = _s->vpp_handle;                                       \
121   if (_s->peer_addr.is_ip4)                                             \
122     {                                                                   \
123       ELOG_TYPE_DECLARE (_e) =                                          \
124       {                                                                 \
125         .format = "accept:S:%x addr:%d.%d.%d.%d:%d",                    \
126         .format_args = "i8i1i1i1i1i2",                                  \
127       };                                                                \
128       CLIB_PACKED (struct {                                             \
129         u32 s_idx;                                                      \
130         u8 addr[4];                                                     \
131         u16 port;                                                       \
132       }) * ed;                                                          \
133       ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);       \
134       ed->s_idx = _s_idx;                                               \
135       ed->addr[0] = _s->peer_addr.ip46.ip4.as_u8[0];                    \
136       ed->addr[1] = _s->peer_addr.ip46.ip4.as_u8[1];                    \
137       ed->addr[2] = _s->peer_addr.ip46.ip4.as_u8[2];                    \
138       ed->addr[3] = _s->peer_addr.ip46.ip4.as_u8[3];                    \
139       ed->port = clib_net_to_host_u16 (_s->peer_port);                  \
140     }                                                                   \
141   else                                                                  \
142     {                                                                   \
143       /* TBD */                                                         \
144     }                                                                   \
145 }
146
147 #define VCL_EVT_CREATE_HANDLER(_s, _proto, _state, _is_nb, _s_idx, ...) \
148 {                                                                       \
149   VCL_EVT_SESSION_INIT_HANDLER (_s, _s_idx);                            \
150   ELOG_TYPE_DECLARE (_e) =                                              \
151   {                                                                     \
152     .format = "create:proto:%d state:%d is_nonblk:%d idx: %d",          \
153     .format_args = "i4i4i4i4",                                          \
154   };                                                                    \
155   VCL_DECLARE_ETD (_s, _e, 4);                                          \
156   ed->data[0] = _proto;                                                 \
157   ed->data[1] = _state;                                                 \
158   ed->data[2] = _is_nb;                                                 \
159   ed->data[3] = _s_idx;                                                 \
160 }
161
162 #define VCL_EVT_CLOSE_HANDLER(_s, _rv, ...)                             \
163 {                                                                       \
164   ELOG_TYPE_DECLARE (_e) =                                              \
165   {                                                                     \
166     .format = "session_close:rv:%d",                                    \
167     .format_args = "i4",                                                \
168   };                                                                    \
169   VCL_DECLARE_ETD (_s, _e, 1);                                          \
170   ed->data[0] = _rv;                                                    \
171 }
172
173 #define VCL_EVT_SESSION_TIMEOUT_HANDLER(_s, _state, ...)                \
174 {                                                                       \
175   ELOG_TYPE_DECLARE (_e) =                                              \
176   {                                                                     \
177     .format = "ERR: timeout state:%d",                                  \
178     .format_args = "i4",                                                \
179   };                                                                    \
180   VCL_DECLARE_ETD (_s, _e, 1);                                          \
181   ed->data[0] = _state;                                                 \
182 }
183
184 #define VCL_EVT_TIMEOUT_HANDLER(_vcm, _state, ...)                      \
185 {                                                                       \
186   ELOG_TYPE_DECLARE (_e) =                                              \
187   {                                                                     \
188     .format = "ERR: timeout state:%d",                                  \
189     .format_args = "i4",                                                \
190   };                                                                    \
191   struct { u32 data; } * ed;                                            \
192   ed = ELOG_TRACK_DATA (&_vcm->elog_main, _e, _vcm->elog_track);        \
193   ed->data[0] = _state;                                                 \
194 }
195
196 #define VCL_EVT_DETACH_HANDLER(_vcm, ...)                               \
197 {                                                                       \
198   ELOG_TYPE_DECLARE (_e) =                                              \
199   {                                                                     \
200     .format = "app_detach:C:%d",                                        \
201     .format_args = "i4",                                                \
202   };                                                                    \
203   struct { u32 data; } * ed;                                            \
204   ed = ELOG_TRACK_DATA (&_vcm->elog_main, _e, _vcm->elog_track);        \
205   ed->data = _vcm->my_client_index;                                     \
206 }
207
208 #define VCL_EVT_UNBIND_HANDLER(_s, ...)                                 \
209 {                                                                       \
210   ELOG_TYPE_DECLARE (_e) =                                              \
211   {                                                                     \
212     .format = "unbind: handle:%x",                                      \
213     .format_args = "i8",                                                \
214   };                                                                    \
215   struct { u64 data; } * ed;                                            \
216   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);           \
217   ed->data = _s->vpp_handle;                                            \
218 }
219
220 #define VCL_EVT_EPOLL_CREATE_HANDLER(_s, _s_idx, ...)                   \
221 {                                                                       \
222   VCL_EVT_SESSION_INIT_HANDLER (_s, _s_idx);                            \
223   ELOG_TYPE_DECLARE (_e) =                                              \
224   {                                                                     \
225     .format = "create epoll vep_idx: %d",                               \
226     .format_args = "i4",                                                \
227   };                                                                    \
228   VCL_DECLARE_ETD (_s, _e, 1);                                          \
229   ed->data[0] = _s_idx;                                                 \
230 }
231
232 #define VCL_EVT_EPOLL_CTLADD_HANDLER(_s, _evts, _evt_data, ...)         \
233 {                                                                       \
234   ELOG_TYPE_DECLARE (_e) =                                              \
235   {                                                                     \
236     .format = "epoll_ctladd: events:%x data:%x",                        \
237     .format_args = "i4",                                                \
238   };                                                                    \
239   struct {                                                              \
240     u32 events;                                                         \
241     u64 event_data;                                                     \
242   } * ed;                                                               \
243   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);           \
244   ed->events = _evts;                                                   \
245   ed->event_data = _evt_data;                                           \
246 }
247
248 #define VCL_EVT_EPOLL_CTLDEL_HANDLER(_s, _vep_idx, ...)                 \
249 {                                                                       \
250   ELOG_TYPE_DECLARE (_e) =                                              \
251   {                                                                     \
252     .format = "epoll_ctldel: vep:%d",                                   \
253     .format_args = "i4",                                                \
254   };                                                                    \
255   VCL_DECLARE_ETD (_s, _e, 1);                                          \
256   ed->data[0] = _vep_idx;                                               \
257 }
258
259 #define vcl_elog_init(_vcm)                                             \
260 {                                                                       \
261   _vcm->elog_main.lock = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, \
262                                                  CLIB_CACHE_LINE_BYTES);\
263   _vcm->elog_main.lock[0] = 0;                                          \
264   _vcm->elog_main.event_ring_size = _vcm->cfg.event_ring_size;          \
265   elog_init (&_vcm->elog_main, _vcm->elog_main.event_ring_size);        \
266   elog_enable_disable (&_vcm->elog_main, 1);                            \
267 }
268
269 #define vcl_elog_stop(_vcm)                                             \
270 {                                                                       \
271   clib_error_t *error = 0;                                              \
272   char *chroot_file = (char *) format (0, "%s/%d-%d-vcl-elog%c",        \
273                                        _vcm->cfg.event_log_path,        \
274                                        _vcm->my_client_index,           \
275                                        getpid (), 0);                   \
276   error = elog_write_file (&_vcm->elog_main, chroot_file,               \
277                            1 /* flush ring */ );                        \
278   if (error)                                                            \
279     clib_error_report (error);                                          \
280   clib_warning ("[%d] Event Log:'%s' ", getpid (), chroot_file);        \
281   vec_free (chroot_file);                                               \
282 }
283
284 #define CONCAT_HELPER(_a, _b) _a##_b
285 #define CC(_a, _b) CONCAT_HELPER(_a, _b)
286 #define vcl_evt(_evt, _args...) CC(_evt, _HANDLER)(_args)
287 #else
288 #define vcl_evt(_evt, _args...)
289 #define vcl_elog_init(_vcm)
290 #define vcl_elog_stop(_vcm)
291 #endif
292
293 #endif /* SRC_VCL_VCL_DEBUG_H_ */
294
295 /*
296  * fd.io coding-style-patch-verification: ON
297  *
298  * Local Variables:
299  * eval: (c-set-style "gnu")
300  * End:
301  */