mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nadav Amit <namit@vmware.com>
To: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Edward Cree <ecree@solarflare.com>,
	LKML <linux-kernel@vger.kernel.org>,
	"x86@kernel.org" <x86@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>
Subject: Re: [PATCH v2 0/4] Static calls
Date: Wed, 12 Dec 2018 05:59:55 +0000	[thread overview]
Message-ID: <86D72260-838C-4CE0-ACE3-BE92A3E9CFD8@vmware.com> (raw)
In-Reply-To: <20181211180521.ljdvnnztjnvoijge@treble>

> On Dec 11, 2018, at 10:05 AM, Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> 
> On Fri, Dec 07, 2018 at 04:06:32PM +0000, Edward Cree wrote:
>> Sorry if this has been pointed out before (it's a very long thread), but
>> in the out-of-line implementation, it appears that static_call_update()
>> never alters key->func.  Am I right in thinking that this should be
>> fixed by adding 'WRITE_ONCE(key->func, func);' just after the call to
>> arch_static_call_transform() on line 159 of include/linux/static_call.h?
> 
> Yes, you're right about both bugs in the out-of-line case: key->func
> needs to be written, and __static_call_update() needs to be called by
> static_call_update.  I was so focused on getting the inline case working
> that I overlooked those.
> 
>> Some background (why does key->func matter for the
>> CONFIG_HAVE_STATIC_CALL_OUTLINE case?): I am experimenting with
>> combining these static calls with the 'indirect call wrappers' notion
>> that Paolo Abeni has been working on [1], using runtime instrumentation
>> to determine a list of potential callees.  (This allows us to cope with
>> cases where the callees are in modules, or where different workloads may
>> use different sets of callees for a given call site, neither of which is
>> handled by Paolo's approach).
>> The core of my design looks something like:
>> 
>> static int dynamic_call_xyz(int (*func)(some_args), some_args)
>> {
>> 	if (func == dynamic_call_xyz_1.func)
>> 		return static_call(dynamic_call_xyz_1, some_args);
>> 	if (func == dynamic_call_xyz_2.func)
>> 		return static_call(dynamic_call_xyz_2, some_args);
>> 	return (*func)(some_args);
>> }
>> 
>> albeit with a bunch of extra (and currently rather ugly) stuff to collect
>> the statistics needed to decide what to put in the static call keys, and
>> mechanisms (RCU in my current case) to ensure that the static call isn't
>> changed between checking its .func and actually calling it.
>> 
>> -Ed
>> 
>> PS: not on list, please keep me in CC.
>> 
>> [1] https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flwn.net%2FArticles%2F773985%2F&amp;data=02%7C01%7Cnamit%40vmware.com%7C147894d6c56d4ce6c1fc08d65f933adf%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636801483286688490&amp;sdata=QOZcfWXjvPqoR0oujtf1QTQLenv%2BiEu6jUA5fiav6Mo%3D&amp;reserved=0
> 
> Thanks, this sounds very interesting.  Adding Nadav to CC, as he has
> been looking at a different approach to solving the same problem:
> 
>  https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml.kernel.org%2Fr%2F20181018005420.82993-1-namit%40vmware.com&amp;data=02%7C01%7Cnamit%40vmware.com%7C147894d6c56d4ce6c1fc08d65f933adf%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636801483286688490&amp;sdata=bCI2N2xKUVyyyPAnWDH3mC3DsSk%2Bzy5nmI0DV%2F%2FaYYw%3D&amp;reserved=0

Thanks for cc’ing me. (I didn’t know about the other patch-sets.)

Allow me to share my experience, because I was studying this issue for some
time and have implemented more than I shared, since the code need more
cleanup. Some of the proposed approaches are things we either considered or
actually implemented (and later dropped). Eventually, our design was guided
by performance profiling and a grain of “what’s academic” consideration.

I think that eventually you would want to go with one central mechanism for
the various situations:

1. Registered targets (static) and automatically learnt targets (dynamic).
Registration does not work in some cases (e.g., file-system function
pointers, there are too many of those). On the other hand, if you know your
target it is obviously simpler/better.

2. With/without retpoline fallback. We’ve have always had the retpoline as
fallback, but if you use a registration mechanism, it’s not necessary.

3. Single and multiple targets. For multiple targets we decided to use
outline block in order not to inflate the code for no reason. There were
over 10000 indirect branches in our kernel build, but in our workloads only
~500 were actually run.

If you got with the approach that Edward mentioned, you may want to
associate each “function" with identifier (think about file_operations
having an additional field that holds a unique ID, or using the struct
address). This would allow you to use a “binary search” to find the right
target, which would be slightly more efficient. We actually used a
binary-search for a different reason - learning the most frequent syscalls
per process and calling them in this manner (we actually had an indirection
table to choose the right one).

3. Call-chains which are mostly fixed (next). You want to unroll those.

4. Per-process calls. The case that bothered us the most is seccomp. On our
setup, systemd installed 17(!) BPF seccomp programs on Redis server, causing
every syscall to go through 17 indirect branches to invoke them. But
similarly you have mmu-notifiers and others. We used a per-process
trampoline page for this matter.

Now there is of course the question of whether to go through automatic
inference of the indirect call sites (using asm macros/GCC plugin) or
manually marking them (using C macros). Initially we used C macros, which we
created using semi-automatically generated Coccinelle scripts. As I
remembered how I was crucified in the past over “uglification” of the code,
I thought a transparent modification of the code would be better, so we went
with asm macros for our prototype.

Finally, I should mention that the impact of most of these mechanisms should
not be significant (or even positive) if retpolines were not used. Having
said that, the automatically-learnt indirect branch promotion (with a single
target) showed up to roughly 2% performance improvement.

Please let me know how you want to proceed. I didn’t know about your
patch-set, but I think that having two similar (yet different) separate
mechanisms is not great. If you want, I’ll finish addressing the issues
you’ve raised and send another RFC.

Regards,
Nadav

  reply	other threads:[~2018-12-12  6:00 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-26 13:54 Josh Poimboeuf
2018-11-26 13:54 ` [PATCH v2 1/4] compiler.h: Make __ADDRESSABLE() symbol truly unique Josh Poimboeuf
2018-11-27  8:49   ` Ard Biesheuvel
2018-11-26 13:54 ` [PATCH v2 2/4] static_call: Add static call infrastructure Josh Poimboeuf
2018-11-26 13:54 ` [PATCH v2 3/4] x86/static_call: Add out-of-line static call implementation Josh Poimboeuf
2018-11-26 15:43   ` Peter Zijlstra
2018-11-26 16:19     ` Steven Rostedt
2018-11-26 13:55 ` [PATCH v2 4/4] x86/static_call: Add inline static call implementation for x86-64 Josh Poimboeuf
2018-11-26 16:02   ` Peter Zijlstra
2018-11-26 17:10     ` Josh Poimboeuf
2018-11-26 17:56       ` Josh Poimboeuf
2018-11-26 20:00         ` Peter Zijlstra
2018-11-26 20:08         ` Peter Zijlstra
2018-11-26 21:26           ` Josh Poimboeuf
2018-11-27  8:43             ` Peter Zijlstra
2018-11-27  8:50               ` Peter Zijlstra
2018-11-29  6:05               ` Andy Lutomirski
2018-11-29  9:42                 ` Peter Zijlstra
2018-11-29 13:11                   ` Josh Poimboeuf
2018-11-29 13:37                   ` Andy Lutomirski
2018-11-29 14:38                     ` Peter Zijlstra
2018-11-29 14:42                       ` Jiri Kosina
2018-11-29 16:33                       ` Josh Poimboeuf
2018-11-29 16:49                         ` Peter Zijlstra
2018-11-29 16:59                           ` Andy Lutomirski
2018-11-29 17:10                             ` Josh Poimboeuf
2018-11-29 22:01                               ` Peter Zijlstra
2018-11-29 22:14                                 ` Josh Poimboeuf
2018-11-29 22:22                                   ` Peter Zijlstra
2018-11-29 22:25                                     ` Andy Lutomirski
2018-11-29 22:30                                       ` Josh Poimboeuf
2018-11-29 17:15                             ` Peter Zijlstra
2018-11-29 17:20                               ` Steven Rostedt
2018-11-29 17:21                                 ` Steven Rostedt
2018-11-29 17:41                                   ` Andy Lutomirski
2018-11-29 17:45                                     ` Josh Poimboeuf
2018-11-29 17:52                                       ` Andy Lutomirski
2018-11-29 17:49                                     ` Steven Rostedt
2018-11-29 18:37                               ` Josh Poimboeuf
2018-11-29 16:50                         ` Linus Torvalds
2018-11-29 16:55                           ` Steven Rostedt
2018-11-29 17:02                           ` Andy Lutomirski
2018-11-29 17:07                             ` Peter Zijlstra
2018-11-29 17:31                               ` Andy Lutomirski
2018-11-29 17:35                                 ` Jiri Kosina
2018-11-29 17:13                             ` Steven Rostedt
2018-11-29 17:35                               ` Linus Torvalds
2018-11-29 17:44                                 ` Steven Rostedt
2018-11-29 17:50                                   ` Linus Torvalds
2018-11-29 17:54                                     ` Linus Torvalds
2018-11-29 17:58                                     ` Steven Rostedt
2018-11-29 18:23                                       ` Linus Torvalds
2018-11-29 18:47                                         ` Steven Rostedt
2018-11-29 18:58                                           ` Linus Torvalds
2018-11-29 19:08                                             ` Linus Torvalds
2018-11-29 19:11                                               ` Linus Torvalds
2018-12-10 23:58                                                 ` Pavel Machek
2018-12-11  1:43                                                   ` Linus Torvalds
2018-11-29 19:12                                               ` Steven Rostedt
2018-11-29 19:27                                               ` Andy Lutomirski
2018-11-29 20:24                                                 ` Josh Poimboeuf
2018-11-29 22:17                                                   ` Josh Poimboeuf
2018-11-29 23:04                                                   ` Linus Torvalds
2018-11-30 16:27                                                     ` Josh Poimboeuf
2018-12-11  9:41                                                       ` David Laight
2018-12-11 17:19                                                         ` Josh Poimboeuf
2018-12-12 18:29                                                     ` Josh Poimboeuf
2018-11-30 16:42                                                   ` Andy Lutomirski
2018-11-30 18:39                                                     ` Josh Poimboeuf
2018-11-30 19:45                                                       ` Linus Torvalds
2018-11-30 20:18                                                         ` Andy Lutomirski
2018-11-30 20:28                                                           ` Steven Rostedt
2018-11-30 20:59                                                             ` Andy Lutomirski
2018-11-30 21:01                                                               ` Steven Rostedt
2018-11-30 21:13                                                               ` Jiri Kosina
2018-11-30 21:10                                                           ` Josh Poimboeuf
2018-11-29 19:16                                             ` Steven Rostedt
2018-11-29 19:22                                               ` Josh Poimboeuf
2018-11-29 19:27                                                 ` Steven Rostedt
2018-11-30 22:16                                                 ` Rasmus Villemoes
2018-11-30 22:24                                                   ` Josh Poimboeuf
2018-11-29 19:24                                               ` Linus Torvalds
2018-11-29 19:28                                                 ` Andy Lutomirski
2018-11-29 19:31                                                 ` Steven Rostedt
2018-11-29 20:12                                             ` Josh Poimboeuf
2018-11-29 18:00                                     ` Andy Lutomirski
2018-11-29 18:42                                       ` Linus Torvalds
2018-11-29 18:55                                       ` Steven Rostedt
2018-11-29 17:29                             ` Linus Torvalds
2018-11-29 17:35                               ` Andy Lutomirski
2018-11-26 18:28       ` Andy Lutomirski
2018-11-26 20:14         ` Josh Poimboeuf
2018-11-27  8:46           ` Peter Zijlstra
2018-11-26 16:08   ` Peter Zijlstra
2018-11-26 16:11     ` Ard Biesheuvel
2018-11-26 16:33       ` Andy Lutomirski
2018-11-26 16:39       ` Peter Zijlstra
2018-11-26 16:44         ` Josh Poimboeuf
2018-11-26 14:01 ` [PATCH v2 0/4] Static calls Josh Poimboeuf
2018-11-26 20:54 ` Steven Rostedt
2018-11-26 22:24   ` Josh Poimboeuf
2018-11-26 22:53     ` Steven Rostedt
2018-12-04 23:08 ` Steven Rostedt
2018-12-04 23:41   ` Andy Lutomirski
2018-12-05 15:04     ` Josh Poimboeuf
2018-12-05 23:36       ` Andy Lutomirski
2018-12-07 16:06 ` Edward Cree
2018-12-07 16:49   ` Edward Cree
2018-12-11 18:05   ` Josh Poimboeuf
2018-12-12  5:59     ` Nadav Amit [this message]
2018-12-12 17:11       ` Edward Cree
2018-12-12 17:47         ` [RFC/WIP PATCH 0/2] dynamic calls Edward Cree
2018-12-12 17:50           ` [RFC PATCH 1/2] static_call: fix out-of-line static call implementation Edward Cree
2018-12-12 17:52           ` [RFC PATCH 2/2] net: core: rather hacky PoC implementation of dynamic calls Edward Cree
2018-12-12 18:14         ` [PATCH v2 0/4] Static calls Nadav Amit
2018-12-12 18:33           ` Edward Cree
2018-12-12 21:15             ` Nadav Amit
2018-12-12 21:36               ` Edward Cree
2018-12-12 21:45                 ` Nadav Amit
2018-12-10 23:57 ` Pavel Machek

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=86D72260-838C-4CE0-ACE3-BE92A3E9CFD8@vmware.com \
    --to=namit@vmware.com \
    --cc=ecree@solarflare.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=x86@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

all inboxes | Powered by JetHome®