linux/kernel/trace/trace_seq.c
<<
>>
Prefs
   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 */
  39static 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 */
  54int 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 */
  84void 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}
 104EXPORT_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 */
 114void 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}
 131EXPORT_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 */
 144void 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}
 161EXPORT_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 */
 178void 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}
 196EXPORT_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 */
 208void 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}
 224EXPORT_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 */
 236void 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}
 250EXPORT_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 */
 262void 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}
 276EXPORT_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 */
 288void 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}
 313EXPORT_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 */
 327int 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}
 351EXPORT_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 */
 373int 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}
 378EXPORT_SYMBOL_GPL(trace_seq_to_user);
 379