xref: /linux-6.15/include/linux/trace_seq.h (revision 196a0626)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
29504504cSSteven Rostedt #ifndef _LINUX_TRACE_SEQ_H
39504504cSSteven Rostedt #define _LINUX_TRACE_SEQ_H
49504504cSSteven Rostedt 
53a161d99SSteven Rostedt (Red Hat) #include <linux/seq_buf.h>
66d723736SSteven Rostedt 
778be6914SWu Zhangjin #include <asm/page.h>
878be6914SWu Zhangjin 
99504504cSSteven Rostedt /*
109504504cSSteven Rostedt  * Trace sequences are used to allow a function to call several other functions
1140fc60e3SSteven Rostedt (Google)  * to create a string of data to use.
126f42249fSSteven Rostedt (Google)  *
136f42249fSSteven Rostedt (Google)  * Have the trace seq to be 8K which is typically PAGE_SIZE * 2 on
146f42249fSSteven Rostedt (Google)  * most architectures. The TRACE_SEQ_BUFFER_SIZE (which is
156f42249fSSteven Rostedt (Google)  * TRACE_SEQ_SIZE minus the other fields of trace_seq), is the
166f42249fSSteven Rostedt (Google)  * max size the output of a trace event may be.
179504504cSSteven Rostedt  */
189504504cSSteven Rostedt 
196f42249fSSteven Rostedt (Google) #define TRACE_SEQ_SIZE		8192
206f42249fSSteven Rostedt (Google) #define TRACE_SEQ_BUFFER_SIZE	(TRACE_SEQ_SIZE - \
2140fc60e3SSteven Rostedt (Google) 	(sizeof(struct seq_buf) + sizeof(size_t) + sizeof(int)))
2240fc60e3SSteven Rostedt (Google) 
239504504cSSteven Rostedt struct trace_seq {
2440fc60e3SSteven Rostedt (Google) 	char			buffer[TRACE_SEQ_BUFFER_SIZE];
253a161d99SSteven Rostedt (Red Hat) 	struct seq_buf		seq;
26d0ed46b6SMatthew Wilcox (Oracle) 	size_t			readpos;
27d184b31cSJohannes Berg 	int			full;
289504504cSSteven Rostedt };
299504504cSSteven Rostedt 
309504504cSSteven Rostedt static inline void
trace_seq_init(struct trace_seq * s)319504504cSSteven Rostedt trace_seq_init(struct trace_seq *s)
329504504cSSteven Rostedt {
3340fc60e3SSteven Rostedt (Google) 	seq_buf_init(&s->seq, s->buffer, TRACE_SEQ_BUFFER_SIZE);
34d184b31cSJohannes Berg 	s->full = 0;
35d0ed46b6SMatthew Wilcox (Oracle) 	s->readpos = 0;
369504504cSSteven Rostedt }
379504504cSSteven Rostedt 
387b039cb4SSteven Rostedt (Red Hat) /**
395ac48378SSteven Rostedt (Red Hat)  * trace_seq_used - amount of actual data written to buffer
405ac48378SSteven Rostedt (Red Hat)  * @s: trace sequence descriptor
415ac48378SSteven Rostedt (Red Hat)  *
425ac48378SSteven Rostedt (Red Hat)  * Returns the amount of data written to the buffer.
435ac48378SSteven Rostedt (Red Hat)  *
445ac48378SSteven Rostedt (Red Hat)  * IMPORTANT!
455ac48378SSteven Rostedt (Red Hat)  *
465ac48378SSteven Rostedt (Red Hat)  * Use this instead of @s->seq.len if you need to pass the amount
475ac48378SSteven Rostedt (Red Hat)  * of data from the buffer to another buffer (userspace, or what not).
485ac48378SSteven Rostedt (Red Hat)  * The @s->seq.len on overflow is bigger than the buffer size and
495ac48378SSteven Rostedt (Red Hat)  * using it can cause access to undefined memory.
505ac48378SSteven Rostedt (Red Hat)  */
trace_seq_used(struct trace_seq * s)515ac48378SSteven Rostedt (Red Hat) static inline int trace_seq_used(struct trace_seq *s)
525ac48378SSteven Rostedt (Red Hat) {
535ac48378SSteven Rostedt (Red Hat) 	return seq_buf_used(&s->seq);
545ac48378SSteven Rostedt (Red Hat) }
555ac48378SSteven Rostedt (Red Hat) 
565ac48378SSteven Rostedt (Red Hat) /**
577b039cb4SSteven Rostedt (Red Hat)  * trace_seq_buffer_ptr - return pointer to next location in buffer
587b039cb4SSteven Rostedt (Red Hat)  * @s: trace sequence descriptor
597b039cb4SSteven Rostedt (Red Hat)  *
607b039cb4SSteven Rostedt (Red Hat)  * Returns the pointer to the buffer where the next write to
617b039cb4SSteven Rostedt (Red Hat)  * the buffer will happen. This is useful to save the location
627b039cb4SSteven Rostedt (Red Hat)  * that is about to be written to and then return the result
637b039cb4SSteven Rostedt (Red Hat)  * of that write.
647b039cb4SSteven Rostedt (Red Hat)  */
65d9a9280aSArnd Bergmann static inline char *
trace_seq_buffer_ptr(struct trace_seq * s)667b039cb4SSteven Rostedt (Red Hat) trace_seq_buffer_ptr(struct trace_seq *s)
677b039cb4SSteven Rostedt (Red Hat) {
685ac48378SSteven Rostedt (Red Hat) 	return s->buffer + seq_buf_used(&s->seq);
697b039cb4SSteven Rostedt (Red Hat) }
707b039cb4SSteven Rostedt (Red Hat) 
7119a7fe20SSteven Rostedt (Red Hat) /**
7219a7fe20SSteven Rostedt (Red Hat)  * trace_seq_has_overflowed - return true if the trace_seq took too much
7319a7fe20SSteven Rostedt (Red Hat)  * @s: trace sequence descriptor
7419a7fe20SSteven Rostedt (Red Hat)  *
7519a7fe20SSteven Rostedt (Red Hat)  * Returns true if too much data was added to the trace_seq and it is
7619a7fe20SSteven Rostedt (Red Hat)  * now full and will not take anymore.
7719a7fe20SSteven Rostedt (Red Hat)  */
trace_seq_has_overflowed(struct trace_seq * s)7819a7fe20SSteven Rostedt (Red Hat) static inline bool trace_seq_has_overflowed(struct trace_seq *s)
7919a7fe20SSteven Rostedt (Red Hat) {
803a161d99SSteven Rostedt (Red Hat) 	return s->full || seq_buf_has_overflowed(&s->seq);
8119a7fe20SSteven Rostedt (Red Hat) }
8219a7fe20SSteven Rostedt (Red Hat) 
839504504cSSteven Rostedt /*
849504504cSSteven Rostedt  * Currently only defined when tracing is enabled.
859504504cSSteven Rostedt  */
869504504cSSteven Rostedt #ifdef CONFIG_TRACING
87b9075fa9SJoe Perches extern __printf(2, 3)
88dba39448SSteven Rostedt (Red Hat) void trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
89b9075fa9SJoe Perches extern __printf(2, 0)
90dba39448SSteven Rostedt (Red Hat) void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args);
91*196a0626SAndy Shevchenko extern __printf(2, 0)
92*196a0626SAndy Shevchenko void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
93a63ce5b3SSteven Rostedt extern int trace_print_seq(struct seq_file *m, struct trace_seq *s);
9436aabfffSSteven Rostedt (Red Hat) extern int trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
9536aabfffSSteven Rostedt (Red Hat) 			     int cnt);
96dba39448SSteven Rostedt (Red Hat) extern void trace_seq_puts(struct trace_seq *s, const char *str);
97dba39448SSteven Rostedt (Red Hat) extern void trace_seq_putc(struct trace_seq *s, unsigned char c);
98dba39448SSteven Rostedt (Red Hat) extern void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len);
99dba39448SSteven Rostedt (Red Hat) extern void trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
10036aabfffSSteven Rostedt (Red Hat) 				unsigned int len);
10138eff289SAl Viro extern int trace_seq_path(struct trace_seq *s, const struct path *path);
1029504504cSSteven Rostedt 
103dba39448SSteven Rostedt (Red Hat) extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
1044449bf92SSteven Rostedt (Red Hat) 			     int nmaskbits);
1054449bf92SSteven Rostedt (Red Hat) 
106ef56e047SPiotr Maziarz extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str,
107ef56e047SPiotr Maziarz 			      int prefix_type, int rowsize, int groupsize,
108ef56e047SPiotr Maziarz 			      const void *buf, size_t len, bool ascii);
109a9c4bdd5SLinyu Yuan char *trace_seq_acquire(struct trace_seq *s, unsigned int len);
110ef56e047SPiotr Maziarz 
1119504504cSSteven Rostedt #else /* CONFIG_TRACING */
112bfd5a5e8SDavid Howells static inline __printf(2, 3)
trace_seq_printf(struct trace_seq * s,const char * fmt,...)113bfd5a5e8SDavid Howells void trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
1149504504cSSteven Rostedt {
1159504504cSSteven Rostedt }
116*196a0626SAndy Shevchenko static inline __printf(2, 0)
trace_seq_bprintf(struct trace_seq * s,const char * fmt,const u32 * binary)117*196a0626SAndy Shevchenko void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
1189504504cSSteven Rostedt {
1199504504cSSteven Rostedt }
1209504504cSSteven Rostedt 
121dba39448SSteven Rostedt (Red Hat) static inline void
trace_seq_bitmask(struct trace_seq * s,const unsigned long * maskp,int nmaskbits)1224449bf92SSteven Rostedt (Red Hat) trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
1234449bf92SSteven Rostedt (Red Hat) 		  int nmaskbits)
1244449bf92SSteven Rostedt (Red Hat) {
1254449bf92SSteven Rostedt (Red Hat) }
1264449bf92SSteven Rostedt (Red Hat) 
trace_print_seq(struct seq_file * m,struct trace_seq * s)127a63ce5b3SSteven Rostedt static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s)
1289504504cSSteven Rostedt {
129a63ce5b3SSteven Rostedt 	return 0;
1309504504cSSteven Rostedt }
trace_seq_to_user(struct trace_seq * s,char __user * ubuf,int cnt)13136aabfffSSteven Rostedt (Red Hat) static inline int trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
13236aabfffSSteven Rostedt (Red Hat) 				    int cnt)
1339504504cSSteven Rostedt {
1349504504cSSteven Rostedt 	return 0;
1359504504cSSteven Rostedt }
trace_seq_puts(struct trace_seq * s,const char * str)136dba39448SSteven Rostedt (Red Hat) static inline void trace_seq_puts(struct trace_seq *s, const char *str)
1379504504cSSteven Rostedt {
1389504504cSSteven Rostedt }
trace_seq_putc(struct trace_seq * s,unsigned char c)139dba39448SSteven Rostedt (Red Hat) static inline void trace_seq_putc(struct trace_seq *s, unsigned char c)
1409504504cSSteven Rostedt {
1419504504cSSteven Rostedt }
142dba39448SSteven Rostedt (Red Hat) static inline void
trace_seq_putmem(struct trace_seq * s,const void * mem,unsigned int len)14336aabfffSSteven Rostedt (Red Hat) trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
1449504504cSSteven Rostedt {
1459504504cSSteven Rostedt }
trace_seq_putmem_hex(struct trace_seq * s,const void * mem,unsigned int len)146dba39448SSteven Rostedt (Red Hat) static inline void trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
14736aabfffSSteven Rostedt (Red Hat) 				       unsigned int len)
1489504504cSSteven Rostedt {
1499504504cSSteven Rostedt }
trace_seq_path(struct trace_seq * s,const struct path * path)15038eff289SAl Viro static inline int trace_seq_path(struct trace_seq *s, const struct path *path)
1519504504cSSteven Rostedt {
1529504504cSSteven Rostedt 	return 0;
1539504504cSSteven Rostedt }
trace_seq_acquire(struct trace_seq * s,unsigned int len)154a9c4bdd5SLinyu Yuan static inline char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
155a9c4bdd5SLinyu Yuan {
156a9c4bdd5SLinyu Yuan 	return NULL;
157a9c4bdd5SLinyu Yuan }
1589504504cSSteven Rostedt #endif /* CONFIG_TRACING */
1599504504cSSteven Rostedt 
1609504504cSSteven Rostedt #endif /* _LINUX_TRACE_SEQ_H */
161