]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mm: folio_zero_user: open code range computation in folio_zero_user()
authorAnkur Arora <ankur.a.arora@oracle.com>
Wed, 28 Jan 2026 18:59:43 +0000 (10:59 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 12 Feb 2026 23:42:53 +0000 (15:42 -0800)
riscv64-gcc-linux-gnu (v8.5) reports a compile time assert in:

   r[2] = DEFINE_RANGE(clamp_t(s64, fault_idx - radius, pg.start, pg.end),
         clamp_t(s64, fault_idx + radius, pg.start, pg.end));

where it decides that pg.start > pg.end in:
  clamp_t(s64, fault_idx + radius, pg.start, pg.end));

where pg comes from:
  const struct range pg = DEFINE_RANGE(0, folio_nr_pages(folio) - 1);

That does not seem like it could be true. Even for pg.start == pg.end,
we would need folio_test_large() to evaluate to false at compile time:

  static inline unsigned long folio_nr_pages(const struct folio *folio)
  {
if (!folio_test_large(folio))
return 1;
return folio_large_nr_pages(folio);
  }

Workaround by open coding the range computation. Also, simplify the type
declarations for the relevant variables.

[ankur.a.arora@oracle.com: remove unneeded cast, per David]
Link: https://lkml.kernel.org/r/20260206223801.2617497-1-ankur.a.arora@oracle.com
Link: https://lkml.kernel.org/r/20260206223801.2617497-1-ankur.a.arora@oracle.com
Link: https://lkml.kernel.org/r/20260128185943.2397128-1-ankur.a.arora@oracle.com
Fixes: 93552c9a3350 ("mm: folio_zero_user: cache neighbouring pages")
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202601240453.QCjgGdJa-lkp@intel.com/
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: "Borislav Petkov (AMD)" <bp@alien8.de>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Konrad Rzessutek Wilk <konrad.wilk@oracle.com>
Cc: Lance Yang <ioworker0@gmail.com>
Cc: Li Zhe <lizhe.67@bytedance.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Raghavendra K T <raghavendra.kt@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memory.c

index 15a6c09d54ee5dd6fafabf3ffc3d066e822dda22..cf32e2666e71b548a5e48a3d8b3e076d7b0a3a6d 100644 (file)
@@ -7316,7 +7316,7 @@ void folio_zero_user(struct folio *folio, unsigned long addr_hint)
        const unsigned long base_addr = ALIGN_DOWN(addr_hint, folio_size(folio));
        const long fault_idx = (addr_hint - base_addr) / PAGE_SIZE;
        const struct range pg = DEFINE_RANGE(0, folio_nr_pages(folio) - 1);
-       const int radius = FOLIO_ZERO_LOCALITY_RADIUS;
+       const long radius = FOLIO_ZERO_LOCALITY_RADIUS;
        struct range r[3];
        int i;
 
@@ -7324,20 +7324,19 @@ void folio_zero_user(struct folio *folio, unsigned long addr_hint)
         * Faulting page and its immediate neighbourhood. Will be cleared at the
         * end to keep its cachelines hot.
         */
-       r[2] = DEFINE_RANGE(clamp_t(s64, fault_idx - radius, pg.start, pg.end),
-                           clamp_t(s64, fault_idx + radius, pg.start, pg.end));
+       r[2] = DEFINE_RANGE(fault_idx - radius < (long)pg.start ? pg.start : fault_idx - radius,
+                           fault_idx + radius > (long)pg.end   ? pg.end   : fault_idx + radius);
+
 
        /* Region to the left of the fault */
-       r[1] = DEFINE_RANGE(pg.start,
-                           clamp_t(s64, r[2].start - 1, pg.start - 1, r[2].start));
+       r[1] = DEFINE_RANGE(pg.start, r[2].start - 1);
 
        /* Region to the right of the fault: always valid for the common fault_idx=0 case. */
-       r[0] = DEFINE_RANGE(clamp_t(s64, r[2].end + 1, r[2].end, pg.end + 1),
-                           pg.end);
+       r[0] = DEFINE_RANGE(r[2].end + 1, pg.end);
 
        for (i = 0; i < ARRAY_SIZE(r); i++) {
                const unsigned long addr = base_addr + r[i].start * PAGE_SIZE;
-               const unsigned int nr_pages = range_len(&r[i]);
+               const long nr_pages = (long)range_len(&r[i]);
                struct page *page = folio_page(folio, r[i].start);
 
                if (nr_pages > 0)