1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * trace_seq.c 4 * 5 * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 6 * 7 * The trace_seq is a handy tool that allows you to pass a descriptor around 8 * to a buffer that other functions can write to. It is similar to the 9 * seq_file functionality but has some differences. 10 * 11 * To use it, the trace_seq must be initialized with trace_seq_init(). 12 * This will set up the counters within the descriptor. You can call 13 * trace_seq_init() more than once to reset the trace_seq to start 14 * from scratch. 15 * 16 * The buffer size is currently PAGE_SIZE, although it may become dynamic 17 * in the future. 18 * 19 * A write to the buffer will either succed or fail. That is, unlike 20 * sprintf() there will not be a partial write (well it may write into 21 * the buffer but it wont update the pointers). This allows users to 22 * try to write something into the trace_seq buffer and if it fails 23 * they can flush it and try again. 24 * 25 */ 26 #include <linux/uaccess.h> 27 #include <linux/seq_file.h> 28 #include <linux/trace_seq.h> 29 30 /* How much buffer is left on the trace_seq? */ 31 #define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq) 32 33 /* How much buffer is written? */ 34 #define TRACE_SEQ_BUF_USED(s) seq_buf_used(&(s)->seq) 35 36 /* 37 * trace_seq should work with being initialized with 0s. 38 */ 39 static inline void __trace_seq_init(struct trace_seq *s) 40 { 41 if (unlikely(!s->seq.size)) 42 trace_seq_init(s); 43 } 44 45 /** 46 * trace_print_seq - move the contents of trace_seq into a seq_file 47 * @m: the seq_file descriptor that is the destination 48 * @s: the trace_seq descriptor that is the source. 49 * 50 * Returns 0 on success and non zero on error. If it succeeds to 51 * write to the seq_file it will reset the trace_seq, otherwise 52 * it does not modify the trace_seq to let the caller try again. 53 */ 54 int trace_print_seq(struct seq_file *m, struct trace_seq *s) 55 { 56 int ret; 57 58 __trace_seq_init(s); 59 60 ret = seq_buf_print_seq(m, &s->seq); 61 62 /* 63 * Only reset this buffer if we successfully wrote to the 64 * seq_file buffer. This lets the caller try again or 65 * do something else with the contents. 66 */ 67 if (!ret) 68 trace_seq_init(s); 69 70 return ret; 71 } 72 73 /** 74 * trace_seq_printf - sequence printing of trace information 75 * @s: trace sequence descriptor 76 * @fmt: printf format string 77 * 78 * The tracer may use either sequence operations or its own 79 * copy to user routines. To simplify formating of a trace 80 * trace_seq_printf() is used to store strings into a special 81 * buffer (@s). Then the output may be either used by 82 * the sequencer or pulled into another buffer. 83 */ 84 void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) 85 { 86 unsigned int save_len = s->seq.len; 87 va_list ap; 88 89 if (s->full) 90 return; 91 92 __trace_seq_init(s); 93 94 va_start(ap, fmt); 95 seq_buf_vprintf(&s->seq, fmt, ap); 96 va_end(ap); 97 98 /* If we can't write it all, don't bother writing anything */ 99 if (unlikely(seq_buf_has_overflowed(&s->seq))) { 100 s->seq.len = save_len; 101 s->full = 1; 102 } 103 } 104 EXPORT_SYMBOL_GPL(trace_seq_printf); 105 106 /** 107 * trace_seq_bitmask - write a bitmask array in its ASCII representation 108 * @s: trace sequence descriptor 109 * @maskp: points to an array of unsigned longs that represent a bitmask 110 * @nmaskbits: The number of bits that are valid in @maskp 111 * 112 * Writes a ASCII representation of a bitmask string into @s. 113 */ 114 void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, 115 int nmaskbits) 116 { 117 unsigned int save_len = s->seq.len; 118 119 if (s->full) 120 return; 121 122 __trace_seq_init(s); 123 124 seq_buf_printf(&s->seq, "%*pb", nmaskbits, maskp); 125 126 if (unlikely(seq_buf_has_overflowed(&s->seq))) { 127 s->seq.len = save_len; 128 s->full = 1; 129 } 130 } 131 EXPORT_SYMBOL_GPL(trace_seq_bitmask); 132 133 /** 134 * trace_seq_vprintf - sequence printing of trace information 135 * @s: trace sequence descriptor 136 * @fmt: printf format string 137 * 138 * The tracer may use either sequence operations or its own 139 * copy to user routines. To simplify formating of a trace 140 * trace_seq_printf is used to store strings into a special 141 * buffer (@s). Then the output may be either used by 142 * the sequencer or pulled into another buffer. 143 */ 144 void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) 145 { 146 unsigned int save_len = s->seq.len; 147 148 if (s->full) 149 return; 150 151 __trace_seq_init(s); 152 153 seq_buf_vprintf(&s->seq, fmt, args); 154 155 /* If we can't write it all, don't bother writing anything */ 156 if (unlikely(seq_buf_has_overflowed(&s->seq))) { 157 s->seq.len = save_len; 158 s->full = 1; 159 } 160 } 161 EXPORT_SYMBOL_GPL(trace_seq_vprintf); 162 163 /** 164 * trace_seq_bprintf - Write the printf string from binary arguments 165 * @s: trace sequence descriptor 166 * @fmt: The format string for the @binary arguments 167 * @binary: The binary arguments for @fmt. 168 * 169 * When recording in a fast path, a printf may be recorded with just 170 * saving the format and the arguments as they were passed to the 171 * function, instead of wasting cycles converting the arguments into 172 * ASCII characters. Instead, the arguments are saved in a 32 bit 173 * word array that is defined by the format string constraints. 174 * 175 * This function will take the format and the binary array and finish 176 * the conversion into the ASCII string within the buffer. 177 */ 178 void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) 179 { 180 unsigned int save_len = s->seq.len; 181 182 if (s->full) 183 return; 184 185 __trace_seq_init(s); 186 187 seq_buf_bprintf(&s->seq, fmt, binary); 188 189 /* If we can't write it all, don't bother writing anything */ 190 if (unlikely(seq_buf_has_overflowed(&s->seq))) { 191 s->seq.len = save_len; 192 s->full = 1; 193 return; 194 } 195 } 196 EXPORT_SYMBOL_GPL(trace_seq_bprintf); 197 198 /** 199 * trace_seq_puts - trace sequence printing of simple string 200 * @s: trace sequence descriptor 201 * @str: simple string to record 202 * 203 * The tracer may use either the sequence operations or its own 204 * copy to user routines. This function records a simple string 205 * into a special buffer (@s) for later retrieval by a sequencer 206 * or other mechanism. 207 */ 208 void trace_seq_puts(struct trace_seq *s, const char *str) 209 { 210 unsigned int len = strlen(str); 211 212 if (s->full) 213 return; 214 215 __trace_seq_init(s); 216 217 if (len > TRACE_SEQ_BUF_LEFT(s)) { 218 s->full = 1; 219 return; 220 } 221 222 seq_buf_putmem(&s->seq, str, len); 223 } 224 EXPORT_SYMBOL_GPL(trace_seq_puts); 225 226 /** 227 * trace_seq_putc - trace sequence printing of simple character 228 * @s: trace sequence descriptor 229 * @c: simple character to record 230 * 231 * The tracer may use either the sequence operations or its own 232 * copy to user routines. This function records a simple charater 233 * into a special buffer (@s) for later retrieval by a sequencer 234 * or other mechanism. 235 */ 236 void trace_seq_putc(struct trace_seq *s, unsigned char c) 237 { 238 if (s->full) 239 return; 240 241 __trace_seq_init(s); 242 243 if (TRACE_SEQ_BUF_LEFT(s) < 1) { 244 s->full = 1; 245 return; 246 } 247 248 seq_buf_putc(&s->seq, c); 249 } 250 EXPORT_SYMBOL_GPL(trace_seq_putc); 251 252 /** 253 * trace_seq_putmem - write raw data into the trace_seq buffer 254 * @s: trace sequence descriptor 255 * @mem: The raw memory to copy into the buffer 256 * @len: The length of the raw memory to copy (in bytes) 257 * 258 * There may be cases where raw memory needs to be written into the 259 * buffer and a strcpy() would not work. Using this function allows 260 * for such cases. 261 */ 262 void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) 263 { 264 if (s->full) 265 return; 266 267 __trace_seq_init(s); 268 269 if (len > TRACE_SEQ_BUF_LEFT(s)) { 270 s->full = 1; 271 return; 272 } 273 274 seq_buf_putmem(&s->seq, mem, len); 275 } 276 EXPORT_SYMBOL_GPL(trace_seq_putmem); 277 278 /** 279 * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex 280 * @s: trace sequence descriptor 281 * @mem: The raw memory to write its hex ASCII representation of 282 * @len: The length of the raw memory to copy (in bytes) 283 * 284 * This is similar to trace_seq_putmem() except instead of just copying the 285 * raw memory into the buffer it writes its ASCII representation of it 286 * in hex characters. 287 */ 288 void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, 289 unsigned int len) 290 { 291 unsigned int save_len = s->seq.len; 292 293 if (s->full) 294 return; 295 296 __trace_seq_init(s); 297 298 /* Each byte is represented by two chars */ 299 if (len * 2 > TRACE_SEQ_BUF_LEFT(s)) { 300 s->full = 1; 301 return; 302 } 303 304 /* The added spaces can still cause an overflow */ 305 seq_buf_putmem_hex(&s->seq, mem, len); 306 307 if (unlikely(seq_buf_has_overflowed(&s->seq))) { 308 s->seq.len = save_len; 309 s->full = 1; 310 return; 311 } 312 } 313 EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); 314 315 /** 316 * trace_seq_path - copy a path into the sequence buffer 317 * @s: trace sequence descriptor 318 * @path: path to write into the sequence buffer. 319 * 320 * Write a path name into the sequence buffer. 321 * 322 * Returns 1 if we successfully written all the contents to 323 * the buffer. 324 * Returns 0 if we the length to write is bigger than the 325 * reserved buffer space. In this case, nothing gets written. 326 */ 327 int trace_seq_path(struct trace_seq *s, const struct path *path) 328 { 329 unsigned int save_len = s->seq.len; 330 331 if (s->full) 332 return 0; 333 334 __trace_seq_init(s); 335 336 if (TRACE_SEQ_BUF_LEFT(s) < 1) { 337 s->full = 1; 338 return 0; 339 } 340 341 seq_buf_path(&s->seq, path, "\n"); 342 343 if (unlikely(seq_buf_has_overflowed(&s->seq))) { 344 s->seq.len = save_len; 345 s->full = 1; 346 return 0; 347 } 348 349 return 1; 350 } 351 EXPORT_SYMBOL_GPL(trace_seq_path); 352 353 /** 354 * trace_seq_to_user - copy the squence buffer to user space 355 * @s: trace sequence descriptor 356 * @ubuf: The userspace memory location to copy to 357 * @cnt: The amount to copy 358 * 359 * Copies the sequence buffer into the userspace memory pointed to 360 * by @ubuf. It starts from the last read position (@s->readpos) 361 * and writes up to @cnt characters or till it reaches the end of 362 * the content in the buffer (@s->len), which ever comes first. 363 * 364 * On success, it returns a positive number of the number of bytes 365 * it copied. 366 * 367 * On failure it returns -EBUSY if all of the content in the 368 * sequence has been already read, which includes nothing in the 369 * sequenc (@s->len == @s->readpos). 370 * 371 * Returns -EFAULT if the copy to userspace fails. 372 */ 373 int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt) 374 { 375 __trace_seq_init(s); 376 return seq_buf_to_user(&s->seq, ubuf, cnt); 377 } 378 EXPORT_SYMBOL_GPL(trace_seq_to_user); 379