On 11/10/22 14:22, Nadav Amit wrote:
On Nov 10, 2022, at 1:48 PM, Mike Kravetz mike.kravetz@oracle.com wrote:
void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end, struct page *ref_page, zap_flags_t zap_flags) {
struct mmu_notifier_range range; struct mmu_gather tlb;
mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma, vma->vm_mm,
start, end);
adjust_range_if_pmd_sharing_possible(vma, &range.start, &range.end); tlb_gather_mmu(&tlb, vma->vm_mm);
__unmap_hugepage_range(&tlb, vma, start, end, ref_page, zap_flags);
Is there a reason for not using range.start and range.end?
After calling adjust_range_if_pmd_sharing_possible, range.start - range.end could be much greater than the range we actually want to unmap. The range gets adjusted to account for pmd sharing if that is POSSIBLE. It does not know for sure if we will actually 'unshare a pmd'.
I suppose adjust_range_if_pmd_sharing_possible could be modified to actually check if unmapping will result in unsharing, but it does not do that today.
Thanks for the explanation. It’s probably me, but I am still not sure that I understand the the different between __unmap_hugepage_range() using (start, end) and __zap_page_range_single() using (address, range.end). Perhaps it worth a comment in the code?
__zap_page_range_single is wrong. It should have been updated to use the range address - (address + size).
At Peter's suggestion the mmu notifier updates will be broken out in a separate patch. I will also add comments, to make this easier to follow.
But anyhow… shouldn’t unmap_hugepage_range() call mmu_notifier_invalidate_range_start()?
Yes, thanks!