root/kernel/trace/trace_seq.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __trace_seq_init
  2. trace_print_seq
  3. trace_seq_printf
  4. trace_seq_bitmask
  5. trace_seq_vprintf
  6. trace_seq_bprintf
  7. trace_seq_puts
  8. trace_seq_putc
  9. trace_seq_putmem
  10. trace_seq_putmem_hex
  11. trace_seq_path
  12. trace_seq_to_user

   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);

/* [<][>][^][v][top][bottom][index][help] */