linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mm: make folio page count functions return unsigned
@ 2025-08-26 15:37 Aristeu Rozanski
  2025-08-26 19:00 ` Matthew Wilcox
  2025-08-27  9:13 ` David Hildenbrand
  0 siblings, 2 replies; 7+ messages in thread
From: Aristeu Rozanski @ 2025-08-26 15:37 UTC (permalink / raw)
  To: linux-mm
  Cc: David Hildenbrand, Andrew Morton, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter

As raised by Andrew [1], a folio/compound page never spans a negative number
of pages. Consequently, let's use "unsigned long" instead of "long"
consistently for folio_nr_pages(), folio_large_nr_pages() and compound_nr().

Using "unsigned long" as return value is fine, because even
"(long)-folio_nr_pages()" will keep on working as expected. Using "unsigned
int" instead would actually break these use cases.

This patch takes the first step changing these to return unsigned long (and
making drm_gem_get_pages() use the new types instead of replacing min()).

In the future, we might want to make more callers of these functions to
consistently use "unsigned long".

[1] https://lore.kernel.org/linux-mm/20250503182858.5a02729fcffd6d4723afcfc2@linux-foundation.org/

Link: https://lore.kernel.org/linux-mm/20250503182858.5a02729fcffd6d4723afcfc2@linux-foundation.org/
Signed-off-by: Aristeu Rozanski <aris@ruivo.org>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: David Hildenbrand <david@redhat.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>

---
 drivers/gpu/drm/drm_gem.c |    4 ++--
 include/linux/mm.h        |    8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

--- linus-2.6.orig/drivers/gpu/drm/drm_gem.c	2025-08-11 14:52:45.878752324 -0400
+++ linus-2.6/drivers/gpu/drm/drm_gem.c	2025-08-19 00:31:01.495295839 -0400
@@ -620,7 +620,7 @@ struct page **drm_gem_get_pages(struct d
 	struct page **pages;
 	struct folio *folio;
 	struct folio_batch fbatch;
-	long i, j, npages;
+	unsigned long i, j, npages;
 
 	if (WARN_ON(!obj->filp))
 		return ERR_PTR(-EINVAL);
@@ -644,7 +644,7 @@ WARN_ON((obj->size & (PAGE_SIZE - 1)) !=
 
 	i = 0;
 	while (i < npages) {
-		long nr;
+		unsigned long nr;
 		folio = shmem_read_folio_gfp(mapping, i,
 				mapping_gfp_mask(mapping));
 		if (IS_ERR(folio))
--- linus-2.6.orig/include/linux/mm.h	2025-08-11 14:52:45.878752324 -0400
+++ linus-2.6/include/linux/mm.h	2025-08-11 14:53:00.396630632 -0400
@@ -951,12 +951,12 @@ return folio->_flags_1 & 0xff;
 }
 
 #ifdef NR_PAGES_IN_LARGE_FOLIO
-static inline long folio_large_nr_pages(const struct folio *folio)
+static inline unsigned long folio_large_nr_pages(const struct folio *folio)
 {
 	return folio->_nr_pages;
 }
 #else
-static inline long folio_large_nr_pages(const struct folio *folio)
+static inline unsigned long folio_large_nr_pages(const struct folio *folio)
 {
 	return 1L << folio_large_order(folio);
 }
@@ -1971,7 +1971,7 @@ static inline void set_page_links(struct
  *
  * Return: A positive power of two.
  */
-static inline long folio_nr_pages(const struct folio *folio)
+static inline unsigned long folio_nr_pages(const struct folio *folio)
 {
 	if (!folio_test_large(folio))
 		return 1;
@@ -1990,7 +1990,7 @@ static inline long folio_nr_pages(const
  * page.  compound_nr() can be called on a tail page, and is defined to
  * return 1 in that case.
  */
-static inline long compound_nr(struct page *page)
+static inline unsigned long compound_nr(struct page *page)
 {
 	struct folio *folio = (struct folio *)page;
 


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

* Re: [PATCH] mm: make folio page count functions return unsigned
  2025-08-26 15:37 [PATCH] mm: make folio page count functions return unsigned Aristeu Rozanski
@ 2025-08-26 19:00 ` Matthew Wilcox
  2025-08-26 21:45   ` David Hildenbrand
  2025-08-27  9:13 ` David Hildenbrand
  1 sibling, 1 reply; 7+ messages in thread
From: Matthew Wilcox @ 2025-08-26 19:00 UTC (permalink / raw)
  To: Aristeu Rozanski
  Cc: linux-mm, David Hildenbrand, Andrew Morton, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter

On Tue, Aug 26, 2025 at 11:37:21AM -0400, Aristeu Rozanski wrote:
> As raised by Andrew [1], a folio/compound page never spans a negative number
> of pages. Consequently, let's use "unsigned long" instead of "long"
> consistently for folio_nr_pages(), folio_large_nr_pages() and compound_nr().
> 
> Using "unsigned long" as return value is fine, because even
> "(long)-folio_nr_pages()" will keep on working as expected. Using "unsigned
> int" instead would actually break these use cases.

I wish I'd written down what this broke, but it did.

Sometimes we pass -folio_nr_pages() to functions.  If it has an unsigned
long type, things can go wrong.

Please don't do this.


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

* Re: [PATCH] mm: make folio page count functions return unsigned
  2025-08-26 19:00 ` Matthew Wilcox
@ 2025-08-26 21:45   ` David Hildenbrand
  2025-08-26 22:00     ` Aristeu Rozanski
  0 siblings, 1 reply; 7+ messages in thread
From: David Hildenbrand @ 2025-08-26 21:45 UTC (permalink / raw)
  To: Matthew Wilcox, Aristeu Rozanski
  Cc: linux-mm, Andrew Morton, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter

On 26.08.25 21:00, Matthew Wilcox wrote:
> On Tue, Aug 26, 2025 at 11:37:21AM -0400, Aristeu Rozanski wrote:
>> As raised by Andrew [1], a folio/compound page never spans a negative number
>> of pages. Consequently, let's use "unsigned long" instead of "long"
>> consistently for folio_nr_pages(), folio_large_nr_pages() and compound_nr().
>>
>> Using "unsigned long" as return value is fine, because even
>> "(long)-folio_nr_pages()" will keep on working as expected. Using "unsigned
>> int" instead would actually break these use cases.
> 
> I wish I'd written down what this broke, but it did.
> 
> Sometimes we pass -folio_nr_pages() to functions.  If it has an unsigned
> long type, things can go wrong.

IIRC, the issue is if we pass -folio_nr_pages() to functions that expect 
a "long" and we are using "unsigned int" as return type.

Then, e.g., -1 will be (unsigned int)0xffffffff, and casting that to 
"long" means trouble, because we wouldn't sign-extend properly and get 
(long)0x00000000ffffffff.

Using "unsigned long" instead work perfectly fine.

e.g., -1 will be (unsigned long)0xffffffffffffffff. Passing that to a 
function that expects "long" or "unsigned long" works as expected.

At least that's what I remember :)

-- 
Cheers

David / dhildenb



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

* Re: [PATCH] mm: make folio page count functions return unsigned
  2025-08-26 21:45   ` David Hildenbrand
@ 2025-08-26 22:00     ` Aristeu Rozanski
  2025-08-27  1:20       ` Matthew Wilcox
  0 siblings, 1 reply; 7+ messages in thread
From: Aristeu Rozanski @ 2025-08-26 22:00 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Matthew Wilcox, linux-mm, Andrew Morton, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter

On Tue, Aug 26, 2025 at 11:45:52PM +0200, David Hildenbrand wrote:
> IIRC, the issue is if we pass -folio_nr_pages() to functions that expect 
> a "long" and we are using "unsigned int" as return type.

some actually expect an int (e.g. memcg1_charge_statistics()), it'd be a good
idea to get those fixed.

> Then, e.g., -1 will be (unsigned int)0xffffffff, and casting that to 
> "long" means trouble, because we wouldn't sign-extend properly and get 
> (long)0x00000000ffffffff.
> 
> Using "unsigned long" instead work perfectly fine.
> 
> e.g., -1 will be (unsigned long)0xffffffffffffffff. Passing that to a 
> function that expects "long" or "unsigned long" works as expected.

We could run into problems if folio_nr_pages() ever returns an unsigned long
larger than LONG_MAX :^)

-- 
Aristeu



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

* Re: [PATCH] mm: make folio page count functions return unsigned
  2025-08-26 22:00     ` Aristeu Rozanski
@ 2025-08-27  1:20       ` Matthew Wilcox
  2025-08-27  9:14         ` David Hildenbrand
  0 siblings, 1 reply; 7+ messages in thread
From: Matthew Wilcox @ 2025-08-27  1:20 UTC (permalink / raw)
  To: Aristeu Rozanski
  Cc: David Hildenbrand, linux-mm, Andrew Morton, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter

On Tue, Aug 26, 2025 at 06:00:41PM -0400, Aristeu Rozanski wrote:
> some actually expect an int (e.g. memcg1_charge_statistics()), it'd be a good
> idea to get those fixed.

Yes.

> > Then, e.g., -1 will be (unsigned int)0xffffffff, and casting that to 
> > "long" means trouble, because we wouldn't sign-extend properly and get 
> > (long)0x00000000ffffffff.
> > 
> > Using "unsigned long" instead work perfectly fine.
> > 
> > e.g., -1 will be (unsigned long)0xffffffffffffffff. Passing that to a 
> > function that expects "long" or "unsigned long" works as expected.
> 
> We could run into problems if folio_nr_pages() ever returns an unsigned long
> larger than LONG_MAX :^)

I feel comfortable saying that we'll never support a folio size larger
than 2^31 bytes on 32-bit or 2^63 bytes on 64-bit because folio_size()
returns a size_t so that constrains us.  That means folio_nr_pages()
must lie in the range [1..2^19] or [1..2^51] respectively.  We're never
going to support PAGE_SIZE smaller than 4KiB; nobody's interested in
designing hardware to support smaller page sizes.

We are likely to see folio_nr_pages() be larger than 2^31 at some point.
arm64 supports 2^13 pages per level, so a PMD is 2^13, a PUD is 2^26
and a P4D is 2^39 pages.  That's an utterly impractical page size for
most uses, but just wait until the AI people decide that it saaves them
a fraction of a joule per calculation.  I'm not putting any work into
supporting that at this point, but I'm also trying not to do anything
that makes adding that support harder.


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

* Re: [PATCH] mm: make folio page count functions return unsigned
  2025-08-26 15:37 [PATCH] mm: make folio page count functions return unsigned Aristeu Rozanski
  2025-08-26 19:00 ` Matthew Wilcox
@ 2025-08-27  9:13 ` David Hildenbrand
  1 sibling, 0 replies; 7+ messages in thread
From: David Hildenbrand @ 2025-08-27  9:13 UTC (permalink / raw)
  To: Aristeu Rozanski, linux-mm
  Cc: Andrew Morton, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter

On 26.08.25 17:37, Aristeu Rozanski wrote:
> As raised by Andrew [1], a folio/compound page never spans a negative number
> of pages. Consequently, let's use "unsigned long" instead of "long"
> consistently for folio_nr_pages(), folio_large_nr_pages() and compound_nr().
> 
> Using "unsigned long" as return value is fine, because even
> "(long)-folio_nr_pages()" will keep on working as expected. Using "unsigned
> int" instead would actually break these use cases.
> 
> This patch takes the first step changing these to return unsigned long (and
> making drm_gem_get_pages() use the new types instead of replacing min()).
> 
> In the future, we might want to make more callers of these functions to
> consistently use "unsigned long".
> 
> [1] https://lore.kernel.org/linux-mm/20250503182858.5a02729fcffd6d4723afcfc2@linux-foundation.org/
> 
> Link: https://lore.kernel.org/linux-mm/20250503182858.5a02729fcffd6d4723afcfc2@linux-foundation.org/
> Signed-off-by: Aristeu Rozanski <aris@ruivo.org>
> Suggested-by: Andrew Morton <akpm@linux-foundation.org>
> Suggested-by: David Hildenbrand <david@redhat.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Simona Vetter <simona@ffwll.ch>
> 

TL;DR

Acked-by: David Hildenbrand <david@redhat.com>



I agree with Andrew that using an unsigned type is clearer, and it confused me in
the past.

When I last looked at that, I realized that "unsigned int" is problematic
(the hard way ...)  and concluded that "unsigned long" should work as well.

commit 1ea5212aed0682ae1249cba9df7ad7ef539d0a7d
Author: David Hildenbrand <david@redhat.com>
Date:   Mon Mar 3 17:29:55 2025 +0100

     mm: factor out large folio handling from folio_nr_pages() into folio_large_nr_pages()
     
     Let's factor it out into a simple helper function.  This helper will also
     come in handy when working with code where we know that our folio is
     large.
     
     While at it, let's consistently return a "long" value from all these
     similar functions.  Note that we cannot use "unsigned int" (even though
     _folio_nr_pages is of that type), because it would break some callers that
     do stuff like "-folio_nr_pages()".  Both "int" or "unsigned long" would
     work as well.


compound_nr() used "unsigned long" before.

I did a quick test below to make sure I am not missing something.

"unsigned long" works as expected except. The only exception would be 32bit
when we would have a function that expects a signed or unsigned "long long".

Should we be using "unsigned long long"? I don't think so.


Using long long / unsigned long long for something nr_pages (or PFN) related
is highly questionable and should be cleaned up.

Because I am curious, si I looked around (I hope I caught most cases):

$ git grep -e "\- *folio_nr_pages"
include/linux/mm_inline.h:                      -folio_nr_pages(folio));

-> consumes "long nr_pages"

include/linux/vmstat.h: __mod_zone_page_state(folio_zone(folio), item, -folio_nr_pages(folio));
include/linux/vmstat.h: mod_zone_page_state(folio_zone(folio), item, -folio_nr_pages(folio));
include/linux/vmstat.h: __mod_node_page_state(folio_pgdat(folio), item, -folio_nr_pages(folio));
include/linux/vmstat.h: mod_node_page_state(folio_pgdat(folio), item, -folio_nr_pages(folio));

-> consume "long delta"

include/linux/vmstat.h: __lruvec_stat_mod_folio(folio, idx, -folio_nr_pages(folio));
include/linux/vmstat.h: lruvec_stat_mod_folio(folio, idx, -folio_nr_pages(folio));

-> Consume "int val"

mm/khugepaged.c:                        -folio_nr_pages(folio));

-> Consumes "long nr"

mm/memcontrol-v1.c:     memcg1_charge_statistics(memcg, -folio_nr_pages(folio));

-> Consumes "int nr_pages"

mm/migrate.c:                                   folio_is_file_lru(folio), -folio_nr_pages(folio));

-> consume "long delta"

mm/migrate.c:   folio_ref_unfreeze(src, expected_count - folio_nr_pages(src));

-> expected_count is an "int"

mm/migrate.c:                               folio_is_file_lru(src), -folio_nr_pages(src));

-> Consumes "long nr"


$ git grep -e "\-= *folio_nr_pages"
fs/bcachefs/fs-io-buffered.c:                   ractl->_index -= folio_nr_pages(folio);

-> "pgoff_t _index" -> "unsigned long"

fs/btrfs/extent_io.c:                   wbc->nr_to_write -= folio_nr_pages(folio);
fs/ext4/inode.c:        mpd->wbc->nr_to_write -= folio_nr_pages(folio);
fs/ext4/inode.c:        mpd->wbc->nr_to_write -= folio_nr_pages(folio);

-> "long nr_to_write"

mm/memory-failure.c:            count -= folio_nr_pages(page_folio(p));

-> "int count"

mm/page-writeback.c:            wbc->nr_to_write -= folio_nr_pages(folio);

-> "long nr_to_write"

--

$ gcc tst.c -o tst; ./tst
Testing: receive_unsigned_long_long(-return_unsigned_long_long())
         PASS
Testing: receive_unsigned_long_long(-return_long_long())
         PASS
Testing: receive_unsigned_long_long(-return_unsigned_long())
         PASS
Testing: receive_unsigned_long_long(-return_long())
         PASS
Testing: receive_unsigned_long_long(-return_unsigned_int())
         FAIL
Testing: receive_unsigned_long_long(-return_int())
         PASS
Testing: receive_long_long(-return_unsigned_long_long())
         PASS
Testing: receive_long_long(-return_long_long())
         PASS
Testing: receive_long_long(-return_unsigned_long())
         PASS
Testing: receive_long_long(-return_long())
         PASS
Testing: receive_long_long(-return_unsigned_int())
         FAIL
Testing: receive_long_long(-return_int())
         PASS
Testing: receive_unsigned_long(-return_unsigned_long_long())
         PASS
Testing: receive_unsigned_long(-return_long_long())
         PASS
Testing: receive_unsigned_long(-return_unsigned_long())
         PASS
Testing: receive_unsigned_long(-return_long())
         PASS
Testing: receive_unsigned_long(-return_unsigned_int())
         FAIL
Testing: receive_unsigned_long(-return_int())
         PASS
Testing: receive_long(-return_unsigned_long_long())
         PASS
Testing: receive_long(-return_long_long())
         PASS
Testing: receive_long(-return_unsigned_long())
         PASS
Testing: receive_long(-return_long())
         PASS
Testing: receive_long(-return_unsigned_int())
         FAIL
Testing: receive_long(-return_int())
         PASS
Testing: receive_unsigned_int(-return_unsigned_long_long())
         PASS
Testing: receive_unsigned_int(-return_long_long())
         PASS
Testing: receive_unsigned_int(-return_unsigned_long())
         PASS
Testing: receive_unsigned_int(-return_long())
         PASS
Testing: receive_unsigned_int(-return_unsigned_int())
         PASS
Testing: receive_unsigned_int(-return_int())
         PASS
Testing: receive_int(-return_unsigned_long_long())
         PASS
Testing: receive_int(-return_long_long())
         PASS
Testing: receive_int(-return_unsigned_long())
         PASS
Testing: receive_int(-return_long())
         PASS
Testing: receive_int(-return_unsigned_int())
         PASS
Testing: receive_int(-return_int())
         PASS

$ gcc -m32 tst.c -o tst; ./tst
Testing: receive_unsigned_long_long(-return_unsigned_long_long())
         PASS
Testing: receive_unsigned_long_long(-return_long_long())
         PASS
Testing: receive_unsigned_long_long(-return_unsigned_long())
         FAIL
Testing: receive_unsigned_long_long(-return_long())
         PASS
Testing: receive_unsigned_long_long(-return_unsigned_int())
         FAIL
Testing: receive_unsigned_long_long(-return_int())
         PASS
Testing: receive_long_long(-return_unsigned_long_long())
         PASS
Testing: receive_long_long(-return_long_long())
         PASS
Testing: receive_long_long(-return_unsigned_long())
         FAIL
Testing: receive_long_long(-return_long())
         PASS
Testing: receive_long_long(-return_unsigned_int())
         FAIL
Testing: receive_long_long(-return_int())
         PASS
Testing: receive_unsigned_long(-return_unsigned_long_long())
         PASS
Testing: receive_unsigned_long(-return_long_long())
         PASS
Testing: receive_unsigned_long(-return_unsigned_long())
         PASS
Testing: receive_unsigned_long(-return_long())
         PASS
Testing: receive_unsigned_long(-return_unsigned_int())
         PASS
Testing: receive_unsigned_long(-return_int())
         PASS
Testing: receive_long(-return_unsigned_long_long())
         PASS
Testing: receive_long(-return_long_long())
         PASS
Testing: receive_long(-return_unsigned_long())
         PASS
Testing: receive_long(-return_long())
         PASS
Testing: receive_long(-return_unsigned_int())
         PASS
Testing: receive_long(-return_int())
         PASS
Testing: receive_unsigned_int(-return_unsigned_long_long())
         PASS
Testing: receive_unsigned_int(-return_long_long())
         PASS
Testing: receive_unsigned_int(-return_unsigned_long())
         PASS
Testing: receive_unsigned_int(-return_long())
         PASS
Testing: receive_unsigned_int(-return_unsigned_int())
         PASS
Testing: receive_unsigned_int(-return_int())
         PASS
Testing: receive_int(-return_unsigned_long_long())
         PASS
Testing: receive_int(-return_long_long())
         PASS
Testing: receive_int(-return_unsigned_long())
         PASS
Testing: receive_int(-return_long())
         PASS
Testing: receive_int(-return_unsigned_int())
         PASS
Testing: receive_int(-return_int())
         PASS

--

#include <stdio.h>
#include <stdbool.h>

volatile int orig_val = 1234;
volatile int receive_val = -1234;

static unsigned long long return_unsigned_long_long(void)
{
	return orig_val;
}

static long long return_long_long(void)
{
	return orig_val;
}

static unsigned long return_unsigned_long(void)
{
	return orig_val;
}

static long return_long(void)
{
	return orig_val;
}

static unsigned int return_unsigned_int(void)
{
	return orig_val;
}

static int return_int(void)
{
	return orig_val;
}

static bool receive_unsigned_long_long(unsigned long long val)
{
	return val == receive_val;
}

static bool receive_long_long(long long val)
{
	return val == receive_val;
}

static bool receive_unsigned_long(unsigned long val)
{
	return val == receive_val;
}

static bool receive_long(long val)
{
	return val == receive_val;
}

static bool receive_unsigned_int(unsigned int val)
{
	return val == receive_val;
}

static bool receive_int(int val)
{
	return val == receive_val;
}

#define TEST(cmd) \
	do { \
		printf("Testing: " #cmd "\n"); \
		if (cmd) \
			printf("\tPASS\n"); \
		else \
			printf("\tFAIL\n"); \
	} while(0)

int main(int ac, char** av) {
	TEST(receive_unsigned_long_long(-return_unsigned_long_long()));
	TEST(receive_unsigned_long_long(-return_long_long()));
	TEST(receive_unsigned_long_long(-return_unsigned_long()));
	TEST(receive_unsigned_long_long(-return_long()));
	TEST(receive_unsigned_long_long(-return_unsigned_int()));
	TEST(receive_unsigned_long_long(-return_int()));
	TEST(receive_long_long(-return_unsigned_long_long()));
	TEST(receive_long_long(-return_long_long()));
	TEST(receive_long_long(-return_unsigned_long()));
	TEST(receive_long_long(-return_long()));
	TEST(receive_long_long(-return_unsigned_int()));
	TEST(receive_long_long(-return_int()));
	TEST(receive_unsigned_long(-return_unsigned_long_long()));
	TEST(receive_unsigned_long(-return_long_long()));
	TEST(receive_unsigned_long(-return_unsigned_long()));
	TEST(receive_unsigned_long(-return_long()));
	TEST(receive_unsigned_long(-return_unsigned_int()));
	TEST(receive_unsigned_long(-return_int()));
	TEST(receive_long(-return_unsigned_long_long()));
	TEST(receive_long(-return_long_long()));
	TEST(receive_long(-return_unsigned_long()));
	TEST(receive_long(-return_long()));
	TEST(receive_long(-return_unsigned_int()));
	TEST(receive_long(-return_int()));
	TEST(receive_unsigned_int(-return_unsigned_long_long()));
	TEST(receive_unsigned_int(-return_long_long()));
	TEST(receive_unsigned_int(-return_unsigned_long()));
	TEST(receive_unsigned_int(-return_long()));
	TEST(receive_unsigned_int(-return_unsigned_int()));
	TEST(receive_unsigned_int(-return_int()));
	TEST(receive_int(-return_unsigned_long_long()));
	TEST(receive_int(-return_long_long()));
	TEST(receive_int(-return_unsigned_long()));
	TEST(receive_int(-return_long()));
	TEST(receive_int(-return_unsigned_int()));
	TEST(receive_int(-return_int()));
	return 0;
}

-- 
Cheers

David / dhildenb



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

* Re: [PATCH] mm: make folio page count functions return unsigned
  2025-08-27  1:20       ` Matthew Wilcox
@ 2025-08-27  9:14         ` David Hildenbrand
  0 siblings, 0 replies; 7+ messages in thread
From: David Hildenbrand @ 2025-08-27  9:14 UTC (permalink / raw)
  To: Matthew Wilcox, Aristeu Rozanski
  Cc: linux-mm, Andrew Morton, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter

On 27.08.25 03:20, Matthew Wilcox wrote:
> On Tue, Aug 26, 2025 at 06:00:41PM -0400, Aristeu Rozanski wrote:
>> some actually expect an int (e.g. memcg1_charge_statistics()), it'd be a good
>> idea to get those fixed.
> 
> Yes.
> 
>>> Then, e.g., -1 will be (unsigned int)0xffffffff, and casting that to
>>> "long" means trouble, because we wouldn't sign-extend properly and get
>>> (long)0x00000000ffffffff.
>>>
>>> Using "unsigned long" instead work perfectly fine.
>>>
>>> e.g., -1 will be (unsigned long)0xffffffffffffffff. Passing that to a
>>> function that expects "long" or "unsigned long" works as expected.
>>
>> We could run into problems if folio_nr_pages() ever returns an unsigned long
>> larger than LONG_MAX :^)
> 
> I feel comfortable saying that we'll never support a folio size larger
> than 2^31 bytes on 32-bit or 2^63 bytes on 64-bit because folio_size()
> returns a size_t so that constrains us.
Right, otherwise we're back in highmem days where "unsigned long pfn" 
works but "unsigned long long size" is required.

(I hope we'll never have to deal with highmem on 6bit :D ... well, and 
that we can get rid of highmem support on 32bit)

-- 
Cheers

David / dhildenb



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

end of thread, other threads:[~2025-08-27  9:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-26 15:37 [PATCH] mm: make folio page count functions return unsigned Aristeu Rozanski
2025-08-26 19:00 ` Matthew Wilcox
2025-08-26 21:45   ` David Hildenbrand
2025-08-26 22:00     ` Aristeu Rozanski
2025-08-27  1:20       ` Matthew Wilcox
2025-08-27  9:14         ` David Hildenbrand
2025-08-27  9:13 ` David Hildenbrand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).