linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Willy Tarreau <w@1wt.eu>
To: Douglas Gilbert <dgilbert@interlog.com>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: Re: how many memset(,0,) calls in kernel ?
Date: Sun, 12 Sep 2021 06:56:09 +0200	[thread overview]
Message-ID: <20210912045608.GB16216@1wt.eu> (raw)
In-Reply-To: <1c4a94df-fc2f-1bb2-8bce-2d71f9f1f5df@interlog.com>

On Sat, Sep 11, 2021 at 11:36:07PM -0400, Douglas Gilbert wrote:
> Here is a pretty rough estimate:
> $ find . -name '*.c' -exec fgrep "memset(" {} \; > memset_in_kern.txt
> 
> $ cat memset_in_kern.txt | wc -l
>     20159
> 
> Some of those are in comments, EXPORTs, etc, but the vast majority are
> in code. Plus there will be memset()s in header files not counted by
> that find. Checking in that output file I see:
> 
> $ grep ", 0," memset_in_kern.txt | wc -l
>     18107
> $ grep ", 0" memset_in_kern.txt | wc -l
>     19349
> $ grep ", 0x" memset_in_kern.txt | wc -l
>     1210
> $ grep ", 0x01" memset_in_kern.txt | wc -l
>     3
> $ grep ", 0x0," memset_in_kern.txt | wc -l
>     199
> $ grep ",0," memset_in_kern.txt | wc -l
>     72

Note that in order to get something faster and slightly more accurate,
you can use 'git grep':

   $ git grep 'memset([^,]*,\s*0\(\|x0*\),' |wc -l
   18822

> If the BSD flavours of Unix had not given us:
>    void bzero(void *s, size_t n);
> would the Linux kernel have something similar in common usage (e.g.
> memzero() or mem0() ), that was less wasteful than the standard:
>    void *memset(void *s, int c, size_t n);
> in the extremely common case where c=0 and the return value is
> not used?

What do you mean by "wasteful" here ? What are you trying to preserve,
caracters in the source code maybe ? Because the output code is already
adapted to the context thanks to memset() being builtin. Let's take one
of the first instances I found that's easy to match against asm code:

net/core/dev.c:

  int __init netdev_boot_setup(char *str)
  {
        int ints[5];
        struct ifmap map;

        str = get_options(str, ARRAY_SIZE(ints), ints);
        if (!str || !*str)
                return 0;

        /* Save settings */
        memset(&map, 0, sizeof(map));
        ...
  }

It gives this:

  16:   e8 00 00 00 00          callq  1b <netdev_boot_setup+0x1b>
                        17: R_X86_64_PC32       get_options-0x4
  1b:   48 89 c6                mov    %rax,%rsi

note that we're zeroing %eax below in preparation for the "return 0"
statement:

  1e:   31 c0                   xor    %eax,%eax

This is the "if (!str || !*str)" :

  20:   48 85 f6                test   %rsi,%rsi
  23:   0f 84 98 00 00 00       je     c1 <netdev_boot_setup+0xc1>
  29:   80 3e 00                cmpb   $0x0,(%rsi)
  2c:   0f 84 8f 00 00 00       je     c1 <netdev_boot_setup+0xc1>

%r12 is set to &map:

  32:   4c 8d 65 d0             lea    -0x30(%rbp),%r12

And this is the memset "call" itself, which reuses the zero from
the %eax register:

  36:   b9 06 00 00 00          mov    $0x6,%ecx
  3b:   4c 89 e7                mov    %r12,%rdi
  3e:   f3 ab                   rep stos %eax,%es:(%rdi)

The last line does exactly "memset(%rdi, %eax, %ecx)". Just two bytes
for some code that modern processors are even able to optimize.

As you can see there's not much waste here in the output code, and
in fact using any dedicated function would be larger and likely
slower.

Hoping this helps,
Willy

  reply	other threads:[~2021-09-12  5:02 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-12  3:36 how many memset(,0,) calls in kernel ? Douglas Gilbert
2021-09-12  4:56 ` Willy Tarreau [this message]
2021-09-13 16:03   ` David Laight
2021-09-13 16:09     ` Willy Tarreau
2021-09-14  8:23       ` David Laight
2021-09-14 16:46         ` Willy Tarreau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210912045608.GB16216@1wt.eu \
    --to=w@1wt.eu \
    --cc=dgilbert@interlog.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).