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 1BFAAEB64DD for ; Tue, 4 Jul 2023 23:48:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231532AbjGDXsC (ORCPT ); Tue, 4 Jul 2023 19:48:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229671AbjGDXsA (ORCPT ); Tue, 4 Jul 2023 19:48:00 -0400 Received: from mail-qt1-x833.google.com (mail-qt1-x833.google.com [IPv6:2607:f8b0:4864:20::833]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F17F3B2 for ; Tue, 4 Jul 2023 16:47:58 -0700 (PDT) Received: by mail-qt1-x833.google.com with SMTP id d75a77b69052e-401d1d967beso790211cf.0 for ; Tue, 04 Jul 2023 16:47:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1688514477; x=1691106477; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=vzsW9V6cYwbiTk6roJohmCrKlCh8UZOL6XV8hys3VC0=; b=aENPbEDVN2wLWR/YyuQfA60jQp2CSZg91/i3dh1idVI6i+y04ds1g4UidyhRFB+Kua /Xw5RZe3VVRTKX18667MpwQ/lwxpbd6zVx8ayOGcHjLvGLCnJiHr9wG/skS2wpQUlnAH sOE6M3D8Tk3iT+02VU77gDZ1p4h0D3e/BlGkdn6tCdZT9hVYxOAZ6T590bXQNZ/N0O91 6EUPRB6J74Kk4LV4+Lce6/OWC12ZkL5Xcegm3gGvF1RFt/1g93hmXv5rpPMRD+LiWUFX Ps2NnW2p1CVbHLpw606wMm0qCCxB7qVT2yhYrdPkOeAZbvLLdKLgkkrkeyhUklldMQ1j 38IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688514477; x=1691106477; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vzsW9V6cYwbiTk6roJohmCrKlCh8UZOL6XV8hys3VC0=; b=EJHcukavbErlK18M72nI3bPk9WI35WRriqwOh7LyGPUwDB+vRuzwoGFQXTbm/p9zMA FZ5j6vm5eHF6VpcAdvdfMIuP78l6AxLXB+eh1NHVQ4SjzRDunf4gfNUaT1wBEw4lJTcT sTX+5rk98CxewsAURwou0NSWuEO+V4z3q5DWSbD4bskotPsYv0z/E2EMJsqL6NdunlB+ uE9O7hxa6Vj9ZUKPcLWMlyXQkfabErQbt8SGHXimjR80TnfdXTqKvZOdzRTV/5JG8DTT sL7npYT34x+9CBAPDuKhcv7IxYV8AJQx/BNN763ArB3IdJR269+KhBSQ2BdjYV7oJQ7D VSAg== X-Gm-Message-State: ABy/qLb+c9Y83R4OPniiFbV6tZj1xgYyWf0KTruUsTlsuv7Ga+ov2XcZ vbvLssh4xmSclAX1GnPjbxwfOC4cCpASzTlB+kWd2Q== X-Google-Smtp-Source: APBJJlFGIJpdidlpiYWYiWyVVrCdDl+ScMHCwAcJcohMT1PeBBzoe7HzBh6g2H0tnuYdXDBZ/SPgV02h9Sj1ZW3MUzs= X-Received: by 2002:a05:622a:15ce:b0:3f0:af20:1a37 with SMTP id d14-20020a05622a15ce00b003f0af201a37mr10671qty.15.1688514476834; Tue, 04 Jul 2023 16:47:56 -0700 (PDT) MIME-Version: 1.0 References: <20230703135330.1865927-1-ryan.roberts@arm.com> <20230703135330.1865927-5-ryan.roberts@arm.com> <22b23340-5fad-01be-6bac-fa30a3724b27@arm.com> In-Reply-To: <22b23340-5fad-01be-6bac-fa30a3724b27@arm.com> From: Yu Zhao Date: Tue, 4 Jul 2023 17:47:20 -0600 Message-ID: Subject: Re: [PATCH v2 4/5] mm: FLEXIBLE_THP for improved performance To: Ryan Roberts Cc: Andrew Morton , Matthew Wilcox , "Kirill A. Shutemov" , Yin Fengwei , David Hildenbrand , Catalin Marinas , Will Deacon , Anshuman Khandual , Yang Shi , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jul 4, 2023 at 8:08=E2=80=AFAM Ryan Roberts = wrote: > > On 04/07/2023 02:35, Yu Zhao wrote: > > On Mon, Jul 3, 2023 at 7:53=E2=80=AFAM Ryan Roberts wrote: > >> > >> Introduce FLEXIBLE_THP feature, which allows anonymous memory to be > >> allocated in large folios of a specified order. All pages of the large > >> folio are pte-mapped during the same page fault, significantly reducin= g > >> the number of page faults. The number of per-page operations (e.g. ref > >> counting, rmap management lru list management) are also significantly > >> reduced since those ops now become per-folio. > >> > >> The new behaviour is hidden behind the new FLEXIBLE_THP Kconfig, which > >> defaults to disabled for now; there is a long list of todos to make > >> FLEXIBLE_THP robust with existing features (e.g. compaction, mlock, so= me > >> madvise ops, etc). These items will be tackled in subsequent patches. > >> > >> When enabled, the preferred folio order is as returned by > >> arch_wants_pte_order(), which may be overridden by the arch as it sees > >> fit. Some architectures (e.g. arm64) can coalsece TLB entries if a > > > > coalesce > > ACK > > > > >> contiguous set of ptes map physically contigious, naturally aligned > > > > contiguous > > ACK > > > > >> memory, so this mechanism allows the architecture to optimize as > >> required. > >> > >> If the preferred order can't be used (e.g. because the folio would > >> breach the bounds of the vma, or because ptes in the region are alread= y > >> mapped) then we fall back to a suitable lower order. > >> > >> Signed-off-by: Ryan Roberts > >> --- > >> mm/Kconfig | 10 ++++ > >> mm/memory.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++---= - > >> 2 files changed, 165 insertions(+), 13 deletions(-) > >> > >> diff --git a/mm/Kconfig b/mm/Kconfig > >> index 7672a22647b4..1c06b2c0a24e 100644 > >> --- a/mm/Kconfig > >> +++ b/mm/Kconfig > >> @@ -822,6 +822,16 @@ config READ_ONLY_THP_FOR_FS > >> support of file THPs will be developed in the next few relea= se > >> cycles. > >> > >> +config FLEXIBLE_THP > >> + bool "Flexible order THP" > >> + depends on TRANSPARENT_HUGEPAGE > >> + default n > > > > The default value is already N. > > Is there a coding standard for this? Personally I prefer to make it expli= cit. > > > > >> + help > >> + Use large (bigger than order-0) folios to back anonymous mem= ory where > >> + possible, even if the order of the folio is smaller than the= PMD > >> + order. This reduces the number of page faults, as well as ot= her > >> + per-page overheads to improve performance for many workloads= . > >> + > >> endif # TRANSPARENT_HUGEPAGE > >> > >> # > >> diff --git a/mm/memory.c b/mm/memory.c > >> index fb30f7523550..abe2ea94f3f5 100644 > >> --- a/mm/memory.c > >> +++ b/mm/memory.c > >> @@ -3001,6 +3001,116 @@ static vm_fault_t fault_dirty_shared_page(stru= ct vm_fault *vmf) > >> return 0; > >> } > >> > >> +#ifdef CONFIG_FLEXIBLE_THP > >> +/* > >> + * Allocates, zeros and returns a folio of the requested order for us= e as > >> + * anonymous memory. > >> + */ > >> +static struct folio *alloc_anon_folio(struct vm_area_struct *vma, > >> + unsigned long addr, int order) > >> +{ > >> + gfp_t gfp; > >> + struct folio *folio; > >> + > >> + if (order =3D=3D 0) > >> + return vma_alloc_zeroed_movable_folio(vma, addr); > >> + > >> + gfp =3D vma_thp_gfp_mask(vma); > >> + folio =3D vma_alloc_folio(gfp, order, vma, addr, true); > >> + if (folio) > >> + clear_huge_page(&folio->page, addr, folio_nr_pages(fol= io)); > >> + > >> + return folio; > >> +} > >> + > >> +/* > >> + * Preferred folio order to allocate for anonymous memory. > >> + */ > >> +#define max_anon_folio_order(vma) arch_wants_pte_order(vma) > >> +#else > >> +#define alloc_anon_folio(vma, addr, order) \ > >> + vma_alloc_zeroed_movable_folio(vma, ad= dr) > >> +#define max_anon_folio_order(vma) 0 > >> +#endif > >> + > >> +/* > >> + * Returns index of first pte that is not none, or nr if all are none= . > >> + */ > >> +static inline int check_ptes_none(pte_t *pte, int nr) > >> +{ > >> + int i; > >> + > >> + for (i =3D 0; i < nr; i++) { > >> + if (!pte_none(ptep_get(pte++))) > >> + return i; > >> + } > >> + > >> + return nr; > >> +} > >> + > >> +static int calc_anon_folio_order_alloc(struct vm_fault *vmf, int orde= r) > >> +{ > >> + /* > >> + * The aim here is to determine what size of folio we should a= llocate > >> + * for this fault. Factors include: > >> + * - Order must not be higher than `order` upon entry > >> + * - Folio must be naturally aligned within VA space > >> + * - Folio must be fully contained inside one pmd entry > >> + * - Folio must not breach boundaries of vma > >> + * - Folio must not overlap any non-none ptes > >> + * > >> + * Additionally, we do not allow order-1 since this breaks ass= umptions > >> + * elsewhere in the mm; THP pages must be at least order-2 (si= nce they > >> + * store state up to the 3rd struct page subpage), and these p= ages must > >> + * be THP in order to correctly use pre-existing THP infrastru= cture such > >> + * as folio_split(). > >> + * > >> + * Note that the caller may or may not choose to lock the pte.= If > >> + * unlocked, the result is racy and the user must re-check any= overlap > >> + * with non-none ptes under the lock. > >> + */ > >> + > >> + struct vm_area_struct *vma =3D vmf->vma; > >> + int nr; > >> + unsigned long addr; > >> + pte_t *pte; > >> + pte_t *first_set =3D NULL; > >> + int ret; > >> + > >> + order =3D min(order, PMD_SHIFT - PAGE_SHIFT); > >> + > >> + for (; order > 1; order--) { > > > > I'm not sure how we can justify this policy. As an initial step, it'd > > be a lot easier to sell if we only considered the order of > > arch_wants_pte_order() and the order 0. > > My justification is in the cover letter; I see performance regression (vs= the > unpatched kernel) when using the policy you suggest. This policy performs= much > better in my tests. (I'll reply directly to your follow up questions in t= he > cover letter shortly). > > What are your technical concerns about this approach? It is pretty light = weight > (I only touch each PTE once, regardless of the number of loops). If we ha= ve > strong technical reasons for reverting to the less performant approach th= en fair > enough, but I'd like to hear the rational first. Yes, mainly from three different angles: 1. The engineering principle: we'd want to separate the mechanical part and the policy part when attacking something large. This way it'd be easier to root cause any regressions if they happen. In our case, assuming the regression is real, it might actually prove my point here: I really don't think the two checks (if a vma range fits and if it does, which is unlikely according to your description, if all 64 PTEs are none) caused the regression. My theory is that 64KB itself caused the regression, but smaller sizes made an improvement. If this is really the case, I'd say the fallback policy masked the real problem, which is that 64KB is too large to begin with. 2. The benchmark methodology: I appreciate your effort in doing it, but we also need to consider that the setup is an uncommon scenario. The common scenarios are devices that have been running for weeks without reboots, generally having higher external fragmentation. In addition, for client devices, they are often under memory pressure, which makes fragmentation worse. So we should take the result with a grain of salt, and for that matter, results from after refresh reboots. 3. The technical concern: an ideal policy would consider all three major factors: the h/w features, userspace behaviors and the page allocator behavior. So far we only have the first one handy. The second one is too challenging, so let's forget about it for now. The third one is why I really don't like this best-fit policy. By falling back to smaller orders, we can waste a limited number of physically contiguous pages on wrong vmas (small vmas only), leading to failures to serve large vmas which otherwise would have a higher overall ROI. This can only be addressed within the page allocator: we need to enlighten it to return the highest order available, i.e., not breaking up any higher orders. I'm not really saying we should never try this fallback policy. I'm just thinking we can leave it for later, probably after we've addressed all the concerns with basic functionality. 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 EA154EB64D9 for ; Tue, 4 Jul 2023 23:48:31 +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:Cc:To:Subject:Message-ID:Date:From: In-Reply-To:References:MIME-Version:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=mpZKtvN7QzQT5stR0rJhM5cTUxTf5fqk9yGcks6ECvA=; b=iYJk8nRq0XVtvY N9I6i/yNH9EMeIr8M6wSNrVirF36rbnElXE4QAiOijZ98Bu1Rhy+rYCMj4olRj5RxShrk2OsoW9va bHIRwuTCzaYaP7mQGaQY2rw8ndvBtaOGPI0bEgRJmCKPfjZDEf+NySeBioeh/V8djR0NVPTLUqpsJ 6qAYGZUI0zYUPRZ65199VrsWrCymaXk6EfNHCUH0R5zF7wQkK4BNJ3yXtGmIgSW2lJa9u84E+fgNE fmwQBUrrQdqkBO/qL0XSO4jPlvVbpd6FpS1EGLCINlhK3dhzF/pBHbgclB+KndFSkSP3tqNBcro2i SMICVaMTmUpK09UfuqTg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qGpkY-00EP0i-2q; Tue, 04 Jul 2023 23:48:02 +0000 Received: from mail-qt1-x834.google.com ([2607:f8b0:4864:20::834]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qGpkV-00EOzi-2l for linux-arm-kernel@lists.infradead.org; Tue, 04 Jul 2023 23:48:01 +0000 Received: by mail-qt1-x834.google.com with SMTP id d75a77b69052e-40371070eb7so240501cf.1 for ; Tue, 04 Jul 2023 16:47:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1688514477; x=1691106477; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=vzsW9V6cYwbiTk6roJohmCrKlCh8UZOL6XV8hys3VC0=; b=aENPbEDVN2wLWR/YyuQfA60jQp2CSZg91/i3dh1idVI6i+y04ds1g4UidyhRFB+Kua /Xw5RZe3VVRTKX18667MpwQ/lwxpbd6zVx8ayOGcHjLvGLCnJiHr9wG/skS2wpQUlnAH sOE6M3D8Tk3iT+02VU77gDZ1p4h0D3e/BlGkdn6tCdZT9hVYxOAZ6T590bXQNZ/N0O91 6EUPRB6J74Kk4LV4+Lce6/OWC12ZkL5Xcegm3gGvF1RFt/1g93hmXv5rpPMRD+LiWUFX Ps2NnW2p1CVbHLpw606wMm0qCCxB7qVT2yhYrdPkOeAZbvLLdKLgkkrkeyhUklldMQ1j 38IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688514477; x=1691106477; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vzsW9V6cYwbiTk6roJohmCrKlCh8UZOL6XV8hys3VC0=; b=i5SjuA4lczGmZSveAi7GLYKChp4NEMrtOWTSYg6CbfrUN8Fe6zq2Fyytonj4deNL02 DeppfEbZqEJNaMZpO7UrDIzVYcYC9Of8nibgsYD5jrT/G2Wc+TzGAtfJF5KanGoli7/M JKGrms4t1NIYq+uBPhzOy2NMt9myFA5SBi+v6q+iqevPAtZz9/Zcu11miP+saNB89gUq o+ab8LQBJDUP9nQcaen2s7H8EtizKWlZh2DYU1Tl5L34oPEhnGKOskIMwQtPcDBuhcqy xPUi608feybn33p2e7vyz+HbW9PtgyqDlj9PsmW0Kb8xxpy2mVvLS89OD4G8/ulSBB0+ TFQQ== X-Gm-Message-State: ABy/qLbY6euOxiiTz5dVubxeLqBLRCGbRh9/3zfO31L1fnFEyLlS5U8e plseW1+GJxiXjp7UiAVPTy0g+BZ47a5Je1D0JMl/0w== X-Google-Smtp-Source: APBJJlFGIJpdidlpiYWYiWyVVrCdDl+ScMHCwAcJcohMT1PeBBzoe7HzBh6g2H0tnuYdXDBZ/SPgV02h9Sj1ZW3MUzs= X-Received: by 2002:a05:622a:15ce:b0:3f0:af20:1a37 with SMTP id d14-20020a05622a15ce00b003f0af201a37mr10671qty.15.1688514476834; Tue, 04 Jul 2023 16:47:56 -0700 (PDT) MIME-Version: 1.0 References: <20230703135330.1865927-1-ryan.roberts@arm.com> <20230703135330.1865927-5-ryan.roberts@arm.com> <22b23340-5fad-01be-6bac-fa30a3724b27@arm.com> In-Reply-To: <22b23340-5fad-01be-6bac-fa30a3724b27@arm.com> From: Yu Zhao Date: Tue, 4 Jul 2023 17:47:20 -0600 Message-ID: Subject: Re: [PATCH v2 4/5] mm: FLEXIBLE_THP for improved performance To: Ryan Roberts Cc: Andrew Morton , Matthew Wilcox , "Kirill A. Shutemov" , Yin Fengwei , David Hildenbrand , Catalin Marinas , Will Deacon , Anshuman Khandual , Yang Shi , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230704_164759_914681_CA06471C X-CRM114-Status: GOOD ( 53.58 ) 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 T24gVHVlLCBKdWwgNCwgMjAyMyBhdCA4OjA44oCvQU0gUnlhbiBSb2JlcnRzIDxyeWFuLnJvYmVy dHNAYXJtLmNvbT4gd3JvdGU6Cj4KPiBPbiAwNC8wNy8yMDIzIDAyOjM1LCBZdSBaaGFvIHdyb3Rl Ogo+ID4gT24gTW9uLCBKdWwgMywgMjAyMyBhdCA3OjUz4oCvQU0gUnlhbiBSb2JlcnRzIDxyeWFu LnJvYmVydHNAYXJtLmNvbT4gd3JvdGU6Cj4gPj4KPiA+PiBJbnRyb2R1Y2UgRkxFWElCTEVfVEhQ IGZlYXR1cmUsIHdoaWNoIGFsbG93cyBhbm9ueW1vdXMgbWVtb3J5IHRvIGJlCj4gPj4gYWxsb2Nh dGVkIGluIGxhcmdlIGZvbGlvcyBvZiBhIHNwZWNpZmllZCBvcmRlci4gQWxsIHBhZ2VzIG9mIHRo ZSBsYXJnZQo+ID4+IGZvbGlvIGFyZSBwdGUtbWFwcGVkIGR1cmluZyB0aGUgc2FtZSBwYWdlIGZh dWx0LCBzaWduaWZpY2FudGx5IHJlZHVjaW5nCj4gPj4gdGhlIG51bWJlciBvZiBwYWdlIGZhdWx0 cy4gVGhlIG51bWJlciBvZiBwZXItcGFnZSBvcGVyYXRpb25zIChlLmcuIHJlZgo+ID4+IGNvdW50 aW5nLCBybWFwIG1hbmFnZW1lbnQgbHJ1IGxpc3QgbWFuYWdlbWVudCkgYXJlIGFsc28gc2lnbmlm aWNhbnRseQo+ID4+IHJlZHVjZWQgc2luY2UgdGhvc2Ugb3BzIG5vdyBiZWNvbWUgcGVyLWZvbGlv Lgo+ID4+Cj4gPj4gVGhlIG5ldyBiZWhhdmlvdXIgaXMgaGlkZGVuIGJlaGluZCB0aGUgbmV3IEZM RVhJQkxFX1RIUCBLY29uZmlnLCB3aGljaAo+ID4+IGRlZmF1bHRzIHRvIGRpc2FibGVkIGZvciBu b3c7IHRoZXJlIGlzIGEgbG9uZyBsaXN0IG9mIHRvZG9zIHRvIG1ha2UKPiA+PiBGTEVYSUJMRV9U SFAgcm9idXN0IHdpdGggZXhpc3RpbmcgZmVhdHVyZXMgKGUuZy4gY29tcGFjdGlvbiwgbWxvY2ss IHNvbWUKPiA+PiBtYWR2aXNlIG9wcywgZXRjKS4gVGhlc2UgaXRlbXMgd2lsbCBiZSB0YWNrbGVk IGluIHN1YnNlcXVlbnQgcGF0Y2hlcy4KPiA+Pgo+ID4+IFdoZW4gZW5hYmxlZCwgdGhlIHByZWZl cnJlZCBmb2xpbyBvcmRlciBpcyBhcyByZXR1cm5lZCBieQo+ID4+IGFyY2hfd2FudHNfcHRlX29y ZGVyKCksIHdoaWNoIG1heSBiZSBvdmVycmlkZGVuIGJ5IHRoZSBhcmNoIGFzIGl0IHNlZXMKPiA+ PiBmaXQuIFNvbWUgYXJjaGl0ZWN0dXJlcyAoZS5nLiBhcm02NCkgY2FuIGNvYWxzZWNlIFRMQiBl bnRyaWVzIGlmIGEKPiA+Cj4gPiBjb2FsZXNjZQo+Cj4gQUNLCj4KPiA+Cj4gPj4gY29udGlndW91 cyBzZXQgb2YgcHRlcyBtYXAgcGh5c2ljYWxseSBjb250aWdpb3VzLCBuYXR1cmFsbHkgYWxpZ25l ZAo+ID4KPiA+IGNvbnRpZ3VvdXMKPgo+IEFDSwo+Cj4gPgo+ID4+IG1lbW9yeSwgc28gdGhpcyBt ZWNoYW5pc20gYWxsb3dzIHRoZSBhcmNoaXRlY3R1cmUgdG8gb3B0aW1pemUgYXMKPiA+PiByZXF1 aXJlZC4KPiA+Pgo+ID4+IElmIHRoZSBwcmVmZXJyZWQgb3JkZXIgY2FuJ3QgYmUgdXNlZCAoZS5n LiBiZWNhdXNlIHRoZSBmb2xpbyB3b3VsZAo+ID4+IGJyZWFjaCB0aGUgYm91bmRzIG9mIHRoZSB2 bWEsIG9yIGJlY2F1c2UgcHRlcyBpbiB0aGUgcmVnaW9uIGFyZSBhbHJlYWR5Cj4gPj4gbWFwcGVk KSB0aGVuIHdlIGZhbGwgYmFjayB0byBhIHN1aXRhYmxlIGxvd2VyIG9yZGVyLgo+ID4+Cj4gPj4g U2lnbmVkLW9mZi1ieTogUnlhbiBSb2JlcnRzIDxyeWFuLnJvYmVydHNAYXJtLmNvbT4KPiA+PiAt LS0KPiA+PiAgbW0vS2NvbmZpZyAgfCAgMTAgKysrKwo+ID4+ICBtbS9tZW1vcnkuYyB8IDE2OCAr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystLS0tCj4gPj4g IDIgZmlsZXMgY2hhbmdlZCwgMTY1IGluc2VydGlvbnMoKyksIDEzIGRlbGV0aW9ucygtKQo+ID4+ Cj4gPj4gZGlmZiAtLWdpdCBhL21tL0tjb25maWcgYi9tbS9LY29uZmlnCj4gPj4gaW5kZXggNzY3 MmEyMjY0N2I0Li4xYzA2YjJjMGEyNGUgMTAwNjQ0Cj4gPj4gLS0tIGEvbW0vS2NvbmZpZwo+ID4+ ICsrKyBiL21tL0tjb25maWcKPiA+PiBAQCAtODIyLDYgKzgyMiwxNiBAQCBjb25maWcgUkVBRF9P TkxZX1RIUF9GT1JfRlMKPiA+PiAgICAgICAgICAgc3VwcG9ydCBvZiBmaWxlIFRIUHMgd2lsbCBi ZSBkZXZlbG9wZWQgaW4gdGhlIG5leHQgZmV3IHJlbGVhc2UKPiA+PiAgICAgICAgICAgY3ljbGVz Lgo+ID4+Cj4gPj4gK2NvbmZpZyBGTEVYSUJMRV9USFAKPiA+PiArICAgICAgIGJvb2wgIkZsZXhp YmxlIG9yZGVyIFRIUCIKPiA+PiArICAgICAgIGRlcGVuZHMgb24gVFJBTlNQQVJFTlRfSFVHRVBB R0UKPiA+PiArICAgICAgIGRlZmF1bHQgbgo+ID4KPiA+IFRoZSBkZWZhdWx0IHZhbHVlIGlzIGFs cmVhZHkgTi4KPgo+IElzIHRoZXJlIGEgY29kaW5nIHN0YW5kYXJkIGZvciB0aGlzPyBQZXJzb25h bGx5IEkgcHJlZmVyIHRvIG1ha2UgaXQgZXhwbGljaXQuCj4KPiA+Cj4gPj4gKyAgICAgICBoZWxw Cj4gPj4gKyAgICAgICAgIFVzZSBsYXJnZSAoYmlnZ2VyIHRoYW4gb3JkZXItMCkgZm9saW9zIHRv IGJhY2sgYW5vbnltb3VzIG1lbW9yeSB3aGVyZQo+ID4+ICsgICAgICAgICBwb3NzaWJsZSwgZXZl biBpZiB0aGUgb3JkZXIgb2YgdGhlIGZvbGlvIGlzIHNtYWxsZXIgdGhhbiB0aGUgUE1ECj4gPj4g KyAgICAgICAgIG9yZGVyLiBUaGlzIHJlZHVjZXMgdGhlIG51bWJlciBvZiBwYWdlIGZhdWx0cywg YXMgd2VsbCBhcyBvdGhlcgo+ID4+ICsgICAgICAgICBwZXItcGFnZSBvdmVyaGVhZHMgdG8gaW1w cm92ZSBwZXJmb3JtYW5jZSBmb3IgbWFueSB3b3JrbG9hZHMuCj4gPj4gKwo+ID4+ICBlbmRpZiAj IFRSQU5TUEFSRU5UX0hVR0VQQUdFCj4gPj4KPiA+PiAgIwo+ID4+IGRpZmYgLS1naXQgYS9tbS9t ZW1vcnkuYyBiL21tL21lbW9yeS5jCj4gPj4gaW5kZXggZmIzMGY3NTIzNTUwLi5hYmUyZWE5NGYz ZjUgMTAwNjQ0Cj4gPj4gLS0tIGEvbW0vbWVtb3J5LmMKPiA+PiArKysgYi9tbS9tZW1vcnkuYwo+ ID4+IEBAIC0zMDAxLDYgKzMwMDEsMTE2IEBAIHN0YXRpYyB2bV9mYXVsdF90IGZhdWx0X2RpcnR5 X3NoYXJlZF9wYWdlKHN0cnVjdCB2bV9mYXVsdCAqdm1mKQo+ID4+ICAgICAgICAgcmV0dXJuIDA7 Cj4gPj4gIH0KPiA+Pgo+ID4+ICsjaWZkZWYgQ09ORklHX0ZMRVhJQkxFX1RIUAo+ID4+ICsvKgo+ ID4+ICsgKiBBbGxvY2F0ZXMsIHplcm9zIGFuZCByZXR1cm5zIGEgZm9saW8gb2YgdGhlIHJlcXVl c3RlZCBvcmRlciBmb3IgdXNlIGFzCj4gPj4gKyAqIGFub255bW91cyBtZW1vcnkuCj4gPj4gKyAq Lwo+ID4+ICtzdGF0aWMgc3RydWN0IGZvbGlvICphbGxvY19hbm9uX2ZvbGlvKHN0cnVjdCB2bV9h cmVhX3N0cnVjdCAqdm1hLAo+ID4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgdW5zaWduZWQgbG9uZyBhZGRyLCBpbnQgb3JkZXIpCj4gPj4gK3sKPiA+PiArICAgICAgIGdm cF90IGdmcDsKPiA+PiArICAgICAgIHN0cnVjdCBmb2xpbyAqZm9saW87Cj4gPj4gKwo+ID4+ICsg ICAgICAgaWYgKG9yZGVyID09IDApCj4gPj4gKyAgICAgICAgICAgICAgIHJldHVybiB2bWFfYWxs b2NfemVyb2VkX21vdmFibGVfZm9saW8odm1hLCBhZGRyKTsKPiA+PiArCj4gPj4gKyAgICAgICBn ZnAgPSB2bWFfdGhwX2dmcF9tYXNrKHZtYSk7Cj4gPj4gKyAgICAgICBmb2xpbyA9IHZtYV9hbGxv Y19mb2xpbyhnZnAsIG9yZGVyLCB2bWEsIGFkZHIsIHRydWUpOwo+ID4+ICsgICAgICAgaWYgKGZv bGlvKQo+ID4+ICsgICAgICAgICAgICAgICBjbGVhcl9odWdlX3BhZ2UoJmZvbGlvLT5wYWdlLCBh ZGRyLCBmb2xpb19ucl9wYWdlcyhmb2xpbykpOwo+ID4+ICsKPiA+PiArICAgICAgIHJldHVybiBm b2xpbzsKPiA+PiArfQo+ID4+ICsKPiA+PiArLyoKPiA+PiArICogUHJlZmVycmVkIGZvbGlvIG9y ZGVyIHRvIGFsbG9jYXRlIGZvciBhbm9ueW1vdXMgbWVtb3J5Lgo+ID4+ICsgKi8KPiA+PiArI2Rl ZmluZSBtYXhfYW5vbl9mb2xpb19vcmRlcih2bWEpICAgICAgYXJjaF93YW50c19wdGVfb3JkZXIo dm1hKQo+ID4+ICsjZWxzZQo+ID4+ICsjZGVmaW5lIGFsbG9jX2Fub25fZm9saW8odm1hLCBhZGRy LCBvcmRlcikgXAo+ID4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm1hX2FsbG9j X3plcm9lZF9tb3ZhYmxlX2ZvbGlvKHZtYSwgYWRkcikKPiA+PiArI2RlZmluZSBtYXhfYW5vbl9m b2xpb19vcmRlcih2bWEpICAgICAgMAo+ID4+ICsjZW5kaWYKPiA+PiArCj4gPj4gKy8qCj4gPj4g KyAqIFJldHVybnMgaW5kZXggb2YgZmlyc3QgcHRlIHRoYXQgaXMgbm90IG5vbmUsIG9yIG5yIGlm IGFsbCBhcmUgbm9uZS4KPiA+PiArICovCj4gPj4gK3N0YXRpYyBpbmxpbmUgaW50IGNoZWNrX3B0 ZXNfbm9uZShwdGVfdCAqcHRlLCBpbnQgbnIpCj4gPj4gK3sKPiA+PiArICAgICAgIGludCBpOwo+ ID4+ICsKPiA+PiArICAgICAgIGZvciAoaSA9IDA7IGkgPCBucjsgaSsrKSB7Cj4gPj4gKyAgICAg ICAgICAgICAgIGlmICghcHRlX25vbmUocHRlcF9nZXQocHRlKyspKSkKPiA+PiArICAgICAgICAg ICAgICAgICAgICAgICByZXR1cm4gaTsKPiA+PiArICAgICAgIH0KPiA+PiArCj4gPj4gKyAgICAg ICByZXR1cm4gbnI7Cj4gPj4gK30KPiA+PiArCj4gPj4gK3N0YXRpYyBpbnQgY2FsY19hbm9uX2Zv bGlvX29yZGVyX2FsbG9jKHN0cnVjdCB2bV9mYXVsdCAqdm1mLCBpbnQgb3JkZXIpCj4gPj4gK3sK PiA+PiArICAgICAgIC8qCj4gPj4gKyAgICAgICAgKiBUaGUgYWltIGhlcmUgaXMgdG8gZGV0ZXJt aW5lIHdoYXQgc2l6ZSBvZiBmb2xpbyB3ZSBzaG91bGQgYWxsb2NhdGUKPiA+PiArICAgICAgICAq IGZvciB0aGlzIGZhdWx0LiBGYWN0b3JzIGluY2x1ZGU6Cj4gPj4gKyAgICAgICAgKiAtIE9yZGVy IG11c3Qgbm90IGJlIGhpZ2hlciB0aGFuIGBvcmRlcmAgdXBvbiBlbnRyeQo+ID4+ICsgICAgICAg ICogLSBGb2xpbyBtdXN0IGJlIG5hdHVyYWxseSBhbGlnbmVkIHdpdGhpbiBWQSBzcGFjZQo+ID4+ ICsgICAgICAgICogLSBGb2xpbyBtdXN0IGJlIGZ1bGx5IGNvbnRhaW5lZCBpbnNpZGUgb25lIHBt ZCBlbnRyeQo+ID4+ICsgICAgICAgICogLSBGb2xpbyBtdXN0IG5vdCBicmVhY2ggYm91bmRhcmll cyBvZiB2bWEKPiA+PiArICAgICAgICAqIC0gRm9saW8gbXVzdCBub3Qgb3ZlcmxhcCBhbnkgbm9u LW5vbmUgcHRlcwo+ID4+ICsgICAgICAgICoKPiA+PiArICAgICAgICAqIEFkZGl0aW9uYWxseSwg d2UgZG8gbm90IGFsbG93IG9yZGVyLTEgc2luY2UgdGhpcyBicmVha3MgYXNzdW1wdGlvbnMKPiA+ PiArICAgICAgICAqIGVsc2V3aGVyZSBpbiB0aGUgbW07IFRIUCBwYWdlcyBtdXN0IGJlIGF0IGxl YXN0IG9yZGVyLTIgKHNpbmNlIHRoZXkKPiA+PiArICAgICAgICAqIHN0b3JlIHN0YXRlIHVwIHRv IHRoZSAzcmQgc3RydWN0IHBhZ2Ugc3VicGFnZSksIGFuZCB0aGVzZSBwYWdlcyBtdXN0Cj4gPj4g KyAgICAgICAgKiBiZSBUSFAgaW4gb3JkZXIgdG8gY29ycmVjdGx5IHVzZSBwcmUtZXhpc3Rpbmcg VEhQIGluZnJhc3RydWN0dXJlIHN1Y2gKPiA+PiArICAgICAgICAqIGFzIGZvbGlvX3NwbGl0KCku Cj4gPj4gKyAgICAgICAgKgo+ID4+ICsgICAgICAgICogTm90ZSB0aGF0IHRoZSBjYWxsZXIgbWF5 IG9yIG1heSBub3QgY2hvb3NlIHRvIGxvY2sgdGhlIHB0ZS4gSWYKPiA+PiArICAgICAgICAqIHVu bG9ja2VkLCB0aGUgcmVzdWx0IGlzIHJhY3kgYW5kIHRoZSB1c2VyIG11c3QgcmUtY2hlY2sgYW55 IG92ZXJsYXAKPiA+PiArICAgICAgICAqIHdpdGggbm9uLW5vbmUgcHRlcyB1bmRlciB0aGUgbG9j ay4KPiA+PiArICAgICAgICAqLwo+ID4+ICsKPiA+PiArICAgICAgIHN0cnVjdCB2bV9hcmVhX3N0 cnVjdCAqdm1hID0gdm1mLT52bWE7Cj4gPj4gKyAgICAgICBpbnQgbnI7Cj4gPj4gKyAgICAgICB1 bnNpZ25lZCBsb25nIGFkZHI7Cj4gPj4gKyAgICAgICBwdGVfdCAqcHRlOwo+ID4+ICsgICAgICAg cHRlX3QgKmZpcnN0X3NldCA9IE5VTEw7Cj4gPj4gKyAgICAgICBpbnQgcmV0Owo+ID4+ICsKPiA+ PiArICAgICAgIG9yZGVyID0gbWluKG9yZGVyLCBQTURfU0hJRlQgLSBQQUdFX1NISUZUKTsKPiA+ PiArCj4gPj4gKyAgICAgICBmb3IgKDsgb3JkZXIgPiAxOyBvcmRlci0tKSB7Cj4gPgo+ID4gSSdt IG5vdCBzdXJlIGhvdyB3ZSBjYW4ganVzdGlmeSB0aGlzIHBvbGljeS4gQXMgYW4gaW5pdGlhbCBz dGVwLCBpdCdkCj4gPiBiZSBhIGxvdCBlYXNpZXIgdG8gc2VsbCBpZiB3ZSBvbmx5IGNvbnNpZGVy ZWQgdGhlIG9yZGVyIG9mCj4gPiBhcmNoX3dhbnRzX3B0ZV9vcmRlcigpIGFuZCB0aGUgb3JkZXIg MC4KPgo+IE15IGp1c3RpZmljYXRpb24gaXMgaW4gdGhlIGNvdmVyIGxldHRlcjsgSSBzZWUgcGVy Zm9ybWFuY2UgcmVncmVzc2lvbiAodnMgdGhlCj4gdW5wYXRjaGVkIGtlcm5lbCkgd2hlbiB1c2lu ZyB0aGUgcG9saWN5IHlvdSBzdWdnZXN0LiBUaGlzIHBvbGljeSBwZXJmb3JtcyBtdWNoCj4gYmV0 dGVyIGluIG15IHRlc3RzLiAoSSdsbCByZXBseSBkaXJlY3RseSB0byB5b3VyIGZvbGxvdyB1cCBx dWVzdGlvbnMgaW4gdGhlCj4gY292ZXIgbGV0dGVyIHNob3J0bHkpLgo+Cj4gV2hhdCBhcmUgeW91 ciB0ZWNobmljYWwgY29uY2VybnMgYWJvdXQgdGhpcyBhcHByb2FjaD8gSXQgaXMgcHJldHR5IGxp Z2h0IHdlaWdodAo+IChJIG9ubHkgdG91Y2ggZWFjaCBQVEUgb25jZSwgcmVnYXJkbGVzcyBvZiB0 aGUgbnVtYmVyIG9mIGxvb3BzKS4gSWYgd2UgaGF2ZQo+IHN0cm9uZyB0ZWNobmljYWwgcmVhc29u cyBmb3IgcmV2ZXJ0aW5nIHRvIHRoZSBsZXNzIHBlcmZvcm1hbnQgYXBwcm9hY2ggdGhlbiBmYWly Cj4gZW5vdWdoLCBidXQgSSdkIGxpa2UgdG8gaGVhciB0aGUgcmF0aW9uYWwgZmlyc3QuCgpZZXMs IG1haW5seSBmcm9tIHRocmVlIGRpZmZlcmVudCBhbmdsZXM6CjEuIFRoZSBlbmdpbmVlcmluZyBw cmluY2lwbGU6IHdlJ2Qgd2FudCB0byBzZXBhcmF0ZSB0aGUgbWVjaGFuaWNhbApwYXJ0IGFuZCB0 aGUgcG9saWN5IHBhcnQgd2hlbiBhdHRhY2tpbmcgc29tZXRoaW5nIGxhcmdlLiBUaGlzIHdheSBp dCdkCmJlIGVhc2llciB0byByb290IGNhdXNlIGFueSByZWdyZXNzaW9ucyBpZiB0aGV5IGhhcHBl bi4gSW4gb3VyIGNhc2UsCmFzc3VtaW5nIHRoZSByZWdyZXNzaW9uIGlzIHJlYWwsIGl0IG1pZ2h0 IGFjdHVhbGx5IHByb3ZlIG15IHBvaW50CmhlcmU6IEkgcmVhbGx5IGRvbid0IHRoaW5rIHRoZSB0 d28gY2hlY2tzIChpZiBhIHZtYSByYW5nZSBmaXRzIGFuZCBpZgppdCBkb2VzLCB3aGljaCBpcyB1 bmxpa2VseSBhY2NvcmRpbmcgdG8geW91ciBkZXNjcmlwdGlvbiwgaWYgYWxsIDY0ClBURXMgYXJl IG5vbmUpIGNhdXNlZCB0aGUgcmVncmVzc2lvbi4gTXkgdGhlb3J5IGlzIHRoYXQgNjRLQiBpdHNl bGYKY2F1c2VkIHRoZSByZWdyZXNzaW9uLCBidXQgc21hbGxlciBzaXplcyBtYWRlIGFuIGltcHJv dmVtZW50LiBJZiB0aGlzCmlzIHJlYWxseSB0aGUgY2FzZSwgSSdkIHNheSB0aGUgZmFsbGJhY2sg cG9saWN5IG1hc2tlZCB0aGUgcmVhbApwcm9ibGVtLCB3aGljaCBpcyB0aGF0IDY0S0IgaXMgdG9v IGxhcmdlIHRvIGJlZ2luIHdpdGguCjIuIFRoZSBiZW5jaG1hcmsgbWV0aG9kb2xvZ3k6IEkgYXBw cmVjaWF0ZSB5b3VyIGVmZm9ydCBpbiBkb2luZyBpdCwKYnV0IHdlIGFsc28gbmVlZCB0byBjb25z aWRlciB0aGF0IHRoZSBzZXR1cCBpcyBhbiB1bmNvbW1vbiBzY2VuYXJpby4KVGhlIGNvbW1vbiBz Y2VuYXJpb3MgYXJlIGRldmljZXMgdGhhdCBoYXZlIGJlZW4gcnVubmluZyBmb3Igd2Vla3MKd2l0 aG91dCByZWJvb3RzLCBnZW5lcmFsbHkgaGF2aW5nIGhpZ2hlciBleHRlcm5hbCBmcmFnbWVudGF0 aW9uLiBJbgphZGRpdGlvbiwgZm9yIGNsaWVudCBkZXZpY2VzLCB0aGV5IGFyZSBvZnRlbiB1bmRl ciBtZW1vcnkgcHJlc3N1cmUsCndoaWNoIG1ha2VzIGZyYWdtZW50YXRpb24gd29yc2UuIFNvIHdl IHNob3VsZCB0YWtlIHRoZSByZXN1bHQgd2l0aCBhCmdyYWluIG9mIHNhbHQsIGFuZCBmb3IgdGhh dCBtYXR0ZXIsIHJlc3VsdHMgZnJvbSBhZnRlciByZWZyZXNoCnJlYm9vdHMuCjMuIFRoZSB0ZWNo bmljYWwgY29uY2VybjogYW4gaWRlYWwgcG9saWN5IHdvdWxkIGNvbnNpZGVyIGFsbCB0aHJlZQpt YWpvciBmYWN0b3JzOiB0aGUgaC93IGZlYXR1cmVzLCB1c2Vyc3BhY2UgYmVoYXZpb3JzIGFuZCB0 aGUgcGFnZQphbGxvY2F0b3IgYmVoYXZpb3IuIFNvIGZhciB3ZSBvbmx5IGhhdmUgdGhlIGZpcnN0 IG9uZSBoYW5keS4gVGhlCnNlY29uZCBvbmUgaXMgdG9vIGNoYWxsZW5naW5nLCBzbyBsZXQncyBm b3JnZXQgYWJvdXQgaXQgZm9yIG5vdy4gVGhlCnRoaXJkIG9uZSBpcyB3aHkgSSByZWFsbHkgZG9u J3QgbGlrZSB0aGlzIGJlc3QtZml0IHBvbGljeS4gQnkgZmFsbGluZwpiYWNrIHRvIHNtYWxsZXIg b3JkZXJzLCB3ZSBjYW4gd2FzdGUgYSBsaW1pdGVkIG51bWJlciBvZiBwaHlzaWNhbGx5CmNvbnRp Z3VvdXMgcGFnZXMgb24gd3Jvbmcgdm1hcyAoc21hbGwgdm1hcyBvbmx5KSwgbGVhZGluZyB0byBm YWlsdXJlcwp0byBzZXJ2ZSBsYXJnZSB2bWFzIHdoaWNoIG90aGVyd2lzZSB3b3VsZCBoYXZlIGEg aGlnaGVyIG92ZXJhbGwgUk9JLgpUaGlzIGNhbiBvbmx5IGJlIGFkZHJlc3NlZCB3aXRoaW4gdGhl IHBhZ2UgYWxsb2NhdG9yOiB3ZSBuZWVkIHRvCmVubGlnaHRlbiBpdCB0byByZXR1cm4gdGhlIGhp Z2hlc3Qgb3JkZXIgYXZhaWxhYmxlLCBpLmUuLCBub3QgYnJlYWtpbmcKdXAgYW55IGhpZ2hlciBv cmRlcnMuCgpJJ20gbm90IHJlYWxseSBzYXlpbmcgd2Ugc2hvdWxkIG5ldmVyIHRyeSB0aGlzIGZh bGxiYWNrIHBvbGljeS4gSSdtCmp1c3QgdGhpbmtpbmcgd2UgY2FuIGxlYXZlIGl0IGZvciBsYXRl ciwgcHJvYmFibHkgYWZ0ZXIgd2UndmUKYWRkcmVzc2VkIGFsbCB0aGUgY29uY2VybnMgd2l0aCBi YXNpYyBmdW5jdGlvbmFsaXR5LgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5l bEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4v bGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=