]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: add tracepoints for hash ops, thread events
authorQuentin Young <qlyoung@nvidia.com>
Mon, 14 Sep 2020 22:04:33 +0000 (18:04 -0400)
committerQuentin Young <qlyoung@nvidia.com>
Fri, 23 Oct 2020 19:13:51 +0000 (15:13 -0400)
Define some initial tracepoints for hash table operations, thread
schedules, and thread cancels

Signed-off-by: Quentin Young <qlyoung@nvidia.com>
lib/hash.c
lib/thread.c
lib/trace.h

index 85982774ac8162c1d0c1ccdf2a9515fc44a0e303..99a9e2e3ab887a933b8c44879539de574e0a6284 100644 (file)
@@ -29,6 +29,7 @@
 #include "command.h"
 #include "libfrr.h"
 #include "frr_pthread.h"
+#include "trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, HASH, "Hash")
 DEFINE_MTYPE_STATIC(LIB, HASH_BACKET, "Hash Bucket")
@@ -138,6 +139,8 @@ static void hash_expand(struct hash *hash)
 
 void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
 {
+       tracepoint(frr_libfrr, hash_get, hash, data);
+
        unsigned int key;
        unsigned int index;
        void *newdata;
@@ -206,7 +209,7 @@ unsigned int string_hash_make(const char *str)
 
 void *hash_release(struct hash *hash, void *data)
 {
-       void *ret;
+       void *ret = NULL;
        unsigned int key;
        unsigned int index;
        struct hash_bucket *bucket;
@@ -236,11 +239,14 @@ void *hash_release(struct hash *hash, void *data)
                        ret = bucket->data;
                        XFREE(MTYPE_HASH_BACKET, bucket);
                        hash->count--;
-                       return ret;
+                       break;
                }
                pp = bucket;
        }
-       return NULL;
+
+       tracepoint(frr_libfrr, hash_release, hash, data, ret);
+
+       return ret;
 }
 
 void hash_iterate(struct hash *hash, void (*func)(struct hash_bucket *, void *),
index db35a3f031d094958725a78345fb25fbe7b77f13..8679454367a96d0c1bb66c300af6d343860756a2 100644 (file)
@@ -35,6 +35,7 @@
 #include "frratomic.h"
 #include "frr_pthread.h"
 #include "lib_errors.h"
+#include "trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread")
 DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master")
@@ -787,6 +788,13 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m,
        struct thread *thread = NULL;
        struct thread **thread_array;
 
+       if (dir == THREAD_READ)
+               tracepoint(frr_libfrr, schedule_read, m, funcname, schedfrom,
+                          fromln, t_ptr, fd, 0, arg, 0);
+       else
+               tracepoint(frr_libfrr, schedule_write, m, funcname, schedfrom,
+                          fromln, t_ptr, fd, 0, arg, 0);
+
        assert(fd >= 0 && fd < m->fd_limit);
        frr_with_mutex(&m->mtx) {
                if (t_ptr && *t_ptr)
@@ -861,6 +869,9 @@ funcname_thread_add_timer_timeval(struct thread_master *m,
        assert(type == THREAD_TIMER);
        assert(time_relative);
 
+       tracepoint(frr_libfrr, schedule_timer, m, funcname, schedfrom, fromln,
+                  t_ptr, 0, 0, arg, (long)time_relative->tv_sec);
+
        frr_with_mutex(&m->mtx) {
                if (t_ptr && *t_ptr)
                        /* thread is already scheduled; don't reschedule */
@@ -939,6 +950,9 @@ struct thread *funcname_thread_add_event(struct thread_master *m,
 {
        struct thread *thread = NULL;
 
+       tracepoint(frr_libfrr, schedule_event, m, funcname, schedfrom, fromln,
+                  t_ptr, 0, val, arg, 0);
+
        assert(m != NULL);
 
        frr_with_mutex(&m->mtx) {
@@ -1167,6 +1181,11 @@ void thread_cancel(struct thread *thread)
 {
        struct thread_master *master = thread->master;
 
+       tracepoint(frr_libfrr, thread_cancel, master, thread->funcname,
+                  thread->schedfrom, thread->schedfrom_line, NULL,
+                  thread->u.fd, thread->u.val, thread->arg,
+                  thread->u.sands.tv_sec);
+
        assert(master->owner == pthread_self());
 
        frr_with_mutex(&master->mtx) {
@@ -1206,6 +1225,17 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread,
                         void *eventobj)
 {
        assert(!(thread && eventobj) && (thread || eventobj));
+
+       if (thread && *thread)
+               tracepoint(frr_libfrr, thread_cancel_async, master,
+                          (*thread)->funcname, (*thread)->schedfrom,
+                          (*thread)->schedfrom_line, NULL, (*thread)->u.fd,
+                          (*thread)->u.val, (*thread)->arg,
+                          (*thread)->u.sands.tv_sec);
+       else
+               tracepoint(frr_libfrr, thread_cancel_async, master, NULL, NULL,
+                          0, NULL, 0, 0, eventobj, 0);
+
        assert(master->owner != pthread_self());
 
        frr_with_mutex(&master->mtx) {
@@ -1581,6 +1611,11 @@ void thread_call(struct thread *thread)
        GETRUSAGE(&before);
        thread->real = before.real;
 
+       tracepoint(frr_libfrr, thread_call, thread->master, thread->funcname,
+                  thread->schedfrom, thread->schedfrom_line, NULL,
+                  thread->u.fd, thread->u.val, thread->arg,
+                  thread->u.sands.tv_sec);
+
        pthread_setspecific(thread_current, thread);
        (*thread->func)(thread);
        pthread_setspecific(thread_current, NULL);
index b30bdd5110a0aa267609e72e1725f4473d5ef202..dd6fb73ae40dc74b028773531f1f3448d964f094 100644 (file)
 #undef TRACEPOINT_INCLUDE
 #define TRACEPOINT_INCLUDE "./trace.h"
 
-/* tracepoint definitions go here */
-
 #include <lttng/tracepoint.h>
+
+#include "hash.h"
+#include "thread.h"
+
+/* clang-format off */
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       hash_get,
+       TP_ARGS(struct hash *, hash, void *, data),
+       TP_FIELDS(
+               ctf_string(name, hash->name ? hash->name : "(unnamed)")
+               ctf_integer(unsigned int, index_size, hash->size)
+               ctf_integer(unsigned long, item_count, hash->count)
+               ctf_integer_hex(intptr_t, data_ptr, data)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_get, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       hash_release,
+       TP_ARGS(struct hash *, hash, void *, data, void *, released_item),
+       TP_FIELDS(
+               ctf_string(name, hash->name ? hash->name : "(unnamed)")
+               ctf_integer(unsigned int, index_size, hash->size)
+               ctf_integer(unsigned long, item_count, hash->count)
+               ctf_integer_hex(intptr_t, data_ptr, data)
+               ctf_integer_hex(intptr_t, released_item, data)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_release, TRACE_INFO)
+
+#define THREAD_SCHEDULE_ARGS                                                   \
+       TP_ARGS(struct thread_master *, master, const char *, funcname,        \
+               const char *, schedfrom, int, fromln, struct thread **,        \
+               thread_ptr, int, fd, int, val, void *, arg, long, time)
+
+TRACEPOINT_EVENT_CLASS(
+       frr_libfrr,
+       thread_operation,
+       THREAD_SCHEDULE_ARGS,
+       TP_FIELDS(
+               ctf_string(threadmaster_name, master->name)
+               ctf_string(function_name, funcname ? funcname : "(unknown function)")
+               ctf_string(scheduled_from, schedfrom ? schedfrom : "(unknown file)")
+               ctf_integer(int, scheduled_on_line, fromln)
+               ctf_integer_hex(intptr_t, thread_addr, thread_ptr ? *thread_ptr : NULL)
+               ctf_integer(int, file_descriptor, fd)
+               ctf_integer(int, event_value, val)
+               ctf_integer_hex(intptr_t, argument_ptr, arg)
+               ctf_integer(long, timer, time)
+       )
+)
+
+#define THREAD_OPERATION_TRACEPOINT_INSTANCE(name)                             \
+       TRACEPOINT_EVENT_INSTANCE(frr_libfrr, thread_operation, name,          \
+                                 THREAD_SCHEDULE_ARGS)                        \
+       TRACEPOINT_LOGLEVEL(frr_libfrr, name, TRACE_INFO)
+
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_timer)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_event)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_read)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_write)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel_async)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_call)
+
+/* clang-format on */
+
 #include <lttng/tracepoint-event.h>
 
 #else /* HAVE_LTTNG */