diff mbox series

[6/6] mm/page_alloc.c: avoid allocating highmem pages via alloc_pages_exact_nid()

Message ID 20210830141051.64090-7-linmiaohe@huawei.com (mailing list archive)
State New
Headers show
Series Cleanups and fixup for page_alloc | expand

Commit Message

Miaohe Lin Aug. 30, 2021, 2:10 p.m. UTC
Don't use with __GFP_HIGHMEM because page_address() cannot represent
highmem pages without kmap(). Newly allocated pages would leak as
page_address() will return NULL for highmem pages here. But It works
now because the only caller does not specify __GFP_HIGHMEM now.

Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
---
 mm/page_alloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Matthew Wilcox Aug. 30, 2021, 2:24 p.m. UTC | #1
On Mon, Aug 30, 2021 at 10:10:51PM +0800, Miaohe Lin wrote:
> Don't use with __GFP_HIGHMEM because page_address() cannot represent
> highmem pages without kmap(). Newly allocated pages would leak as
> page_address() will return NULL for highmem pages here. But It works
> now because the only caller does not specify __GFP_HIGHMEM now.

This is a misunderstanding of how alloc_pages_exact() /
alloc_pages_exact_nid() work.  You simply can't call them with
GFP_HIGHMEM.

If you really must change anything here,
s/__GFP_COMP/(__GFP_COMP|__GFP_HIGHMEM)/g throughout both
alloc_pages_exact() and alloc_pages_exact_nid().
Miaohe Lin Aug. 31, 2021, 1:56 a.m. UTC | #2
On 2021/8/30 22:24, Matthew Wilcox wrote:
> On Mon, Aug 30, 2021 at 10:10:51PM +0800, Miaohe Lin wrote:
>> Don't use with __GFP_HIGHMEM because page_address() cannot represent
>> highmem pages without kmap(). Newly allocated pages would leak as
>> page_address() will return NULL for highmem pages here. But It works
>> now because the only caller does not specify __GFP_HIGHMEM now.
> 
> This is a misunderstanding of how alloc_pages_exact() /
> alloc_pages_exact_nid() work.  You simply can't call them with
> GFP_HIGHMEM.
> 

Yep, they can't work with GFP_HIGHMEM. So IMO it might be better to
get rid of GFP_HIGHMEM explicitly or add a comment to clarify this
situation to avoid future misbehavior. But this may be a unnecessary
worry... Do you prefer to not change anything here?

Many thanks.

> If you really must change anything here,
> s/__GFP_COMP/(__GFP_COMP|__GFP_HIGHMEM)/g throughout both
> alloc_pages_exact() and alloc_pages_exact_nid().
> .
>
Vlastimil Babka Aug. 31, 2021, 4:37 p.m. UTC | #3
On 8/31/21 03:56, Miaohe Lin wrote:
> On 2021/8/30 22:24, Matthew Wilcox wrote:
>> On Mon, Aug 30, 2021 at 10:10:51PM +0800, Miaohe Lin wrote:
>>> Don't use with __GFP_HIGHMEM because page_address() cannot represent
>>> highmem pages without kmap(). Newly allocated pages would leak as
>>> page_address() will return NULL for highmem pages here. But It works
>>> now because the only caller does not specify __GFP_HIGHMEM now.
>> 
>> This is a misunderstanding of how alloc_pages_exact() /
>> alloc_pages_exact_nid() work.  You simply can't call them with
>> GFP_HIGHMEM.
>> 
> 
> Yep, they can't work with GFP_HIGHMEM. So IMO it might be better to
> get rid of GFP_HIGHMEM explicitly or add a comment to clarify this
> situation to avoid future misbehavior. But this may be a unnecessary
> worry... Do you prefer to not change anything here?

I agree with the suggestion below...

> Many thanks.
> 
>> If you really must change anything here,
>> s/__GFP_COMP/(__GFP_COMP|__GFP_HIGHMEM)/g throughout both
>> alloc_pages_exact() and alloc_pages_exact_nid().

... which means __GFP_HIGHMEM would be stripped and additionally there would
be a warning.
Miaohe Lin Sept. 1, 2021, 8:05 a.m. UTC | #4
On 2021/9/1 0:37, Vlastimil Babka wrote:
> On 8/31/21 03:56, Miaohe Lin wrote:
>> On 2021/8/30 22:24, Matthew Wilcox wrote:
>>> On Mon, Aug 30, 2021 at 10:10:51PM +0800, Miaohe Lin wrote:
>>>> Don't use with __GFP_HIGHMEM because page_address() cannot represent
>>>> highmem pages without kmap(). Newly allocated pages would leak as
>>>> page_address() will return NULL for highmem pages here. But It works
>>>> now because the only caller does not specify __GFP_HIGHMEM now.
>>>
>>> This is a misunderstanding of how alloc_pages_exact() /
>>> alloc_pages_exact_nid() work.  You simply can't call them with
>>> GFP_HIGHMEM.
>>>
>>
>> Yep, they can't work with GFP_HIGHMEM. So IMO it might be better to
>> get rid of GFP_HIGHMEM explicitly or add a comment to clarify this
>> situation to avoid future misbehavior. But this may be a unnecessary
>> worry... Do you prefer to not change anything here?
> 
> I agree with the suggestion below...
> 
>> Many thanks.
>>
>>> If you really must change anything here,
>>> s/__GFP_COMP/(__GFP_COMP|__GFP_HIGHMEM)/g throughout both
>>> alloc_pages_exact() and alloc_pages_exact_nid().
> 
> ... which means __GFP_HIGHMEM would be stripped and additionally there would
> be a warning.
> 

Looks good for me. Will do. Many thanks!

> .
>
diff mbox series

Patch

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d87b7e6e9e6b..858fd45ecaea 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5639,7 +5639,7 @@  void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask)
 	if (WARN_ON_ONCE(gfp_mask & __GFP_COMP))
 		gfp_mask &= ~__GFP_COMP;
 
-	p = alloc_pages_node(nid, gfp_mask, order);
+	p = alloc_pages_node(nid, gfp_mask & ~__GFP_HIGHMEM, order);
 	if (!p)
 		return NULL;
 	return make_alloc_exact((unsigned long)page_address(p), order, size);