Skip to content

Commit

Permalink
seq_file: Optimize seq_puts()
Browse files Browse the repository at this point in the history
Most of seq_puts() usages are done with a string literal. In such cases,
the length of the string car be computed at compile time in order to save
a strlen() call at run-time. seq_putc() or seq_write() can then be used
instead.

This saves a few cycles.

To have an estimation of how often this optimization triggers:
   $ git grep seq_puts.*\" | wc -l
   3436

   $ git grep seq_puts.*\".\" | wc -l
   84

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/a8589bffe4830dafcb9111e22acf06603fea7132.1713781332.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Christian Brauner <brauner@kernel.org>
The output for seq_putc() generation has also be checked and works.
  • Loading branch information
Christophe JAILLET authored and Christian Brauner committed May 2, 2024
1 parent 0a960ba commit 4575109
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
4 changes: 2 additions & 2 deletions fs/seq_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ void seq_putc(struct seq_file *m, char c)
}
EXPORT_SYMBOL(seq_putc);

void seq_puts(struct seq_file *m, const char *s)
void __seq_puts(struct seq_file *m, const char *s)
{
int len = strlen(s);

Expand All @@ -680,7 +680,7 @@ void seq_puts(struct seq_file *m, const char *s)
memcpy(m->buf + m->count, s, len);
m->count += len;
}
EXPORT_SYMBOL(seq_puts);
EXPORT_SYMBOL(__seq_puts);

/**
* seq_put_decimal_ull_width - A helper routine for putting decimal numbers
Expand Down
13 changes: 12 additions & 1 deletion include/linux/seq_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,18 @@ void seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
__printf(2, 3)
void seq_printf(struct seq_file *m, const char *fmt, ...);
void seq_putc(struct seq_file *m, char c);
void seq_puts(struct seq_file *m, const char *s);
void __seq_puts(struct seq_file *m, const char *s);

static __always_inline void seq_puts(struct seq_file *m, const char *s)
{
if (!__builtin_constant_p(*s))
__seq_puts(m, s);
else if (s[0] && !s[1])
seq_putc(m, s[0]);
else
seq_write(m, s, __builtin_strlen(s));
}

void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter,
unsigned long long num, unsigned int width);
void seq_put_decimal_ull(struct seq_file *m, const char *delimiter,
Expand Down

0 comments on commit 4575109

Please sign in to comment.