Re: [PATCH] seq_file: Optimize seq_puts()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Le 04/01/2024 à 14:29, Christophe JAILLET a écrit :
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_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
    3391

Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx>

Hi,

any feed-back on this small optimisation of seq_puts()?

Most of its usage would be optimized and a strlen() would be saved in all the corresponding cases.


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

$ git grep seq_puts | wc -l
3644

CJ

---
Checked by comparing the output of a few .s files.
Here is one of these outputs:

$ diff -u drivers/clk/clk.s.old drivers/clk/clk.s | grep -C6 seq_w

  	call	clk_prepare_unlock	#
  # drivers/clk/clk.c:3320: 	seq_puts(s, "}\n");
  	movq	%r12, %rdi	# s,
+	movl	$2, %edx	#,
  	movq	$.LC66, %rsi	#,
-	call	seq_puts	#
+	call	seq_write	#
  	call	__tsan_func_exit	#
  # drivers/clk/clk.c:3322: }
  	xorl	%eax, %eax	#
@@ -34520,6 +34521,7 @@
  	popq	%rbp	#
  	popq	%r12	#
--
  # drivers/clk/clk.c:3205: 		seq_puts(s, "-----");
  	call	__sanitizer_cov_trace_pc	#
+	movl	$5, %edx	#,
  	movq	$.LC72, %rsi	#,
  	movq	%r13, %rdi	# s,
-	call	seq_puts	#
+	call	seq_write	#
  	jmp	.L2134	#
  .L2144:
  # drivers/clk/clk.c:1793: 	return clk_core_get_accuracy_no_lock(core);
@@ -35225,20 +35228,23 @@
  	leaq	240(%r12), %rdi	#, tmp95
  	call	__tsan_read8	#
--
  	movq	%r12, %rdi	# s,
+	movq	$.LC77, %rsi	#,
  # drivers/clk/clk.c:3244: 	struct hlist_head **lists = s->private;
  	movq	240(%r12), %rbp	# s_9(D)->private, lists
  # drivers/clk/clk.c:3246: 	seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
-	call	seq_puts	#
+	call	seq_write	#
  # drivers/clk/clk.c:3247: 	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
+	movl	$142, %edx	#,
  	movq	$.LC78, %rsi	#,
  	movq	%r12, %rdi	# s,
-	call	seq_puts	#
+	call	seq_write	#
  # drivers/clk/clk.c:3248: 	seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
+	movl	$142, %edx	#,
  	movq	$.LC79, %rsi	#,
  	movq	%r12, %rdi	# s,
-	call	seq_puts	#
+	call	seq_write	#
  # drivers/clk/clk.c:3251: 	clk_prepare_lock();
  	call	clk_prepare_lock	#
  .L2207:
@@ -37511,7 +37517,7 @@
  	subq	$16, %rsp	#,
  # drivers/clk/clk.c:3082: {
---
  fs/seq_file.c            |  4 ++--
  include/linux/seq_file.h | 10 +++++++++-
  2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index f5fdaf3b1572..8ef0a07033ca 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -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);
@@ -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
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 234bcdb1fba4..15abf45d62c5 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -118,7 +118,15 @@ 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);
+#define seq_puts(m, s)						\
+do {								\
+	if (__builtin_constant_p(s))				\
+		seq_write(m, s, __builtin_strlen(s));		\
+	else							\
+		__seq_puts(m, s);				\
+} while (0)
+
  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,





[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux