]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/damon/core: use mult_frac()
authorSeongJae Park <sj@kernel.org>
Sat, 7 Mar 2026 19:53:49 +0000 (11:53 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Sun, 5 Apr 2026 20:53:22 +0000 (13:53 -0700)
Patch series "mm/damon: improve/fixup/update ratio calculation, test and
documentation".

Yet another batch of misc/minor improvements and fixups.  Use mult_frac()
instead of the worse open-coding for rate calculations (patch 1).  Add a
test for a previously found and fixed bug (patch 2).  Improve and update
comments and documentations for easier code review and up-to-date
information (patches 3-6).  Finally, fix an obvious typo (patch 7).

This patch (of 7):

There are multiple places in core code that do open-code rate
calculations.  Use mult_frac(), which is developed for doing that in a way
more safe from overflow and precision loss.

Link: https://lkml.kernel.org/r/20260307195356.203753-1-sj@kernel.org
Link: https://lkml.kernel.org/r/20260307195356.203753-2-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Acked-by: wang lian <lianux.mm@gmail.com>
Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/damon/core.c

index 0c167bbc9c1c4b881534ec5fa0e698697fda32ce..db44294745e6e01a272b90730d5627909c64038d 100644 (file)
@@ -665,7 +665,7 @@ static unsigned int damon_accesses_bp_to_nr_accesses(
 static unsigned int damon_nr_accesses_to_accesses_bp(
                unsigned int nr_accesses, struct damon_attrs *attrs)
 {
-       return nr_accesses * 10000 / damon_max_nr_accesses(attrs);
+       return mult_frac(nr_accesses, 10000, damon_max_nr_accesses(attrs));
 }
 
 static unsigned int damon_nr_accesses_for_new_attrs(unsigned int nr_accesses,
@@ -1724,7 +1724,7 @@ static unsigned long damon_get_intervals_score(struct damon_ctx *c)
        }
        target_access_events = max_access_events * goal_bp / 10000;
        target_access_events = target_access_events ? : 1;
-       return access_events * 10000 / target_access_events;
+       return mult_frac(access_events, 10000, target_access_events);
 }
 
 static unsigned long damon_feed_loop_next_input(unsigned long last_input,
@@ -2204,7 +2204,7 @@ static __kernel_ulong_t damos_get_node_mem_bp(
                numerator = i.totalram - i.freeram;
        else    /* DAMOS_QUOTA_NODE_MEM_FREE_BP */
                numerator = i.freeram;
-       return numerator * 10000 / i.totalram;
+       return mult_frac(numerator, 10000, i.totalram);
 }
 
 static unsigned long damos_get_node_memcg_used_bp(
@@ -2237,7 +2237,7 @@ static unsigned long damos_get_node_memcg_used_bp(
                numerator = used_pages;
        else    /* DAMOS_QUOTA_NODE_MEMCG_FREE_BP */
                numerator = i.totalram - used_pages;
-       return numerator * 10000 / i.totalram;
+       return mult_frac(numerator, 10000, i.totalram);
 }
 #else
 static __kernel_ulong_t damos_get_node_mem_bp(
@@ -2267,8 +2267,8 @@ static unsigned int damos_get_in_active_mem_bp(bool active_ratio)
                global_node_page_state(NR_LRU_BASE + LRU_INACTIVE_FILE);
        total = active + inactive;
        if (active_ratio)
-               return active * 10000 / total;
-       return inactive * 10000 / total;
+               return mult_frac(active, 10000, total);
+       return mult_frac(inactive, 10000, total);
 }
 
 static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
@@ -2311,8 +2311,8 @@ static unsigned long damos_quota_score(struct damos_quota *quota)
        damos_for_each_quota_goal(goal, quota) {
                damos_set_quota_goal_current_value(goal);
                highest_score = max(highest_score,
-                               goal->current_value * 10000 /
-                               goal->target_value);
+                               mult_frac(goal->current_value, 10000,
+                                       goal->target_value));
        }
 
        return highest_score;
@@ -2342,8 +2342,8 @@ static void damos_set_effective_quota(struct damos_quota *quota)
 
        if (quota->ms) {
                if (quota->total_charged_ns)
-                       throughput = mult_frac(quota->total_charged_sz, 1000000,
-                                                       quota->total_charged_ns);
+                       throughput = mult_frac(quota->total_charged_sz,
+                                       1000000, quota->total_charged_ns);
                else
                        throughput = PAGE_SIZE * 1024;
                esz = min(throughput * quota->ms, esz);