linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Roman Gushchin <roman.gushchin@linux.dev>
To: Alexander Fedorov <halcien@gmail.com>
Cc: Michal Hocko <mhocko@suse.com>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Shakeel Butt <shakeelb@google.com>,
	Vladimir Davydov <vdavydov.dev@gmail.com>,
	Muchun Song <songmuchun@bytedance.com>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	cgroups@vger.kernel.org, linux-mm@kvack.org
Subject: Re: Possible race in obj_stock_flush_required() vs drain_obj_stock()
Date: Tue, 4 Oct 2022 09:18:26 -0700	[thread overview]
Message-ID: <Yzxc0jzOnAu667F8@P9FQF9L96D.lan> (raw)
In-Reply-To: <2f9bdffd-062e-a364-90c4-da7f09c95619@gmail.com>

On Mon, Oct 03, 2022 at 06:01:35PM +0300, Alexander Fedorov wrote:
> On 03.10.2022 17:27, Michal Hocko wrote:
> > On Mon 03-10-22 17:09:15, Alexander Fedorov wrote:
> >> On 03.10.2022 16:32, Michal Hocko wrote:
> >>> On Mon 03-10-22 15:47:10, Alexander Fedorov wrote:
> >>>> @@ -3197,17 +3197,30 @@ static void drain_obj_stock(struct memcg_stock_pcp *stock)
> >>>>  		stock->nr_bytes = 0;
> >>>>  	}
> >>>>  
> >>>> -	obj_cgroup_put(old);
> >>>> +	/*
> >>>> +	 * Clear pointer before freeing memory so that
> >>>> +	 * drain_all_stock() -> obj_stock_flush_required()
> >>>> +	 * does not see a freed pointer.
> >>>> +	 */
> >>>>  	stock->cached_objcg = NULL;
> >>>> +	obj_cgroup_put(old);
> >>>
> >>> Do we need barrier() or something else to ensure there is no reordering?
> >>> I am not reallyu sure what kind of barriers are implied by the pcp ref
> >>> counting.
> >>
> >> obj_cgroup_put() -> kfree_rcu() -> synchronize_rcu() should take care
> >> of this:
> > 
> > This is a very subtle guarantee. Also it would only apply if this is the
> > last reference, right?
> 
> Hmm, yes, for the last reference only, also not sure about pcp ref
> counter ordering rules for previous references.
> 
> > Is there any reason to not use
> > 	WRITE_ONCE(stock->cached_objcg, NULL);
> > 	obj_cgroup_put(old);
> > 
> > IIRC this should prevent any reordering. 
> 
> Now that I think about it we actually must use WRITE_ONCE everywhere
> when writing cached_objcg because otherwise compiler might split the
> pointer-sized store into several smaller-sized ones (store tearing),
> and obj_stock_flush_required() would read garbage instead of pointer.
>
> And thinking about memory barriers, maybe we need them too alongside
> WRITE_ONCE when setting pointer to non-null value?  Otherwise
> drain_all_stock() -> obj_stock_flush_required() might read old data.
> Since that's exactly what rcu_assign_pointer() does, it seems
> that we are going back to using rcu_*() primitives everywhere?

Hm, Idk, I'm still somewhat resistant to the idea of putting rcu primitives,
but maybe it's the right thing. Maybe instead we should always schedule draining
on all cpus instead and perform a cpu-local check and bail out if a flush is not
required? Michal, Johannes, what do you think?

Btw the same approach is used for the memcg part (stock->cached),
so if we're going to change anything, we need to change it too.

Thanks!


  reply	other threads:[~2022-10-04 16:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-30 14:06 Alexander Fedorov
2022-09-30 18:26 ` Roman Gushchin
2022-10-01 12:38   ` Alexander Fedorov
2022-10-02 16:16     ` Roman Gushchin
2022-10-03 12:47       ` Alexander Fedorov
2022-10-03 13:32         ` Michal Hocko
2022-10-03 14:09           ` Alexander Fedorov
2022-10-03 14:27             ` Michal Hocko
2022-10-03 15:01               ` Alexander Fedorov
2022-10-04 16:18                 ` Roman Gushchin [this message]
2022-10-12 17:23                   ` Johannes Weiner
2022-10-12 18:49                     ` Roman Gushchin
2022-10-12 19:18                       ` Johannes Weiner

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=Yzxc0jzOnAu667F8@P9FQF9L96D.lan \
    --to=roman.gushchin@linux.dev \
    --cc=bigeasy@linutronix.de \
    --cc=cgroups@vger.kernel.org \
    --cc=halcien@gmail.com \
    --cc=hannes@cmpxchg.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@suse.com \
    --cc=shakeelb@google.com \
    --cc=songmuchun@bytedance.com \
    --cc=vdavydov.dev@gmail.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