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