From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ryan Roberts Subject: Re: [PATCH v1 01/10] mm: Expose clear_huge_page() unconditionally Date: Wed, 28 Jun 2023 11:56:50 +0100 Message-ID: References: <20230626171430.3167004-1-ryan.roberts@arm.com> <20230626171430.3167004-2-ryan.roberts@arm.com> <2ff8ccf6-bf36-48b2-7dc2-e6c0d962f8b7@arm.com> <91e3364f-1d1b-f959-636b-4f60bf5a577b@arm.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Return-path: In-Reply-To: List-ID: Content-Type: text/plain; charset="utf-8" To: Yu Zhao Cc: Andrew Morton , "Matthew Wilcox (Oracle)" , "Kirill A. Shutemov" , Yin Fengwei , David Hildenbrand , Catalin Marinas , Will Deacon , Geert Uytterhoeven , Christian Borntraeger , Sven Schnelle , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-alpha@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-ia64@vger.kernel.org, linux-m68k@lists On 27/06/2023 19:26, Yu Zhao wrote: > On Tue, Jun 27, 2023 at 3:41 AM Ryan Roberts wrote: >> >> On 27/06/2023 09:29, Yu Zhao wrote: >>> On Tue, Jun 27, 2023 at 1:21 AM Ryan Roberts wrote: >>>> >>>> On 27/06/2023 02:55, Yu Zhao wrote: >>>>> On Mon, Jun 26, 2023 at 11:14 AM Ryan Roberts wrote: >>>>>> >>>>>> In preparation for extending vma_alloc_zeroed_movable_folio() to >>>>>> allocate a arbitrary order folio, expose clear_huge_page() >>>>>> unconditionally, so that it can be used to zero the allocated folio in >>>>>> the generic implementation of vma_alloc_zeroed_movable_folio(). >>>>>> >>>>>> Signed-off-by: Ryan Roberts >>>>>> --- >>>>>> include/linux/mm.h | 3 ++- >>>>>> mm/memory.c | 2 +- >>>>>> 2 files changed, 3 insertions(+), 2 deletions(-) >>>>>> >>>>>> diff --git a/include/linux/mm.h b/include/linux/mm.h >>>>>> index 7f1741bd870a..7e3bf45e6491 100644 >>>>>> --- a/include/linux/mm.h >>>>>> +++ b/include/linux/mm.h >>>>>> @@ -3684,10 +3684,11 @@ enum mf_action_page_type { >>>>>> */ >>>>>> extern const struct attribute_group memory_failure_attr_group; >>>>>> >>>>>> -#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) >>>>>> extern void clear_huge_page(struct page *page, >>>>>> unsigned long addr_hint, >>>>>> unsigned int pages_per_huge_page); >>>>>> + >>>>>> +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) >>>>> >>>>> We might not want to depend on THP eventually. Right now, we still >>>>> have to, unless splitting is optional, which seems to contradict >>>>> 06/10. (deferred_split_folio() is a nop without THP.) >>>> >>>> Yes, I agree - for large anon folios to work, we depend on THP. But I don't >>>> think that helps us here. >>>> >>>> In the next patch, I give vma_alloc_zeroed_movable_folio() an extra `order` >>>> parameter. So the generic/default version of the function now needs a way to >>>> clear a compound page. >>>> >>>> I guess I could do something like: >>>> >>>> static inline >>>> struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma, >>>> unsigned long vaddr, gfp_t gfp, int order) >>>> { >>>> struct folio *folio; >>>> >>>> folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE | gfp, >>>> order, vma, vaddr, false); >>>> if (folio) { >>>> #ifdef CONFIG_LARGE_FOLIO >>>> clear_huge_page(&folio->page, vaddr, 1U << order); >>>> #else >>>> BUG_ON(order != 0); >>>> clear_user_highpage(&folio->page, vaddr); >>>> #endif >>>> } >>>> >>>> return folio; >>>> } >>>> >>>> But that's pretty messy and there's no reason why other users might come along >>>> that pass order != 0 and will be surprised by the BUG_ON. >>> >>> #ifdef CONFIG_LARGE_ANON_FOLIO // depends on CONFIG_TRANSPARENT_HUGE_PAGE >>> struct folio *alloc_anon_folio(struct vm_area_struct *vma, unsigned >>> long vaddr, int order) >>> { >>> // how do_huge_pmd_anonymous_page() allocs and clears >>> vma_alloc_folio(..., *true*); >> >> This controls the mem allocation policy (see mempolicy.c::vma_alloc_folio()) not >> clearing. Clearing is done in __do_huge_pmd_anonymous_page(): >> >> clear_huge_page(page, vmf->address, HPAGE_PMD_NR); > > Sorry for rushing this previously. This is what I meant. The #ifdef > makes it safe to use clear_huge_page() without 01/10. I highlighted > the last parameter to vma_alloc_folio() only because it's different > from what you chose (not implying it clears the folio).> >>> } >>> #else >>> #define alloc_anon_folio(vma, addr, order) >>> vma_alloc_zeroed_movable_folio(vma, addr) >>> #endif >> >> Sorry I don't get this at all... If you are suggesting to bypass >> vma_alloc_zeroed_movable_folio() entirely for the LARGE_ANON_FOLIO case > > Correct. > >> I don't >> think that works because the arch code adds its own gfp flags there. For >> example, arm64 adds __GFP_ZEROTAGS for VM_MTE VMAs. > > I think it's the opposite: it should be safer to reuse the THP code because > 1. It's an existing case that has been working for PMD_ORDER folios > mapped by PTEs, and it's an arch-independent API which would be easier > to review. > 2. Use vma_alloc_zeroed_movable_folio() for large folios is a *new* > case. It's an arch-*dependent* API which I have no idea what VM_MTE > does (should do) to large folios and don't plan to answer that for > now. I've done some archaology on this now, and convinced myself that your suggestion is a good one - sorry for doubting it! If you are interested here are the details: Only arm64 and ia64 do something non-standard in vma_alloc_zeroed_movable_folio(). ia64 flushes the dcache for the folio - but given it does not support THP this is not a problem for the THP path. arm64 adds the __GFP_ZEROTAGS flag which means that the MTE tags will be zeroed at the same time as the page is zeroed. This is a perf optimization - if its not performed then it will be done at set_pte_at(), which is how this works for the THP path. So on that basis, I agree we can use your proposed alloc_anon_folio() approach. arm64 will lose the MTE optimization but that can be added back later if needed. So no need to unconditionally expose clear_huge_page() and no need to modify all the arch vma_alloc_zeroed_movable_folio() implementations. Thanks, Ryan > >> Perhaps we can do away with an arch-owned vma_alloc_zeroed_movable_folio() and >> replace it with a new arch_get_zeroed_movable_gfp_flags() then >> alloc_anon_folio() add in those flags? >> >> But I still think the cleanest, simplest change is just to unconditionally >> expose clear_huge_page() as I've done it. > > The fundamental choice there as I see it is to whether the first step > of large anon folios should lean toward the THP code base or the base > page code base (I'm a big fan of the answer "Neither -- we should > create something entirely new instead"). My POV is that the THP code > base would allow us to move faster, since it's proven to work for a > very similar case (PMD_ORDER folios mapped by PTEs). 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57D47EB64DA for ; Wed, 28 Jun 2023 10:57:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230424AbjF1K5B (ORCPT ); Wed, 28 Jun 2023 06:57:01 -0400 Received: from foss.arm.com ([217.140.110.172]:53656 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230451AbjF1K4z (ORCPT ); Wed, 28 Jun 2023 06:56:55 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6555AC14; Wed, 28 Jun 2023 03:57:38 -0700 (PDT) Received: from [10.57.76.180] (unknown [10.57.76.180]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BC1553F663; Wed, 28 Jun 2023 03:56:51 -0700 (PDT) Message-ID: Date: Wed, 28 Jun 2023 11:56:50 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: Re: [PATCH v1 01/10] mm: Expose clear_huge_page() unconditionally To: Yu Zhao Cc: Andrew Morton , "Matthew Wilcox (Oracle)" , "Kirill A. Shutemov" , Yin Fengwei , David Hildenbrand , Catalin Marinas , Will Deacon , Geert Uytterhoeven , Christian Borntraeger , Sven Schnelle , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-alpha@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-ia64@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linux-s390@vger.kernel.org References: <20230626171430.3167004-1-ryan.roberts@arm.com> <20230626171430.3167004-2-ryan.roberts@arm.com> <2ff8ccf6-bf36-48b2-7dc2-e6c0d962f8b7@arm.com> <91e3364f-1d1b-f959-636b-4f60bf5a577b@arm.com> From: Ryan Roberts In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-ia64@vger.kernel.org On 27/06/2023 19:26, Yu Zhao wrote: > On Tue, Jun 27, 2023 at 3:41 AM Ryan Roberts wrote: >> >> On 27/06/2023 09:29, Yu Zhao wrote: >>> On Tue, Jun 27, 2023 at 1:21 AM Ryan Roberts wrote: >>>> >>>> On 27/06/2023 02:55, Yu Zhao wrote: >>>>> On Mon, Jun 26, 2023 at 11:14 AM Ryan Roberts wrote: >>>>>> >>>>>> In preparation for extending vma_alloc_zeroed_movable_folio() to >>>>>> allocate a arbitrary order folio, expose clear_huge_page() >>>>>> unconditionally, so that it can be used to zero the allocated folio in >>>>>> the generic implementation of vma_alloc_zeroed_movable_folio(). >>>>>> >>>>>> Signed-off-by: Ryan Roberts >>>>>> --- >>>>>> include/linux/mm.h | 3 ++- >>>>>> mm/memory.c | 2 +- >>>>>> 2 files changed, 3 insertions(+), 2 deletions(-) >>>>>> >>>>>> diff --git a/include/linux/mm.h b/include/linux/mm.h >>>>>> index 7f1741bd870a..7e3bf45e6491 100644 >>>>>> --- a/include/linux/mm.h >>>>>> +++ b/include/linux/mm.h >>>>>> @@ -3684,10 +3684,11 @@ enum mf_action_page_type { >>>>>> */ >>>>>> extern const struct attribute_group memory_failure_attr_group; >>>>>> >>>>>> -#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) >>>>>> extern void clear_huge_page(struct page *page, >>>>>> unsigned long addr_hint, >>>>>> unsigned int pages_per_huge_page); >>>>>> + >>>>>> +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) >>>>> >>>>> We might not want to depend on THP eventually. Right now, we still >>>>> have to, unless splitting is optional, which seems to contradict >>>>> 06/10. (deferred_split_folio() is a nop without THP.) >>>> >>>> Yes, I agree - for large anon folios to work, we depend on THP. But I don't >>>> think that helps us here. >>>> >>>> In the next patch, I give vma_alloc_zeroed_movable_folio() an extra `order` >>>> parameter. So the generic/default version of the function now needs a way to >>>> clear a compound page. >>>> >>>> I guess I could do something like: >>>> >>>> static inline >>>> struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma, >>>> unsigned long vaddr, gfp_t gfp, int order) >>>> { >>>> struct folio *folio; >>>> >>>> folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE | gfp, >>>> order, vma, vaddr, false); >>>> if (folio) { >>>> #ifdef CONFIG_LARGE_FOLIO >>>> clear_huge_page(&folio->page, vaddr, 1U << order); >>>> #else >>>> BUG_ON(order != 0); >>>> clear_user_highpage(&folio->page, vaddr); >>>> #endif >>>> } >>>> >>>> return folio; >>>> } >>>> >>>> But that's pretty messy and there's no reason why other users might come along >>>> that pass order != 0 and will be surprised by the BUG_ON. >>> >>> #ifdef CONFIG_LARGE_ANON_FOLIO // depends on CONFIG_TRANSPARENT_HUGE_PAGE >>> struct folio *alloc_anon_folio(struct vm_area_struct *vma, unsigned >>> long vaddr, int order) >>> { >>> // how do_huge_pmd_anonymous_page() allocs and clears >>> vma_alloc_folio(..., *true*); >> >> This controls the mem allocation policy (see mempolicy.c::vma_alloc_folio()) not >> clearing. Clearing is done in __do_huge_pmd_anonymous_page(): >> >> clear_huge_page(page, vmf->address, HPAGE_PMD_NR); > > Sorry for rushing this previously. This is what I meant. The #ifdef > makes it safe to use clear_huge_page() without 01/10. I highlighted > the last parameter to vma_alloc_folio() only because it's different > from what you chose (not implying it clears the folio).> >>> } >>> #else >>> #define alloc_anon_folio(vma, addr, order) >>> vma_alloc_zeroed_movable_folio(vma, addr) >>> #endif >> >> Sorry I don't get this at all... If you are suggesting to bypass >> vma_alloc_zeroed_movable_folio() entirely for the LARGE_ANON_FOLIO case > > Correct. > >> I don't >> think that works because the arch code adds its own gfp flags there. For >> example, arm64 adds __GFP_ZEROTAGS for VM_MTE VMAs. > > I think it's the opposite: it should be safer to reuse the THP code because > 1. It's an existing case that has been working for PMD_ORDER folios > mapped by PTEs, and it's an arch-independent API which would be easier > to review. > 2. Use vma_alloc_zeroed_movable_folio() for large folios is a *new* > case. It's an arch-*dependent* API which I have no idea what VM_MTE > does (should do) to large folios and don't plan to answer that for > now. I've done some archaology on this now, and convinced myself that your suggestion is a good one - sorry for doubting it! If you are interested here are the details: Only arm64 and ia64 do something non-standard in vma_alloc_zeroed_movable_folio(). ia64 flushes the dcache for the folio - but given it does not support THP this is not a problem for the THP path. arm64 adds the __GFP_ZEROTAGS flag which means that the MTE tags will be zeroed at the same time as the page is zeroed. This is a perf optimization - if its not performed then it will be done at set_pte_at(), which is how this works for the THP path. So on that basis, I agree we can use your proposed alloc_anon_folio() approach. arm64 will lose the MTE optimization but that can be added back later if needed. So no need to unconditionally expose clear_huge_page() and no need to modify all the arch vma_alloc_zeroed_movable_folio() implementations. Thanks, Ryan > >> Perhaps we can do away with an arch-owned vma_alloc_zeroed_movable_folio() and >> replace it with a new arch_get_zeroed_movable_gfp_flags() then >> alloc_anon_folio() add in those flags? >> >> But I still think the cleanest, simplest change is just to unconditionally >> expose clear_huge_page() as I've done it. > > The fundamental choice there as I see it is to whether the first step > of large anon folios should lean toward the THP code base or the base > page code base (I'm a big fan of the answer "Neither -- we should > create something entirely new instead"). My POV is that the THP code > base would allow us to move faster, since it's proven to work for a > very similar case (PMD_ORDER folios mapped by PTEs). 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 C27CDEB64D7 for ; Wed, 28 Jun 2023 10:57:27 +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-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To: 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=IHqeL5mof11w4G57qp2mxppX91hviyIl6P0Xcxii9XQ=; b=KiEJU11b2/DKTa VG4YDHMhKYX9QfvP51XObjY+glZq9RAEhtIvRvsvBlowYZpocUDkkzbRioesXIoeO2tdhnWY+MDuJ wqbmuQVW9B1kc8mZYA2SlZsBaP6WrByXS4N1VY+89hIn7yTmuGjaHKTzOElJFluLeJDC7cBMy4pLh sa130C3GHQ/kJBYLJgFQF3wvR4oKL0S1RYUSUUno7TuFUV1LRF2/CcEfL6QiXTcS5T0Sq8iSHml0m utzoGAyjY92WTLJ04KuWo/LSW/GyKjb3H4SxuH+21n1+RuH3nmGc5ZIVfCV+c/YljztGf0fysGO88 NCO/xafF/Z/vGyQ2iyZw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qESr7-00FTh4-0x; Wed, 28 Jun 2023 10:57:01 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qESr3-00FTd4-2v for linux-arm-kernel@lists.infradead.org; Wed, 28 Jun 2023 10:56:59 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6555AC14; Wed, 28 Jun 2023 03:57:38 -0700 (PDT) Received: from [10.57.76.180] (unknown [10.57.76.180]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BC1553F663; Wed, 28 Jun 2023 03:56:51 -0700 (PDT) Message-ID: Date: Wed, 28 Jun 2023 11:56:50 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: Re: [PATCH v1 01/10] mm: Expose clear_huge_page() unconditionally To: Yu Zhao Cc: Andrew Morton , "Matthew Wilcox (Oracle)" , "Kirill A. Shutemov" , Yin Fengwei , David Hildenbrand , Catalin Marinas , Will Deacon , Geert Uytterhoeven , Christian Borntraeger , Sven Schnelle , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-alpha@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-ia64@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linux-s390@vger.kernel.org References: <20230626171430.3167004-1-ryan.roberts@arm.com> <20230626171430.3167004-2-ryan.roberts@arm.com> <2ff8ccf6-bf36-48b2-7dc2-e6c0d962f8b7@arm.com> <91e3364f-1d1b-f959-636b-4f60bf5a577b@arm.com> From: Ryan Roberts In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230628_035658_060120_2AFC835F X-CRM114-Status: GOOD ( 39.26 ) 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: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gMjcvMDYvMjAyMyAxOToyNiwgWXUgWmhhbyB3cm90ZToKPiBPbiBUdWUsIEp1biAyNywgMjAy MyBhdCAzOjQx4oCvQU0gUnlhbiBSb2JlcnRzIDxyeWFuLnJvYmVydHNAYXJtLmNvbT4gd3JvdGU6 Cj4+Cj4+IE9uIDI3LzA2LzIwMjMgMDk6MjksIFl1IFpoYW8gd3JvdGU6Cj4+PiBPbiBUdWUsIEp1 biAyNywgMjAyMyBhdCAxOjIx4oCvQU0gUnlhbiBSb2JlcnRzIDxyeWFuLnJvYmVydHNAYXJtLmNv bT4gd3JvdGU6Cj4+Pj4KPj4+PiBPbiAyNy8wNi8yMDIzIDAyOjU1LCBZdSBaaGFvIHdyb3RlOgo+ Pj4+PiBPbiBNb24sIEp1biAyNiwgMjAyMyBhdCAxMToxNOKAr0FNIFJ5YW4gUm9iZXJ0cyA8cnlh bi5yb2JlcnRzQGFybS5jb20+IHdyb3RlOgo+Pj4+Pj4KPj4+Pj4+IEluIHByZXBhcmF0aW9uIGZv ciBleHRlbmRpbmcgdm1hX2FsbG9jX3plcm9lZF9tb3ZhYmxlX2ZvbGlvKCkgdG8KPj4+Pj4+IGFs bG9jYXRlIGEgYXJiaXRyYXJ5IG9yZGVyIGZvbGlvLCBleHBvc2UgY2xlYXJfaHVnZV9wYWdlKCkK Pj4+Pj4+IHVuY29uZGl0aW9uYWxseSwgc28gdGhhdCBpdCBjYW4gYmUgdXNlZCB0byB6ZXJvIHRo ZSBhbGxvY2F0ZWQgZm9saW8gaW4KPj4+Pj4+IHRoZSBnZW5lcmljIGltcGxlbWVudGF0aW9uIG9m IHZtYV9hbGxvY196ZXJvZWRfbW92YWJsZV9mb2xpbygpLgo+Pj4+Pj4KPj4+Pj4+IFNpZ25lZC1v ZmYtYnk6IFJ5YW4gUm9iZXJ0cyA8cnlhbi5yb2JlcnRzQGFybS5jb20+Cj4+Pj4+PiAtLS0KPj4+ Pj4+ICBpbmNsdWRlL2xpbnV4L21tLmggfCAzICsrLQo+Pj4+Pj4gIG1tL21lbW9yeS5jICAgICAg ICB8IDIgKy0KPj4+Pj4+ICAyIGZpbGVzIGNoYW5nZWQsIDMgaW5zZXJ0aW9ucygrKSwgMiBkZWxl dGlvbnMoLSkKPj4+Pj4+Cj4+Pj4+PiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9tbS5oIGIv aW5jbHVkZS9saW51eC9tbS5oCj4+Pj4+PiBpbmRleCA3ZjE3NDFiZDg3MGEuLjdlM2JmNDVlNjQ5 MSAxMDA2NDQKPj4+Pj4+IC0tLSBhL2luY2x1ZGUvbGludXgvbW0uaAo+Pj4+Pj4gKysrIGIvaW5j bHVkZS9saW51eC9tbS5oCj4+Pj4+PiBAQCAtMzY4NCwxMCArMzY4NCwxMSBAQCBlbnVtIG1mX2Fj dGlvbl9wYWdlX3R5cGUgewo+Pj4+Pj4gICAqLwo+Pj4+Pj4gIGV4dGVybiBjb25zdCBzdHJ1Y3Qg YXR0cmlidXRlX2dyb3VwIG1lbW9yeV9mYWlsdXJlX2F0dHJfZ3JvdXA7Cj4+Pj4+Pgo+Pj4+Pj4g LSNpZiBkZWZpbmVkKENPTkZJR19UUkFOU1BBUkVOVF9IVUdFUEFHRSkgfHwgZGVmaW5lZChDT05G SUdfSFVHRVRMQkZTKQo+Pj4+Pj4gIGV4dGVybiB2b2lkIGNsZWFyX2h1Z2VfcGFnZShzdHJ1Y3Qg cGFnZSAqcGFnZSwKPj4+Pj4+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBs b25nIGFkZHJfaGludCwKPj4+Pj4+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25l ZCBpbnQgcGFnZXNfcGVyX2h1Z2VfcGFnZSk7Cj4+Pj4+PiArCj4+Pj4+PiArI2lmIGRlZmluZWQo Q09ORklHX1RSQU5TUEFSRU5UX0hVR0VQQUdFKSB8fCBkZWZpbmVkKENPTkZJR19IVUdFVExCRlMp Cj4+Pj4+Cj4+Pj4+IFdlIG1pZ2h0IG5vdCB3YW50IHRvIGRlcGVuZCBvbiBUSFAgZXZlbnR1YWxs eS4gUmlnaHQgbm93LCB3ZSBzdGlsbAo+Pj4+PiBoYXZlIHRvLCB1bmxlc3Mgc3BsaXR0aW5nIGlz IG9wdGlvbmFsLCB3aGljaCBzZWVtcyB0byBjb250cmFkaWN0Cj4+Pj4+IDA2LzEwLiAoZGVmZXJy ZWRfc3BsaXRfZm9saW8oKSAgaXMgYSBub3Agd2l0aG91dCBUSFAuKQo+Pj4+Cj4+Pj4gWWVzLCBJ IGFncmVlIC0gZm9yIGxhcmdlIGFub24gZm9saW9zIHRvIHdvcmssIHdlIGRlcGVuZCBvbiBUSFAu IEJ1dCBJIGRvbid0Cj4+Pj4gdGhpbmsgdGhhdCBoZWxwcyB1cyBoZXJlLgo+Pj4+Cj4+Pj4gSW4g dGhlIG5leHQgcGF0Y2gsIEkgZ2l2ZSB2bWFfYWxsb2NfemVyb2VkX21vdmFibGVfZm9saW8oKSBh biBleHRyYSBgb3JkZXJgCj4+Pj4gcGFyYW1ldGVyLiBTbyB0aGUgZ2VuZXJpYy9kZWZhdWx0IHZl cnNpb24gb2YgdGhlIGZ1bmN0aW9uIG5vdyBuZWVkcyBhIHdheSB0bwo+Pj4+IGNsZWFyIGEgY29t cG91bmQgcGFnZS4KPj4+Pgo+Pj4+IEkgZ3Vlc3MgSSBjb3VsZCBkbyBzb21ldGhpbmcgbGlrZToK Pj4+Pgo+Pj4+ICBzdGF0aWMgaW5saW5lCj4+Pj4gIHN0cnVjdCBmb2xpbyAqdm1hX2FsbG9jX3pl cm9lZF9tb3ZhYmxlX2ZvbGlvKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hLAo+Pj4+ICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyB2YWRkciwgZ2ZwX3Qg Z2ZwLCBpbnQgb3JkZXIpCj4+Pj4gIHsKPj4+PiAgICAgICAgIHN0cnVjdCBmb2xpbyAqZm9saW87 Cj4+Pj4KPj4+PiAgICAgICAgIGZvbGlvID0gdm1hX2FsbG9jX2ZvbGlvKEdGUF9ISUdIVVNFUl9N T1ZBQkxFIHwgZ2ZwLAo+Pj4+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBvcmRlciwgdm1hLCB2YWRkciwgZmFsc2UpOwo+Pj4+ICAgICAgICAgaWYgKGZvbGlvKSB7Cj4+ Pj4gI2lmZGVmIENPTkZJR19MQVJHRV9GT0xJTwo+Pj4+ICAgICAgICAgICAgICAgICBjbGVhcl9o dWdlX3BhZ2UoJmZvbGlvLT5wYWdlLCB2YWRkciwgMVUgPDwgb3JkZXIpOwo+Pj4+ICNlbHNlCj4+ Pj4gICAgICAgICAgICAgICAgIEJVR19PTihvcmRlciAhPSAwKTsKPj4+PiAgICAgICAgICAgICAg ICAgY2xlYXJfdXNlcl9oaWdocGFnZSgmZm9saW8tPnBhZ2UsIHZhZGRyKTsKPj4+PiAjZW5kaWYK Pj4+PiAgICAgICAgIH0KPj4+Pgo+Pj4+ICAgICAgICAgcmV0dXJuIGZvbGlvOwo+Pj4+ICB9Cj4+ Pj4KPj4+PiBCdXQgdGhhdCdzIHByZXR0eSBtZXNzeSBhbmQgdGhlcmUncyBubyByZWFzb24gd2h5 IG90aGVyIHVzZXJzIG1pZ2h0IGNvbWUgYWxvbmcKPj4+PiB0aGF0IHBhc3Mgb3JkZXIgIT0gMCBh bmQgd2lsbCBiZSBzdXJwcmlzZWQgYnkgdGhlIEJVR19PTi4KPj4+Cj4+PiAjaWZkZWYgQ09ORklH X0xBUkdFX0FOT05fRk9MSU8gLy8gZGVwZW5kcyBvbiBDT05GSUdfVFJBTlNQQVJFTlRfSFVHRV9Q QUdFCj4+PiBzdHJ1Y3QgZm9saW8gKmFsbG9jX2Fub25fZm9saW8oc3RydWN0IHZtX2FyZWFfc3Ry dWN0ICp2bWEsIHVuc2lnbmVkCj4+PiBsb25nIHZhZGRyLCBpbnQgb3JkZXIpCj4+PiB7Cj4+PiAg IC8vIGhvdyBkb19odWdlX3BtZF9hbm9ueW1vdXNfcGFnZSgpIGFsbG9jcyBhbmQgY2xlYXJzCj4+ PiAgIHZtYV9hbGxvY19mb2xpbyguLi4sICp0cnVlKik7Cj4+Cj4+IFRoaXMgY29udHJvbHMgdGhl IG1lbSBhbGxvY2F0aW9uIHBvbGljeSAoc2VlIG1lbXBvbGljeS5jOjp2bWFfYWxsb2NfZm9saW8o KSkgbm90Cj4+IGNsZWFyaW5nLiBDbGVhcmluZyBpcyBkb25lIGluIF9fZG9faHVnZV9wbWRfYW5v bnltb3VzX3BhZ2UoKToKPj4KPj4gICBjbGVhcl9odWdlX3BhZ2UocGFnZSwgdm1mLT5hZGRyZXNz LCBIUEFHRV9QTURfTlIpOwo+IAo+IFNvcnJ5IGZvciBydXNoaW5nIHRoaXMgcHJldmlvdXNseS4g VGhpcyBpcyB3aGF0IEkgbWVhbnQuIFRoZSAjaWZkZWYKPiBtYWtlcyBpdCBzYWZlIHRvIHVzZSBj bGVhcl9odWdlX3BhZ2UoKSB3aXRob3V0IDAxLzEwLiBJIGhpZ2hsaWdodGVkCj4gdGhlIGxhc3Qg cGFyYW1ldGVyIHRvIHZtYV9hbGxvY19mb2xpbygpIG9ubHkgYmVjYXVzZSBpdCdzIGRpZmZlcmVu dAo+IGZyb20gd2hhdCB5b3UgY2hvc2UgKG5vdCBpbXBseWluZyBpdCBjbGVhcnMgdGhlIGZvbGlv KS4+Cj4+PiB9Cj4+PiAjZWxzZQo+Pj4gI2RlZmluZSBhbGxvY19hbm9uX2ZvbGlvKHZtYSwgYWRk ciwgb3JkZXIpCj4+PiB2bWFfYWxsb2NfemVyb2VkX21vdmFibGVfZm9saW8odm1hLCBhZGRyKQo+ Pj4gI2VuZGlmCj4+Cj4+IFNvcnJ5IEkgZG9uJ3QgZ2V0IHRoaXMgYXQgYWxsLi4uIElmIHlvdSBh cmUgc3VnZ2VzdGluZyB0byBieXBhc3MKPj4gdm1hX2FsbG9jX3plcm9lZF9tb3ZhYmxlX2ZvbGlv KCkgZW50aXJlbHkgZm9yIHRoZSBMQVJHRV9BTk9OX0ZPTElPIGNhc2UKPiAKPiBDb3JyZWN0Lgo+ IAo+PiBJIGRvbid0Cj4+IHRoaW5rIHRoYXQgd29ya3MgYmVjYXVzZSB0aGUgYXJjaCBjb2RlIGFk ZHMgaXRzIG93biBnZnAgZmxhZ3MgdGhlcmUuIEZvcgo+PiBleGFtcGxlLCBhcm02NCBhZGRzIF9f R0ZQX1pFUk9UQUdTIGZvciBWTV9NVEUgVk1Bcy4KPiAKPiBJIHRoaW5rIGl0J3MgdGhlIG9wcG9z aXRlOiBpdCBzaG91bGQgYmUgc2FmZXIgdG8gcmV1c2UgdGhlIFRIUCBjb2RlIGJlY2F1c2UKPiAx LiBJdCdzIGFuIGV4aXN0aW5nIGNhc2UgdGhhdCBoYXMgYmVlbiB3b3JraW5nIGZvciBQTURfT1JE RVIgZm9saW9zCj4gbWFwcGVkIGJ5IFBURXMsIGFuZCBpdCdzIGFuIGFyY2gtaW5kZXBlbmRlbnQg QVBJIHdoaWNoIHdvdWxkIGJlIGVhc2llcgo+IHRvIHJldmlldy4KPiAyLiBVc2Ugdm1hX2FsbG9j X3plcm9lZF9tb3ZhYmxlX2ZvbGlvKCkgZm9yIGxhcmdlIGZvbGlvcyBpcyBhICpuZXcqCj4gY2Fz ZS4gSXQncyBhbiBhcmNoLSpkZXBlbmRlbnQqIEFQSSB3aGljaCBJIGhhdmUgbm8gaWRlYSB3aGF0 IFZNX01URQo+IGRvZXMgKHNob3VsZCBkbykgdG8gbGFyZ2UgZm9saW9zIGFuZCBkb24ndCBwbGFu IHRvIGFuc3dlciB0aGF0IGZvcgo+IG5vdy4KCkkndmUgZG9uZSBzb21lIGFyY2hhb2xvZ3kgb24g dGhpcyBub3csIGFuZCBjb252aW5jZWQgbXlzZWxmIHRoYXQgeW91ciBzdWdnZXN0aW9uCmlzIGEg Z29vZCBvbmUgLSBzb3JyeSBmb3IgZG91YnRpbmcgaXQhCgpJZiB5b3UgYXJlIGludGVyZXN0ZWQg aGVyZSBhcmUgdGhlIGRldGFpbHM6IE9ubHkgYXJtNjQgYW5kIGlhNjQgZG8gc29tZXRoaW5nCm5v bi1zdGFuZGFyZCBpbiB2bWFfYWxsb2NfemVyb2VkX21vdmFibGVfZm9saW8oKS4gaWE2NCBmbHVz aGVzIHRoZSBkY2FjaGUgZm9yCnRoZSBmb2xpbyAtIGJ1dCBnaXZlbiBpdCBkb2VzIG5vdCBzdXBw b3J0IFRIUCB0aGlzIGlzIG5vdCBhIHByb2JsZW0gZm9yIHRoZSBUSFAKcGF0aC4gYXJtNjQgYWRk cyB0aGUgX19HRlBfWkVST1RBR1MgZmxhZyB3aGljaCBtZWFucyB0aGF0IHRoZSBNVEUgdGFncyB3 aWxsIGJlCnplcm9lZCBhdCB0aGUgc2FtZSB0aW1lIGFzIHRoZSBwYWdlIGlzIHplcm9lZC4gVGhp cyBpcyBhIHBlcmYgb3B0aW1pemF0aW9uIC0gaWYKaXRzIG5vdCBwZXJmb3JtZWQgdGhlbiBpdCB3 aWxsIGJlIGRvbmUgYXQgc2V0X3B0ZV9hdCgpLCB3aGljaCBpcyBob3cgdGhpcyB3b3Jrcwpmb3Ig dGhlIFRIUCBwYXRoLgoKU28gb24gdGhhdCBiYXNpcywgSSBhZ3JlZSB3ZSBjYW4gdXNlIHlvdXIg cHJvcG9zZWQgYWxsb2NfYW5vbl9mb2xpbygpIGFwcHJvYWNoLgphcm02NCB3aWxsIGxvc2UgdGhl IE1URSBvcHRpbWl6YXRpb24gYnV0IHRoYXQgY2FuIGJlIGFkZGVkIGJhY2sgbGF0ZXIgaWYgbmVl ZGVkLgpTbyBubyBuZWVkIHRvIHVuY29uZGl0aW9uYWxseSBleHBvc2UgY2xlYXJfaHVnZV9wYWdl KCkgYW5kIG5vIG5lZWQgdG8gbW9kaWZ5IGFsbAp0aGUgYXJjaCB2bWFfYWxsb2NfemVyb2VkX21v dmFibGVfZm9saW8oKSBpbXBsZW1lbnRhdGlvbnMuCgpUaGFua3MsClJ5YW4KCgo+IAo+PiBQZXJo YXBzIHdlIGNhbiBkbyBhd2F5IHdpdGggYW4gYXJjaC1vd25lZCB2bWFfYWxsb2NfemVyb2VkX21v dmFibGVfZm9saW8oKSBhbmQKPj4gcmVwbGFjZSBpdCB3aXRoIGEgbmV3IGFyY2hfZ2V0X3plcm9l ZF9tb3ZhYmxlX2dmcF9mbGFncygpIHRoZW4KPj4gYWxsb2NfYW5vbl9mb2xpbygpIGFkZCBpbiB0 aG9zZSBmbGFncz8KPj4KPj4gQnV0IEkgc3RpbGwgdGhpbmsgdGhlIGNsZWFuZXN0LCBzaW1wbGVz dCBjaGFuZ2UgaXMganVzdCB0byB1bmNvbmRpdGlvbmFsbHkKPj4gZXhwb3NlIGNsZWFyX2h1Z2Vf cGFnZSgpIGFzIEkndmUgZG9uZSBpdC4KPiAKPiBUaGUgZnVuZGFtZW50YWwgY2hvaWNlIHRoZXJl IGFzIEkgc2VlIGl0IGlzIHRvIHdoZXRoZXIgdGhlIGZpcnN0IHN0ZXAKPiBvZiBsYXJnZSBhbm9u IGZvbGlvcyBzaG91bGQgbGVhbiB0b3dhcmQgdGhlIFRIUCBjb2RlIGJhc2Ugb3IgdGhlIGJhc2UK PiBwYWdlIGNvZGUgYmFzZSAoSSdtIGEgYmlnIGZhbiBvZiB0aGUgYW5zd2VyICJOZWl0aGVyIC0t IHdlIHNob3VsZAo+IGNyZWF0ZSBzb21ldGhpbmcgZW50aXJlbHkgbmV3IGluc3RlYWQiKS4gTXkg UE9WIGlzIHRoYXQgdGhlIFRIUCBjb2RlCj4gYmFzZSB3b3VsZCBhbGxvdyB1cyB0byBtb3ZlIGZh c3Rlciwgc2luY2UgaXQncyBwcm92ZW4gdG8gd29yayBmb3IgYQo+IHZlcnkgc2ltaWxhciBjYXNl IChQTURfT1JERVIgZm9saW9zIG1hcHBlZCBieSBQVEVzKS4KCgpfX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlz dApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJh ZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==