kernel: Bring back object tracking

When CONFIG_TRACING_OBJECT_TRACKING is enabled, the kernel will keep
lists of some objects (detailed below), so that debuggers or other tools
can keep track of them.

The lists of objects are:

struct k_timer *_track_list_k_timer;
struct k_mem_slab *_track_list_k_mem_slab;
struct k_sem *_track_list_k_sem;
struct k_mutex *_track_list_k_mutex;
struct k_stack *_track_list_k_stack;
struct k_msgq *_track_list_k_msgq;
struct k_mbox *_track_list_k_mbox;
struct k_pipe *_track_list_k_pipe;
struct k_queue *_track_list_k_queue;

Note that while CONFIG_TRACING is needed, one can always use
CONFIG_TRACE_NONE=y. Also, tracking will only be done for objects that
are also being traced (so, to prevent tracking of some type of object,
such as k_timer, just make CONFIG_TRACING_TIMER=n).

Some simple "sanity checking" tests are also added in this patch.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza 2021-11-22 14:46:19 -08:00 committed by Anas Nashif
commit bdaac354f4
12 changed files with 544 additions and 0 deletions

View file

@ -1288,6 +1288,7 @@ struct k_timer {
/* user-specific data, also used to support legacy features */
void *user_data;
SYS_PORT_TRACING_TRACKING_FIELD(k_timer)
};
#define Z_TIMER_INITIALIZER(obj, expiry, stop) \
@ -1670,6 +1671,8 @@ struct k_queue {
_wait_q_t wait_q;
_POLL_EVENT;
SYS_PORT_TRACING_TRACKING_FIELD(k_queue)
};
#define Z_QUEUE_INITIALIZER(obj) \
@ -2548,6 +2551,8 @@ struct k_stack {
stack_data_t *base, *next, *top;
uint8_t flags;
SYS_PORT_TRACING_TRACKING_FIELD(k_stack)
};
#define Z_STACK_INITIALIZER(obj, stack_buffer, stack_num_entries) \
@ -2705,6 +2710,8 @@ struct k_mutex {
/** Original thread priority */
int owner_orig_prio;
SYS_PORT_TRACING_TRACKING_FIELD(k_mutex)
};
/**
@ -2888,6 +2895,8 @@ struct k_sem {
_POLL_EVENT;
SYS_PORT_TRACING_TRACKING_FIELD(k_sem)
};
#define Z_SEM_INITIALIZER(obj, initial_count, count_limit) \
@ -4328,6 +4337,8 @@ struct k_msgq {
/** Message queue */
uint8_t flags;
SYS_PORT_TRACING_TRACKING_FIELD(k_msgq)
};
/**
* @cond INTERNAL_HIDDEN
@ -4617,6 +4628,7 @@ struct k_mbox {
_wait_q_t rx_msg_queue;
struct k_spinlock lock;
SYS_PORT_TRACING_TRACKING_FIELD(k_mbox)
};
/**
* @cond INTERNAL_HIDDEN
@ -4756,6 +4768,8 @@ struct k_pipe {
} wait_q; /** Wait queue */
uint8_t flags; /**< Flags */
SYS_PORT_TRACING_TRACKING_FIELD(k_pipe)
};
/**
@ -4929,6 +4943,7 @@ struct k_mem_slab {
uint32_t max_used;
#endif
SYS_PORT_TRACING_TRACKING_FIELD(k_mem_slab)
};
#define Z_MEM_SLAB_INITIALIZER(obj, slab_buffer, slab_block_size, \

View file

@ -8,6 +8,8 @@
#include <kernel.h>
#include "tracking.h"
#if defined CONFIG_SEGGER_SYSTEMVIEW
#include "tracing_sysview.h"
#elif defined CONFIG_TRACING_CTF

View file

@ -18,6 +18,8 @@
#define SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(obj_type, func, obj, ...) do { } while (false)
#define SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func, obj, ...) do { } while (false)
#define SYS_PORT_TRACING_TRACKING_FIELD(type)
#else
/**
@ -54,6 +56,15 @@
#define _SYS_PORT_TRACING_OBJ_FUNC_EXIT(name, func) \
sys_port_trace_ ## name ## _ ## func ## _exit
/*
* Helper macros for the object tracking system
*/
#define _SYS_PORT_TRACKING_OBJ_INIT(name) \
sys_port_track_ ## name ## _init
#define _SYS_PORT_TRACKING_OBJ_FUNC(name, func) \
sys_port_track_ ## name ## _ ## func
/*
* Object trace macros part of the system for checking if certain
* objects should be traced or not depending on the tracing configuration.
@ -252,6 +263,8 @@
do { \
SYS_PORT_TRACING_TYPE_MASK(obj_type, \
_SYS_PORT_TRACING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \
SYS_PORT_TRACING_TYPE_MASK(obj_type, \
_SYS_PORT_TRACKING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \
} while (false)
/**
@ -268,6 +281,8 @@
do { \
SYS_PORT_TRACING_TYPE_MASK(obj_type, \
_SYS_PORT_TRACING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \
SYS_PORT_TRACING_TYPE_MASK(obj_type, \
_SYS_PORT_TRACKING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \
} while (false)
/**
@ -322,6 +337,14 @@
_SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func)(obj, ##__VA_ARGS__)); \
} while (false)
/**
* @brief Field added to kernel objects so they are tracked.
*
* @param type Type of object being tracked (k_thread, k_sem, etc.)
*/
#define SYS_PORT_TRACING_TRACKING_FIELD(type) \
SYS_PORT_TRACING_TYPE_MASK(type, struct type *_obj_track_next;)
/** @} */ /* end of subsys_tracing_macros */
#endif /* CONFIG_TRACING */

142
include/tracing/tracking.h Normal file
View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_TRACING_TRACKING_H_
#define ZEPHYR_INCLUDE_TRACING_TRACKING_H_
#include <kernel.h>
#include <kernel_structs.h>
#if defined(CONFIG_TRACING_OBJECT_TRACKING) || defined(__DOXYGEN__)
/**
* @brief Object tracking
*
* Object tracking provides lists to kernel objects, so their
* existence and current status can be tracked.
*
* The following global variables are the heads of available lists:
* - _track_list_k_timer
* - _track_list_k_mem_slab
* - _track_list_k_sem
* - _track_list_k_mutex
* - _track_list_k_stack
* - _track_list_k_msgq
* - _track_list_k_mbox
* - _track_list_k_pipe
* - _track_list_k_queue
*
* @defgroup subsys_tracing_object_tracking Object tracking
* @ingroup subsys_tracing
* @{
*/
extern struct k_timer *_track_list_k_timer;
extern struct k_mem_slab *_track_list_k_mem_slab;
extern struct k_sem *_track_list_k_sem;
extern struct k_mutex *_track_list_k_mutex;
extern struct k_stack *_track_list_k_stack;
extern struct k_msgq *_track_list_k_msgq;
extern struct k_mbox *_track_list_k_mbox;
extern struct k_pipe *_track_list_k_pipe;
extern struct k_queue *_track_list_k_queue;
/**
* @brief Gets node's next element in a object tracking list.
*
* @param list Node to get next element from.
*/
#define SYS_PORT_TRACK_NEXT(list)((list)->_obj_track_next)
/** @cond INTERNAL_HIDDEN */
#define sys_port_track_k_thread_start(thread)
#define sys_port_track_k_thread_create(new_thread)
#define sys_port_track_k_thread_sched_ready(thread)
#define sys_port_track_k_thread_wakeup(thread)
#define sys_port_track_k_thread_sched_priority_set(thread, prio)
#define sys_port_track_k_work_delayable_init(dwork)
#define sys_port_track_k_work_queue_init(queue)
#define sys_port_track_k_work_init(work)
#define sys_port_track_k_mutex_init(mutex, ret) \
sys_track_k_mutex_init(mutex)
#define sys_port_track_k_timer_stop(timer)
#define sys_port_track_k_timer_start(timer)
#define sys_port_track_k_timer_init(timer) \
sys_track_k_timer_init(timer)
#define sys_port_track_k_queue_peek_tail(queue, ret)
#define sys_port_track_k_queue_peek_head(queue, ret)
#define sys_port_track_k_queue_cancel_wait(queue)
#define sys_port_track_k_queue_init(queue) \
sys_track_k_queue_init(queue)
#define sys_port_track_k_pipe_init(pipe) \
sys_track_k_pipe_init(pipe)
#define sys_port_track_k_condvar_init(condvar, ret)
#define sys_port_track_k_stack_init(stack) \
sys_track_k_stack_init(stack)
#define sys_port_track_k_thread_name_set(thread, ret)
#define sys_port_track_k_sem_reset(sem)
#define sys_port_track_k_sem_init(sem, ret) \
sys_track_k_sem_init(sem)
#define sys_port_track_k_msgq_purge(msgq)
#define sys_port_track_k_msgq_peek(msgq, ret)
#define sys_port_track_k_msgq_init(msgq) \
sys_track_k_msgq_init(msgq)
#define sys_port_track_k_mbox_init(mbox) \
sys_track_k_mbox_init(mbox)
#define sys_port_track_k_mem_slab_init(slab, rc) \
sys_track_k_mem_slab_init(slab)
#define sys_port_track_k_heap_free(h)
#define sys_port_track_k_heap_init(h)
void sys_track_k_timer_init(struct k_timer *timer);
void sys_track_k_mem_slab_init(struct k_mem_slab *slab);
void sys_track_k_sem_init(struct k_sem *sem);
void sys_track_k_mutex_init(struct k_mutex *mutex);
void sys_track_k_stack_init(struct k_stack *stack);
void sys_track_k_msgq_init(struct k_msgq *msgq);
void sys_track_k_mbox_init(struct k_mbox *mbox);
void sys_track_k_pipe_init(struct k_pipe *pipe);
void sys_track_k_queue_init(struct k_queue *queue);
/** @endcond */
/** @} */ /* end of subsys_tracing_object_tracking */
#else
#define sys_port_track_k_thread_start(thread)
#define sys_port_track_k_thread_create(new_thread)
#define sys_port_track_k_thread_sched_ready(thread)
#define sys_port_track_k_thread_wakeup(thread)
#define sys_port_track_k_thread_sched_priority_set(thread, prio)
#define sys_port_track_k_work_delayable_init(dwork)
#define sys_port_track_k_work_queue_init(queue)
#define sys_port_track_k_work_init(work)
#define sys_port_track_k_mutex_init(mutex, ret)
#define sys_port_track_k_timer_stop(timer)
#define sys_port_track_k_timer_start(timer)
#define sys_port_track_k_timer_init(timer)
#define sys_port_track_k_queue_peek_tail(queue, ret)
#define sys_port_track_k_queue_peek_head(queue, ret)
#define sys_port_track_k_queue_cancel_wait(queue)
#define sys_port_track_k_queue_init(queue)
#define sys_port_track_k_pipe_init(pipe)
#define sys_port_track_k_condvar_init(condvar, ret)
#define sys_port_track_k_stack_init(stack)
#define sys_port_track_k_thread_name_set(thread, ret)
#define sys_port_track_k_sem_reset(sem)
#define sys_port_track_k_sem_init(sem, ret)
#define sys_port_track_k_msgq_purge(msgq)
#define sys_port_track_k_msgq_peek(msgq, ret)
#define sys_port_track_k_msgq_init(msgq)
#define sys_port_track_k_mbox_init(mbox)
#define sys_port_track_k_mem_slab_init(slab, rc)
#define sys_port_track_k_heap_free(h)
#define sys_port_track_k_heap_init(h)
#endif
#endif /* ZEPHYR_INCLUDE_TRACING_TRACKING_H_ */