Thread (48 messages) 48 messages, 5 authors, 2020-10-09

Re: [External] Re: [RFC PATCH 00/24] mm/hugetlb: Free some vmemmap pages of hugetlb page

From: Muchun Song <hidden>
Date: 2020-09-15 18:04:14
Also in: linux-fsdevel, linux-mm, lkml

On Wed, Sep 16, 2020 at 1:39 AM Matthew Wilcox [off-list ref] wrote:
On Wed, Sep 16, 2020 at 01:32:46AM +0800, Muchun Song wrote:
quoted
On Tue, Sep 15, 2020 at 11:42 PM Matthew Wilcox [off-list ref] wrote:
quoted
On Tue, Sep 15, 2020 at 11:28:01PM +0800, Muchun Song wrote:
quoted
On Tue, Sep 15, 2020 at 10:32 PM Matthew Wilcox [off-list ref] wrote:
quoted
On Tue, Sep 15, 2020 at 08:59:23PM +0800, Muchun Song wrote:
quoted
This patch series will free some vmemmap pages(struct page structures)
associated with each hugetlbpage when preallocated to save memory.
It would be lovely to be able to do this.  Unfortunately, it's completely
impossible right now.  Consider, for example, get_user_pages() called
on the fifth page of a hugetlb page.
Can you elaborate on the problem? Thanks so much.
OK, let's say you want to do a 2kB I/O to offset 0x5000 of a 2MB page
on a 4kB base page system.  Today, that results in a bio_vec containing
{head+5, 0, 0x800}.  Then we call page_to_phys() on that (head+5) struct
page to get the physical address of the I/O, and we turn it into a struct
scatterlist, which similarly has a reference to the page (head+5).
As I know, in this case, the get_user_pages() will get a reference
to the head page (head+0) before returning such that the hugetlb
page can not be freed. Although get_user_pages() returns the
page (head+5) and the scatterlist has a reference to the page
(head+5), this patch series can handle this situation. I can not
figure out where the problem is. What I missed? Thanks.
You freed pages 4-511 from the vmemmap so they could be used for
something else.  Page 5 isn't there any more.  So if you return head+5,
then when we complete the I/O, we'll look for the compound_head() of
head+5 and we won't find head.
We do not free pages 4-511 from the vmemmap. Actually, we only
free pages 128-511 from the vmemmap.

The 512 struct pages occupy 8 pages of physical memory. We only
free 6 physical page frames to the buddy. But we will create a new
mapping just like below. The virtual address of the freed pages will
remap to the second page frame. So the second page frame is
reused.

When a hugetlbpage is preallocated, we can change the mapping to
bellow.

   hugetlbpage                   struct page(8 pages)          page
frame(8 pages)
  +-----------+ ---virt_to_page---> +-----------+   mapping to   +-----------+
  |           |                     |     0     | -------------> |     0     |
  |           |                     |     1     | -------------> |     1     |
  |           |                     |     2     | -------------> +-----------+
  |           |                     |     3     | -----------------^ ^ ^ ^ ^
  |           |                     |     4     | -------------------+ | | |
  |     2M    |                     |     5     | ---------------------+ | |
  |           |                     |     6     | -----------------------+ |
  |           |                     |     7     | -------------------------+
  |           |                     +-----------+
  |           |
  |           |
  +-----------+

As you can see, we reuse the first tail page.

-- 
Yours,
Muchun
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help