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