note: support note filtering at runtime

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
yinshengkai 2023-02-28 16:16:55 +08:00 committed by Xiang Xiao
parent b99a96a7d0
commit 67461175fe
2 changed files with 187 additions and 88 deletions

View File

@ -99,12 +99,15 @@
struct note_filter_s
{
struct note_filter_mode_s mode;
#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
# ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
struct note_filter_tag_s tag_mask;
# endif
# ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
struct note_filter_irq_s irq_mask;
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
# endif
# ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
struct note_filter_syscall_s syscall_mask;
#endif
# endif
};
#endif
@ -445,7 +448,7 @@ static inline int note_isenabled_irq(int irq, bool enter)
* Check whether the dump instrumentation is enabled.
*
* Input Parameters:
* None
* tag: The dump instrumentation tag
*
* Returned Value:
* True is returned if the instrumentation is enabled.
@ -453,9 +456,9 @@ static inline int note_isenabled_irq(int irq, bool enter)
****************************************************************************/
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
static inline int note_isenabled_dump(void)
static inline int note_isenabled_dump(uint32_t tag)
{
#ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
# ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
if (!note_isenabled())
{
return false;
@ -463,11 +466,12 @@ static inline int note_isenabled_dump(void)
/* If the dump trace is disabled, do nothing. */
if ((g_note_filter.mode.flag & NOTE_FILTER_MODE_FLAG_DUMP) == 0)
if (!(g_note_filter.mode.flag & NOTE_FILTER_MODE_FLAG_DUMP) ||
NOTE_FILTER_DUMPMASK_ISSET(tag, &g_note_filter.tag_mask))
{
return false;
}
#endif
# endif
return true;
}
@ -1340,7 +1344,7 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter)
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
void sched_note_string(uintptr_t ip, FAR const char *buf)
void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf)
{
FAR struct note_string_s *note;
uint8_t data[255];
@ -1349,7 +1353,7 @@ void sched_note_string(uintptr_t ip, FAR const char *buf)
bool formatted = false;
FAR struct tcb_s *tcb = this_task();
if (!note_isenabled_dump())
if (!note_isenabled_dump(tag))
{
return;
}
@ -1390,8 +1394,8 @@ void sched_note_string(uintptr_t ip, FAR const char *buf)
}
}
void sched_note_dump(uintptr_t ip, uint8_t event,
FAR const void *buf, size_t len)
void sched_note_dump_ip(uint32_t tag, uintptr_t ip, uint8_t event,
FAR const void *buf, size_t len)
{
FAR struct note_binary_s *note;
FAR struct note_driver_s **driver;
@ -1400,7 +1404,7 @@ void sched_note_dump(uintptr_t ip, uint8_t event,
unsigned int length;
FAR struct tcb_s *tcb = this_task();
if (!note_isenabled_dump())
if (!note_isenabled_dump(tag))
{
return;
}
@ -1442,8 +1446,8 @@ void sched_note_dump(uintptr_t ip, uint8_t event,
}
}
void sched_note_vprintf(uintptr_t ip,
FAR const char *fmt, va_list va)
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
FAR const char *fmt, va_list va)
{
FAR struct note_string_s *note;
uint8_t data[255];
@ -1452,7 +1456,7 @@ void sched_note_vprintf(uintptr_t ip,
bool formatted = false;
FAR struct tcb_s *tcb = this_task();
if (!note_isenabled_dump())
if (!note_isenabled_dump(tag))
{
return;
}
@ -1496,8 +1500,8 @@ void sched_note_vprintf(uintptr_t ip,
}
}
void sched_note_vbprintf(uintptr_t ip, uint8_t event,
FAR const char *fmt, va_list va)
void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, uint8_t event,
FAR const char *fmt, va_list va)
{
FAR struct note_binary_s *note;
FAR struct note_driver_s **driver;
@ -1534,7 +1538,7 @@ void sched_note_vbprintf(uintptr_t ip, uint8_t event,
int next = 0;
FAR struct tcb_s *tcb = this_task();
if (!note_isenabled_dump())
if (!note_isenabled_dump(tag))
{
return;
}
@ -1715,21 +1719,21 @@ void sched_note_vbprintf(uintptr_t ip, uint8_t event,
}
}
void sched_note_printf(uintptr_t ip,
FAR const char *fmt, ...)
void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
FAR const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
sched_note_vprintf(ip, fmt, va);
sched_note_vprintf_ip(tag, ip, fmt, va);
va_end(va);
}
void sched_note_bprintf(uintptr_t ip, uint8_t event,
FAR const char *fmt, ...)
void sched_note_bprintf_ip(uint32_t tag, uintptr_t ip, uint8_t event,
FAR const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
sched_note_vbprintf(ip, event, fmt, va);
sched_note_vbprintf_ip(tag, ip, event, fmt, va);
va_end(va);
}
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
@ -1868,6 +1872,52 @@ void sched_note_filter_irq(FAR struct note_filter_irq_s *oldf,
}
#endif
/****************************************************************************
* Name: sched_note_filter_tag
*
* Description:
* Set and get tsg filter setting
* (Same as NOTECTL_GETDUMPFILTER / NOTECTL_SETDUMPFILTER ioctls)
*
* Input Parameters:
* oldf - A writable pointer to struct note_filter_tag_s to get
* current dump filter setting
* If 0, no data is written.
* newf - A read-only pointer to struct note_filter_tag_s of the
* new dump filter setting
* If 0, the setting is not updated.
*
* Returned Value:
* None
*
****************************************************************************/
# ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
void sched_note_filter_dump(FAR struct note_filter_tag_s *oldf,
FAR struct note_filter_tag_s *newf)
{
irqstate_t falgs;
falgs = spin_lock_irqsave_wo_note(&g_note_lock);
if (oldf != NULL)
{
/* Return the current filter setting */
*oldf = g_note_filter.tag_mask;
}
if (newf != NULL)
{
/* Replace the dump filter mask by the provided setting */
g_note_filter.tag_mask = *newf;
}
spin_unlock_irqrestore_wo_note(&g_note_lock, falgs);
}
# endif
#endif /* CONFIG_SCHED_INSTRUMENTATION_FILTER */
#if CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE > 0

View File

@ -106,6 +106,19 @@
memset((s), 0, sizeof(struct note_filter_irq_s))
#endif
/* Helper macros for dump instrumentation filter */
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
# define NOTE_FILTER_DUMPMASK_SET(tag, s) \
((s)->tag_mask[(tag) / 8] |= (1 << ((tag) % 8)))
# define NOTE_FILTER_DUMPMASK_CLR(tag, s) \
((s)->tag_mask[(tag) / 8] &= ~(1 << ((tag) % 8)))
# define NOTE_FILTER_DUMPMASK_ISSET(tag, s) \
((s)->tag_mask[(tag) / 8] & (1 << ((tag) % 8)))
# define NOTE_FILTER_DUMPMASK_ZERO(s) \
memset((s), 0, sizeof(struct note_filter_tag_s));
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
# define SCHED_NOTE_LABEL__(x, y) x ## y
# define SCHED_NOTE_LABEL_(x, y) SCHED_NOTE_LABEL__(x, y)
@ -113,35 +126,36 @@
SCHED_NOTE_LABEL_(sched_note_here, __LINE__)
# define SCHED_NOTE_IP \
({SCHED_NOTE_LABEL: (uintptr_t)&&SCHED_NOTE_LABEL;})
# define SCHED_NOTE_STRING(buf) \
sched_note_string(SCHED_NOTE_IP, buf)
# define SCHED_NOTE_DUMP(event, buf, len) \
sched_note_dump(SCHED_NOTE_IP, event, buf, len)
# define SCHED_NOTE_VPRINTF(fmt, va) \
sched_note_vprintf(SCHED_NOTE_IP, fmt, va)
# define SCHED_NOTE_VBPRINTF(event, fmt, va) \
sched_note_vbprintf(SCHED_NOTE_IP, event, fmt, va)
# define SCHED_NOTE_PRINTF(fmt, ...) \
sched_note_printf(SCHED_NOTE_IP, fmt, ##__VA_ARGS__)
# define SCHED_NOTE_BPRINTF(event, fmt, ...) \
sched_note_bprintf(SCHED_NOTE_IP, event, fmt, ##__VA_ARGS__)
# define SCHED_NOTE_BEGINEX(str) \
sched_note_printf(SCHED_NOTE_IP, "B|%d|%s", gettid(), str)
# define SCHED_NOTE_ENDEX(str) \
sched_note_printf(SCHED_NOTE_IP, "E|%d|%s", gettid(), str)
# define SCHED_NOTE_BEGIN() \
sched_note_begin(SCHED_NOTE_IP)
# define SCHED_NOTE_END() \
sched_note_end(SCHED_NOTE_IP)
# define sched_note_string(tag, buf) \
sched_note_string_ip(tag, SCHED_NOTE_IP, buf)
# define sched_note_dump(tag, event, buf, len) \
sched_note_dump_ip(tag, SCHED_NOTE_IP, event, buf, len)
# define sched_note_vprintf(tag, fmt, va) \
sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, va)
# define sched_note_vbprintf(event, fmt, va) \
sched_note_vbprintf_ip(tag, SCHED_NOTE_IP, event, fmt, va)
# define sched_note_printf(tag, fmt, ...) \
sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__)
# define sched_note_bprintf(tag, event, fmt, ...) \
sched_note_bprintf_ip(tag, SCHED_NOTE_IP, event, \
fmt, ##__VA_ARGS__)
# define sched_note_beginex(tag, str) \
sched_note_printf_ip(tag, SCHED_NOTE_IP, "B|%d|%s", gettid(), str)
# define sched_note_endex(tag, str) \
sched_note_printf_ip(tag, SCHED_NOTE_IP, "E|%d|%s", gettid(), str)
# define sched_note_begin(tag, ip) \
sched_note_string_ip(tag, SCHED_NOTE_IP, "B")
# define sched_note_end(tag, ip) \
sched_note_string_ip(tag, SCHED_NOTE_IP, "E")
#else
# define SCHED_NOTE_STRING(buf)
# define SCHED_NOTE_DUMP(event, buf, len)
# define SCHED_NOTE_VPRINTF(fmt, va)
# define SCHED_NOTE_VBPRINTF(event, fmt, va)
# define SCHED_NOTE_PRINTF(fmt, ...)
# define SCHED_NOTE_BPRINTF(event, fmt, ...)
# define SCHED_NOTE_BEGIN()
# define SCHED_NOTE_END()
# define sched_note_string(tag, buf)
# define sched_note_dump(tag, event, buf, len)
# define sched_note_vprintf(tag, fmt, va)
# define sched_note_vbprintf(tag, event, fmt, va)
# define sched_note_printf(tag, fmt, ...)
# define sched_note_bprintf(tag, event, fmt, ...)
# define sched_note_begin(tag)
# define sched_note_end(tag)
#endif
/****************************************************************************
@ -205,6 +219,30 @@ enum note_type_e
#endif
};
enum note_tag_e
{
NOTE_TAG_ALWAYS = 0,
NOTE_TAG_APP,
NOTE_TAG_ARCH,
NOTE_TAG_AUDIO,
NOTE_TAG_BOARD,
NOTE_TAG_CRYPTO,
NOTE_TAG_DRIVERS,
NOTE_TAG_FS,
NOTE_TAG_GRAPHICS,
NOTE_TAG_INPUT,
NOTE_TAG_MM,
NOTE_TAG_NET,
NOTE_TAG_SCHED,
NOTE_TAG_VIDEO,
NOTE_TAG_WIRLESS,
/* Always last */
NOTE_TAG_LAST,
NOTE_TAG_MAX = NOTE_TAG_LAST + 16
};
/* This structure provides the common header of each note */
struct note_common_s
@ -439,6 +477,13 @@ struct note_filter_irq_s
};
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
struct note_filter_tag_s
{
uint8_t tag_mask[(NOTE_TAG_MAX + 7) / 8];
};
#endif
#endif /* CONFIG_SCHED_INSTRUMENTATION_FILTER */
/****************************************************************************
@ -540,24 +585,25 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter);
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
void sched_note_string(uintptr_t ip, FAR const char *buf);
void sched_note_dump(uintptr_t ip, uint8_t event,
FAR const void *buf, size_t len);
void sched_note_vprintf(uintptr_t ip, FAR const char *fmt,
va_list va) printf_like(2, 0);
void sched_note_vbprintf(uintptr_t ip, uint8_t event,
FAR const char *fmt, va_list va) printf_like(3, 0);
void sched_note_printf(uintptr_t ip,
FAR const char *fmt, ...) printf_like(2, 3);
void sched_note_bprintf(uintptr_t ip, uint8_t event,
FAR const char *fmt, ...) printf_like(3, 4);
void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf);
void sched_note_dump_ip(uint32_t tag, uintptr_t ip, uint8_t event,
FAR const void *buf, size_t len);
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
va_list va) printf_like(3, 0);
void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, uint8_t event,
FAR const char *fmt,
va_list va) printf_like(4, 0);
void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
FAR const char *fmt, ...) printf_like(3, 4);
void sched_note_bprintf_ip(uint32_t tag, uintptr_t ip, uint8_t event,
FAR const char *fmt, ...) printf_like(4, 5);
#else
# define sched_note_string(ip,b)
# define sched_note_dump(ip,e,b,l)
# define sched_note_vprintf(ip,f,v)
# define sched_note_vbprintf(ip,e,f,v)
# define sched_note_printf(ip,f,...)
# define sched_note_bprintf(ip,e,f,...)
# define sched_note_string_ip(t,ip,b)
# define sched_note_dump_ip(t,ip,e,b,l)
# define sched_note_vprintf_ip(t,ip,f,v)
# define sched_note_vbprintf_ip(t,ip,e,f,v)
# define sched_note_printf_ip(t,ip,f,...)
# define sched_note_bprintf_ip(t,ip,e,f,...)
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
#if defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT)
@ -639,6 +685,12 @@ void sched_note_filter_irq(FAR struct note_filter_irq_s *oldf,
FAR struct note_filter_irq_s *newf);
#endif
#if defined(CONFIG_SCHED_INSTRUMENTATION_FILTER) && \
defined(CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER)
void sched_note_filter_tag(FAR struct note_filter_tag_s *oldf,
FAR struct note_filter_tag_s *newf);
#endif
#endif /* defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT) */
#undef EXTERN
@ -648,14 +700,14 @@ void sched_note_filter_irq(FAR struct note_filter_irq_s *oldf,
#else /* CONFIG_SCHED_INSTRUMENTATION */
# define SCHED_NOTE_STRING(buf)
# define SCHED_NOTE_DUMP(event, buf, len)
# define SCHED_NOTE_VPRINTF(fmt, va)
# define SCHED_NOTE_VBPRINTF(event, fmt, va)
# define SCHED_NOTE_PRINTF(fmt, ...)
# define SCHED_NOTE_BPRINTF(event, fmt, ...)
# define SCHED_NOTE_BEGIN()
# define SCHED_NOTE_END()
# define sched_note_string(buf)
# define sched_note_dump(event, buf, len)
# define sched_note_vprintf(fmt, va)
# define sched_note_vbprintf(event, fmt, va)
# define sched_note_printf(fmt, ...)
# define sched_note_bprintf(event, fmt, ...)
# define sched_note_begin()
# define sched_note_end()
# define sched_note_start(t)
# define sched_note_stop(t)
@ -673,16 +725,13 @@ void sched_note_filter_irq(FAR struct note_filter_irq_s *oldf,
# define sched_note_syscall_enter(n,a,...)
# define sched_note_syscall_leave(n,r)
# define sched_note_irqhandler(i,h,e)
# define sched_note_string(ip,b)
# define sched_note_dump(ip,e,b,l)
# define sched_note_vprintf(ip,f,v)
# define sched_note_vbprintf(ip,e,f,v)
# define sched_note_printf(ip,f,...)
# define sched_note_bprintf(ip,e,f,...)
# define sched_note_string_ip(t,ip,b)
# define sched_note_dump_ip(t,ip,e,b,l)
# define sched_note_vprintf_ip(t,ip,f,v)
# define sched_note_vbprintf_ip(t,ip,e,f,v)
# define sched_note_printf_ip(t,ip,f,...)
# define sched_note_bprintf_ip(t,ip,e,f,...)
#endif /* CONFIG_SCHED_INSTRUMENTATION */
#define sched_note_begin(ip) sched_note_string(ip, "B")
#define sched_note_end(ip) sched_note_string(ip, "E")
#endif /* __INCLUDE_NUTTX_SCHED_NOTE_H */