Subject: Re: linux-next: build warnings after merge of the tip tree

From: Steven Rostedt <[email-masked]>
Date: Tue, 22 Mar 2022 09:12:42 -0400

On Tue, 22 Mar 2022 08:54:55 +0100
Peter Zijlstra <[email-masked]> wrote:

> On Mon, Mar 21, 2022 at 12:54:19PM -0400, Steven Rostedt wrote:
> > On Mon, 21 Mar 2022 17:50:50 +0100
> > Peter Zijlstra <[email-masked]> wrote:
> >   
> > > > This also assumes that we need to trace everything that is marked. I
> > > > mentioned in another email, what do we do if we only trace funcA?    
> > > 
> > > Like I said later on; if we inhibit tail-calls to notrace, this goes
> > > away.  
> > 
> > Please no. The number of "notrace" functions is increasing to the point
> > that it's starting to make function tracing useless in a lot of
> > circumstances. I've already lost my ability to see when user space goes
> > into the kernel (which I have to hack up custom coding to enable again).  
> 
> I really can't follow the argument there, nor on IRC.
> 
> Suppose:
> 
> notrace func_B()
> {
> 	...
> }
> 
> func_A()
> {
> 	...
> 	return func_B();
> }
> 
> then inhibiting tail calls would end up looking like:

If we inhibit tail calls, then we do not need to make func_B notrace.

> 
> func_A:
> 	call __fentry__
> 	...
> 	call func_B
> 	call __fexit__
> 	ret
> 
> Then A is fully traced, B is invisible, as per spec. What is the
> problem?

The above is fine, but then func_B is not a tail call and can also be
traced.

> 
> The problem you initially had, of doing a tail-call into a notrace, was
> that the __fexit__ call went missing, because notrace will obviously not
> have that. But that's avoided by inhibiting all tail-calls between
> notrace and !notrace functions (note that notrace must also not
> tail-call !notrace).

I'm confused by the above. Why can't a notrace tail call a !notrace?
If we tail call to a

func_B:
	call __fentry__
	...
	call __fexit__
	ret

then the fentry and fexit show a perfectly valid trace of func_B.

> 
> Your worry seems to stem about loosing visiblilty of !notrace functions,
> but AFAICT that doesn't happen.

My worry is:

func_A:
	call __fentry__
	...
	jmp func_B

Where do we do the call __fexit__ ?

That was the original concern, and I think the proposed solutions have
convoluted our thoughts about what we are trying to fix. So let's go back
to the beginning, and see how to deal with it.

That is, we have:

func_C:
	call __fenty__
	...
	call func_A:
	...
	call func_B:
	...
	call __fexit__
	ret

func_A:
	call __fentry__
	...
	jmp func_B

func_B:
	call __fentry__
	...
	call __fexit__
	ret

Where the above is C calling A and B as normal functions, A calling B as a
tail call and B just being a normal function called by both A and C (and
many other functions).

And note, I do not want to limit function tracing (which does not rely on
__fexit__) just because we can't figure out how to handle __fexit__.

-- Steve