Message ID | 20200914024452.19167-3-longman@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm/memcg: Miscellaneous cleanups and streamlining | expand |
On Sun 13-09-20 22:44:51, Waiman Long wrote: > The mem_cgroup_get_max() function used to get memory+swap max from > both the v1 memsw and v2 memory+swap page counters & return the maximum > of these 2 values. This is redundant and it is more efficient to just > get either the v1 or the v2 values depending on which one is currently > in use. > > Signed-off-by: Waiman Long <longman@redhat.com> > --- > mm/memcontrol.c | 20 +++++++++----------- > 1 file changed, 9 insertions(+), 11 deletions(-) > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > index 8c74f1200261..ca36bed588d1 100644 > --- a/mm/memcontrol.c > +++ b/mm/memcontrol.c > @@ -1633,17 +1633,15 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) > */ > unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) > { > - unsigned long max; > - > - max = READ_ONCE(memcg->memory.max); > - if (mem_cgroup_swappiness(memcg)) { > - unsigned long memsw_max; > - unsigned long swap_max; > - > - memsw_max = memcg->memsw.max; > - swap_max = READ_ONCE(memcg->swap.max); > - swap_max = min(swap_max, (unsigned long)total_swap_pages); > - max = min(max + swap_max, memsw_max); > + unsigned long max = READ_ONCE(memcg->memory.max); > + > + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) { > + if (mem_cgroup_swappiness(memcg)) > + max += min(READ_ONCE(memcg->swap.max), > + (unsigned long)total_swap_pages); > + } else { /* v1 */ > + if (mem_cgroup_swappiness(memcg)) > + max = memcg->memsw.max; I agree that making v1 vs. v2 distinction here makes the code more obvious. But I do not think your code is correct for v1. In a default state it would lead to max = PAGE_COUNTER_MAX which is not something we want, right? instead you want max += min(READ_ONCE(memcg->memsw.max), total_swap_pages); > } > return max; > } > -- > 2.18.1 >
On 9/14/20 7:48 AM, Michal Hocko wrote: > On Sun 13-09-20 22:44:51, Waiman Long wrote: >> The mem_cgroup_get_max() function used to get memory+swap max from >> both the v1 memsw and v2 memory+swap page counters & return the maximum >> of these 2 values. This is redundant and it is more efficient to just >> get either the v1 or the v2 values depending on which one is currently >> in use. >> >> Signed-off-by: Waiman Long <longman@redhat.com> >> --- >> mm/memcontrol.c | 20 +++++++++----------- >> 1 file changed, 9 insertions(+), 11 deletions(-) >> >> diff --git a/mm/memcontrol.c b/mm/memcontrol.c >> index 8c74f1200261..ca36bed588d1 100644 >> --- a/mm/memcontrol.c >> +++ b/mm/memcontrol.c >> @@ -1633,17 +1633,15 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) >> */ >> unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) >> { >> - unsigned long max; >> - >> - max = READ_ONCE(memcg->memory.max); >> - if (mem_cgroup_swappiness(memcg)) { >> - unsigned long memsw_max; >> - unsigned long swap_max; >> - >> - memsw_max = memcg->memsw.max; >> - swap_max = READ_ONCE(memcg->swap.max); >> - swap_max = min(swap_max, (unsigned long)total_swap_pages); >> - max = min(max + swap_max, memsw_max); >> + unsigned long max = READ_ONCE(memcg->memory.max); >> + >> + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) { >> + if (mem_cgroup_swappiness(memcg)) >> + max += min(READ_ONCE(memcg->swap.max), >> + (unsigned long)total_swap_pages); >> + } else { /* v1 */ >> + if (mem_cgroup_swappiness(memcg)) >> + max = memcg->memsw.max; > I agree that making v1 vs. v2 distinction here makes the code more > obvious. But I do not think your code is correct for v1. In a default > state it would lead to max = PAGE_COUNTER_MAX which is not something > we want, right? > > instead you want > max += min(READ_ONCE(memcg->memsw.max), total_swap_pages); > You are right, it is a bit tricky for v1. I will change it to max += min(READ_ONCE(memcg->memsw.max) - max, total_swap_pages): Thanks, Longman
On Mon, Sep 14, 2020 at 09:51:26AM -0400, Waiman Long wrote: > On 9/14/20 7:48 AM, Michal Hocko wrote: > > On Sun 13-09-20 22:44:51, Waiman Long wrote: > > > The mem_cgroup_get_max() function used to get memory+swap max from > > > both the v1 memsw and v2 memory+swap page counters & return the maximum > > > of these 2 values. This is redundant and it is more efficient to just > > > get either the v1 or the v2 values depending on which one is currently > > > in use. > > > > > > Signed-off-by: Waiman Long <longman@redhat.com> > > > --- > > > mm/memcontrol.c | 20 +++++++++----------- > > > 1 file changed, 9 insertions(+), 11 deletions(-) > > > > > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > > > index 8c74f1200261..ca36bed588d1 100644 > > > --- a/mm/memcontrol.c > > > +++ b/mm/memcontrol.c > > > @@ -1633,17 +1633,15 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) > > > */ > > > unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) > > > { > > > - unsigned long max; > > > - > > > - max = READ_ONCE(memcg->memory.max); > > > - if (mem_cgroup_swappiness(memcg)) { > > > - unsigned long memsw_max; > > > - unsigned long swap_max; > > > - > > > - memsw_max = memcg->memsw.max; > > > - swap_max = READ_ONCE(memcg->swap.max); > > > - swap_max = min(swap_max, (unsigned long)total_swap_pages); > > > - max = min(max + swap_max, memsw_max); > > > + unsigned long max = READ_ONCE(memcg->memory.max); > > > + > > > + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) { > > > + if (mem_cgroup_swappiness(memcg)) > > > + max += min(READ_ONCE(memcg->swap.max), > > > + (unsigned long)total_swap_pages); > > > + } else { /* v1 */ > > > + if (mem_cgroup_swappiness(memcg)) > > > + max = memcg->memsw.max; > > I agree that making v1 vs. v2 distinction here makes the code more > > obvious. But I do not think your code is correct for v1. In a default > > state it would lead to max = PAGE_COUNTER_MAX which is not something > > we want, right? > > > > instead you want > > max += min(READ_ONCE(memcg->memsw.max), total_swap_pages); > > > You are right, it is a bit tricky for v1. > > I will change it to > > max += min(READ_ONCE(memcg->memsw.max) - max, total_swap_pages): memsw.max can be smaller than max. max = min3(max, READ_ONCE(memcg->memsw.max), total_swap_pages)?
On Mon, Sep 14, 2020 at 05:29:06PM -0400, Johannes Weiner wrote: > On Mon, Sep 14, 2020 at 09:51:26AM -0400, Waiman Long wrote: > > On 9/14/20 7:48 AM, Michal Hocko wrote: > > > On Sun 13-09-20 22:44:51, Waiman Long wrote: > > > > The mem_cgroup_get_max() function used to get memory+swap max from > > > > both the v1 memsw and v2 memory+swap page counters & return the maximum > > > > of these 2 values. This is redundant and it is more efficient to just > > > > get either the v1 or the v2 values depending on which one is currently > > > > in use. > > > > > > > > Signed-off-by: Waiman Long <longman@redhat.com> > > > > --- > > > > mm/memcontrol.c | 20 +++++++++----------- > > > > 1 file changed, 9 insertions(+), 11 deletions(-) > > > > > > > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > > > > index 8c74f1200261..ca36bed588d1 100644 > > > > --- a/mm/memcontrol.c > > > > +++ b/mm/memcontrol.c > > > > @@ -1633,17 +1633,15 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) > > > > */ > > > > unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) > > > > { > > > > - unsigned long max; > > > > - > > > > - max = READ_ONCE(memcg->memory.max); > > > > - if (mem_cgroup_swappiness(memcg)) { > > > > - unsigned long memsw_max; > > > > - unsigned long swap_max; > > > > - > > > > - memsw_max = memcg->memsw.max; > > > > - swap_max = READ_ONCE(memcg->swap.max); > > > > - swap_max = min(swap_max, (unsigned long)total_swap_pages); > > > > - max = min(max + swap_max, memsw_max); > > > > + unsigned long max = READ_ONCE(memcg->memory.max); > > > > + > > > > + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) { > > > > + if (mem_cgroup_swappiness(memcg)) > > > > + max += min(READ_ONCE(memcg->swap.max), > > > > + (unsigned long)total_swap_pages); > > > > + } else { /* v1 */ > > > > + if (mem_cgroup_swappiness(memcg)) > > > > + max = memcg->memsw.max; > > > I agree that making v1 vs. v2 distinction here makes the code more > > > obvious. But I do not think your code is correct for v1. In a default > > > state it would lead to max = PAGE_COUNTER_MAX which is not something > > > we want, right? > > > > > > instead you want > > > max += min(READ_ONCE(memcg->memsw.max), total_swap_pages); > > > > > You are right, it is a bit tricky for v1. > > > > I will change it to > > > > max += min(READ_ONCE(memcg->memsw.max) - max, total_swap_pages): > > memsw.max can be smaller than max. > > max = min3(max, READ_ONCE(memcg->memsw.max), total_swap_pages)? Nevermind, I saw the follow-up below, and it's indeed not allowed to configure it like that.
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 8c74f1200261..ca36bed588d1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1633,17 +1633,15 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) */ unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) { - unsigned long max; - - max = READ_ONCE(memcg->memory.max); - if (mem_cgroup_swappiness(memcg)) { - unsigned long memsw_max; - unsigned long swap_max; - - memsw_max = memcg->memsw.max; - swap_max = READ_ONCE(memcg->swap.max); - swap_max = min(swap_max, (unsigned long)total_swap_pages); - max = min(max + swap_max, memsw_max); + unsigned long max = READ_ONCE(memcg->memory.max); + + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) { + if (mem_cgroup_swappiness(memcg)) + max += min(READ_ONCE(memcg->swap.max), + (unsigned long)total_swap_pages); + } else { /* v1 */ + if (mem_cgroup_swappiness(memcg)) + max = memcg->memsw.max; } return max; }
The mem_cgroup_get_max() function used to get memory+swap max from both the v1 memsw and v2 memory+swap page counters & return the maximum of these 2 values. This is redundant and it is more efficient to just get either the v1 or the v2 values depending on which one is currently in use. Signed-off-by: Waiman Long <longman@redhat.com> --- mm/memcontrol.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)