netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
	Ingo Molnar <mingo@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Ingo Molnar <mingo@redhat.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Dmitry Vyukov <dvyukov@google.com>,
	Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
	Yonghong Song <yhs@fb.com>, Andrii Nakryiko <andriin@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@chromium.org>, netdev <netdev@vger.kernel.org>,
	bpf <bpf@vger.kernel.org>, Kees Cook <keescook@chromium.org>,
	Florian Weimer <fw@deneb.enyo.de>,
	syzbot+83aa762ef23b6f0d1991@syzkaller.appspotmail.com,
	syzbot+d29e58bb557324e55e5e@syzkaller.appspotmail.com,
	Matt Mullins <mmullins@mmlx.us>
Subject: Re: [for-next][PATCH 14/15] tracepoint: Do not fail unregistering a probe due to memory failure
Date: Thu, 4 Feb 2021 11:50:29 -0500	[thread overview]
Message-ID: <20210204115029.3b707236@gandalf.local.home> (raw)
In-Reply-To: <1836191179.6214.1612375044968.JavaMail.zimbra@efficios.com>

On Wed, 3 Feb 2021 12:57:24 -0500 (EST)
Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote:

> > @@ -147,14 +154,34 @@ func_add(struct tracepoint_func **funcs, struct
> > tracepoint_func *tp_func,
> > 			if (old[nr_probes].func == tp_func->func &&
> > 			    old[nr_probes].data == tp_func->data)
> > 				return ERR_PTR(-EEXIST);
> > +			if (old[nr_probes].func == tp_stub_func)
> > +				stub_funcs++;
> > 		}
> > 	}
> > -	/* + 2 : one for new probe, one for NULL func */
> > -	new = allocate_probes(nr_probes + 2);
> > +	/* + 2 : one for new probe, one for NULL func - stub functions */
> > +	new = allocate_probes(nr_probes + 2 - stub_funcs);
> > 	if (new == NULL)
> > 		return ERR_PTR(-ENOMEM);
> > 	if (old) {
> > -		if (pos < 0) {
> > +		if (stub_funcs) {  
> 
> Considering that we end up implementing a case where we carefully copy over
> each item, I recommend we replace the two "memcpy" branches by a single item-wise
> implementation. It's a slow-path anyway, and reducing the overall complexity
> is a benefit for slow paths. Fewer bugs, less code to review, and it's easier to
> reach a decent testing state-space coverage.

Sure.

> 
> > +			/* Need to copy one at a time to remove stubs */
> > +			int probes = 0;
> > +
> > +			pos = -1;
> > +			for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
> > +				if (old[nr_probes].func == tp_stub_func)
> > +					continue;
> > +				if (pos < 0 && old[nr_probes].prio < prio)
> > +					pos = probes++;
> > +				new[probes++] = old[nr_probes];
> > +			}
> > +			nr_probes = probes;  
> 
> Repurposing "nr_probes" from accounting for the number of items in the old
> array to counting the number of items in the new array in the middle of the
> function is confusing.
> 
> > +			if (pos < 0)
> > +				pos = probes;
> > +			else
> > +				nr_probes--; /* Account for insertion */  
> 
> This is probably why you need to play tricks with nr_probes here.
> 
> > +		} else if (pos < 0) {
> > 			pos = nr_probes;
> > 			memcpy(new, old, nr_probes * sizeof(struct tracepoint_func));
> > 		} else {
> > @@ -188,8 +215,9 @@ static void *func_remove(struct tracepoint_func **funcs,
> > 	/* (N -> M), (N > 1, M >= 0) probes */
> > 	if (tp_func->func) {
> > 		for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
> > -			if (old[nr_probes].func == tp_func->func &&
> > -			     old[nr_probes].data == tp_func->data)
> > +			if ((old[nr_probes].func == tp_func->func &&
> > +			     old[nr_probes].data == tp_func->data) ||
> > +			    old[nr_probes].func == tp_stub_func)
> > 				nr_del++;
> > 		}
> > 	}
> > @@ -208,14 +236,32 @@ static void *func_remove(struct tracepoint_func **funcs,
> > 		/* N -> M, (N > 1, M > 0) */
> > 		/* + 1 for NULL */
> > 		new = allocate_probes(nr_probes - nr_del + 1);
> > -		if (new == NULL)
> > -			return ERR_PTR(-ENOMEM);
> > -		for (i = 0; old[i].func; i++)
> > -			if (old[i].func != tp_func->func
> > -					|| old[i].data != tp_func->data)
> > -				new[j++] = old[i];
> > -		new[nr_probes - nr_del].func = NULL;
> > -		*funcs = new;
> > +		if (new) {
> > +			for (i = 0; old[i].func; i++)
> > +				if ((old[i].func != tp_func->func
> > +				     || old[i].data != tp_func->data)
> > +				    && old[i].func != tp_stub_func)
> > +					new[j++] = old[i];
> > +			new[nr_probes - nr_del].func = NULL;
> > +			*funcs = new;
> > +		} else {
> > +			/*
> > +			 * Failed to allocate, replace the old function
> > +			 * with calls to tp_stub_func.
> > +			 */
> > +			for (i = 0; old[i].func; i++)
> > +				if (old[i].func == tp_func->func &&
> > +				    old[i].data == tp_func->data) {
> > +					old[i].func = tp_stub_func;  
> 
> This updates "func" while readers are loading it concurrently. I would recommend
> using WRITE_ONCE here paired with READ_ONCE within __traceiter_##_name.

I'm fine with this change, but it shouldn't make a difference. As we don't
change the data, it doesn't matter which function the compiler calls.
Unless you are worried about the compiler tearing the read. It shouldn't,
but I'm fine with doing things for paranoid sake (especially if it doesn't
affect the performance).

> 
> > +					/* Set the prio to the next event. */  
> 
> I don't get why the priority needs to be changed here. Could it simply stay
> at its original value ? It's already in the correct priority order anyway.

I think it was left over from one of the various changes. As I went to v5,
and then back to v3, I missed revisiting the code, as I was under the
assumption that I had cleaned it up :-/

> 
> > +					if (old[i + 1].func)
> > +						old[i].prio =
> > +							old[i + 1].prio;
> > +					else
> > +						old[i].prio = -1;
> > +				}
> > +			*funcs = old;  
> 
> I'm not sure what setting *funcs to old achieves ? Isn't it already pointing
> to old ?

Again, I think one iteration may have changed it. And I kinda remember
keeping it just to be consistent (*funcs gets updated in the other paths,
and figured it was good to be "safe" and updated it again, even though the
logic has it already set).

> 
> I'll send a patch which applies on top of yours implementing my recommendations.
> It shrinks the code complexity nicely:

Looking at it now.

Thanks,

-- Steve

      reply	other threads:[~2021-02-04 16:53 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20210203160517.982448432@goodmis.org>
2021-02-03 16:05 ` [for-next][PATCH 14/15] tracepoint: Do not fail unregistering a probe due to memory failure Steven Rostedt
2021-02-03 17:05   ` Peter Zijlstra
2021-02-03 17:09   ` Peter Zijlstra
2021-02-03 17:23     ` Steven Rostedt
2021-02-03 17:57   ` Mathieu Desnoyers
2021-02-04 16:50     ` Steven Rostedt [this message]

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=20210204115029.3b707236@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=andriin@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dvyukov@google.com \
    --cc=fw@deneb.enyo.de \
    --cc=john.fastabend@gmail.com \
    --cc=jpoimboe@redhat.com \
    --cc=kafai@fb.com \
    --cc=keescook@chromium.org \
    --cc=kpsingh@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=mmullins@mmlx.us \
    --cc=netdev@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=songliubraving@fb.com \
    --cc=syzbot+83aa762ef23b6f0d1991@syzkaller.appspotmail.com \
    --cc=syzbot+d29e58bb557324e55e5e@syzkaller.appspotmail.com \
    --cc=yhs@fb.com \
    /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).