From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ryan Roberts Subject: Re: [PATCH v1 03/10] mm: Introduce try_vma_alloc_movable_folio() Date: Tue, 27 Jun 2023 08:56:57 +0100 Message-ID: References: <20230626171430.3167004-1-ryan.roberts@arm.com> <20230626171430.3167004-4-ryan.roberts@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 06:29, Yu Zhao wrote: > On Mon, Jun 26, 2023 at 8:34 PM Yu Zhao wrote: >> >> On Mon, Jun 26, 2023 at 11:14 AM Ryan Roberts wrote: >>> >>> Opportunistically attempt to allocate high-order folios in highmem, >>> optionally zeroed. Retry with lower orders all the way to order-0, until >>> success. Although, of note, order-1 allocations are skipped since a >>> large folio must be at least order-2 to work with the THP machinery. The >>> user must check what they got with folio_order(). >>> >>> This will be used to oportunistically allocate large folios for >>> anonymous memory with a sensible fallback under memory pressure. >>> >>> For attempts to allocate non-0 orders, we set __GFP_NORETRY to prevent >>> high latency due to reclaim, instead preferring to just try for a lower >>> order. The same approach is used by the readahead code when allocating >>> large folios. >>> >>> Signed-off-by: Ryan Roberts >>> --- >>> mm/memory.c | 33 +++++++++++++++++++++++++++++++++ >>> 1 file changed, 33 insertions(+) >>> >>> diff --git a/mm/memory.c b/mm/memory.c >>> index 367bbbb29d91..53896d46e686 100644 >>> --- a/mm/memory.c >>> +++ b/mm/memory.c >>> @@ -3001,6 +3001,39 @@ static vm_fault_t fault_dirty_shared_page(struct vm_fault *vmf) >>> return 0; >>> } >>> >>> +static inline struct folio *vma_alloc_movable_folio(struct vm_area_struct *vma, >>> + unsigned long vaddr, int order, bool zeroed) >>> +{ >>> + gfp_t gfp = order > 0 ? __GFP_NORETRY | __GFP_NOWARN : 0; >>> + >>> + if (zeroed) >>> + return vma_alloc_zeroed_movable_folio(vma, vaddr, gfp, order); >>> + else >>> + return vma_alloc_folio(GFP_HIGHUSER_MOVABLE | gfp, order, vma, >>> + vaddr, false); >>> +} >>> + >>> +/* >>> + * Opportunistically attempt to allocate high-order folios, retrying with lower >>> + * orders all the way to order-0, until success. order-1 allocations are skipped >>> + * since a folio must be at least order-2 to work with the THP machinery. The >>> + * user must check what they got with folio_order(). vaddr can be any virtual >>> + * address that will be mapped by the allocated folio. >>> + */ >>> +static struct folio *try_vma_alloc_movable_folio(struct vm_area_struct *vma, >>> + unsigned long vaddr, int order, bool zeroed) >>> +{ >>> + struct folio *folio; >>> + >>> + for (; order > 1; order--) { >>> + folio = vma_alloc_movable_folio(vma, vaddr, order, zeroed); >>> + if (folio) >>> + return folio; >>> + } >>> + >>> + return vma_alloc_movable_folio(vma, vaddr, 0, zeroed); >>> +} >> >> I'd drop this patch. Instead, in do_anonymous_page(): >> >> if (IS_ENABLED(CONFIG_ARCH_WANTS_PTE_ORDER)) >> folio = vma_alloc_zeroed_movable_folio(vma, addr, >> CONFIG_ARCH_WANTS_PTE_ORDER)) >> >> if (!folio) >> folio = vma_alloc_zeroed_movable_folio(vma, addr, 0); > > I meant a runtime function arch_wants_pte_order() (Its default > implementation would return 0.) There are a bunch of things which you are implying here which I'll try to make explicit: I think you are implying that we shouldn't retry allocation with intermediate orders; but only try the order requested by the arch (arch_wants_pte_order()) and 0. Correct? For arm64 at least, I would like the VMA's THP hint to be a factor in determining the preferred order (see patches 8 and 9). So I would add a vma parameter to arch_wants_pte_order() to allow for this. For the case where the THP hint is present, then the arch will request 2M (if the page size is 16K or 64K). If that fails to allocate, there is still value in allocating a 64K folio (which is order 2 in the 16K case). Without the retry with intermediate orders logic, we would not get this. We can't just blindly allocate a folio of arch_wants_pte_order() size because it might overlap with existing populated PTEs, or cross the bounds of the VMA (or a number of other things - see calc_anon_folio_order_alloc() in patch 10). Are you implying that if there is any kind of issue like this, then we should go directly to order 0? I can kind of see the argument from a minimizing fragmentation perspective, but for best possible performance I think we are better off "packing the bin" with intermediate orders. You're also implying that a runtime arch_wants_pte_order() function is better than the Kconfig stuff I did in patch 8. On reflection, I agree with you here. I think you mentioned that AMD supports coalescing 8 pages on some CPUs - so you would probably want runtime logic to determine if you are on an appropriate AMD CPU as part of the decision in that function? The real reason for the existance of try_vma_alloc_movable_folio() is that I'm reusing it on the other fault paths (which are no longer part of this series). But I guess that's not a good reason to keep this until we get to those patches. 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 42FB1C001DF for ; Tue, 27 Jun 2023 07:57:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230219AbjF0H5E (ORCPT ); Tue, 27 Jun 2023 03:57:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229524AbjF0H5D (ORCPT ); Tue, 27 Jun 2023 03:57:03 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 41682172A; Tue, 27 Jun 2023 00:57:02 -0700 (PDT) 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 071BB11FB; Tue, 27 Jun 2023 00:57:46 -0700 (PDT) Received: from [10.57.76.16] (unknown [10.57.76.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EA0443F663; Tue, 27 Jun 2023 00:56:58 -0700 (PDT) Message-ID: Date: Tue, 27 Jun 2023 08:56:57 +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 03/10] mm: Introduce try_vma_alloc_movable_folio() 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-4-ryan.roberts@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 06:29, Yu Zhao wrote: > On Mon, Jun 26, 2023 at 8:34 PM Yu Zhao wrote: >> >> On Mon, Jun 26, 2023 at 11:14 AM Ryan Roberts wrote: >>> >>> Opportunistically attempt to allocate high-order folios in highmem, >>> optionally zeroed. Retry with lower orders all the way to order-0, until >>> success. Although, of note, order-1 allocations are skipped since a >>> large folio must be at least order-2 to work with the THP machinery. The >>> user must check what they got with folio_order(). >>> >>> This will be used to oportunistically allocate large folios for >>> anonymous memory with a sensible fallback under memory pressure. >>> >>> For attempts to allocate non-0 orders, we set __GFP_NORETRY to prevent >>> high latency due to reclaim, instead preferring to just try for a lower >>> order. The same approach is used by the readahead code when allocating >>> large folios. >>> >>> Signed-off-by: Ryan Roberts >>> --- >>> mm/memory.c | 33 +++++++++++++++++++++++++++++++++ >>> 1 file changed, 33 insertions(+) >>> >>> diff --git a/mm/memory.c b/mm/memory.c >>> index 367bbbb29d91..53896d46e686 100644 >>> --- a/mm/memory.c >>> +++ b/mm/memory.c >>> @@ -3001,6 +3001,39 @@ static vm_fault_t fault_dirty_shared_page(struct vm_fault *vmf) >>> return 0; >>> } >>> >>> +static inline struct folio *vma_alloc_movable_folio(struct vm_area_struct *vma, >>> + unsigned long vaddr, int order, bool zeroed) >>> +{ >>> + gfp_t gfp = order > 0 ? __GFP_NORETRY | __GFP_NOWARN : 0; >>> + >>> + if (zeroed) >>> + return vma_alloc_zeroed_movable_folio(vma, vaddr, gfp, order); >>> + else >>> + return vma_alloc_folio(GFP_HIGHUSER_MOVABLE | gfp, order, vma, >>> + vaddr, false); >>> +} >>> + >>> +/* >>> + * Opportunistically attempt to allocate high-order folios, retrying with lower >>> + * orders all the way to order-0, until success. order-1 allocations are skipped >>> + * since a folio must be at least order-2 to work with the THP machinery. The >>> + * user must check what they got with folio_order(). vaddr can be any virtual >>> + * address that will be mapped by the allocated folio. >>> + */ >>> +static struct folio *try_vma_alloc_movable_folio(struct vm_area_struct *vma, >>> + unsigned long vaddr, int order, bool zeroed) >>> +{ >>> + struct folio *folio; >>> + >>> + for (; order > 1; order--) { >>> + folio = vma_alloc_movable_folio(vma, vaddr, order, zeroed); >>> + if (folio) >>> + return folio; >>> + } >>> + >>> + return vma_alloc_movable_folio(vma, vaddr, 0, zeroed); >>> +} >> >> I'd drop this patch. Instead, in do_anonymous_page(): >> >> if (IS_ENABLED(CONFIG_ARCH_WANTS_PTE_ORDER)) >> folio = vma_alloc_zeroed_movable_folio(vma, addr, >> CONFIG_ARCH_WANTS_PTE_ORDER)) >> >> if (!folio) >> folio = vma_alloc_zeroed_movable_folio(vma, addr, 0); > > I meant a runtime function arch_wants_pte_order() (Its default > implementation would return 0.) There are a bunch of things which you are implying here which I'll try to make explicit: I think you are implying that we shouldn't retry allocation with intermediate orders; but only try the order requested by the arch (arch_wants_pte_order()) and 0. Correct? For arm64 at least, I would like the VMA's THP hint to be a factor in determining the preferred order (see patches 8 and 9). So I would add a vma parameter to arch_wants_pte_order() to allow for this. For the case where the THP hint is present, then the arch will request 2M (if the page size is 16K or 64K). If that fails to allocate, there is still value in allocating a 64K folio (which is order 2 in the 16K case). Without the retry with intermediate orders logic, we would not get this. We can't just blindly allocate a folio of arch_wants_pte_order() size because it might overlap with existing populated PTEs, or cross the bounds of the VMA (or a number of other things - see calc_anon_folio_order_alloc() in patch 10). Are you implying that if there is any kind of issue like this, then we should go directly to order 0? I can kind of see the argument from a minimizing fragmentation perspective, but for best possible performance I think we are better off "packing the bin" with intermediate orders. You're also implying that a runtime arch_wants_pte_order() function is better than the Kconfig stuff I did in patch 8. On reflection, I agree with you here. I think you mentioned that AMD supports coalescing 8 pages on some CPUs - so you would probably want runtime logic to determine if you are on an appropriate AMD CPU as part of the decision in that function? The real reason for the existance of try_vma_alloc_movable_folio() is that I'm reusing it on the other fault paths (which are no longer part of this series). But I guess that's not a good reason to keep this until we get to those patches. 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 C00BBEB64D9 for ; Tue, 27 Jun 2023 07:57:37 +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=6hvESuP9oEuD2g4QQMet3MWF8HKatCsfo4h/Y3Nb6iQ=; b=QJPXMI5MHpyRji UVubkXsO0OLiHeLlq5G9S9gXb8yQR79kzHWfIIb328LNkiNJd571aZlb0ArQjrCbG9LZH7DkP2Pf0 CJ66d5fDEQm1w1vK6Zkc8/YCQx+gtqzIDzKfJiGOvcR9JPb+xr2UaVDpmG5mkCNlxJ0JH5szrj7zl RRJvT/cXHPubFOxGaE/2G6chlichyuW7cmsrjbZvqauTil6hbYfZxDTZi78W4AaIC3lgiBBz1E9Yv th7mTuy4v1m5f1OdKWGbmXhLwai4BqgkCqqcBz7qOEHan6g+wdBTRjFgH2tIyaWxgbseOPT7VQXic ZEpzCbXOFCrlNhAnTsPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qE3ZT-00CTQ8-0A; Tue, 27 Jun 2023 07:57:07 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qE3ZP-00CTOm-0g for linux-arm-kernel@lists.infradead.org; Tue, 27 Jun 2023 07:57:04 +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 071BB11FB; Tue, 27 Jun 2023 00:57:46 -0700 (PDT) Received: from [10.57.76.16] (unknown [10.57.76.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EA0443F663; Tue, 27 Jun 2023 00:56:58 -0700 (PDT) Message-ID: Date: Tue, 27 Jun 2023 08:56:57 +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 03/10] mm: Introduce try_vma_alloc_movable_folio() 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-4-ryan.roberts@arm.com> From: Ryan Roberts In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230627_005703_350535_E7E19C24 X-CRM114-Status: GOOD ( 28.73 ) 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 T24gMjcvMDYvMjAyMyAwNjoyOSwgWXUgWmhhbyB3cm90ZToKPiBPbiBNb24sIEp1biAyNiwgMjAy MyBhdCA4OjM04oCvUE0gWXUgWmhhbyA8eXV6aGFvQGdvb2dsZS5jb20+IHdyb3RlOgo+Pgo+PiBP biBNb24sIEp1biAyNiwgMjAyMyBhdCAxMToxNOKAr0FNIFJ5YW4gUm9iZXJ0cyA8cnlhbi5yb2Jl cnRzQGFybS5jb20+IHdyb3RlOgo+Pj4KPj4+IE9wcG9ydHVuaXN0aWNhbGx5IGF0dGVtcHQgdG8g YWxsb2NhdGUgaGlnaC1vcmRlciBmb2xpb3MgaW4gaGlnaG1lbSwKPj4+IG9wdGlvbmFsbHkgemVy b2VkLiBSZXRyeSB3aXRoIGxvd2VyIG9yZGVycyBhbGwgdGhlIHdheSB0byBvcmRlci0wLCB1bnRp bAo+Pj4gc3VjY2Vzcy4gQWx0aG91Z2gsIG9mIG5vdGUsIG9yZGVyLTEgYWxsb2NhdGlvbnMgYXJl IHNraXBwZWQgc2luY2UgYQo+Pj4gbGFyZ2UgZm9saW8gbXVzdCBiZSBhdCBsZWFzdCBvcmRlci0y IHRvIHdvcmsgd2l0aCB0aGUgVEhQIG1hY2hpbmVyeS4gVGhlCj4+PiB1c2VyIG11c3QgY2hlY2sg d2hhdCB0aGV5IGdvdCB3aXRoIGZvbGlvX29yZGVyKCkuCj4+Pgo+Pj4gVGhpcyB3aWxsIGJlIHVz ZWQgdG8gb3BvcnR1bmlzdGljYWxseSBhbGxvY2F0ZSBsYXJnZSBmb2xpb3MgZm9yCj4+PiBhbm9u eW1vdXMgbWVtb3J5IHdpdGggYSBzZW5zaWJsZSBmYWxsYmFjayB1bmRlciBtZW1vcnkgcHJlc3N1 cmUuCj4+Pgo+Pj4gRm9yIGF0dGVtcHRzIHRvIGFsbG9jYXRlIG5vbi0wIG9yZGVycywgd2Ugc2V0 IF9fR0ZQX05PUkVUUlkgdG8gcHJldmVudAo+Pj4gaGlnaCBsYXRlbmN5IGR1ZSB0byByZWNsYWlt LCBpbnN0ZWFkIHByZWZlcnJpbmcgdG8ganVzdCB0cnkgZm9yIGEgbG93ZXIKPj4+IG9yZGVyLiBU aGUgc2FtZSBhcHByb2FjaCBpcyB1c2VkIGJ5IHRoZSByZWFkYWhlYWQgY29kZSB3aGVuIGFsbG9j YXRpbmcKPj4+IGxhcmdlIGZvbGlvcy4KPj4+Cj4+PiBTaWduZWQtb2ZmLWJ5OiBSeWFuIFJvYmVy dHMgPHJ5YW4ucm9iZXJ0c0Bhcm0uY29tPgo+Pj4gLS0tCj4+PiAgbW0vbWVtb3J5LmMgfCAzMyAr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4+ICAxIGZpbGUgY2hhbmdlZCwgMzMg aW5zZXJ0aW9ucygrKQo+Pj4KPj4+IGRpZmYgLS1naXQgYS9tbS9tZW1vcnkuYyBiL21tL21lbW9y eS5jCj4+PiBpbmRleCAzNjdiYmJiMjlkOTEuLjUzODk2ZDQ2ZTY4NiAxMDA2NDQKPj4+IC0tLSBh L21tL21lbW9yeS5jCj4+PiArKysgYi9tbS9tZW1vcnkuYwo+Pj4gQEAgLTMwMDEsNiArMzAwMSwz OSBAQCBzdGF0aWMgdm1fZmF1bHRfdCBmYXVsdF9kaXJ0eV9zaGFyZWRfcGFnZShzdHJ1Y3Qgdm1f ZmF1bHQgKnZtZikKPj4+ICAgICAgICAgcmV0dXJuIDA7Cj4+PiAgfQo+Pj4KPj4+ICtzdGF0aWMg aW5saW5lIHN0cnVjdCBmb2xpbyAqdm1hX2FsbG9jX21vdmFibGVfZm9saW8oc3RydWN0IHZtX2Fy ZWFfc3RydWN0ICp2bWEsCj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2ln bmVkIGxvbmcgdmFkZHIsIGludCBvcmRlciwgYm9vbCB6ZXJvZWQpCj4+PiArewo+Pj4gKyAgICAg ICBnZnBfdCBnZnAgPSBvcmRlciA+IDAgPyBfX0dGUF9OT1JFVFJZIHwgX19HRlBfTk9XQVJOIDog MDsKPj4+ICsKPj4+ICsgICAgICAgaWYgKHplcm9lZCkKPj4+ICsgICAgICAgICAgICAgICByZXR1 cm4gdm1hX2FsbG9jX3plcm9lZF9tb3ZhYmxlX2ZvbGlvKHZtYSwgdmFkZHIsIGdmcCwgb3JkZXIp Owo+Pj4gKyAgICAgICBlbHNlCj4+PiArICAgICAgICAgICAgICAgcmV0dXJuIHZtYV9hbGxvY19m b2xpbyhHRlBfSElHSFVTRVJfTU9WQUJMRSB8IGdmcCwgb3JkZXIsIHZtYSwKPj4+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2 YWRkciwgZmFsc2UpOwo+Pj4gK30KPj4+ICsKPj4+ICsvKgo+Pj4gKyAqIE9wcG9ydHVuaXN0aWNh bGx5IGF0dGVtcHQgdG8gYWxsb2NhdGUgaGlnaC1vcmRlciBmb2xpb3MsIHJldHJ5aW5nIHdpdGgg bG93ZXIKPj4+ICsgKiBvcmRlcnMgYWxsIHRoZSB3YXkgdG8gb3JkZXItMCwgdW50aWwgc3VjY2Vz cy4gb3JkZXItMSBhbGxvY2F0aW9ucyBhcmUgc2tpcHBlZAo+Pj4gKyAqIHNpbmNlIGEgZm9saW8g bXVzdCBiZSBhdCBsZWFzdCBvcmRlci0yIHRvIHdvcmsgd2l0aCB0aGUgVEhQIG1hY2hpbmVyeS4g VGhlCj4+PiArICogdXNlciBtdXN0IGNoZWNrIHdoYXQgdGhleSBnb3Qgd2l0aCBmb2xpb19vcmRl cigpLiB2YWRkciBjYW4gYmUgYW55IHZpcnR1YWwKPj4+ICsgKiBhZGRyZXNzIHRoYXQgd2lsbCBi ZSBtYXBwZWQgYnkgdGhlIGFsbG9jYXRlZCBmb2xpby4KPj4+ICsgKi8KPj4+ICtzdGF0aWMgc3Ry dWN0IGZvbGlvICp0cnlfdm1hX2FsbG9jX21vdmFibGVfZm9saW8oc3RydWN0IHZtX2FyZWFfc3Ry dWN0ICp2bWEsCj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxv bmcgdmFkZHIsIGludCBvcmRlciwgYm9vbCB6ZXJvZWQpCj4+PiArewo+Pj4gKyAgICAgICBzdHJ1 Y3QgZm9saW8gKmZvbGlvOwo+Pj4gKwo+Pj4gKyAgICAgICBmb3IgKDsgb3JkZXIgPiAxOyBvcmRl ci0tKSB7Cj4+PiArICAgICAgICAgICAgICAgZm9saW8gPSB2bWFfYWxsb2NfbW92YWJsZV9mb2xp byh2bWEsIHZhZGRyLCBvcmRlciwgemVyb2VkKTsKPj4+ICsgICAgICAgICAgICAgICBpZiAoZm9s aW8pCj4+PiArICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9saW87Cj4+PiArICAgICAg IH0KPj4+ICsKPj4+ICsgICAgICAgcmV0dXJuIHZtYV9hbGxvY19tb3ZhYmxlX2ZvbGlvKHZtYSwg dmFkZHIsIDAsIHplcm9lZCk7Cj4+PiArfQo+Pgo+PiBJJ2QgZHJvcCB0aGlzIHBhdGNoLiBJbnN0 ZWFkLCBpbiBkb19hbm9ueW1vdXNfcGFnZSgpOgo+Pgo+PiAgIGlmIChJU19FTkFCTEVEKENPTkZJ R19BUkNIX1dBTlRTX1BURV9PUkRFUikpCj4+ICAgICBmb2xpbyA9IHZtYV9hbGxvY196ZXJvZWRf bW92YWJsZV9mb2xpbyh2bWEsIGFkZHIsCj4+IENPTkZJR19BUkNIX1dBTlRTX1BURV9PUkRFUikp Cj4+Cj4+ICAgaWYgKCFmb2xpbykKPj4gICAgIGZvbGlvID0gdm1hX2FsbG9jX3plcm9lZF9tb3Zh YmxlX2ZvbGlvKHZtYSwgYWRkciwgMCk7Cj4gCj4gSSBtZWFudCBhIHJ1bnRpbWUgZnVuY3Rpb24g YXJjaF93YW50c19wdGVfb3JkZXIoKSAoSXRzIGRlZmF1bHQKPiBpbXBsZW1lbnRhdGlvbiB3b3Vs ZCByZXR1cm4gMC4pCgpUaGVyZSBhcmUgYSBidW5jaCBvZiB0aGluZ3Mgd2hpY2ggeW91IGFyZSBp bXBseWluZyBoZXJlIHdoaWNoIEknbGwgdHJ5IHRvIG1ha2UKZXhwbGljaXQ6CgpJIHRoaW5rIHlv dSBhcmUgaW1wbHlpbmcgdGhhdCB3ZSBzaG91bGRuJ3QgcmV0cnkgYWxsb2NhdGlvbiB3aXRoIGlu dGVybWVkaWF0ZQpvcmRlcnM7IGJ1dCBvbmx5IHRyeSB0aGUgb3JkZXIgcmVxdWVzdGVkIGJ5IHRo ZSBhcmNoIChhcmNoX3dhbnRzX3B0ZV9vcmRlcigpKQphbmQgMC4gQ29ycmVjdD8gRm9yIGFybTY0 IGF0IGxlYXN0LCBJIHdvdWxkIGxpa2UgdGhlIFZNQSdzIFRIUCBoaW50IHRvIGJlIGEKZmFjdG9y IGluIGRldGVybWluaW5nIHRoZSBwcmVmZXJyZWQgb3JkZXIgKHNlZSBwYXRjaGVzIDggYW5kIDkp LiBTbyBJIHdvdWxkIGFkZAphIHZtYSBwYXJhbWV0ZXIgdG8gYXJjaF93YW50c19wdGVfb3JkZXIo KSB0byBhbGxvdyBmb3IgdGhpcy4KCkZvciB0aGUgY2FzZSB3aGVyZSB0aGUgVEhQIGhpbnQgaXMg cHJlc2VudCwgdGhlbiB0aGUgYXJjaCB3aWxsIHJlcXVlc3QgMk0gKGlmCnRoZSBwYWdlIHNpemUg aXMgMTZLIG9yIDY0SykuIElmIHRoYXQgZmFpbHMgdG8gYWxsb2NhdGUsIHRoZXJlIGlzIHN0aWxs IHZhbHVlIGluCmFsbG9jYXRpbmcgYSA2NEsgZm9saW8gKHdoaWNoIGlzIG9yZGVyIDIgaW4gdGhl IDE2SyBjYXNlKS4gV2l0aG91dCB0aGUgcmV0cnkKd2l0aCBpbnRlcm1lZGlhdGUgb3JkZXJzIGxv Z2ljLCB3ZSB3b3VsZCBub3QgZ2V0IHRoaXMuCgpXZSBjYW4ndCBqdXN0IGJsaW5kbHkgYWxsb2Nh dGUgYSBmb2xpbyBvZiBhcmNoX3dhbnRzX3B0ZV9vcmRlcigpIHNpemUgYmVjYXVzZSBpdAptaWdo dCBvdmVybGFwIHdpdGggZXhpc3RpbmcgcG9wdWxhdGVkIFBURXMsIG9yIGNyb3NzIHRoZSBib3Vu ZHMgb2YgdGhlIFZNQSAob3IgYQpudW1iZXIgb2Ygb3RoZXIgdGhpbmdzIC0gc2VlIGNhbGNfYW5v bl9mb2xpb19vcmRlcl9hbGxvYygpIGluIHBhdGNoIDEwKS4gQXJlIHlvdQppbXBseWluZyB0aGF0 IGlmIHRoZXJlIGlzIGFueSBraW5kIG9mIGlzc3VlIGxpa2UgdGhpcywgdGhlbiB3ZSBzaG91bGQg Z28KZGlyZWN0bHkgdG8gb3JkZXIgMD8gSSBjYW4ga2luZCBvZiBzZWUgdGhlIGFyZ3VtZW50IGZy b20gYSBtaW5pbWl6aW5nCmZyYWdtZW50YXRpb24gcGVyc3BlY3RpdmUsIGJ1dCBmb3IgYmVzdCBw b3NzaWJsZSBwZXJmb3JtYW5jZSBJIHRoaW5rIHdlIGFyZQpiZXR0ZXIgb2ZmICJwYWNraW5nIHRo ZSBiaW4iIHdpdGggaW50ZXJtZWRpYXRlIG9yZGVycy4KCllvdSdyZSBhbHNvIGltcGx5aW5nIHRo YXQgYSBydW50aW1lIGFyY2hfd2FudHNfcHRlX29yZGVyKCkgZnVuY3Rpb24gaXMgYmV0dGVyCnRo YW4gdGhlIEtjb25maWcgc3R1ZmYgSSBkaWQgaW4gcGF0Y2ggOC4gT24gcmVmbGVjdGlvbiwgSSBh Z3JlZSB3aXRoIHlvdSBoZXJlLiBJCnRoaW5rIHlvdSBtZW50aW9uZWQgdGhhdCBBTUQgc3VwcG9y dHMgY29hbGVzY2luZyA4IHBhZ2VzIG9uIHNvbWUgQ1BVcyAtIHNvIHlvdQp3b3VsZCBwcm9iYWJs eSB3YW50IHJ1bnRpbWUgbG9naWMgdG8gZGV0ZXJtaW5lIGlmIHlvdSBhcmUgb24gYW4gYXBwcm9w cmlhdGUgQU1ECkNQVSBhcyBwYXJ0IG9mIHRoZSBkZWNpc2lvbiBpbiB0aGF0IGZ1bmN0aW9uPwoK VGhlIHJlYWwgcmVhc29uIGZvciB0aGUgZXhpc3RhbmNlIG9mIHRyeV92bWFfYWxsb2NfbW92YWJs ZV9mb2xpbygpIGlzIHRoYXQgSSdtCnJldXNpbmcgaXQgb24gdGhlIG90aGVyIGZhdWx0IHBhdGhz ICh3aGljaCBhcmUgbm8gbG9uZ2VyIHBhcnQgb2YgdGhpcyBzZXJpZXMpLgpCdXQgSSBndWVzcyB0 aGF0J3Mgbm90IGEgZ29vZCByZWFzb24gdG8ga2VlcCB0aGlzIHVudGlsIHdlIGdldCB0byB0aG9z ZSBwYXRjaGVzLgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5p bmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8v bGludXgtYXJtLWtlcm5lbAo=