public inbox for linux-mm@kvack.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] fix unexpected type conversions and potential overflows
@ 2026-03-27 10:16 Qi Zheng
  2026-03-27 10:16 ` [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long Qi Zheng
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Qi Zheng @ 2026-03-27 10:16 UTC (permalink / raw)
  To: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, ziy, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642
  Cc: linux-mm, linux-kernel, Qi Zheng

From: Qi Zheng <zhengqi.arch@bytedance.com>

Changes in v3:
 - squash [PATCH v2 4/4] into [PATCH v2 2/4] (suggested-by Lorenzo Stoakes)
 - split complex calculation into multiple steps (suggested-by Lorenzo Stoakes)
 - collect Reviewed-bys
 - rebase onto the next-20260326

Changes in v2:
 - modified all commit messages. (suggested-by Lorenzo Stoakes)
 - added a fix patch to resolve the unexpected massive positive number
   (pointed-by Harry Yoo and sashiko)
 - fix the print type mismatch in [PATCH 3/3]
 - collect Reviewed-by

Hi all,

As Harry Yoo pointed out [1], in scenarios where massive state updates occur
(e.g., during the reparenting of LRU folios), the values passed to memcg stat
update functions can accumulate and exceed the upper limit of a 32-bit integer.

If the parameter types are not large enough (like 'int') or are handled
incorrectly, it can lead to severe truncation, potential overflow issues,
and unexpected type conversion bugs.

This series aims to address these issues by correcting the parameter types
in the relevant functions, and fixing an implicit conversion bug in
memcg_state_val_in_pages().

This series is based on the next-20260326.

Comments and suggestions are welcome!

Thanks,
Qi

[1]. https://lore.kernel.org/all/acDxaEgnqPI-Z4be@hyeyoo/

Qi Zheng (3):
  mm: memcontrol: correct the type of stats_updates to unsigned long
  mm: memcontrol: change val type to long in
    __mod_memcg_{lruvec_}state()
  mm: memcontrol: correct the nr_pages parameter type of
    mem_cgroup_update_lru_size()

 include/linux/memcontrol.h   |  2 +-
 include/trace/events/memcg.h | 10 ++++-----
 mm/memcontrol.c              | 40 +++++++++++++++++++++---------------
 3 files changed, 29 insertions(+), 23 deletions(-)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long
  2026-03-27 10:16 [PATCH v3 0/3] fix unexpected type conversions and potential overflows Qi Zheng
@ 2026-03-27 10:16 ` Qi Zheng
  2026-03-27 15:45   ` Zi Yan
  2026-03-27 10:16 ` [PATCH v3 2/3] mm: memcontrol: change val type to long in __mod_memcg_{lruvec_}state() Qi Zheng
  2026-03-27 10:16 ` [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size() Qi Zheng
  2 siblings, 1 reply; 8+ messages in thread
From: Qi Zheng @ 2026-03-27 10:16 UTC (permalink / raw)
  To: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, ziy, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642
  Cc: linux-mm, linux-kernel, Qi Zheng

From: Qi Zheng <zhengqi.arch@bytedance.com>

The memcg_rstat_updated() tracks updates for vmstats_percpu->state
and lruvec_stats_percpu->state. Since these state values are of type long,
change the val parameter passed to memcg_rstat_updated() to long as well.

Correspondingly, change the type of stats_updates in struct
memcg_vmstats_percpu and struct memcg_vmstats from unsigned int and
atomic_t to unsigned long and atomic_long_t respectively to prevent
potential overflow when handling large state updates during the
reparenting of LRU folios.

Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
---
 mm/memcontrol.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index ac7b46c4d67e4..3daab9b46429a 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -608,7 +608,7 @@ static inline int memcg_events_index(enum vm_event_item idx)
 
 struct memcg_vmstats_percpu {
 	/* Stats updates since the last flush */
-	unsigned int			stats_updates;
+	unsigned long			stats_updates;
 
 	/* Cached pointers for fast iteration in memcg_rstat_updated() */
 	struct memcg_vmstats_percpu __percpu	*parent_pcpu;
@@ -639,7 +639,7 @@ struct memcg_vmstats {
 	unsigned long		events_pending[NR_MEMCG_EVENTS];
 
 	/* Stats updates since the last flush */
-	atomic_t		stats_updates;
+	atomic_long_t		stats_updates;
 };
 
 /*
@@ -665,16 +665,16 @@ static u64 flush_last_time;
 
 static bool memcg_vmstats_needs_flush(struct memcg_vmstats *vmstats)
 {
-	return atomic_read(&vmstats->stats_updates) >
+	return atomic_long_read(&vmstats->stats_updates) >
 		MEMCG_CHARGE_BATCH * num_online_cpus();
 }
 
-static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val,
+static inline void memcg_rstat_updated(struct mem_cgroup *memcg, long val,
 				       int cpu)
 {
 	struct memcg_vmstats_percpu __percpu *statc_pcpu;
 	struct memcg_vmstats_percpu *statc;
-	unsigned int stats_updates;
+	unsigned long stats_updates;
 
 	if (!val)
 		return;
@@ -697,7 +697,7 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val,
 			continue;
 
 		stats_updates = this_cpu_xchg(statc_pcpu->stats_updates, 0);
-		atomic_add(stats_updates, &statc->vmstats->stats_updates);
+		atomic_long_add(stats_updates, &statc->vmstats->stats_updates);
 	}
 }
 
@@ -705,7 +705,7 @@ static void __mem_cgroup_flush_stats(struct mem_cgroup *memcg, bool force)
 {
 	bool needs_flush = memcg_vmstats_needs_flush(memcg->vmstats);
 
-	trace_memcg_flush_stats(memcg, atomic_read(&memcg->vmstats->stats_updates),
+	trace_memcg_flush_stats(memcg, atomic_long_read(&memcg->vmstats->stats_updates),
 		force, needs_flush);
 
 	if (!force && !needs_flush)
@@ -4446,8 +4446,8 @@ static void mem_cgroup_css_rstat_flush(struct cgroup_subsys_state *css, int cpu)
 	}
 	WRITE_ONCE(statc->stats_updates, 0);
 	/* We are in a per-cpu loop here, only do the atomic write once */
-	if (atomic_read(&memcg->vmstats->stats_updates))
-		atomic_set(&memcg->vmstats->stats_updates, 0);
+	if (atomic_long_read(&memcg->vmstats->stats_updates))
+		atomic_long_set(&memcg->vmstats->stats_updates, 0);
 }
 
 static void mem_cgroup_fork(struct task_struct *task)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/3] mm: memcontrol: change val type to long in __mod_memcg_{lruvec_}state()
  2026-03-27 10:16 [PATCH v3 0/3] fix unexpected type conversions and potential overflows Qi Zheng
  2026-03-27 10:16 ` [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long Qi Zheng
@ 2026-03-27 10:16 ` Qi Zheng
  2026-03-27 15:48   ` Zi Yan
  2026-03-27 10:16 ` [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size() Qi Zheng
  2 siblings, 1 reply; 8+ messages in thread
From: Qi Zheng @ 2026-03-27 10:16 UTC (permalink / raw)
  To: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, ziy, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642
  Cc: linux-mm, linux-kernel, Qi Zheng, Harry Yoo (Oracle)

From: Qi Zheng <zhengqi.arch@bytedance.com>

The __mod_memcg_state() and __mod_memcg_lruvec_state() functions are also
used to reparent non-hierarchical stats. In this scenario, the values
passed to them are accumulated statistics that might be extremely large
and exceed the upper limit of a 32-bit integer.

Change the val parameter type from int to long in these functions and
their corresponding tracepoints (memcg_rstat_stats) to prevent potential
overflow issues.

After that, in memcg_state_val_in_pages(), if the passed val is negative,
the expression val * unit / PAGE_SIZE could be implicitly converted to a
massive positive number when compared with 1UL in the max() macro.
This leads to returning an incorrect massive positive value.

Fix this by using abs(val) to calculate the magnitude first, and then
restoring the sign of the value before returning the result. Additionally,
use mult_frac() to prevent potential overflow during the multiplication of
val and unit.

Reported-by: Harry Yoo (Oracle) <harry@kernel.org>
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
---
 include/trace/events/memcg.h | 10 +++++-----
 mm/memcontrol.c              | 18 ++++++++++++------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/include/trace/events/memcg.h b/include/trace/events/memcg.h
index dfe2f51019b4c..51b62c5931fc2 100644
--- a/include/trace/events/memcg.h
+++ b/include/trace/events/memcg.h
@@ -11,14 +11,14 @@
 
 DECLARE_EVENT_CLASS(memcg_rstat_stats,
 
-	TP_PROTO(struct mem_cgroup *memcg, int item, int val),
+	TP_PROTO(struct mem_cgroup *memcg, int item, long val),
 
 	TP_ARGS(memcg, item, val),
 
 	TP_STRUCT__entry(
 		__field(u64, id)
 		__field(int, item)
-		__field(int, val)
+		__field(long, val)
 	),
 
 	TP_fast_assign(
@@ -27,20 +27,20 @@ DECLARE_EVENT_CLASS(memcg_rstat_stats,
 		__entry->val = val;
 	),
 
-	TP_printk("memcg_id=%llu item=%d val=%d",
+	TP_printk("memcg_id=%llu item=%d val=%ld",
 		  __entry->id, __entry->item, __entry->val)
 );
 
 DEFINE_EVENT(memcg_rstat_stats, mod_memcg_state,
 
-	TP_PROTO(struct mem_cgroup *memcg, int item, int val),
+	TP_PROTO(struct mem_cgroup *memcg, int item, long val),
 
 	TP_ARGS(memcg, item, val)
 );
 
 DEFINE_EVENT(memcg_rstat_stats, mod_memcg_lruvec_state,
 
-	TP_PROTO(struct mem_cgroup *memcg, int item, int val),
+	TP_PROTO(struct mem_cgroup *memcg, int item, long val),
 
 	TP_ARGS(memcg, item, val)
 );
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3daab9b46429a..51d72ddf08119 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -527,7 +527,7 @@ unsigned long lruvec_page_state_local(struct lruvec *lruvec,
 
 #ifdef CONFIG_MEMCG_V1
 static void __mod_memcg_lruvec_state(struct mem_cgroup_per_node *pn,
-				     enum node_stat_item idx, int val);
+				     enum node_stat_item idx, long val);
 
 void reparent_memcg_lruvec_state_local(struct mem_cgroup *memcg,
 				       struct mem_cgroup *parent, int idx)
@@ -784,14 +784,20 @@ static int memcg_page_state_unit(int item);
  * Normalize the value passed into memcg_rstat_updated() to be in pages. Round
  * up non-zero sub-page updates to 1 page as zero page updates are ignored.
  */
-static int memcg_state_val_in_pages(int idx, int val)
+static long memcg_state_val_in_pages(int idx, long val)
 {
 	int unit = memcg_page_state_unit(idx);
+	long res;
 
 	if (!val || unit == PAGE_SIZE)
 		return val;
-	else
-		return max(val * unit / PAGE_SIZE, 1UL);
+
+	/* Get the absolute value of (val * unit / PAGE_SIZE). */
+	res = mult_frac(abs(val), unit, PAGE_SIZE);
+	/* Round up zero values. */
+	res = res ? : 1;
+
+	return val < 0 ? -res : res;
 }
 
 #ifdef CONFIG_MEMCG_V1
@@ -831,7 +837,7 @@ static inline void get_non_dying_memcg_end(void)
 #endif
 
 static void __mod_memcg_state(struct mem_cgroup *memcg,
-			      enum memcg_stat_item idx, int val)
+			      enum memcg_stat_item idx, long val)
 {
 	int i = memcg_stats_index(idx);
 	int cpu;
@@ -896,7 +902,7 @@ void reparent_memcg_state_local(struct mem_cgroup *memcg,
 #endif
 
 static void __mod_memcg_lruvec_state(struct mem_cgroup_per_node *pn,
-				     enum node_stat_item idx, int val)
+				     enum node_stat_item idx, long val)
 {
 	struct mem_cgroup *memcg = pn->memcg;
 	int i = memcg_stats_index(idx);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size()
  2026-03-27 10:16 [PATCH v3 0/3] fix unexpected type conversions and potential overflows Qi Zheng
  2026-03-27 10:16 ` [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long Qi Zheng
  2026-03-27 10:16 ` [PATCH v3 2/3] mm: memcontrol: change val type to long in __mod_memcg_{lruvec_}state() Qi Zheng
@ 2026-03-27 10:16 ` Qi Zheng
  2026-03-27 10:22   ` Lorenzo Stoakes (Oracle)
  2026-03-27 15:49   ` Zi Yan
  2 siblings, 2 replies; 8+ messages in thread
From: Qi Zheng @ 2026-03-27 10:16 UTC (permalink / raw)
  To: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, ziy, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642
  Cc: linux-mm, linux-kernel, Qi Zheng

From: Qi Zheng <zhengqi.arch@bytedance.com>

The nr_pages parameter of mem_cgroup_update_lru_size() represents a page
count. During the reparenting of LRU folios, the value passed to it can
potentially exceed the maximum value of a 32-bit integer. It should be
declared as long instead of int to match the types used in lruvec size
accounting and to prevent possible overflow.

Update the parameter type to long to ensure correctness.

Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
---
 include/linux/memcontrol.h | 2 +-
 mm/memcontrol.c            | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 0782c72a1997b..4a7d8c4f55b48 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -874,7 +874,7 @@ static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
 }
 
 void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
-		int zid, int nr_pages);
+		int zid, long nr_pages);
 
 static inline
 unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec,
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 51d72ddf08119..bf74167d77c5b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1472,7 +1472,7 @@ struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio,
  * to or just after a page is removed from an lru list.
  */
 void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
-				int zid, int nr_pages)
+				int zid, long nr_pages)
 {
 	struct mem_cgroup_per_node *mz;
 	unsigned long *lru_size;
@@ -1489,7 +1489,7 @@ void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
 
 	size = *lru_size;
 	if (WARN_ONCE(size < 0,
-		"%s(%p, %d, %d): lru_size %ld\n",
+		"%s(%p, %d, %ld): lru_size %ld\n",
 		__func__, lruvec, lru, nr_pages, size)) {
 		VM_BUG_ON(1);
 		*lru_size = 0;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size()
  2026-03-27 10:16 ` [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size() Qi Zheng
@ 2026-03-27 10:22   ` Lorenzo Stoakes (Oracle)
  2026-03-27 15:49   ` Zi Yan
  1 sibling, 0 replies; 8+ messages in thread
From: Lorenzo Stoakes (Oracle) @ 2026-03-27 10:22 UTC (permalink / raw)
  To: Qi Zheng
  Cc: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ziy, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642,
	linux-mm, linux-kernel, Qi Zheng

On Fri, Mar 27, 2026 at 06:16:30PM +0800, Qi Zheng wrote:
> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> The nr_pages parameter of mem_cgroup_update_lru_size() represents a page
> count. During the reparenting of LRU folios, the value passed to it can
> potentially exceed the maximum value of a 32-bit integer. It should be
> declared as long instead of int to match the types used in lruvec size
> accounting and to prevent possible overflow.
>
> Update the parameter type to long to ensure correctness.
>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>

LGTM so:

Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>

> ---
>  include/linux/memcontrol.h | 2 +-
>  mm/memcontrol.c            | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 0782c72a1997b..4a7d8c4f55b48 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -874,7 +874,7 @@ static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
>  }
>
>  void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
> -		int zid, int nr_pages);
> +		int zid, long nr_pages);
>
>  static inline
>  unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec,
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 51d72ddf08119..bf74167d77c5b 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -1472,7 +1472,7 @@ struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio,
>   * to or just after a page is removed from an lru list.
>   */
>  void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
> -				int zid, int nr_pages)
> +				int zid, long nr_pages)
>  {
>  	struct mem_cgroup_per_node *mz;
>  	unsigned long *lru_size;
> @@ -1489,7 +1489,7 @@ void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
>
>  	size = *lru_size;
>  	if (WARN_ONCE(size < 0,
> -		"%s(%p, %d, %d): lru_size %ld\n",
> +		"%s(%p, %d, %ld): lru_size %ld\n",
>  		__func__, lruvec, lru, nr_pages, size)) {
>  		VM_BUG_ON(1);
>  		*lru_size = 0;
> --
> 2.20.1
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long
  2026-03-27 10:16 ` [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long Qi Zheng
@ 2026-03-27 15:45   ` Zi Yan
  0 siblings, 0 replies; 8+ messages in thread
From: Zi Yan @ 2026-03-27 15:45 UTC (permalink / raw)
  To: Qi Zheng
  Cc: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642,
	linux-mm, linux-kernel, Qi Zheng

On 27 Mar 2026, at 6:16, Qi Zheng wrote:

> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> The memcg_rstat_updated() tracks updates for vmstats_percpu->state
> and lruvec_stats_percpu->state. Since these state values are of type long,
> change the val parameter passed to memcg_rstat_updated() to long as well.
>
> Correspondingly, change the type of stats_updates in struct
> memcg_vmstats_percpu and struct memcg_vmstats from unsigned int and
> atomic_t to unsigned long and atomic_long_t respectively to prevent
> potential overflow when handling large state updates during the
> reparenting of LRU folios.
>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
>  mm/memcontrol.c | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
>

Acked-by: Zi Yan <ziy@nvidia.com>

Best Regards,
Yan, Zi


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/3] mm: memcontrol: change val type to long in __mod_memcg_{lruvec_}state()
  2026-03-27 10:16 ` [PATCH v3 2/3] mm: memcontrol: change val type to long in __mod_memcg_{lruvec_}state() Qi Zheng
@ 2026-03-27 15:48   ` Zi Yan
  0 siblings, 0 replies; 8+ messages in thread
From: Zi Yan @ 2026-03-27 15:48 UTC (permalink / raw)
  To: Qi Zheng
  Cc: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642,
	linux-mm, linux-kernel, Qi Zheng, Harry Yoo (Oracle)

On 27 Mar 2026, at 6:16, Qi Zheng wrote:

> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> The __mod_memcg_state() and __mod_memcg_lruvec_state() functions are also
> used to reparent non-hierarchical stats. In this scenario, the values
> passed to them are accumulated statistics that might be extremely large
> and exceed the upper limit of a 32-bit integer.
>
> Change the val parameter type from int to long in these functions and
> their corresponding tracepoints (memcg_rstat_stats) to prevent potential
> overflow issues.
>
> After that, in memcg_state_val_in_pages(), if the passed val is negative,
> the expression val * unit / PAGE_SIZE could be implicitly converted to a
> massive positive number when compared with 1UL in the max() macro.
> This leads to returning an incorrect massive positive value.
>
> Fix this by using abs(val) to calculate the magnitude first, and then
> restoring the sign of the value before returning the result. Additionally,
> use mult_frac() to prevent potential overflow during the multiplication of
> val and unit.
>
> Reported-by: Harry Yoo (Oracle) <harry@kernel.org>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
>  include/trace/events/memcg.h | 10 +++++-----
>  mm/memcontrol.c              | 18 ++++++++++++------
>  2 files changed, 17 insertions(+), 11 deletions(-)
>
Acked-by: Zi Yan <ziy@nvidia.com>

Best Regards,
Yan, Zi


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size()
  2026-03-27 10:16 ` [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size() Qi Zheng
  2026-03-27 10:22   ` Lorenzo Stoakes (Oracle)
@ 2026-03-27 15:49   ` Zi Yan
  1 sibling, 0 replies; 8+ messages in thread
From: Zi Yan @ 2026-03-27 15:49 UTC (permalink / raw)
  To: Qi Zheng
  Cc: hannes, hughd, mhocko, roman.gushchin, shakeel.butt, muchun.song,
	david, ljs, harry.yoo, yosry.ahmed, imran.f.khan,
	kamalesh.babulal, axelrasmussen, yuanchu, weixugc, chenridong,
	mkoutny, akpm, hamzamahfooz, apais, lance.yang, bhe, usamaarif642,
	linux-mm, linux-kernel, Qi Zheng

On 27 Mar 2026, at 6:16, Qi Zheng wrote:

> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> The nr_pages parameter of mem_cgroup_update_lru_size() represents a page
> count. During the reparenting of LRU folios, the value passed to it can
> potentially exceed the maximum value of a 32-bit integer. It should be
> declared as long instead of int to match the types used in lruvec size
> accounting and to prevent possible overflow.
>
> Update the parameter type to long to ensure correctness.
>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> ---
>  include/linux/memcontrol.h | 2 +-
>  mm/memcontrol.c            | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
Acked-by: Zi Yan <ziy@nvidia.com>

Best Regards,
Yan, Zi


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-03-27 15:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-27 10:16 [PATCH v3 0/3] fix unexpected type conversions and potential overflows Qi Zheng
2026-03-27 10:16 ` [PATCH v3 1/3] mm: memcontrol: correct the type of stats_updates to unsigned long Qi Zheng
2026-03-27 15:45   ` Zi Yan
2026-03-27 10:16 ` [PATCH v3 2/3] mm: memcontrol: change val type to long in __mod_memcg_{lruvec_}state() Qi Zheng
2026-03-27 15:48   ` Zi Yan
2026-03-27 10:16 ` [PATCH v3 3/3] mm: memcontrol: correct the nr_pages parameter type of mem_cgroup_update_lru_size() Qi Zheng
2026-03-27 10:22   ` Lorenzo Stoakes (Oracle)
2026-03-27 15:49   ` Zi Yan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox