From: Waiman Long <longman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Sebastian Andrzej Siewior
<bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Cc: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>,
Michal Hocko <mhocko-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Vladimir Davydov
<vdavydov.dev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Andrew Morton
<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org,
Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Subject: Re: [PATCH-next v3] mm/memcg: Properly handle memcg_stock access for PREEMPT_RT
Date: Fri, 17 Dec 2021 13:46:53 -0500 [thread overview]
Message-ID: <b82efbad-1eb2-9441-ab0b-cbb3d2b5eac6@redhat.com> (raw)
In-Reply-To: <Ybx3ubNFfGpCqhn0-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
On 12/17/21 06:42, Sebastian Andrzej Siewior wrote:
> On 2021-12-14 09:44:12 [-0500], Waiman Long wrote:
>> --- a/mm/memcontrol.c
>> +++ b/mm/memcontrol.c
>> @@ -2096,7 +2096,12 @@ struct obj_stock {
>> #endif
>> };
>>
>> +/*
>> + * The local_lock protects the whole memcg_stock_pcp structure including
>> + * the embedded obj_stock structures.
>> + */
>> struct memcg_stock_pcp {
>> + local_lock_t lock;
>> struct mem_cgroup *cached; /* this never be root cgroup */
>> unsigned int nr_pages;
>> struct obj_stock task_obj;
>> @@ -2145,7 +2150,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
>> if (nr_pages > MEMCG_CHARGE_BATCH)
>> return ret;
>>
>> - local_irq_save(flags);
>> + local_lock_irqsave(&memcg_stock.lock, flags);
> This still does not explain why the lock is acquired here where it
> appears to be unrelated to memcg_stock.lock.
consume_stock() can be called in both task and irq context. irq context
may include softirq where interrupt may have been enabled and something
get interrupt again. The original code just do a local_irq_save()
without documenting why we are doing so. So I didn't see a need to add
comment about that.
>>
>> stock = this_cpu_ptr(&memcg_stock);
>> if (memcg == stock->cached && stock->nr_pages >= nr_pages) {
>> @@ -2779,29 +2784,34 @@ static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
>> * which is cheap in non-preempt kernel. The interrupt context object stock
>> * can only be accessed after disabling interrupt. User context code can
>> * access interrupt object stock, but not vice versa.
>> + *
>> + * This task and interrupt context optimization is disabled for PREEMPT_RT
>> + * as there is no performance gain in this case and changes will be made to
>> + * irq_obj only.
>> + *
>> + * For non-PREEMPT_RT, we are not replacing preempt_disable() by local_lock()
>> + * as nesting of task_obj and irq_obj are allowed which may cause lockdep
>> + * splat if local_lock() is used. Using separate local locks will complicate
>> + * the interaction between obj_stock and the broader memcg_stock object.
>> */
>> static inline struct obj_stock *get_obj_stock(unsigned long *pflags)
>> {
>> - struct memcg_stock_pcp *stock;
>> -
>> - if (likely(in_task())) {
>> + if (likely(in_task()) && !IS_ENABLED(CONFIG_PREEMPT_RT)) {
>> *pflags = 0UL;
>> preempt_disable();
>> - stock = this_cpu_ptr(&memcg_stock);
>> - return &stock->task_obj;
>> + return this_cpu_ptr(&memcg_stock.task_obj);
> Do we need to keep the memcg_stock.task_obj for !RT?
> I'm not really convinced that disabling either preemption or interrupts
> is so much better compared to actual locking locking with lockdep
> annotation. Looking at the history, I'm also impressed by that fact that
> disabling/ enabling interrupts is *so* expensive that all this is
> actually worth it.
For !RT with voluntary or no preemption, preempt_disable() is just a
compiler barrier. So it is definitely cheaper than disabling interrupt.
The performance benefit is less with preemptible but !RT kernel.
Microbenchmark testing shows a performance improvement of a few percents
depending on the exact benchmark.
Cheers,
Longman
WARNING: multiple messages have this Message-ID (diff)
From: Waiman Long <longman@redhat.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Johannes Weiner <hannes@cmpxchg.org>,
Michal Hocko <mhocko@kernel.org>,
Vladimir Davydov <vdavydov.dev@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
linux-kernel@vger.kernel.org, cgroups@vger.kernel.org,
linux-mm@kvack.org, Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH-next v3] mm/memcg: Properly handle memcg_stock access for PREEMPT_RT
Date: Fri, 17 Dec 2021 13:46:53 -0500 [thread overview]
Message-ID: <b82efbad-1eb2-9441-ab0b-cbb3d2b5eac6@redhat.com> (raw)
In-Reply-To: <Ybx3ubNFfGpCqhn0@linutronix.de>
On 12/17/21 06:42, Sebastian Andrzej Siewior wrote:
> On 2021-12-14 09:44:12 [-0500], Waiman Long wrote:
>> --- a/mm/memcontrol.c
>> +++ b/mm/memcontrol.c
>> @@ -2096,7 +2096,12 @@ struct obj_stock {
>> #endif
>> };
>>
>> +/*
>> + * The local_lock protects the whole memcg_stock_pcp structure including
>> + * the embedded obj_stock structures.
>> + */
>> struct memcg_stock_pcp {
>> + local_lock_t lock;
>> struct mem_cgroup *cached; /* this never be root cgroup */
>> unsigned int nr_pages;
>> struct obj_stock task_obj;
>> @@ -2145,7 +2150,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
>> if (nr_pages > MEMCG_CHARGE_BATCH)
>> return ret;
>>
>> - local_irq_save(flags);
>> + local_lock_irqsave(&memcg_stock.lock, flags);
> This still does not explain why the lock is acquired here where it
> appears to be unrelated to memcg_stock.lock.
consume_stock() can be called in both task and irq context. irq context
may include softirq where interrupt may have been enabled and something
get interrupt again. The original code just do a local_irq_save()
without documenting why we are doing so. So I didn't see a need to add
comment about that.
>>
>> stock = this_cpu_ptr(&memcg_stock);
>> if (memcg == stock->cached && stock->nr_pages >= nr_pages) {
>> @@ -2779,29 +2784,34 @@ static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
>> * which is cheap in non-preempt kernel. The interrupt context object stock
>> * can only be accessed after disabling interrupt. User context code can
>> * access interrupt object stock, but not vice versa.
>> + *
>> + * This task and interrupt context optimization is disabled for PREEMPT_RT
>> + * as there is no performance gain in this case and changes will be made to
>> + * irq_obj only.
>> + *
>> + * For non-PREEMPT_RT, we are not replacing preempt_disable() by local_lock()
>> + * as nesting of task_obj and irq_obj are allowed which may cause lockdep
>> + * splat if local_lock() is used. Using separate local locks will complicate
>> + * the interaction between obj_stock and the broader memcg_stock object.
>> */
>> static inline struct obj_stock *get_obj_stock(unsigned long *pflags)
>> {
>> - struct memcg_stock_pcp *stock;
>> -
>> - if (likely(in_task())) {
>> + if (likely(in_task()) && !IS_ENABLED(CONFIG_PREEMPT_RT)) {
>> *pflags = 0UL;
>> preempt_disable();
>> - stock = this_cpu_ptr(&memcg_stock);
>> - return &stock->task_obj;
>> + return this_cpu_ptr(&memcg_stock.task_obj);
> Do we need to keep the memcg_stock.task_obj for !RT?
> I'm not really convinced that disabling either preemption or interrupts
> is so much better compared to actual locking locking with lockdep
> annotation. Looking at the history, I'm also impressed by that fact that
> disabling/ enabling interrupts is *so* expensive that all this is
> actually worth it.
For !RT with voluntary or no preemption, preempt_disable() is just a
compiler barrier. So it is definitely cheaper than disabling interrupt.
The performance benefit is less with preemptible but !RT kernel.
Microbenchmark testing shows a performance improvement of a few percents
depending on the exact benchmark.
Cheers,
Longman
next prev parent reply other threads:[~2021-12-17 18:46 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-14 14:44 [PATCH-next v3] mm/memcg: Properly handle memcg_stock access for PREEMPT_RT Waiman Long
[not found] ` <20211214144412.447035-1-longman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2021-12-15 4:36 ` Davidlohr Bueso
2021-12-15 4:36 ` Davidlohr Bueso
2021-12-15 16:58 ` Waiman Long
2021-12-15 16:58 ` Waiman Long
2021-12-17 11:42 ` Sebastian Andrzej Siewior
2021-12-17 11:42 ` Sebastian Andrzej Siewior
[not found] ` <Ybx3ubNFfGpCqhn0-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2021-12-17 18:21 ` Sebastian Andrzej Siewior
2021-12-17 18:21 ` Sebastian Andrzej Siewior
2021-12-17 18:46 ` Waiman Long [this message]
2021-12-17 18:46 ` Waiman Long
[not found] ` <b82efbad-1eb2-9441-ab0b-cbb3d2b5eac6-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2021-12-17 19:48 ` Sebastian Andrzej Siewior
2021-12-17 19:48 ` Sebastian Andrzej Siewior
2021-12-19 13:20 ` [mm/memcg] 3928ba024a: WARNING:possible_recursive_locking_detected kernel test robot
2021-12-19 13:20 ` kernel test robot
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=b82efbad-1eb2-9441-ab0b-cbb3d2b5eac6@redhat.com \
--to=longman-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
--cc=bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
--cc=cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org \
--cc=mhocko-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
--cc=vdavydov.dev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.