diff --git a/drivers/note/note_driver.c b/drivers/note/note_driver.c index ec35d72653e..bb9b06b08bd 100644 --- a/drivers/note/note_driver.c +++ b/drivers/note/note_driver.c @@ -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 diff --git a/include/nuttx/sched_note.h b/include/nuttx/sched_note.h index 9be8a950ba2..946a70f7280 100644 --- a/include/nuttx/sched_note.h +++ b/include/nuttx/sched_note.h @@ -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 */