Skip to content

Commit d0ed46b

Browse files
Matthew Wilcox (Oracle)rostedt
authored andcommitted
tracing: Move readpos from seq_buf to trace_seq
To make seq_buf more lightweight as a string buf, move the readpos member from seq_buf to its container, trace_seq. That puts the responsibility of maintaining the readpos entirely in the tracing code. If some future users want to package up the readpos with a seq_buf, we can define a new struct then. Link: https://lore.kernel.org/linux-trace-kernel/20231020033545.2587554-2-willy@infradead.org Cc: Kees Cook <keescook@chromium.org> Cc: Justin Stitt <justinstitt@google.com> Cc: Kent Overstreet <kent.overstreet@linux.dev> Cc: Petr Mladek <pmladek@suse.com> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: Sergey Senozhatsky <senozhatsky@chromium.org> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 64bf2f6 commit d0ed46b

5 files changed

Lines changed: 23 additions & 22 deletions

File tree

include/linux/seq_buf.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,16 @@
1414
* @buffer: pointer to the buffer
1515
* @size: size of the buffer
1616
* @len: the amount of data inside the buffer
17-
* @readpos: The next position to read in the buffer.
1817
*/
1918
struct seq_buf {
2019
char *buffer;
2120
size_t size;
2221
size_t len;
23-
loff_t readpos;
2422
};
2523

2624
static inline void seq_buf_clear(struct seq_buf *s)
2725
{
2826
s->len = 0;
29-
s->readpos = 0;
3027
}
3128

3229
static inline void
@@ -143,7 +140,7 @@ extern __printf(2, 0)
143140
int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
144141
extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s);
145142
extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf,
146-
int cnt);
143+
size_t start, int cnt);
147144
extern int seq_buf_puts(struct seq_buf *s, const char *str);
148145
extern int seq_buf_putc(struct seq_buf *s, unsigned char c);
149146
extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len);

include/linux/trace_seq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
struct trace_seq {
1515
char buffer[PAGE_SIZE];
1616
struct seq_buf seq;
17+
size_t readpos;
1718
int full;
1819
};
1920

@@ -22,6 +23,7 @@ trace_seq_init(struct trace_seq *s)
2223
{
2324
seq_buf_init(&s->seq, s->buffer, PAGE_SIZE);
2425
s->full = 0;
26+
s->readpos = 0;
2527
}
2628

2729
/**

kernel/trace/trace.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,15 +1731,15 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
17311731
{
17321732
int len;
17331733

1734-
if (trace_seq_used(s) <= s->seq.readpos)
1734+
if (trace_seq_used(s) <= s->readpos)
17351735
return -EBUSY;
17361736

1737-
len = trace_seq_used(s) - s->seq.readpos;
1737+
len = trace_seq_used(s) - s->readpos;
17381738
if (cnt > len)
17391739
cnt = len;
1740-
memcpy(buf, s->buffer + s->seq.readpos, cnt);
1740+
memcpy(buf, s->buffer + s->readpos, cnt);
17411741

1742-
s->seq.readpos += cnt;
1742+
s->readpos += cnt;
17431743
return cnt;
17441744
}
17451745

@@ -7008,7 +7008,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
70087008

70097009
/* Now copy what we have to the user */
70107010
sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
7011-
if (iter->seq.seq.readpos >= trace_seq_used(&iter->seq))
7011+
if (iter->seq.readpos >= trace_seq_used(&iter->seq))
70127012
trace_seq_init(&iter->seq);
70137013

70147014
/*

kernel/trace/trace_seq.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,12 @@ EXPORT_SYMBOL_GPL(trace_seq_path);
370370
*/
371371
int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt)
372372
{
373+
int ret;
373374
__trace_seq_init(s);
374-
return seq_buf_to_user(&s->seq, ubuf, cnt);
375+
ret = seq_buf_to_user(&s->seq, ubuf, s->readpos, cnt);
376+
if (ret > 0)
377+
s->readpos += ret;
378+
return ret;
375379
}
376380
EXPORT_SYMBOL_GPL(trace_seq_to_user);
377381

lib/seq_buf.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,23 +324,24 @@ int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc)
324324
* seq_buf_to_user - copy the sequence buffer to user space
325325
* @s: seq_buf descriptor
326326
* @ubuf: The userspace memory location to copy to
327+
* @start: The first byte in the buffer to copy
327328
* @cnt: The amount to copy
328329
*
329330
* Copies the sequence buffer into the userspace memory pointed to
330-
* by @ubuf. It starts from the last read position (@s->readpos)
331-
* and writes up to @cnt characters or till it reaches the end of
332-
* the content in the buffer (@s->len), which ever comes first.
331+
* by @ubuf. It starts from @start and writes up to @cnt characters
332+
* or until it reaches the end of the content in the buffer (@s->len),
333+
* whichever comes first.
333334
*
334335
* On success, it returns a positive number of the number of bytes
335336
* it copied.
336337
*
337338
* On failure it returns -EBUSY if all of the content in the
338339
* sequence has been already read, which includes nothing in the
339-
* sequence (@s->len == @s->readpos).
340+
* sequence (@s->len == @start).
340341
*
341342
* Returns -EFAULT if the copy to userspace fails.
342343
*/
343-
int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt)
344+
int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, size_t start, int cnt)
344345
{
345346
int len;
346347
int ret;
@@ -350,20 +351,17 @@ int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt)
350351

351352
len = seq_buf_used(s);
352353

353-
if (len <= s->readpos)
354+
if (len <= start)
354355
return -EBUSY;
355356

356-
len -= s->readpos;
357+
len -= start;
357358
if (cnt > len)
358359
cnt = len;
359-
ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
360+
ret = copy_to_user(ubuf, s->buffer + start, cnt);
360361
if (ret == cnt)
361362
return -EFAULT;
362363

363-
cnt -= ret;
364-
365-
s->readpos += cnt;
366-
return cnt;
364+
return cnt - ret;
367365
}
368366

369367
/**

0 commit comments

Comments
 (0)