All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Kravetz <mike.kravetz@oracle.com>
To: Miaohe Lin <linmiaohe@huawei.com>, akpm@linux-foundation.org
Cc: n-horiguchi@ah.jp.nec.com, linux-kernel@vger.kernel.org,
	linux-mm@kvack.org
Subject: Re: [PATCH 3/4] mm/hugeltb: fix potential wrong gbl_reserve value for hugetlb_acct_memory()
Date: Thu, 8 Apr 2021 15:53:41 -0700	[thread overview]
Message-ID: <90188b1a-a206-5586-2da9-683f7537f960@oracle.com> (raw)
In-Reply-To: <0ebaa062-80e8-b380-c02e-7eb72e67f973@huawei.com>

On 4/7/21 8:26 PM, Miaohe Lin wrote:
> On 2021/4/8 11:24, Miaohe Lin wrote:
>> On 2021/4/8 4:53, Mike Kravetz wrote:
>>> On 4/7/21 12:24 AM, Miaohe Lin wrote:
>>>> Hi:
>>>> On 2021/4/7 10:49, Mike Kravetz wrote:
>>>>> On 4/2/21 2:32 AM, Miaohe Lin wrote:
>>>>>> The resv_map could be NULL since this routine can be called in the evict
>>>>>> inode path for all hugetlbfs inodes. So we could have chg = 0 and this
>>>>>> would result in a negative value when chg - freed. This is unexpected for
>>>>>> hugepage_subpool_put_pages() and hugetlb_acct_memory().
>>>>>
>>>>> I am not sure if this is possible.
>>>>>
>>>>> It is true that resv_map could be NULL.  However, I believe resv map
>>>>> can only be NULL for inodes that are not regular or link inodes.  This
>>>>> is the inode creation code in hugetlbfs_get_inode().
>>>>>
>>>>>        /*
>>>>>          * Reserve maps are only needed for inodes that can have associated
>>>>>          * page allocations.
>>>>>          */
>>>>>         if (S_ISREG(mode) || S_ISLNK(mode)) {
>>>>>                 resv_map = resv_map_alloc();
>>>>>                 if (!resv_map)
>>>>>                         return NULL;
>>>>>         }
>>>>>
>>>>
>>>> Agree.
>>>>
>>>>> If resv_map is NULL, then no hugetlb pages can be allocated/associated
>>>>> with the file.  As a result, remove_inode_hugepages will never find any
>>>>> huge pages associated with the inode and the passed value 'freed' will
>>>>> always be zero.
>>>>>
>>>>
>>>> But I am confused now. AFAICS, remove_inode_hugepages() searches the address_space of
>>>> the inode to remove the hugepages while does not care if inode has associated resv_map.
>>>> How does it prevent hugetlb pages from being allocated/associated with the file if
>>>> resv_map is NULL? Could you please explain this more?
>>>>
>>>
>>> Recall that there are only two ways to get huge pages associated with
>>> a hugetlbfs file: fallocate and mmap/write fault.  Directly writing to
>>> hugetlbfs files is not supported.
>>>
>>> If you take a closer look at hugetlbfs_get_inode, it has that code to
>>> allocate the resv map mentioned above as well as the following:
>>>
>>> 		switch (mode & S_IFMT) {
>>> 		default:
>>> 			init_special_inode(inode, mode, dev);
>>> 			break;
>>> 		case S_IFREG:
>>> 			inode->i_op = &hugetlbfs_inode_operations;
>>> 			inode->i_fop = &hugetlbfs_file_operations;
>>> 			break;
>>> 		case S_IFDIR:
>>> 			inode->i_op = &hugetlbfs_dir_inode_operations;
>>> 			inode->i_fop = &simple_dir_operations;
>>>
>>> 			/* directory inodes start off with i_nlink == 2 (for "." entry) */
>>> 			inc_nlink(inode);
>>> 			break;
>>> 		case S_IFLNK:
>>> 			inode->i_op = &page_symlink_inode_operations;
>>> 			inode_nohighmem(inode);
>>> 			break;
>>> 		}
>>>
>>> Notice that only S_IFREG inodes will have i_fop == &hugetlbfs_file_operations.
>>> hugetlbfs_file_operations contain the hugetlbfs specific mmap and fallocate
>>> routines.  Hence, only files with S_IFREG inodes can potentially have
>>> associated huge pages.  S_IFLNK inodes can as well via file linking.
>>>
>>> If an inode is not S_ISREG(mode) || S_ISLNK(mode), then it will not have
>>> a resv_map.  In addition, it will not have hugetlbfs_file_operations and
>>> can not have associated huge pages.
>>>
>>
>> Many many thanks for detailed and patient explanation! :) I think I have got the idea!
>>
>>> I looked at this closely when adding commits
>>> 58b6e5e8f1ad hugetlbfs: fix memory leak for resv_map
>>> f27a5136f70a hugetlbfs: always use address space in inode for resv_map pointer
>>>
>>> I may not be remembering all of the details correctly.  Commit f27a5136f70a
>>> added the comment that resv_map could be NULL to hugetlb_unreserve_pages.
>>>
>>
>> Since we must have freed == 0 while chg == 0. Should we make this assumption explict
>> by something like below?
>>
>> WARN_ON(chg < freed);
>>
> 
> Or just a comment to avoid confusion ?
> 

Yes, add a comment to hugetlb_unreserve_pages saying that !resv_map
implies freed == 0.

It would also be helpful to check for (chg - freed) == 0 and skip the
calls to hugepage_subpool_put_pages() and hugetlb_acct_memory().  Both
of those routines may perform an unnecessary lock/unlock cycle in this
case.

A simple
	if (chg == free)
		return 0;
before the call to hugepage_subpool_put_pages would work.
-- 
Mike Kravetz

  reply	other threads:[~2021-04-08 22:54 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-02  9:32 [PATCH 0/4] Cleanup and fixup for hugetlb Miaohe Lin
2021-04-02  9:32 ` [PATCH 1/4] mm/hugeltb: remove redundant VM_BUG_ON() in region_add() Miaohe Lin
2021-04-07  0:16   ` Mike Kravetz
2021-04-02  9:32 ` [PATCH 2/4] mm/hugeltb: simplify the return code of __vma_reservation_common() Miaohe Lin
2021-04-07  0:53   ` Mike Kravetz
2021-04-07  2:05     ` Miaohe Lin
2021-04-07  2:37       ` Mike Kravetz
2021-04-07  3:09         ` Miaohe Lin
2021-04-07 21:23           ` Mike Kravetz
2021-04-08  2:44             ` Miaohe Lin
2021-04-08 22:40               ` Mike Kravetz
2021-04-09  2:52                 ` Miaohe Lin
2021-04-02  9:32 ` [PATCH 3/4] mm/hugeltb: fix potential wrong gbl_reserve value for hugetlb_acct_memory() Miaohe Lin
2021-04-07  2:49   ` Mike Kravetz
2021-04-07  7:24     ` Miaohe Lin
2021-04-07 20:53       ` Mike Kravetz
2021-04-08  3:24         ` Miaohe Lin
2021-04-08  3:26           ` Miaohe Lin
2021-04-08 22:53             ` Mike Kravetz [this message]
2021-04-09  3:01               ` Miaohe Lin
2021-04-09  4:37                 ` Mike Kravetz
2021-04-09  6:36                   ` Miaohe Lin
2021-04-02  9:32 ` [PATCH 4/4] mm/hugeltb: handle the error case in hugetlb_fix_reserve_counts() Miaohe Lin
2021-04-08 23:25   ` Mike Kravetz
2021-04-09  3:17     ` Miaohe Lin
2021-04-09  5:04       ` Andrew Morton
2021-04-09  7:07         ` Miaohe Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=90188b1a-a206-5586-2da9-683f7537f960@oracle.com \
    --to=mike.kravetz@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=linmiaohe@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=n-horiguchi@ah.jp.nec.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.