Re: [PATCH 3/3] x86/ftrace: Use text_poke()

From: Peter Zijlstra
Date: Fri Oct 11 2019 - 06:57:57 EST


On Fri, Oct 11, 2019 at 09:37:10AM +0200, Daniel Bristot de Oliveira wrote:
> On 11/10/2019 09:01, Peter Zijlstra wrote:
> > On Fri, Oct 04, 2019 at 10:10:47AM +0200, Daniel Bristot de Oliveira wrote:
> >> Currently, ftrace_rec entries are ordered inside the group of functions, but
> >> "groups of function" are not ordered. So, the current int3 handler does a (*):
> > We can insert a sort() of the vector right before doing
> > text_poke_bp_batch() of course...
>
> I agree!
>
> What I tried to do earlier this week was to order the ftrace_pages in the
> insertion [1], and so, while sequentially reading the pages with
> do_for_each_ftrace_rec() we would already see the "ip"s in order.
>
> As ftrace_pages are inserted only at boot and during a load of a module, this
> would push the ordering for a very very slow path.
>
> It works! But under the assumption that the address of functions in a module
> does not intersect with the address of other modules/kernel, e.g.:
>
> kernel: module A: module B:
> [ 1, 2, 3, 4 ] [ 7, 8, 9 ] [ 15, 16, 19 ]
>
> But this does not happen in practice, as I saw things like:
>
> kernel: module A: module B:
> [ 1, 2, 3, 4 ] [ 7, 8, 18 ] [ 15, 16, 19 ]
> ^^ <--- greater than the first of the next
>
> Is this expected?

Expected is I think a big word. That is, I would certainly not expect
that, but I think I can see how it can happen.

Suppose that init sections are placed at the end (didn't verify, but
makes sense), then suppose that A's 18 is in an init section, which gets
freed once the module load is completed. We then proceed to load B,
which then overlaps with what used to be A's init.

If this were the case, then while we could retain the pach location for
A's 18, we would never actually modify it, because it's gotten marked
freed or something (that's how jump_labels work, I didn't check what
ftrace actually does here).

So while the above contains some assumptions, it is a semi plausable
explanation for what you've described.