From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E43F8C7115C for ; Wed, 25 Jun 2025 10:56:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:In-Reply-To:References:Cc:To:From:Subject:MIME-Version:Date: Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=5+hfwvWC996r2MUYJpb8A4wnft6Q/V6aycecydJia7U=; b=zpRenBSp1hBJrYGOZqAa9qqvqC NXnA3YzmsIoHy3JUSviD134j0RIJDQil73pFzIEaQFdvXtV7dCxwsAXmgjAvcVQjCGt9s2DGAPwjx Y0NV3Umw2NHqaIQ4WCxDNbMHiN3JKCAqDYQfh5rhabzZW1Zjtk1guUBr1VcFeNnPWUr5sjcisNMZg M5ER5Dktkl4Gr9SABWIzriMfnkrtkdYpkL9HccYguNKNVdaEJozswiumA1kdjSGXSbAi5JESAAmGJ TRpkHTopkyGrhvb+cAdzFd/yzGi1yaS6TyhcPzInGdczSzkh8o6C0v0ennXmkowDMjnKuO+RwHwy6 jqhor7XQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uUNnK-00000008OAP-3ZNU; Wed, 25 Jun 2025 10:55:58 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uUMRu-000000088IR-0Rmr for linux-arm-kernel@bombadil.infradead.org; Wed, 25 Jun 2025 09:29:46 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:Content-Type :In-Reply-To:References:Cc:To:From:Subject:MIME-Version:Date:Message-ID: Sender:Reply-To:Content-ID:Content-Description; bh=5+hfwvWC996r2MUYJpb8A4wnft6Q/V6aycecydJia7U=; b=oVJly/v0L4p7JiFbz87gX/hAz7 KUbB22HeZgcjBaqeplmSWDTUeW1Xub6Dg1Urd0N128i5kZBWlP+YcK8C5SiXTHc2E110D2w9f7l/Z pYzWg2E1RAzwK/xReggEjQDC0YwLUdo/qdq69zB3enmmHRPI8FzXre3WvaxyW3w2bUCX7oJwKm4Mv 4446aB7Ih5dAZp2dwsbjr6+f4t1tretxjF/Y1FBinMfVdAoycZimWHd4MjQmMmwrms5ENgB4nAkeP EcpMbDz3gkb2UOIo9i+EUTvclADL3QihO1A0eF3mEIJL82+b4REa/BnofLpFwYQeCutL0HaThi0AI giiJzyFw==; Received: from out-171.mta0.migadu.com ([91.218.175.171]) by desiato.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uUMRq-00000005jiL-2vAX for linux-arm-kernel@lists.infradead.org; Wed, 25 Jun 2025 09:29:45 +0000 Message-ID: <87f7a9fa-d66e-47ba-b511-a8ffb7e5e057@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1750843769; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5+hfwvWC996r2MUYJpb8A4wnft6Q/V6aycecydJia7U=; b=QfWaEPgLZqoluDZbnVOQJdlxb4l2AandwHyP8Yk+Wte6nX7+dMyPVvU1BClhpV3r9u2Sc0 DlxnnH3UZzTG8Vfv/zt1HhMMHicBQEj++Pi1SPk+EZyWL7x9PfMYuYwO+urQViqTihPKqk g+4Fksb2sqRasmtmBRhkskN9SiZZiMk= Date: Wed, 25 Jun 2025 17:29:12 +0800 MIME-Version: 1.0 Subject: Re: [PATCH v4 3/4] mm: Support batched unmap for lazyfree large folios during reclamation Content-Language: en-US X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Lance Yang To: David Hildenbrand Cc: 21cnbao@gmail.com, akpm@linux-foundation.org, baolin.wang@linux.alibaba.com, chrisl@kernel.org, kasong@tencent.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-riscv@lists.infradead.org, lorenzo.stoakes@oracle.com, ryan.roberts@arm.com, v-songbaohua@oppo.com, x86@kernel.org, ying.huang@intel.com, zhengtangquan@oppo.com, Lance Yang References: <20250624152654.38145-1-ioworker0@gmail.com> <2c19a6cf-0b42-477b-a672-ed8c1edd4267@redhat.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250625_102943_416796_A056E297 X-CRM114-Status: GOOD ( 31.86 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On 2025/6/25 16:44, Lance Yang wrote: > > > On 2025/6/24 23:34, David Hildenbrand wrote: >> On 24.06.25 17:26, Lance Yang wrote: >>> On 2025/6/24 20:55, David Hildenbrand wrote: >>>> On 14.02.25 10:30, Barry Song wrote: >>>>> From: Barry Song >>> [...] >>>>> diff --git a/mm/rmap.c b/mm/rmap.c >>>>> index 89e51a7a9509..8786704bd466 100644 >>>>> --- a/mm/rmap.c >>>>> +++ b/mm/rmap.c >>>>> @@ -1781,6 +1781,25 @@ void folio_remove_rmap_pud(struct folio *folio, >>>>> struct page *page, >>>>>    #endif >>>>>    } >>>>> +/* We support batch unmapping of PTEs for lazyfree large folios */ >>>>> +static inline bool can_batch_unmap_folio_ptes(unsigned long addr, >>>>> +            struct folio *folio, pte_t *ptep) >>>>> +{ >>>>> +    const fpb_t fpb_flags = FPB_IGNORE_DIRTY | FPB_IGNORE_SOFT_DIRTY; >>>>> +    int max_nr = folio_nr_pages(folio); >>>> >>>> Let's assume we have the first page of a folio mapped at the last page >>>> table entry in our page table. >>> >>> Good point. I'm curious if it is something we've seen in practice ;) >> >> I challenge you to write a reproducer :P I assume it might be doable >> through simple mremap(). > > Yes! The scenario is indeed reproducible from userspace ;p > > First, I get a 64KB folio by allocating a large anonymous mapping and > advising the kernel with madvise(MADV_HUGEPAGE). After faulting in the > pages, /proc/self/pagemap confirms the PFNs are contiguous. > > Then, the key is to use mremap() with MREMAP_FIXED to move the folio to > a virtual address that crosses a PMD boundary. Doing so ensures the > physically contiguous folio is mapped by PTEs from two different page > tables. Forgot to add: The mTHP split counters didn't change during the mremap, which confirms the large folio was only remapped, not split. Thanks, Lance > > The C reproducer is attached. It was tested on a system with 64KB mTHP > enabled (in madvise mode). Please correct me if I'm wrong ;) > > > ``` > #define _GNU_SOURCE > #include > #include > #include > #include > #include > #include > #include > #include > #include > > #define PAGE_SIZE ((size_t)sysconf(_SC_PAGESIZE)) > #define FOLIO_SIZE (64 * 1024) > #define NUM_PAGES_IN_FOLIO (FOLIO_SIZE / PAGE_SIZE) > #define PMD_SIZE (2 * 1024 * 1024) > > int get_pagemap_entry(uint64_t *entry, int pagemap_fd, uintptr_t vaddr) { >     size_t offset = (vaddr / PAGE_SIZE) * sizeof(uint64_t); >     if (pread(pagemap_fd, entry, sizeof(uint64_t), offset) != > sizeof(uint64_t)) { >         perror("pread pagemap"); >         return -1; >     } >     return 0; > } > > int is_page_present(uint64_t entry) { return (entry >> 63) & 1; } > uint64_t get_pfn(uint64_t entry) { return entry & ((1ULL << 55) - 1); } > > bool verify_contiguity(int pagemap_fd, uintptr_t vaddr, size_t size, > const char *label) { >     printf("\n--- Verifying Contiguity for: %s at 0x%lx ---\n", label, > vaddr); >     printf("Page |      Virtual Address      | Present |   PFN > (Physical)   | Contiguous?\n"); > > printf("-----+---------------------------+---------+-------------------- > +-------------\n"); > >     uint64_t first_pfn = 0; >     bool is_contiguous = true; >     int num_pages = size / PAGE_SIZE; > >     for (int i = 0; i < num_pages; ++i) { >         uintptr_t current_vaddr = vaddr + i * PAGE_SIZE; >         uint64_t pagemap_entry; > >         if (get_pagemap_entry(&pagemap_entry, pagemap_fd, > current_vaddr) != 0) { >             is_contiguous = false; >             break; >         } > >         if (!is_page_present(pagemap_entry)) { >             printf(" %2d  | 0x%016lx |    No   |        N/A         | > Error\n", i, current_vaddr); >             is_contiguous = false; >             continue; >         } > >         uint64_t pfn = get_pfn(pagemap_entry); >         char contiguous_str[4] = "Yes"; > >         if (i == 0) { >             first_pfn = pfn; >         } else { >             if (pfn != first_pfn + i) { >                 strcpy(contiguous_str, "No!"); >                 is_contiguous = false; >             } >         } > >         printf(" %2d  | 0x%016lx |   Yes   | 0x%-16lx |     %s\n", i, > current_vaddr, pfn, contiguous_str); >     } > >     if (is_contiguous) { >         printf("Verification PASSED: PFNs are contiguous for %s.\n", > label); >     } else { >         printf("Verification FAILED: PFNs are NOT contiguous for %s. > \n", label); >     } >     return is_contiguous; > } > > > int main(void) { >     printf("--- Folio-across-PMD-boundary reproducer ---\n"); >     printf("Page size: %zu KB, Folio size: %zu KB, PMD coverage: %zu > MB\n", >            PAGE_SIZE / 1024, FOLIO_SIZE / 1024, PMD_SIZE / (1024 * 1024)); > >     size_t source_size = 4 * 1024 * 1024; >     void *source_addr = mmap(NULL, source_size, PROT_READ | PROT_WRITE, >                              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); >     if (source_addr == MAP_FAILED) { >         perror("mmap source"); exit(EXIT_FAILURE); >     } >     printf("\n1. Source memory mapped at: %p\n", source_addr); > >     if (madvise(source_addr, source_size, MADV_HUGEPAGE) != 0) { >         perror("madvise MADV_HUGEPAGE"); >     } >     printf("2. Advised kernel to use large folios (MADV_HUGEPAGE).\n"); > >     memset(source_addr, 'A', source_size); >     printf("3. Faulted in source pages.\n"); > >     int pagemap_fd = open("/proc/self/pagemap", O_RDONLY); >     if (pagemap_fd < 0) { >         perror("open /proc/self/pagemap"); >         exit(EXIT_FAILURE); >     } > >     if (!verify_contiguity(pagemap_fd, (uintptr_t)source_addr, > FOLIO_SIZE, "Source Address (pre-mremap)")) { >         fprintf(stderr, "\nInitial folio allocation failed. Cannot > proceed.\n"); >         close(pagemap_fd); >         munmap(source_addr, source_size); >         exit(EXIT_FAILURE); >     } > >     uintptr_t search_base = 0x10000000000UL; >     uintptr_t pmd_boundary = (search_base + PMD_SIZE) & ~(PMD_SIZE - 1); >     uintptr_t target_vaddr = pmd_boundary - PAGE_SIZE; >     printf("\n5. Calculated target address to be 0x%lx\n", target_vaddr); > >     munmap((void *)target_vaddr, FOLIO_SIZE); >     void *new_addr = mremap(source_addr, FOLIO_SIZE, FOLIO_SIZE, > MREMAP_MAYMOVE | MREMAP_FIXED, (void *)target_vaddr); >     if (new_addr == MAP_FAILED) { >         perror("mremap"); >         close(pagemap_fd); >         exit(EXIT_FAILURE); >     } >     printf("6. Successfully mremap'd %zu KB to 0x%lx.\n", FOLIO_SIZE / > 1024, (uintptr_t)new_addr); > >     bool final_success = verify_contiguity(pagemap_fd, > (uintptr_t)new_addr, FOLIO_SIZE, "Target Address (post-mremap)"); > >     printf("\n--- Final Conclusion ---\n"); >     if (final_success) { >         printf("✅ SUCCESS: The folio's pages remained physically > contiguous after remapping to a PMD-crossing virtual address.\n"); >         printf("   The reproducer successfully created the desired > edge-case memory layout.\n"); >     } else { >         printf("❌ UNEXPECTED FAILURE: The pages were not contiguous > after mremap.\n"); >     } > >     close(pagemap_fd); >     munmap(new_addr, FOLIO_SIZE); > >     return 0; > } > ``` > > $ a.out > > ``` > --- Folio-across-PMD-boundary reproducer --- > Page size: 4 KB, Folio size: 64 KB, PMD coverage: 2 MB > > 1. Source memory mapped at: 0x7f2e41200000 > 2. Advised kernel to use large folios (MADV_HUGEPAGE). > 3. Faulted in source pages. > > --- Verifying Contiguity for: Source Address (pre-mremap) at > 0x7f2e41200000 --- > Page |      Virtual Address      | Present |   PFN (Physical)   | > Contiguous? > -----+---------------------------+---------+-------------------- > +------------- >   0  | 0x00007f2e41200000 |   Yes   | 0x113aa0           |     Yes >   1  | 0x00007f2e41201000 |   Yes   | 0x113aa1           |     Yes >   2  | 0x00007f2e41202000 |   Yes   | 0x113aa2           |     Yes >   3  | 0x00007f2e41203000 |   Yes   | 0x113aa3           |     Yes >   4  | 0x00007f2e41204000 |   Yes   | 0x113aa4           |     Yes >   5  | 0x00007f2e41205000 |   Yes   | 0x113aa5           |     Yes >   6  | 0x00007f2e41206000 |   Yes   | 0x113aa6           |     Yes >   7  | 0x00007f2e41207000 |   Yes   | 0x113aa7           |     Yes >   8  | 0x00007f2e41208000 |   Yes   | 0x113aa8           |     Yes >   9  | 0x00007f2e41209000 |   Yes   | 0x113aa9           |     Yes >  10  | 0x00007f2e4120a000 |   Yes   | 0x113aaa           |     Yes >  11  | 0x00007f2e4120b000 |   Yes   | 0x113aab           |     Yes >  12  | 0x00007f2e4120c000 |   Yes   | 0x113aac           |     Yes >  13  | 0x00007f2e4120d000 |   Yes   | 0x113aad           |     Yes >  14  | 0x00007f2e4120e000 |   Yes   | 0x113aae           |     Yes >  15  | 0x00007f2e4120f000 |   Yes   | 0x113aaf           |     Yes > Verification PASSED: PFNs are contiguous for Source Address (pre-mremap). > > 5. Calculated target address to be 0x100001ff000 > 6. Successfully mremap'd 64 KB to 0x100001ff000. > > --- Verifying Contiguity for: Target Address (post-mremap) at > 0x100001ff000 --- > Page |      Virtual Address      | Present |   PFN (Physical)   | > Contiguous? > -----+---------------------------+---------+-------------------- > +------------- >   0  | 0x00000100001ff000 |   Yes   | 0x113aa0           |     Yes >   1  | 0x0000010000200000 |   Yes   | 0x113aa1           |     Yes >   2  | 0x0000010000201000 |   Yes   | 0x113aa2           |     Yes >   3  | 0x0000010000202000 |   Yes   | 0x113aa3           |     Yes >   4  | 0x0000010000203000 |   Yes   | 0x113aa4           |     Yes >   5  | 0x0000010000204000 |   Yes   | 0x113aa5           |     Yes >   6  | 0x0000010000205000 |   Yes   | 0x113aa6           |     Yes >   7  | 0x0000010000206000 |   Yes   | 0x113aa7           |     Yes >   8  | 0x0000010000207000 |   Yes   | 0x113aa8           |     Yes >   9  | 0x0000010000208000 |   Yes   | 0x113aa9           |     Yes >  10  | 0x0000010000209000 |   Yes   | 0x113aaa           |     Yes >  11  | 0x000001000020a000 |   Yes   | 0x113aab           |     Yes >  12  | 0x000001000020b000 |   Yes   | 0x113aac           |     Yes >  13  | 0x000001000020c000 |   Yes   | 0x113aad           |     Yes >  14  | 0x000001000020d000 |   Yes   | 0x113aae           |     Yes >  15  | 0x000001000020e000 |   Yes   | 0x113aaf           |     Yes > Verification PASSED: PFNs are contiguous for Target Address (post-mremap). > > --- Final Conclusion --- > ✅ SUCCESS: The folio's pages remained physically contiguous after > remapping to a PMD-crossing virtual address. >    The reproducer successfully created the desired edge-case memory > layout. > ``` > Thanks, > Lance > >> >>> >>>> >>>> What prevents folio_pte_batch() from reading outside the page table? >>> >>> Assuming such a scenario is possible, to prevent any chance of an >>> out-of-bounds read, how about this change: >>> >>> diff --git a/mm/rmap.c b/mm/rmap.c >>> index fb63d9256f09..9aeae811a38b 100644 >>> --- a/mm/rmap.c >>> +++ b/mm/rmap.c >>> @@ -1852,6 +1852,25 @@ static inline bool >>> can_batch_unmap_folio_ptes(unsigned long addr, >>>       const fpb_t fpb_flags = FPB_IGNORE_DIRTY | FPB_IGNORE_SOFT_DIRTY; >>>       int max_nr = folio_nr_pages(folio); >>>       pte_t pte = ptep_get(ptep); >>> +    unsigned long end_addr; >>> + >>> +    /* >>> +     * To batch unmap, the entire folio's PTEs must be contiguous >>> +     * and mapped within the same PTE page table, which corresponds to >>> +     * a single PMD entry. Before calling folio_pte_batch(), which does >>> +     * not perform boundary checks itself, we must verify that the >>> +     * address range covered by the folio does not cross a PMD >>> boundary. >>> +     */ >>> +    end_addr = addr + (max_nr * PAGE_SIZE) - 1; >>> + >>> +    /* >>> +     * A fast way to check for a PMD boundary cross is to align both >>> +     * the start and end addresses to the PMD boundary and see if they >>> +     * are different. If they are, the range spans across at least two >>> +     * different PMD-managed regions. >>> +     */ >>> +    if ((addr & PMD_MASK) != (end_addr & PMD_MASK)) >>> +        return false; >> >> You should not be messing with max_nr = folio_nr_pages(folio) here at >> all. folio_pte_batch() takes care of that. >> >> Also, way too many comments ;) >> >> You may only batch within a single VMA and within a single page table. >> >> So simply align the addr up to the next PMD, and make sure it does not >> exceed the vma end. >> >> ALIGN and friends can help avoiding excessive comments. >> > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 67AB1C7EE30 for ; Wed, 25 Jun 2025 10:53:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:References:Cc:To:From:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=5lHY5WehvxwXV31gUYF/uNi8/t0o3C3lsgkffMre3SI=; b=bXxPgMsdzBt+Di IUuaDLpWNA1MMDP6OdrWm9u9BOguIOGPC21BY7lDp2TWtdSk34MBkJoWvRbxn9lDgFFC/ysJ7fEnS WhpzsKFm0BYdHbO7mDoBgVT4TwCNuqVzITKDU/GAXDr38JAwqVg+XdHKmRCXFU8SgDVM7I/fQLRAg 6APmsBB8h1Xo5PvG8BoCEIXeHfrIjPRCI7et2iIQbtluIvo4nFZUWKfAevvCuxybErwYvF9DaWcjt qMVFpH6R13L6zjHhuDDa5JhQ39h8zM/i7COFbXjrOb8MCDA6yOiwZmtSmt18wLdT8c3Ua8eTx5TQf MUFcKTD7nlbqRcnIhTbA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uUNl7-00000008NP1-49x0; Wed, 25 Jun 2025 10:53:41 +0000 Received: from out-173.mta0.migadu.com ([2001:41d0:1004:224b::ad]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uUMRh-000000088FZ-1I45 for linux-riscv@lists.infradead.org; Wed, 25 Jun 2025 09:29:35 +0000 Message-ID: <87f7a9fa-d66e-47ba-b511-a8ffb7e5e057@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1750843769; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5+hfwvWC996r2MUYJpb8A4wnft6Q/V6aycecydJia7U=; b=QfWaEPgLZqoluDZbnVOQJdlxb4l2AandwHyP8Yk+Wte6nX7+dMyPVvU1BClhpV3r9u2Sc0 DlxnnH3UZzTG8Vfv/zt1HhMMHicBQEj++Pi1SPk+EZyWL7x9PfMYuYwO+urQViqTihPKqk g+4Fksb2sqRasmtmBRhkskN9SiZZiMk= Date: Wed, 25 Jun 2025 17:29:12 +0800 MIME-Version: 1.0 Subject: Re: [PATCH v4 3/4] mm: Support batched unmap for lazyfree large folios during reclamation Content-Language: en-US X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Lance Yang To: David Hildenbrand Cc: 21cnbao@gmail.com, akpm@linux-foundation.org, baolin.wang@linux.alibaba.com, chrisl@kernel.org, kasong@tencent.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-riscv@lists.infradead.org, lorenzo.stoakes@oracle.com, ryan.roberts@arm.com, v-songbaohua@oppo.com, x86@kernel.org, ying.huang@intel.com, zhengtangquan@oppo.com, Lance Yang References: <20250624152654.38145-1-ioworker0@gmail.com> <2c19a6cf-0b42-477b-a672-ed8c1edd4267@redhat.com> In-Reply-To: X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250625_022934_033864_D4615F20 X-CRM114-Status: GOOD ( 30.89 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org CgpPbiAyMDI1LzYvMjUgMTY6NDQsIExhbmNlIFlhbmcgd3JvdGU6Cj4gCj4gCj4gT24gMjAyNS82 LzI0IDIzOjM0LCBEYXZpZCBIaWxkZW5icmFuZCB3cm90ZToKPj4gT24gMjQuMDYuMjUgMTc6MjYs IExhbmNlIFlhbmcgd3JvdGU6Cj4+PiBPbiAyMDI1LzYvMjQgMjA6NTUsIERhdmlkIEhpbGRlbmJy YW5kIHdyb3RlOgo+Pj4+IE9uIDE0LjAyLjI1IDEwOjMwLCBCYXJyeSBTb25nIHdyb3RlOgo+Pj4+ PiBGcm9tOiBCYXJyeSBTb25nIDx2LXNvbmdiYW9odWFAb3Bwby5jb20+Cj4+PiBbLi4uXQo+Pj4+ PiBkaWZmIC0tZ2l0IGEvbW0vcm1hcC5jIGIvbW0vcm1hcC5jCj4+Pj4+IGluZGV4IDg5ZTUxYTdh OTUwOS4uODc4NjcwNGJkNDY2IDEwMDY0NAo+Pj4+PiAtLS0gYS9tbS9ybWFwLmMKPj4+Pj4gKysr IGIvbW0vcm1hcC5jCj4+Pj4+IEBAIC0xNzgxLDYgKzE3ODEsMjUgQEAgdm9pZCBmb2xpb19yZW1v dmVfcm1hcF9wdWQoc3RydWN0IGZvbGlvICpmb2xpbywKPj4+Pj4gc3RydWN0IHBhZ2UgKnBhZ2Us Cj4+Pj4+IMKgwqAgI2VuZGlmCj4+Pj4+IMKgwqAgfQo+Pj4+PiArLyogV2Ugc3VwcG9ydCBiYXRj aCB1bm1hcHBpbmcgb2YgUFRFcyBmb3IgbGF6eWZyZWUgbGFyZ2UgZm9saW9zICovCj4+Pj4+ICtz dGF0aWMgaW5saW5lIGJvb2wgY2FuX2JhdGNoX3VubWFwX2ZvbGlvX3B0ZXModW5zaWduZWQgbG9u ZyBhZGRyLAo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3QgZm9saW8gKmZvbGlv LCBwdGVfdCAqcHRlcCkKPj4+Pj4gK3sKPj4+Pj4gK8KgwqDCoCBjb25zdCBmcGJfdCBmcGJfZmxh Z3MgPSBGUEJfSUdOT1JFX0RJUlRZIHwgRlBCX0lHTk9SRV9TT0ZUX0RJUlRZOwo+Pj4+PiArwqDC oMKgIGludCBtYXhfbnIgPSBmb2xpb19ucl9wYWdlcyhmb2xpbyk7Cj4+Pj4KPj4+PiBMZXQncyBh c3N1bWUgd2UgaGF2ZSB0aGUgZmlyc3QgcGFnZSBvZiBhIGZvbGlvIG1hcHBlZCBhdCB0aGUgbGFz dCBwYWdlCj4+Pj4gdGFibGUgZW50cnkgaW4gb3VyIHBhZ2UgdGFibGUuCj4+Pgo+Pj4gR29vZCBw b2ludC4gSSdtIGN1cmlvdXMgaWYgaXQgaXMgc29tZXRoaW5nIHdlJ3ZlIHNlZW4gaW4gcHJhY3Rp Y2UgOykKPj4KPj4gSSBjaGFsbGVuZ2UgeW91IHRvIHdyaXRlIGEgcmVwcm9kdWNlciA6UCBJIGFz c3VtZSBpdCBtaWdodCBiZSBkb2FibGUgCj4+IHRocm91Z2ggc2ltcGxlIG1yZW1hcCgpLgo+IAo+ IFllcyEgVGhlIHNjZW5hcmlvIGlzIGluZGVlZCByZXByb2R1Y2libGUgZnJvbSB1c2Vyc3BhY2Ug O3AKPiAKPiBGaXJzdCwgSSBnZXQgYSA2NEtCIGZvbGlvIGJ5IGFsbG9jYXRpbmcgYSBsYXJnZSBh bm9ueW1vdXMgbWFwcGluZyBhbmQKPiBhZHZpc2luZyB0aGUga2VybmVsIHdpdGggbWFkdmlzZShN QURWX0hVR0VQQUdFKS4gQWZ0ZXIgZmF1bHRpbmcgaW4gdGhlCj4gcGFnZXMsIC9wcm9jL3NlbGYv cGFnZW1hcCBjb25maXJtcyB0aGUgUEZOcyBhcmUgY29udGlndW91cy4KPiAKPiBUaGVuLCB0aGUg a2V5IGlzIHRvIHVzZSBtcmVtYXAoKSB3aXRoIE1SRU1BUF9GSVhFRCB0byBtb3ZlIHRoZSBmb2xp byB0bwo+IGEgdmlydHVhbCBhZGRyZXNzIHRoYXQgY3Jvc3NlcyBhIFBNRCBib3VuZGFyeS4gRG9p bmcgc28gZW5zdXJlcyB0aGUKPiBwaHlzaWNhbGx5IGNvbnRpZ3VvdXMgZm9saW8gaXMgbWFwcGVk IGJ5IFBURXMgZnJvbSB0d28gZGlmZmVyZW50IHBhZ2UKPiB0YWJsZXMuCgpGb3Jnb3QgdG8gYWRk OgoKVGhlIG1USFAgc3BsaXQgY291bnRlcnMgZGlkbid0IGNoYW5nZSBkdXJpbmcgdGhlIG1yZW1h cCwgd2hpY2ggY29uZmlybXMKdGhlIGxhcmdlIGZvbGlvIHdhcyBvbmx5IHJlbWFwcGVkLCBub3Qg c3BsaXQuCgpUaGFua3MsCkxhbmNlCgo+IAo+IFRoZSBDIHJlcHJvZHVjZXIgaXMgYXR0YWNoZWQu IEl0IHdhcyB0ZXN0ZWQgb24gYSBzeXN0ZW0gd2l0aCA2NEtCIG1USFAKPiBlbmFibGVkIChpbiBt YWR2aXNlIG1vZGUpLiBQbGVhc2UgY29ycmVjdCBtZSBpZiBJJ20gd3JvbmcgOykKPiAKPiAKPiBg YGAKPiAjZGVmaW5lIF9HTlVfU09VUkNFCj4gI2luY2x1ZGUgPHN0ZGlvLmg+Cj4gI2luY2x1ZGUg PHN0ZGxpYi5oPgo+ICNpbmNsdWRlIDxzdHJpbmcuaD4KPiAjaW5jbHVkZSA8c3RkaW50Lmg+Cj4g I2luY2x1ZGUgPHVuaXN0ZC5oPgo+ICNpbmNsdWRlIDxmY250bC5oPgo+ICNpbmNsdWRlIDxlcnJu by5oPgo+ICNpbmNsdWRlIDxzeXMvbW1hbi5oPgo+ICNpbmNsdWRlIDxzdGRib29sLmg+Cj4gCj4g I2RlZmluZSBQQUdFX1NJWkUgKChzaXplX3Qpc3lzY29uZihfU0NfUEFHRVNJWkUpKQo+ICNkZWZp bmUgRk9MSU9fU0laRSAoNjQgKiAxMDI0KQo+ICNkZWZpbmUgTlVNX1BBR0VTX0lOX0ZPTElPIChG T0xJT19TSVpFIC8gUEFHRV9TSVpFKQo+ICNkZWZpbmUgUE1EX1NJWkUgKDIgKiAxMDI0ICogMTAy NCkKPiAKPiBpbnQgZ2V0X3BhZ2VtYXBfZW50cnkodWludDY0X3QgKmVudHJ5LCBpbnQgcGFnZW1h cF9mZCwgdWludHB0cl90IHZhZGRyKSB7Cj4gIMKgwqDCoCBzaXplX3Qgb2Zmc2V0ID0gKHZhZGRy IC8gUEFHRV9TSVpFKSAqIHNpemVvZih1aW50NjRfdCk7Cj4gIMKgwqDCoCBpZiAocHJlYWQocGFn ZW1hcF9mZCwgZW50cnksIHNpemVvZih1aW50NjRfdCksIG9mZnNldCkgIT0gCj4gc2l6ZW9mKHVp bnQ2NF90KSkgewo+ICDCoMKgwqDCoMKgwqDCoCBwZXJyb3IoInByZWFkIHBhZ2VtYXAiKTsKPiAg wqDCoMKgwqDCoMKgwqAgcmV0dXJuIC0xOwo+ICDCoMKgwqAgfQo+ICDCoMKgwqAgcmV0dXJuIDA7 Cj4gfQo+IAo+IGludCBpc19wYWdlX3ByZXNlbnQodWludDY0X3QgZW50cnkpIHsgcmV0dXJuIChl bnRyeSA+PiA2MykgJiAxOyB9Cj4gdWludDY0X3QgZ2V0X3Bmbih1aW50NjRfdCBlbnRyeSkgeyBy ZXR1cm4gZW50cnkgJiAoKDFVTEwgPDwgNTUpIC0gMSk7IH0KPiAKPiBib29sIHZlcmlmeV9jb250 aWd1aXR5KGludCBwYWdlbWFwX2ZkLCB1aW50cHRyX3QgdmFkZHIsIHNpemVfdCBzaXplLCAKPiBj b25zdCBjaGFyICpsYWJlbCkgewo+ICDCoMKgwqAgcHJpbnRmKCJcbi0tLSBWZXJpZnlpbmcgQ29u dGlndWl0eSBmb3I6ICVzIGF0IDB4JWx4IC0tLVxuIiwgbGFiZWwsIAo+IHZhZGRyKTsKPiAgwqDC oMKgIHByaW50ZigiUGFnZSB8wqDCoMKgwqDCoCBWaXJ0dWFsIEFkZHJlc3PCoMKgwqDCoMKgIHwg UHJlc2VudCB8wqDCoCBQRk4gCj4gKFBoeXNpY2FsKcKgwqAgfCBDb250aWd1b3VzP1xuIik7Cj4g Cj4gcHJpbnRmKCItLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0t LS0tLS0tLS0tLS0tLS0tLS0tIAo+ICstLS0tLS0tLS0tLS0tXG4iKTsKPiAKPiAgwqDCoMKgIHVp bnQ2NF90IGZpcnN0X3BmbiA9IDA7Cj4gIMKgwqDCoCBib29sIGlzX2NvbnRpZ3VvdXMgPSB0cnVl Owo+ICDCoMKgwqAgaW50IG51bV9wYWdlcyA9IHNpemUgLyBQQUdFX1NJWkU7Cj4gCj4gIMKgwqDC oCBmb3IgKGludCBpID0gMDsgaSA8IG51bV9wYWdlczsgKytpKSB7Cj4gIMKgwqDCoMKgwqDCoMKg IHVpbnRwdHJfdCBjdXJyZW50X3ZhZGRyID0gdmFkZHIgKyBpICogUEFHRV9TSVpFOwo+ICDCoMKg wqDCoMKgwqDCoCB1aW50NjRfdCBwYWdlbWFwX2VudHJ5Owo+IAo+ICDCoMKgwqDCoMKgwqDCoCBp ZiAoZ2V0X3BhZ2VtYXBfZW50cnkoJnBhZ2VtYXBfZW50cnksIHBhZ2VtYXBfZmQsIAo+IGN1cnJl bnRfdmFkZHIpICE9IDApIHsKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpc19jb250aWd1b3Vz ID0gZmFsc2U7Cj4gIMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYnJlYWs7Cj4gIMKgwqDCoMKgwqDC oMKgIH0KPiAKPiAgwqDCoMKgwqDCoMKgwqAgaWYgKCFpc19wYWdlX3ByZXNlbnQocGFnZW1hcF9l bnRyeSkpIHsKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBwcmludGYoIiAlMmTCoCB8IDB4JTAx Nmx4IHzCoMKgwqAgTm/CoMKgIHzCoMKgwqDCoMKgwqDCoCBOL0HCoMKgwqDCoMKgwqDCoMKgIHwg Cj4gRXJyb3JcbiIsIGksIGN1cnJlbnRfdmFkZHIpOwo+ICDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGlzX2NvbnRpZ3VvdXMgPSBmYWxzZTsKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBjb250aW51 ZTsKPiAgwqDCoMKgwqDCoMKgwqAgfQo+IAo+ICDCoMKgwqDCoMKgwqDCoCB1aW50NjRfdCBwZm4g PSBnZXRfcGZuKHBhZ2VtYXBfZW50cnkpOwo+ICDCoMKgwqDCoMKgwqDCoCBjaGFyIGNvbnRpZ3Vv dXNfc3RyWzRdID0gIlllcyI7Cj4gCj4gIMKgwqDCoMKgwqDCoMKgIGlmIChpID09IDApIHsKPiAg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBmaXJzdF9wZm4gPSBwZm47Cj4gIMKgwqDCoMKgwqDCoMKg IH0gZWxzZSB7Cj4gIMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKHBmbiAhPSBmaXJzdF9wZm4g KyBpKSB7Cj4gIMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJjcHkoY29udGlndW91 c19zdHIsICJObyEiKTsKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlzX2NvbnRp Z3VvdXMgPSBmYWxzZTsKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4gIMKgwqDCoMKgwqDC oMKgIH0KPiAKPiAgwqDCoMKgwqDCoMKgwqAgcHJpbnRmKCIgJTJkwqAgfCAweCUwMTZseCB8wqDC oCBZZXPCoMKgIHwgMHglLTE2bHggfMKgwqDCoMKgICVzXG4iLCBpLCAKPiBjdXJyZW50X3ZhZGRy LCBwZm4sIGNvbnRpZ3VvdXNfc3RyKTsKPiAgwqDCoMKgIH0KPiAKPiAgwqDCoMKgIGlmIChpc19j b250aWd1b3VzKSB7Cj4gIMKgwqDCoMKgwqDCoMKgIHByaW50ZigiVmVyaWZpY2F0aW9uIFBBU1NF RDogUEZOcyBhcmUgY29udGlndW91cyBmb3IgJXMuXG4iLCAKPiBsYWJlbCk7Cj4gIMKgwqDCoCB9 IGVsc2Ugewo+ICDCoMKgwqDCoMKgwqDCoCBwcmludGYoIlZlcmlmaWNhdGlvbiBGQUlMRUQ6IFBG TnMgYXJlIE5PVCBjb250aWd1b3VzIGZvciAlcy4gCj4gXG4iLCBsYWJlbCk7Cj4gIMKgwqDCoCB9 Cj4gIMKgwqDCoCByZXR1cm4gaXNfY29udGlndW91czsKPiB9Cj4gCj4gCj4gaW50IG1haW4odm9p ZCkgewo+ICDCoMKgwqAgcHJpbnRmKCItLS0gRm9saW8tYWNyb3NzLVBNRC1ib3VuZGFyeSByZXBy b2R1Y2VyIC0tLVxuIik7Cj4gIMKgwqDCoCBwcmludGYoIlBhZ2Ugc2l6ZTogJXp1IEtCLCBGb2xp byBzaXplOiAlenUgS0IsIFBNRCBjb3ZlcmFnZTogJXp1IAo+IE1CXG4iLAo+ICDCoMKgwqDCoMKg wqDCoMKgwqDCoCBQQUdFX1NJWkUgLyAxMDI0LCBGT0xJT19TSVpFIC8gMTAyNCwgUE1EX1NJWkUg LyAoMTAyNCAqIDEwMjQpKTsKPiAKPiAgwqDCoMKgIHNpemVfdCBzb3VyY2Vfc2l6ZSA9IDQgKiAx MDI0ICogMTAyNDsKPiAgwqDCoMKgIHZvaWQgKnNvdXJjZV9hZGRyID0gbW1hcChOVUxMLCBzb3Vy Y2Vfc2l6ZSwgUFJPVF9SRUFEIHwgUFJPVF9XUklURSwKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgTUFQX1BSSVZBVEUgfCBNQVBfQU5P TllNT1VTLCAtMSwgMCk7Cj4gIMKgwqDCoCBpZiAoc291cmNlX2FkZHIgPT0gTUFQX0ZBSUxFRCkg ewo+ICDCoMKgwqDCoMKgwqDCoCBwZXJyb3IoIm1tYXAgc291cmNlIik7IGV4aXQoRVhJVF9GQUlM VVJFKTsKPiAgwqDCoMKgIH0KPiAgwqDCoMKgIHByaW50ZigiXG4xLiBTb3VyY2UgbWVtb3J5IG1h cHBlZCBhdDogJXBcbiIsIHNvdXJjZV9hZGRyKTsKPiAKPiAgwqDCoMKgIGlmIChtYWR2aXNlKHNv dXJjZV9hZGRyLCBzb3VyY2Vfc2l6ZSwgTUFEVl9IVUdFUEFHRSkgIT0gMCkgewo+ICDCoMKgwqDC oMKgwqDCoCBwZXJyb3IoIm1hZHZpc2UgTUFEVl9IVUdFUEFHRSIpOwo+ICDCoMKgwqAgfQo+ICDC oMKgwqAgcHJpbnRmKCIyLiBBZHZpc2VkIGtlcm5lbCB0byB1c2UgbGFyZ2UgZm9saW9zIChNQURW X0hVR0VQQUdFKS5cbiIpOwo+IAo+ICDCoMKgwqAgbWVtc2V0KHNvdXJjZV9hZGRyLCAnQScsIHNv dXJjZV9zaXplKTsKPiAgwqDCoMKgIHByaW50ZigiMy4gRmF1bHRlZCBpbiBzb3VyY2UgcGFnZXMu XG4iKTsKPiAKPiAgwqDCoMKgIGludCBwYWdlbWFwX2ZkID0gb3BlbigiL3Byb2Mvc2VsZi9wYWdl bWFwIiwgT19SRE9OTFkpOwo+ICDCoMKgwqAgaWYgKHBhZ2VtYXBfZmQgPCAwKSB7Cj4gIMKgwqDC oMKgwqDCoMKgIHBlcnJvcigib3BlbiAvcHJvYy9zZWxmL3BhZ2VtYXAiKTsKPiAgwqDCoMKgwqDC oMKgwqAgZXhpdChFWElUX0ZBSUxVUkUpOwo+ICDCoMKgwqAgfQo+IAo+ICDCoMKgwqAgaWYgKCF2 ZXJpZnlfY29udGlndWl0eShwYWdlbWFwX2ZkLCAodWludHB0cl90KXNvdXJjZV9hZGRyLCAKPiBG T0xJT19TSVpFLCAiU291cmNlIEFkZHJlc3MgKHByZS1tcmVtYXApIikpIHsKPiAgwqDCoMKgwqDC oMKgwqAgZnByaW50ZihzdGRlcnIsICJcbkluaXRpYWwgZm9saW8gYWxsb2NhdGlvbiBmYWlsZWQu IENhbm5vdCAKPiBwcm9jZWVkLlxuIik7Cj4gIMKgwqDCoMKgwqDCoMKgIGNsb3NlKHBhZ2VtYXBf ZmQpOwo+ICDCoMKgwqDCoMKgwqDCoCBtdW5tYXAoc291cmNlX2FkZHIsIHNvdXJjZV9zaXplKTsK PiAgwqDCoMKgwqDCoMKgwqAgZXhpdChFWElUX0ZBSUxVUkUpOwo+ICDCoMKgwqAgfQo+IAo+ICDC oMKgwqAgdWludHB0cl90IHNlYXJjaF9iYXNlID0gMHgxMDAwMDAwMDAwMFVMOwo+ICDCoMKgwqAg dWludHB0cl90IHBtZF9ib3VuZGFyeSA9IChzZWFyY2hfYmFzZSArIFBNRF9TSVpFKSAmIH4oUE1E X1NJWkUgLSAxKTsKPiAgwqDCoMKgIHVpbnRwdHJfdCB0YXJnZXRfdmFkZHIgPSBwbWRfYm91bmRh cnkgLSBQQUdFX1NJWkU7Cj4gIMKgwqDCoCBwcmludGYoIlxuNS4gQ2FsY3VsYXRlZCB0YXJnZXQg YWRkcmVzcyB0byBiZSAweCVseFxuIiwgdGFyZ2V0X3ZhZGRyKTsKPiAKPiAgwqDCoMKgIG11bm1h cCgodm9pZCAqKXRhcmdldF92YWRkciwgRk9MSU9fU0laRSk7Cj4gIMKgwqDCoCB2b2lkICpuZXdf YWRkciA9IG1yZW1hcChzb3VyY2VfYWRkciwgRk9MSU9fU0laRSwgRk9MSU9fU0laRSwgCj4gTVJF TUFQX01BWU1PVkUgfCBNUkVNQVBfRklYRUQsICh2b2lkICopdGFyZ2V0X3ZhZGRyKTsKPiAgwqDC oMKgIGlmIChuZXdfYWRkciA9PSBNQVBfRkFJTEVEKSB7Cj4gIMKgwqDCoMKgwqDCoMKgIHBlcnJv cigibXJlbWFwIik7Cj4gIMKgwqDCoMKgwqDCoMKgIGNsb3NlKHBhZ2VtYXBfZmQpOwo+ICDCoMKg wqDCoMKgwqDCoCBleGl0KEVYSVRfRkFJTFVSRSk7Cj4gIMKgwqDCoCB9Cj4gIMKgwqDCoCBwcmlu dGYoIjYuIFN1Y2Nlc3NmdWxseSBtcmVtYXAnZCAlenUgS0IgdG8gMHglbHguXG4iLCBGT0xJT19T SVpFIC8gCj4gMTAyNCwgKHVpbnRwdHJfdCluZXdfYWRkcik7Cj4gCj4gIMKgwqDCoCBib29sIGZp bmFsX3N1Y2Nlc3MgPSB2ZXJpZnlfY29udGlndWl0eShwYWdlbWFwX2ZkLCAKPiAodWludHB0cl90 KW5ld19hZGRyLCBGT0xJT19TSVpFLCAiVGFyZ2V0IEFkZHJlc3MgKHBvc3QtbXJlbWFwKSIpOwo+ IAo+ICDCoMKgwqAgcHJpbnRmKCJcbi0tLSBGaW5hbCBDb25jbHVzaW9uIC0tLVxuIik7Cj4gIMKg wqDCoCBpZiAoZmluYWxfc3VjY2Vzcykgewo+ICDCoMKgwqDCoMKgwqDCoCBwcmludGYoIuKchSBT VUNDRVNTOiBUaGUgZm9saW8ncyBwYWdlcyByZW1haW5lZCBwaHlzaWNhbGx5IAo+IGNvbnRpZ3Vv dXMgYWZ0ZXIgcmVtYXBwaW5nIHRvIGEgUE1ELWNyb3NzaW5nIHZpcnR1YWwgYWRkcmVzcy5cbiIp Owo+ICDCoMKgwqDCoMKgwqDCoCBwcmludGYoIsKgwqAgVGhlIHJlcHJvZHVjZXIgc3VjY2Vzc2Z1 bGx5IGNyZWF0ZWQgdGhlIGRlc2lyZWQgCj4gZWRnZS1jYXNlIG1lbW9yeSBsYXlvdXQuXG4iKTsK PiAgwqDCoMKgIH0gZWxzZSB7Cj4gIMKgwqDCoMKgwqDCoMKgIHByaW50Zigi4p2MIFVORVhQRUNU RUQgRkFJTFVSRTogVGhlIHBhZ2VzIHdlcmUgbm90IGNvbnRpZ3VvdXMgCj4gYWZ0ZXIgbXJlbWFw LlxuIik7Cj4gIMKgwqDCoCB9Cj4gCj4gIMKgwqDCoCBjbG9zZShwYWdlbWFwX2ZkKTsKPiAgwqDC oMKgIG11bm1hcChuZXdfYWRkciwgRk9MSU9fU0laRSk7Cj4gCj4gIMKgwqDCoCByZXR1cm4gMDsK PiB9Cj4gYGBgCj4gCj4gJCBhLm91dAo+IAo+IGBgYAo+IC0tLSBGb2xpby1hY3Jvc3MtUE1ELWJv dW5kYXJ5IHJlcHJvZHVjZXIgLS0tCj4gUGFnZSBzaXplOiA0IEtCLCBGb2xpbyBzaXplOiA2NCBL QiwgUE1EIGNvdmVyYWdlOiAyIE1CCj4gCj4gMS4gU291cmNlIG1lbW9yeSBtYXBwZWQgYXQ6IDB4 N2YyZTQxMjAwMDAwCj4gMi4gQWR2aXNlZCBrZXJuZWwgdG8gdXNlIGxhcmdlIGZvbGlvcyAoTUFE Vl9IVUdFUEFHRSkuCj4gMy4gRmF1bHRlZCBpbiBzb3VyY2UgcGFnZXMuCj4gCj4gLS0tIFZlcmlm eWluZyBDb250aWd1aXR5IGZvcjogU291cmNlIEFkZHJlc3MgKHByZS1tcmVtYXApIGF0IAo+IDB4 N2YyZTQxMjAwMDAwIC0tLQo+IFBhZ2UgfMKgwqDCoMKgwqAgVmlydHVhbCBBZGRyZXNzwqDCoMKg wqDCoCB8IFByZXNlbnQgfMKgwqAgUEZOIChQaHlzaWNhbCnCoMKgIHwgCj4gQ29udGlndW91cz8K PiAtLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0t LS0tLS0tLS0tIAo+ICstLS0tLS0tLS0tLS0tCj4gIMKgIDDCoCB8IDB4MDAwMDdmMmU0MTIwMDAw MCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYTDCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAg WWVzCj4gIMKgIDHCoCB8IDB4MDAwMDdmMmU0MTIwMTAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNh YTHCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgIDLCoCB8IDB4MDAwMDdm MmU0MTIwMjAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYTLCoMKgwqDCoMKgwqDCoMKgwqDCoCB8 wqDCoMKgwqAgWWVzCj4gIMKgIDPCoCB8IDB4MDAwMDdmMmU0MTIwMzAwMCB8wqDCoCBZZXPCoMKg IHwgMHgxMTNhYTPCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgIDTCoCB8 IDB4MDAwMDdmMmU0MTIwNDAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYTTCoMKgwqDCoMKgwqDC oMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgIDXCoCB8IDB4MDAwMDdmMmU0MTIwNTAwMCB8wqDC oCBZZXPCoMKgIHwgMHgxMTNhYTXCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4g IMKgIDbCoCB8IDB4MDAwMDdmMmU0MTIwNjAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYTbCoMKg wqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgIDfCoCB8IDB4MDAwMDdmMmU0MTIw NzAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYTfCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKg wqAgWWVzCj4gIMKgIDjCoCB8IDB4MDAwMDdmMmU0MTIwODAwMCB8wqDCoCBZZXPCoMKgIHwgMHgx MTNhYTjCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgIDnCoCB8IDB4MDAw MDdmMmU0MTIwOTAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYTnCoMKgwqDCoMKgwqDCoMKgwqDC oCB8wqDCoMKgwqAgWWVzCj4gIMKgMTDCoCB8IDB4MDAwMDdmMmU0MTIwYTAwMCB8wqDCoCBZZXPC oMKgIHwgMHgxMTNhYWHCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgMTHC oCB8IDB4MDAwMDdmMmU0MTIwYjAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYWLCoMKgwqDCoMKg wqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgMTLCoCB8IDB4MDAwMDdmMmU0MTIwYzAwMCB8 wqDCoCBZZXPCoMKgIHwgMHgxMTNhYWPCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVz Cj4gIMKgMTPCoCB8IDB4MDAwMDdmMmU0MTIwZDAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYWTC oMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gIMKgMTTCoCB8IDB4MDAwMDdmMmU0 MTIwZTAwMCB8wqDCoCBZZXPCoMKgIHwgMHgxMTNhYWXCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDC oMKgwqAgWWVzCj4gIMKgMTXCoCB8IDB4MDAwMDdmMmU0MTIwZjAwMCB8wqDCoCBZZXPCoMKgIHwg MHgxMTNhYWbCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgwqAgWWVzCj4gVmVyaWZpY2F0aW9u IFBBU1NFRDogUEZOcyBhcmUgY29udGlndW91cyBmb3IgU291cmNlIEFkZHJlc3MgKHByZS1tcmVt YXApLgo+IAo+IDUuIENhbGN1bGF0ZWQgdGFyZ2V0IGFkZHJlc3MgdG8gYmUgMHgxMDAwMDFmZjAw MAo+IDYuIFN1Y2Nlc3NmdWxseSBtcmVtYXAnZCA2NCBLQiB0byAweDEwMDAwMWZmMDAwLgo+IAo+ IC0tLSBWZXJpZnlpbmcgQ29udGlndWl0eSBmb3I6IFRhcmdldCBBZGRyZXNzIChwb3N0LW1yZW1h cCkgYXQgCj4gMHgxMDAwMDFmZjAwMCAtLS0KPiBQYWdlIHzCoMKgwqDCoMKgIFZpcnR1YWwgQWRk cmVzc8KgwqDCoMKgwqAgfCBQcmVzZW50IHzCoMKgIFBGTiAoUGh5c2ljYWwpwqDCoCB8IAo+IENv bnRpZ3VvdXM/Cj4gLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSst LS0tLS0tLS0tLS0tLS0tLS0tLSAKPiArLS0tLS0tLS0tLS0tLQo+ICDCoCAwwqAgfCAweDAwMDAw MTAwMDAxZmYwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWEwwqDCoMKgwqDCoMKgwqDCoMKgwqAg fMKgwqDCoMKgIFllcwo+ICDCoCAxwqAgfCAweDAwMDAwMTAwMDAyMDAwMDAgfMKgwqAgWWVzwqDC oCB8IDB4MTEzYWExwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoCAywqAg fCAweDAwMDAwMTAwMDAyMDEwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWEywqDCoMKgwqDCoMKg wqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoCAzwqAgfCAweDAwMDAwMTAwMDAyMDIwMDAgfMKg wqAgWWVzwqDCoCB8IDB4MTEzYWEzwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ ICDCoCA0wqAgfCAweDAwMDAwMTAwMDAyMDMwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWE0wqDC oMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoCA1wqAgfCAweDAwMDAwMTAwMDAy MDQwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWE1wqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDC oMKgIFllcwo+ICDCoCA2wqAgfCAweDAwMDAwMTAwMDAyMDUwMDAgfMKgwqAgWWVzwqDCoCB8IDB4 MTEzYWE2wqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoCA3wqAgfCAweDAw MDAwMTAwMDAyMDYwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWE3wqDCoMKgwqDCoMKgwqDCoMKg wqAgfMKgwqDCoMKgIFllcwo+ICDCoCA4wqAgfCAweDAwMDAwMTAwMDAyMDcwMDAgfMKgwqAgWWVz wqDCoCB8IDB4MTEzYWE4wqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoCA5 wqAgfCAweDAwMDAwMTAwMDAyMDgwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWE5wqDCoMKgwqDC oMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoDEwwqAgfCAweDAwMDAwMTAwMDAyMDkwMDAg fMKgwqAgWWVzwqDCoCB8IDB4MTEzYWFhwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFll cwo+ICDCoDExwqAgfCAweDAwMDAwMTAwMDAyMGEwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWFi wqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoDEywqAgfCAweDAwMDAwMTAw MDAyMGIwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWFjwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKg wqDCoMKgIFllcwo+ICDCoDEzwqAgfCAweDAwMDAwMTAwMDAyMGMwMDAgfMKgwqAgWWVzwqDCoCB8 IDB4MTEzYWFkwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoDE0wqAgfCAw eDAwMDAwMTAwMDAyMGQwMDAgfMKgwqAgWWVzwqDCoCB8IDB4MTEzYWFlwqDCoMKgwqDCoMKgwqDC oMKgwqAgfMKgwqDCoMKgIFllcwo+ICDCoDE1wqAgfCAweDAwMDAwMTAwMDAyMGUwMDAgfMKgwqAg WWVzwqDCoCB8IDB4MTEzYWFmwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoMKgIFllcwo+IFZl cmlmaWNhdGlvbiBQQVNTRUQ6IFBGTnMgYXJlIGNvbnRpZ3VvdXMgZm9yIFRhcmdldCBBZGRyZXNz IChwb3N0LW1yZW1hcCkuCj4gCj4gLS0tIEZpbmFsIENvbmNsdXNpb24gLS0tCj4g4pyFIFNVQ0NF U1M6IFRoZSBmb2xpbydzIHBhZ2VzIHJlbWFpbmVkIHBoeXNpY2FsbHkgY29udGlndW91cyBhZnRl ciAKPiByZW1hcHBpbmcgdG8gYSBQTUQtY3Jvc3NpbmcgdmlydHVhbCBhZGRyZXNzLgo+ICDCoMKg IFRoZSByZXByb2R1Y2VyIHN1Y2Nlc3NmdWxseSBjcmVhdGVkIHRoZSBkZXNpcmVkIGVkZ2UtY2Fz ZSBtZW1vcnkgCj4gbGF5b3V0Lgo+IGBgYAo+IFRoYW5rcywKPiBMYW5jZQo+IAo+Pgo+Pj4KPj4+ Pgo+Pj4+IFdoYXQgcHJldmVudHMgZm9saW9fcHRlX2JhdGNoKCkgZnJvbSByZWFkaW5nIG91dHNp ZGUgdGhlIHBhZ2UgdGFibGU/Cj4+Pgo+Pj4gQXNzdW1pbmcgc3VjaCBhIHNjZW5hcmlvIGlzIHBv c3NpYmxlLCB0byBwcmV2ZW50IGFueSBjaGFuY2Ugb2YgYW4KPj4+IG91dC1vZi1ib3VuZHMgcmVh ZCwgaG93IGFib3V0IHRoaXMgY2hhbmdlOgo+Pj4KPj4+IGRpZmYgLS1naXQgYS9tbS9ybWFwLmMg Yi9tbS9ybWFwLmMKPj4+IGluZGV4IGZiNjNkOTI1NmYwOS4uOWFlYWU4MTFhMzhiIDEwMDY0NAo+ Pj4gLS0tIGEvbW0vcm1hcC5jCj4+PiArKysgYi9tbS9ybWFwLmMKPj4+IEBAIC0xODUyLDYgKzE4 NTIsMjUgQEAgc3RhdGljIGlubGluZSBib29sIAo+Pj4gY2FuX2JhdGNoX3VubWFwX2ZvbGlvX3B0 ZXModW5zaWduZWQgbG9uZyBhZGRyLAo+Pj4gwqDCoMKgwqDCoCBjb25zdCBmcGJfdCBmcGJfZmxh Z3MgPSBGUEJfSUdOT1JFX0RJUlRZIHwgRlBCX0lHTk9SRV9TT0ZUX0RJUlRZOwo+Pj4gwqDCoMKg wqDCoCBpbnQgbWF4X25yID0gZm9saW9fbnJfcGFnZXMoZm9saW8pOwo+Pj4gwqDCoMKgwqDCoCBw dGVfdCBwdGUgPSBwdGVwX2dldChwdGVwKTsKPj4+ICvCoMKgwqAgdW5zaWduZWQgbG9uZyBlbmRf YWRkcjsKPj4+ICsKPj4+ICvCoMKgwqAgLyoKPj4+ICvCoMKgwqDCoCAqIFRvIGJhdGNoIHVubWFw LCB0aGUgZW50aXJlIGZvbGlvJ3MgUFRFcyBtdXN0IGJlIGNvbnRpZ3VvdXMKPj4+ICvCoMKgwqDC oCAqIGFuZCBtYXBwZWQgd2l0aGluIHRoZSBzYW1lIFBURSBwYWdlIHRhYmxlLCB3aGljaCBjb3Jy ZXNwb25kcyB0bwo+Pj4gK8KgwqDCoMKgICogYSBzaW5nbGUgUE1EIGVudHJ5LiBCZWZvcmUgY2Fs bGluZyBmb2xpb19wdGVfYmF0Y2goKSwgd2hpY2ggZG9lcwo+Pj4gK8KgwqDCoMKgICogbm90IHBl cmZvcm0gYm91bmRhcnkgY2hlY2tzIGl0c2VsZiwgd2UgbXVzdCB2ZXJpZnkgdGhhdCB0aGUKPj4+ ICvCoMKgwqDCoCAqIGFkZHJlc3MgcmFuZ2UgY292ZXJlZCBieSB0aGUgZm9saW8gZG9lcyBub3Qg Y3Jvc3MgYSBQTUQgCj4+PiBib3VuZGFyeS4KPj4+ICvCoMKgwqDCoCAqLwo+Pj4gK8KgwqDCoCBl bmRfYWRkciA9IGFkZHIgKyAobWF4X25yICogUEFHRV9TSVpFKSAtIDE7Cj4+PiArCj4+PiArwqDC oMKgIC8qCj4+PiArwqDCoMKgwqAgKiBBIGZhc3Qgd2F5IHRvIGNoZWNrIGZvciBhIFBNRCBib3Vu ZGFyeSBjcm9zcyBpcyB0byBhbGlnbiBib3RoCj4+PiArwqDCoMKgwqAgKiB0aGUgc3RhcnQgYW5k IGVuZCBhZGRyZXNzZXMgdG8gdGhlIFBNRCBib3VuZGFyeSBhbmQgc2VlIGlmIHRoZXkKPj4+ICvC oMKgwqDCoCAqIGFyZSBkaWZmZXJlbnQuIElmIHRoZXkgYXJlLCB0aGUgcmFuZ2Ugc3BhbnMgYWNy b3NzIGF0IGxlYXN0IHR3bwo+Pj4gK8KgwqDCoMKgICogZGlmZmVyZW50IFBNRC1tYW5hZ2VkIHJl Z2lvbnMuCj4+PiArwqDCoMKgwqAgKi8KPj4+ICvCoMKgwqAgaWYgKChhZGRyICYgUE1EX01BU0sp ICE9IChlbmRfYWRkciAmIFBNRF9NQVNLKSkKPj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gZmFs c2U7Cj4+Cj4+IFlvdSBzaG91bGQgbm90IGJlIG1lc3Npbmcgd2l0aCBtYXhfbnIgPSBmb2xpb19u cl9wYWdlcyhmb2xpbykgaGVyZSBhdCAKPj4gYWxsLiBmb2xpb19wdGVfYmF0Y2goKSB0YWtlcyBj YXJlIG9mIHRoYXQuCj4+Cj4+IEFsc28sIHdheSB0b28gbWFueSBjb21tZW50cyA7KQo+Pgo+PiBZ b3UgbWF5IG9ubHkgYmF0Y2ggd2l0aGluIGEgc2luZ2xlIFZNQSBhbmQgd2l0aGluIGEgc2luZ2xl IHBhZ2UgdGFibGUuCj4+Cj4+IFNvIHNpbXBseSBhbGlnbiB0aGUgYWRkciB1cCB0byB0aGUgbmV4 dCBQTUQsIGFuZCBtYWtlIHN1cmUgaXQgZG9lcyBub3QgCj4+IGV4Y2VlZCB0aGUgdm1hIGVuZC4K Pj4KPj4gQUxJR04gYW5kIGZyaWVuZHMgY2FuIGhlbHAgYXZvaWRpbmcgZXhjZXNzaXZlIGNvbW1l bnRzLgo+Pgo+IAoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fCmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51eC1yaXNjdkBsaXN0cy5pbmZyYWRlYWQu b3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcmlz Y3YK