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 X-Spam-Level: X-Spam-Status: No, score=-15.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D468DC433E0 for ; Wed, 24 Feb 2021 11:23:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6094364E6F for ; Wed, 24 Feb 2021 11:23:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234972AbhBXLXQ (ORCPT ); Wed, 24 Feb 2021 06:23:16 -0500 Received: from ste-pvt-msa1.bahnhof.se ([213.80.101.70]:6925 "EHLO ste-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234428AbhBXLXL (ORCPT ); Wed, 24 Feb 2021 06:23:11 -0500 Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 1C7733F6BE; Wed, 24 Feb 2021 12:22:28 +0100 (CET) Authentication-Results: ste-pvt-msa1.bahnhof.se; dkim=pass (1024-bit key; unprotected) header.d=shipmail.org header.i=@shipmail.org header.b=EVaDehv0; dkim-atps=neutral X-Virus-Scanned: Debian amavisd-new at bahnhof.se Received: from ste-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (ste-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 15NA1H9FNQ0V; Wed, 24 Feb 2021 12:22:26 +0100 (CET) Received: by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 4DE4B3F6A9; Wed, 24 Feb 2021 12:22:24 +0100 (CET) Received: from [10.249.254.217] (irdmzpr01-ext.ir.intel.com [192.198.151.36]) by mail1.shipmail.org (Postfix) with ESMTPSA id DDB82360143; Wed, 24 Feb 2021 12:22:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=shipmail.org; s=mail; t=1614165743; bh=n7I66PZkRu3hifCNiv/xeWx2Q6GJ9EWDh6EeIzJr3jA=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=EVaDehv07MSF84yZ+d8dM3x5eGqnDY2z6Yie6r5n3CSDPLDEaE8VussS2LEvOm1je yVqx16FOSdF5bRLNkVmqsOXHfGEIUAjRnN1adVj8doxsTNNAVMwLSz8PbH0CINQM0W ZzF2p9KA51lCQr1Ka/2uTcnlSRxVSMg7ZQ5YDq/A= Subject: Re: [Linaro-mm-sig] [PATCH] dma-fence: Document recoverable page fault implications To: Daniel Vetter Cc: DRI Development , Felix Kuehling , Maarten Lankhorst , "moderated list:DMA BUFFER SHARING FRAMEWORK" , Jerome Glisse , =?UTF-8?Q?Thomas_Hellstr=c3=b6m?= , Daniel Vetter , =?UTF-8?Q?Christian_K=c3=b6nig?= , "open list:DMA BUFFER SHARING FRAMEWORK" References: <20210203152921.2429937-1-daniel.vetter@ffwll.ch> <81df5b1c-2838-49d8-4ae4-bab4f55b411a@shipmail.org> From: =?UTF-8?Q?Thomas_Hellstr=c3=b6m_=28Intel=29?= Message-ID: <8275e507-603d-81aa-872b-f829da1ad1c6@shipmail.org> Date: Wed, 24 Feb 2021 12:22:20 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On 2/24/21 10:26 AM, Daniel Vetter wrote: > On Wed, Feb 24, 2021 at 9:47 AM Thomas Hellström (Intel) > wrote: >> >> On 2/3/21 4:29 PM, Daniel Vetter wrote: >>> Recently there was a fairly long thread about recoreable hardware page >>> faults, how they can deadlock, and what to do about that. >>> >>> While the discussion is still fresh I figured good time to try and >>> document the conclusions a bit. This documentation section explains >>> what's the potential problem, and the remedies we've discussed, >>> roughly ordered from best to worst. >>> >>> v2: Linus -> Linux typoe (Dave) >>> >>> v3: >>> - Make it clear drivers only need to implement one option (Christian) >>> - Make it clearer that implicit sync is out the window with exclusive >>> fences (Christian) >>> - Add the fairly theoretical option of segementing the memory (either >>> statically or through dynamic checks at runtime for which piece of >>> memory is managed how) and explain why it's not a great idea (Felix) >>> >>> References: https://lore.kernel.org/dri-devel/20210107030127.20393-1-Felix.Kuehling@amd.com/ >>> Cc: Dave Airlie >>> Cc: Maarten Lankhorst >>> Cc: Thomas Hellström >>> Cc: "Christian König" >>> Cc: Jerome Glisse >>> Cc: Felix Kuehling >>> Signed-off-by: Daniel Vetter >>> Cc: Sumit Semwal >>> Cc: linux-media@vger.kernel.org >>> Cc: linaro-mm-sig@lists.linaro.org >>> --- >>> Documentation/driver-api/dma-buf.rst | 76 ++++++++++++++++++++++++++++ >>> 1 file changed, 76 insertions(+) >>> >>> diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst >>> index a2133d69872c..7f37ec30d9fd 100644 >>> --- a/Documentation/driver-api/dma-buf.rst >>> +++ b/Documentation/driver-api/dma-buf.rst >>> @@ -257,3 +257,79 @@ fences in the kernel. This means: >>> userspace is allowed to use userspace fencing or long running compute >>> workloads. This also means no implicit fencing for shared buffers in these >>> cases. >>> + >>> +Recoverable Hardware Page Faults Implications >>> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >>> + >>> +Modern hardware supports recoverable page faults, which has a lot of >>> +implications for DMA fences. >>> + >>> +First, a pending page fault obviously holds up the work that's running on the >>> +accelerator and a memory allocation is usually required to resolve the fault. >>> +But memory allocations are not allowed to gate completion of DMA fences, which >>> +means any workload using recoverable page faults cannot use DMA fences for >>> +synchronization. Synchronization fences controlled by userspace must be used >>> +instead. >>> + >>> +On GPUs this poses a problem, because current desktop compositor protocols on >>> +Linux rely on DMA fences, which means without an entirely new userspace stack >>> +built on top of userspace fences, they cannot benefit from recoverable page >>> +faults. Specifically this means implicit synchronization will not be possible. >>> +The exception is when page faults are only used as migration hints and never to >>> +on-demand fill a memory request. For now this means recoverable page >>> +faults on GPUs are limited to pure compute workloads. >>> + >>> +Furthermore GPUs usually have shared resources between the 3D rendering and >>> +compute side, like compute units or command submission engines. If both a 3D >>> +job with a DMA fence and a compute workload using recoverable page faults are >>> +pending they could deadlock: >>> + >>> +- The 3D workload might need to wait for the compute job to finish and release >>> + hardware resources first. >>> + >>> +- The compute workload might be stuck in a page fault, because the memory >>> + allocation is waiting for the DMA fence of the 3D workload to complete. >>> + >>> +There are a few options to prevent this problem, one of which drivers need to >>> +ensure: >>> + >>> +- Compute workloads can always be preempted, even when a page fault is pending >>> + and not yet repaired. Not all hardware supports this. >>> + >>> +- DMA fence workloads and workloads which need page fault handling have >>> + independent hardware resources to guarantee forward progress. This could be >>> + achieved through e.g. through dedicated engines and minimal compute unit >>> + reservations for DMA fence workloads. >>> + >>> +- The reservation approach could be further refined by only reserving the >>> + hardware resources for DMA fence workloads when they are in-flight. This must >>> + cover the time from when the DMA fence is visible to other threads up to >>> + moment when fence is completed through dma_fence_signal(). >>> + >>> +- As a last resort, if the hardware provides no useful reservation mechanics, >>> + all workloads must be flushed from the GPU when switching between jobs >>> + requiring DMA fences or jobs requiring page fault handling: This means all DMA >>> + fences must complete before a compute job with page fault handling can be >>> + inserted into the scheduler queue. And vice versa, before a DMA fence can be >>> + made visible anywhere in the system, all compute workloads must be preempted >>> + to guarantee all pending GPU page faults are flushed. >>> + >>> +- Only a fairly theoretical option would be to untangle these dependencies when >>> + allocating memory to repair hardware page faults, either through separate >>> + memory blocks or runtime tracking of the full dependency graph of all DMA >>> + fences. This results very wide impact on the kernel, since resolving the page >>> + on the CPU side can itself involve a page fault. It is much more feasible and >>> + robust to limit the impact of handling hardware page faults to the specific >>> + driver. >>> + >>> +Note that workloads that run on independent hardware like copy engines or other >>> +GPUs do not have any impact. This allows us to keep using DMA fences internally >>> +in the kernel even for resolving hardware page faults, e.g. by using copy >>> +engines to clear or copy memory needed to resolve the page fault. >>> + >>> +In some ways this page fault problem is a special case of the `Infinite DMA >>> +Fences` discussions: Infinite fences from compute workloads are allowed to >>> +depend on DMA fences, but not the other way around. And not even the page fault >>> +problem is new, because some other CPU thread in userspace might >>> +hit a page fault which holds up a userspace fence - supporting page faults on >>> +GPUs doesn't anything fundamentally new. >> To me, in general this looks good. One thing, though is that for a first >> time reader it might not be totally clear what's special with a compute >> workload. Perhaps some clarification? > In the docs this new section is right after the infinite fence > section, which goes through this kind of stuff. So it's not so much > "compute workloads" but "infinite fences", which I think is explained > plenty enough. > OK, >> Also since the current cross-driver dma_fence locking order is >> >> 1) dma_resv -> >> 2) memory_allocation / reclaim -> >> 3) dma_fence_wait/critical >> >> And the locking order required for recoverable pagefault is >> >> a) dma_resv -> >> b) fence_wait/critical -> >> c) memory_allocation / reclaim >> >> (Possibly with a) and b) interchanged above, Is it possible to service a >> recoverable pagefault without taking the dma_resv lock?) > It's worse, since the lock order we care about is: > 1) mmap_sem > 2) dma_resv > 3) reclaim > 4) dma_fence_wait > > And for this nice brave new world of unified shared memory/hmm, we > really need to be able to resolve arbitrary cpu side page faults (with > fixup_user_fault() like the iommu driver does too for PASID mode) to > be able to serve gpu page faults. So even if we take dma_resv > completely out of the system we still have: > > 1) mmap_sem > 2) reclaim > 3) dma_fence_wait > > So we'd also need to throw out dma_fence_wait, and at that point we're > looking at a new gpu driver stack. > Meaning that the locking order for workloads with recoverable page faults becomes: a) dma_fence_wait/critical b) mmap_sem c) dma_resv d) reclaim which I agree we can't really use with the current stack whatever we do with dma_fence_wait vs reclaim. >> It's clear that the fence critical section in b) is not compatible with >> the dma_fence wait in 3) and thus the memory restrictions are needed. >> But I think given the memory allocation restrictions for recoverable >> pagefaults I guess at some point we must ask ourselves why are they >> necessary and what's the price to be paid for getting rid of them, and >> document also that. *If* it's the case that it all boils down to the 2) >> -> 3) locking order above, and that's mandated *only* by the dma_fence >> wait in the userptr mmu notifiers, I think these restrictions are a >> pretty high price to pay. Wouldn't it be possible now to replace that >> fence wait with either page pinning (which now is coherent since 5.9) or >> preempt-ctx fences + unpinned pages if available and thus invert the 2) >> -> 3) locking order? > It's not just userptr, it's also shrinkers. mmap_sem requires > GFP_KERNEL allocations, so that already excludes our shrinkers if we > want this. That means gpu memory becomes pinned when it's managed with > dma_fence. Christian König just reworked ttm to stop doing that, to > remove the hard and fairly arbitrary "max 50% of system memory" limit. Even with shrinkers, and assuming there is no guarantee we can preempt, one could tag memory / bos for release on next reservation / dma_fence signal whatever happens first, which would not give memory back on direct reclaim, but will eventually release it. Will not help with the mmap_sem issue, though. > > > Note that just preempt-ctx fences alone isn't enough, since you could > end up with something like this: > - compute workload using gpu page faults hangs a all of the > compute/shadercores on page faults, we can't preempt > - concurrently there's a 3d workload running, which because fixed > function, and only preempt between draw calls. it is stuck waiting for > some shader cores to become avaiable. this is possible because most > gpus nowadays have separate command queues for compute/3d workloads > - our kernel page fault handler for the compute job wants to preempt > the 3d workload, which wont happen > - everyone is firmly stuck and the user gets angry Yes, preempt-ctx fences would indeed have to be guaranteed to be able to preempt to work, using one of the options described above, But in general, inverting reclaim and dma_fence_wait would actually resolve this particular situation, even if it doesn't help with recoverable pagefaults due to mmap_sem: - kernel page fault handler ends up in shrinker tagging 3D workload resources for release - Moves on to another shrinker that succeeds to release enough memory - Compute workload proceeds - 3D workload proceeds. ..But just wanting to get the full picture of what the tradeoffs of this really are. /Thomas > > So just requiring that everything uses preempt-ctx fences isn't enough > due to shared resources possible blocking preemption even across > engines. Plus we'd still have the problem that dma_fence_wait from > reclaim isn't allowed, pinning all the 3d workload memory for good. > > Aside: This means that for compute workloads using page faults we > cannot use preempt-ctx fences either, but instead memory reclaim has > to exclusively use pte zapping (both shrinker and mmu notifier). > > Cheers, Daniel 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 X-Spam-Level: X-Spam-Status: No, score=-15.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C9BD9C433E0 for ; Wed, 24 Feb 2021 11:22:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1FD03600CF for ; Wed, 24 Feb 2021 11:22:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1FD03600CF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=shipmail.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6C84989DA5; Wed, 24 Feb 2021 11:22:31 +0000 (UTC) Received: from ste-pvt-msa1.bahnhof.se (ste-pvt-msa1.bahnhof.se [213.80.101.70]) by gabe.freedesktop.org (Postfix) with ESMTPS id C37DC89DA5 for ; Wed, 24 Feb 2021 11:22:29 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 1C7733F6BE; Wed, 24 Feb 2021 12:22:28 +0100 (CET) Authentication-Results: ste-pvt-msa1.bahnhof.se; dkim=pass (1024-bit key; unprotected) header.d=shipmail.org header.i=@shipmail.org header.b=EVaDehv0; dkim-atps=neutral X-Virus-Scanned: Debian amavisd-new at bahnhof.se Received: from ste-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (ste-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 15NA1H9FNQ0V; Wed, 24 Feb 2021 12:22:26 +0100 (CET) Received: by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 4DE4B3F6A9; Wed, 24 Feb 2021 12:22:24 +0100 (CET) Received: from [10.249.254.217] (irdmzpr01-ext.ir.intel.com [192.198.151.36]) by mail1.shipmail.org (Postfix) with ESMTPSA id DDB82360143; Wed, 24 Feb 2021 12:22:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=shipmail.org; s=mail; t=1614165743; bh=n7I66PZkRu3hifCNiv/xeWx2Q6GJ9EWDh6EeIzJr3jA=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=EVaDehv07MSF84yZ+d8dM3x5eGqnDY2z6Yie6r5n3CSDPLDEaE8VussS2LEvOm1je yVqx16FOSdF5bRLNkVmqsOXHfGEIUAjRnN1adVj8doxsTNNAVMwLSz8PbH0CINQM0W ZzF2p9KA51lCQr1Ka/2uTcnlSRxVSMg7ZQ5YDq/A= Subject: Re: [Linaro-mm-sig] [PATCH] dma-fence: Document recoverable page fault implications To: Daniel Vetter References: <20210203152921.2429937-1-daniel.vetter@ffwll.ch> <81df5b1c-2838-49d8-4ae4-bab4f55b411a@shipmail.org> From: =?UTF-8?Q?Thomas_Hellstr=c3=b6m_=28Intel=29?= Message-ID: <8275e507-603d-81aa-872b-f829da1ad1c6@shipmail.org> Date: Wed, 24 Feb 2021 12:22:20 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Felix Kuehling , DRI Development , "moderated list:DMA BUFFER SHARING FRAMEWORK" , Jerome Glisse , =?UTF-8?Q?Thomas_Hellstr=c3=b6m?= , Daniel Vetter , =?UTF-8?Q?Christian_K=c3=b6nig?= , "open list:DMA BUFFER SHARING FRAMEWORK" Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Ck9uIDIvMjQvMjEgMTA6MjYgQU0sIERhbmllbCBWZXR0ZXIgd3JvdGU6Cj4gT24gV2VkLCBGZWIg MjQsIDIwMjEgYXQgOTo0NyBBTSBUaG9tYXMgSGVsbHN0csO2bSAoSW50ZWwpCj4gPHRob21hc19v c0BzaGlwbWFpbC5vcmc+IHdyb3RlOgo+Pgo+PiBPbiAyLzMvMjEgNDoyOSBQTSwgRGFuaWVsIFZl dHRlciB3cm90ZToKPj4+IFJlY2VudGx5IHRoZXJlIHdhcyBhIGZhaXJseSBsb25nIHRocmVhZCBh Ym91dCByZWNvcmVhYmxlIGhhcmR3YXJlIHBhZ2UKPj4+IGZhdWx0cywgaG93IHRoZXkgY2FuIGRl YWRsb2NrLCBhbmQgd2hhdCB0byBkbyBhYm91dCB0aGF0Lgo+Pj4KPj4+IFdoaWxlIHRoZSBkaXNj dXNzaW9uIGlzIHN0aWxsIGZyZXNoIEkgZmlndXJlZCBnb29kIHRpbWUgdG8gdHJ5IGFuZAo+Pj4g ZG9jdW1lbnQgdGhlIGNvbmNsdXNpb25zIGEgYml0LiBUaGlzIGRvY3VtZW50YXRpb24gc2VjdGlv biBleHBsYWlucwo+Pj4gd2hhdCdzIHRoZSBwb3RlbnRpYWwgcHJvYmxlbSwgYW5kIHRoZSByZW1l ZGllcyB3ZSd2ZSBkaXNjdXNzZWQsCj4+PiByb3VnaGx5IG9yZGVyZWQgZnJvbSBiZXN0IHRvIHdv cnN0Lgo+Pj4KPj4+IHYyOiBMaW51cyAtPiBMaW51eCB0eXBvZSAoRGF2ZSkKPj4+Cj4+PiB2MzoK Pj4+IC0gTWFrZSBpdCBjbGVhciBkcml2ZXJzIG9ubHkgbmVlZCB0byBpbXBsZW1lbnQgb25lIG9w dGlvbiAoQ2hyaXN0aWFuKQo+Pj4gLSBNYWtlIGl0IGNsZWFyZXIgdGhhdCBpbXBsaWNpdCBzeW5j IGlzIG91dCB0aGUgd2luZG93IHdpdGggZXhjbHVzaXZlCj4+PiAgICAgZmVuY2VzIChDaHJpc3Rp YW4pCj4+PiAtIEFkZCB0aGUgZmFpcmx5IHRoZW9yZXRpY2FsIG9wdGlvbiBvZiBzZWdlbWVudGlu ZyB0aGUgbWVtb3J5IChlaXRoZXIKPj4+ICAgICBzdGF0aWNhbGx5IG9yIHRocm91Z2ggZHluYW1p YyBjaGVja3MgYXQgcnVudGltZSBmb3Igd2hpY2ggcGllY2Ugb2YKPj4+ICAgICBtZW1vcnkgaXMg bWFuYWdlZCBob3cpIGFuZCBleHBsYWluIHdoeSBpdCdzIG5vdCBhIGdyZWF0IGlkZWEgKEZlbGl4 KQo+Pj4KPj4+IFJlZmVyZW5jZXM6IGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2RyaS1kZXZlbC8y MDIxMDEwNzAzMDEyNy4yMDM5My0xLUZlbGl4Lkt1ZWhsaW5nQGFtZC5jb20vCj4+PiBDYzogRGF2 ZSBBaXJsaWUgPGFpcmxpZWRAZ21haWwuY29tPgo+Pj4gQ2M6IE1hYXJ0ZW4gTGFua2hvcnN0IDxt YWFydGVuLmxhbmtob3JzdEBsaW51eC5pbnRlbC5jb20+Cj4+PiBDYzogVGhvbWFzIEhlbGxzdHLD tm0gPHRob21hcy5oZWxsc3Ryb21AaW50ZWwuY29tPgo+Pj4gQ2M6ICJDaHJpc3RpYW4gS8O2bmln IiA8Y2hyaXN0aWFuLmtvZW5pZ0BhbWQuY29tPgo+Pj4gQ2M6IEplcm9tZSBHbGlzc2UgPGpnbGlz c2VAcmVkaGF0LmNvbT4KPj4+IENjOiBGZWxpeCBLdWVobGluZyA8ZmVsaXgua3VlaGxpbmdAYW1k LmNvbT4KPj4+IFNpZ25lZC1vZmYtYnk6IERhbmllbCBWZXR0ZXIgPGRhbmllbC52ZXR0ZXJAaW50 ZWwuY29tPgo+Pj4gQ2M6IFN1bWl0IFNlbXdhbCA8c3VtaXQuc2Vtd2FsQGxpbmFyby5vcmc+Cj4+ PiBDYzogbGludXgtbWVkaWFAdmdlci5rZXJuZWwub3JnCj4+PiBDYzogbGluYXJvLW1tLXNpZ0Bs aXN0cy5saW5hcm8ub3JnCj4+PiAtLS0KPj4+ICAgIERvY3VtZW50YXRpb24vZHJpdmVyLWFwaS9k bWEtYnVmLnJzdCB8IDc2ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4+ICAgIDEgZmls ZSBjaGFuZ2VkLCA3NiBpbnNlcnRpb25zKCspCj4+Pgo+Pj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50 YXRpb24vZHJpdmVyLWFwaS9kbWEtYnVmLnJzdCBiL0RvY3VtZW50YXRpb24vZHJpdmVyLWFwaS9k bWEtYnVmLnJzdAo+Pj4gaW5kZXggYTIxMzNkNjk4NzJjLi43ZjM3ZWMzMGQ5ZmQgMTAwNjQ0Cj4+ PiAtLS0gYS9Eb2N1bWVudGF0aW9uL2RyaXZlci1hcGkvZG1hLWJ1Zi5yc3QKPj4+ICsrKyBiL0Rv Y3VtZW50YXRpb24vZHJpdmVyLWFwaS9kbWEtYnVmLnJzdAo+Pj4gQEAgLTI1NywzICsyNTcsNzkg QEAgZmVuY2VzIGluIHRoZSBrZXJuZWwuIFRoaXMgbWVhbnM6Cj4+PiAgICAgIHVzZXJzcGFjZSBp cyBhbGxvd2VkIHRvIHVzZSB1c2Vyc3BhY2UgZmVuY2luZyBvciBsb25nIHJ1bm5pbmcgY29tcHV0 ZQo+Pj4gICAgICB3b3JrbG9hZHMuIFRoaXMgYWxzbyBtZWFucyBubyBpbXBsaWNpdCBmZW5jaW5n IGZvciBzaGFyZWQgYnVmZmVycyBpbiB0aGVzZQo+Pj4gICAgICBjYXNlcy4KPj4+ICsKPj4+ICtS ZWNvdmVyYWJsZSBIYXJkd2FyZSBQYWdlIEZhdWx0cyBJbXBsaWNhdGlvbnMKPj4+ICt+fn5+fn5+ fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4KPj4+ICsKPj4+ICtNb2Rlcm4g aGFyZHdhcmUgc3VwcG9ydHMgcmVjb3ZlcmFibGUgcGFnZSBmYXVsdHMsIHdoaWNoIGhhcyBhIGxv dCBvZgo+Pj4gK2ltcGxpY2F0aW9ucyBmb3IgRE1BIGZlbmNlcy4KPj4+ICsKPj4+ICtGaXJzdCwg YSBwZW5kaW5nIHBhZ2UgZmF1bHQgb2J2aW91c2x5IGhvbGRzIHVwIHRoZSB3b3JrIHRoYXQncyBy dW5uaW5nIG9uIHRoZQo+Pj4gK2FjY2VsZXJhdG9yIGFuZCBhIG1lbW9yeSBhbGxvY2F0aW9uIGlz IHVzdWFsbHkgcmVxdWlyZWQgdG8gcmVzb2x2ZSB0aGUgZmF1bHQuCj4+PiArQnV0IG1lbW9yeSBh bGxvY2F0aW9ucyBhcmUgbm90IGFsbG93ZWQgdG8gZ2F0ZSBjb21wbGV0aW9uIG9mIERNQSBmZW5j ZXMsIHdoaWNoCj4+PiArbWVhbnMgYW55IHdvcmtsb2FkIHVzaW5nIHJlY292ZXJhYmxlIHBhZ2Ug ZmF1bHRzIGNhbm5vdCB1c2UgRE1BIGZlbmNlcyBmb3IKPj4+ICtzeW5jaHJvbml6YXRpb24uIFN5 bmNocm9uaXphdGlvbiBmZW5jZXMgY29udHJvbGxlZCBieSB1c2Vyc3BhY2UgbXVzdCBiZSB1c2Vk Cj4+PiAraW5zdGVhZC4KPj4+ICsKPj4+ICtPbiBHUFVzIHRoaXMgcG9zZXMgYSBwcm9ibGVtLCBi ZWNhdXNlIGN1cnJlbnQgZGVza3RvcCBjb21wb3NpdG9yIHByb3RvY29scyBvbgo+Pj4gK0xpbnV4 IHJlbHkgb24gRE1BIGZlbmNlcywgd2hpY2ggbWVhbnMgd2l0aG91dCBhbiBlbnRpcmVseSBuZXcg dXNlcnNwYWNlIHN0YWNrCj4+PiArYnVpbHQgb24gdG9wIG9mIHVzZXJzcGFjZSBmZW5jZXMsIHRo ZXkgY2Fubm90IGJlbmVmaXQgZnJvbSByZWNvdmVyYWJsZSBwYWdlCj4+PiArZmF1bHRzLiBTcGVj aWZpY2FsbHkgdGhpcyBtZWFucyBpbXBsaWNpdCBzeW5jaHJvbml6YXRpb24gd2lsbCBub3QgYmUg cG9zc2libGUuCj4+PiArVGhlIGV4Y2VwdGlvbiBpcyB3aGVuIHBhZ2UgZmF1bHRzIGFyZSBvbmx5 IHVzZWQgYXMgbWlncmF0aW9uIGhpbnRzIGFuZCBuZXZlciB0bwo+Pj4gK29uLWRlbWFuZCBmaWxs IGEgbWVtb3J5IHJlcXVlc3QuIEZvciBub3cgdGhpcyBtZWFucyByZWNvdmVyYWJsZSBwYWdlCj4+ PiArZmF1bHRzIG9uIEdQVXMgYXJlIGxpbWl0ZWQgdG8gcHVyZSBjb21wdXRlIHdvcmtsb2Fkcy4K Pj4+ICsKPj4+ICtGdXJ0aGVybW9yZSBHUFVzIHVzdWFsbHkgaGF2ZSBzaGFyZWQgcmVzb3VyY2Vz IGJldHdlZW4gdGhlIDNEIHJlbmRlcmluZyBhbmQKPj4+ICtjb21wdXRlIHNpZGUsIGxpa2UgY29t cHV0ZSB1bml0cyBvciBjb21tYW5kIHN1Ym1pc3Npb24gZW5naW5lcy4gSWYgYm90aCBhIDNECj4+ PiAram9iIHdpdGggYSBETUEgZmVuY2UgYW5kIGEgY29tcHV0ZSB3b3JrbG9hZCB1c2luZyByZWNv dmVyYWJsZSBwYWdlIGZhdWx0cyBhcmUKPj4+ICtwZW5kaW5nIHRoZXkgY291bGQgZGVhZGxvY2s6 Cj4+PiArCj4+PiArLSBUaGUgM0Qgd29ya2xvYWQgbWlnaHQgbmVlZCB0byB3YWl0IGZvciB0aGUg Y29tcHV0ZSBqb2IgdG8gZmluaXNoIGFuZCByZWxlYXNlCj4+PiArICBoYXJkd2FyZSByZXNvdXJj ZXMgZmlyc3QuCj4+PiArCj4+PiArLSBUaGUgY29tcHV0ZSB3b3JrbG9hZCBtaWdodCBiZSBzdHVj ayBpbiBhIHBhZ2UgZmF1bHQsIGJlY2F1c2UgdGhlIG1lbW9yeQo+Pj4gKyAgYWxsb2NhdGlvbiBp cyB3YWl0aW5nIGZvciB0aGUgRE1BIGZlbmNlIG9mIHRoZSAzRCB3b3JrbG9hZCB0byBjb21wbGV0 ZS4KPj4+ICsKPj4+ICtUaGVyZSBhcmUgYSBmZXcgb3B0aW9ucyB0byBwcmV2ZW50IHRoaXMgcHJv YmxlbSwgb25lIG9mIHdoaWNoIGRyaXZlcnMgbmVlZCB0bwo+Pj4gK2Vuc3VyZToKPj4+ICsKPj4+ ICstIENvbXB1dGUgd29ya2xvYWRzIGNhbiBhbHdheXMgYmUgcHJlZW1wdGVkLCBldmVuIHdoZW4g YSBwYWdlIGZhdWx0IGlzIHBlbmRpbmcKPj4+ICsgIGFuZCBub3QgeWV0IHJlcGFpcmVkLiBOb3Qg YWxsIGhhcmR3YXJlIHN1cHBvcnRzIHRoaXMuCj4+PiArCj4+PiArLSBETUEgZmVuY2Ugd29ya2xv YWRzIGFuZCB3b3JrbG9hZHMgd2hpY2ggbmVlZCBwYWdlIGZhdWx0IGhhbmRsaW5nIGhhdmUKPj4+ ICsgIGluZGVwZW5kZW50IGhhcmR3YXJlIHJlc291cmNlcyB0byBndWFyYW50ZWUgZm9yd2FyZCBw cm9ncmVzcy4gVGhpcyBjb3VsZCBiZQo+Pj4gKyAgYWNoaWV2ZWQgdGhyb3VnaCBlLmcuIHRocm91 Z2ggZGVkaWNhdGVkIGVuZ2luZXMgYW5kIG1pbmltYWwgY29tcHV0ZSB1bml0Cj4+PiArICByZXNl cnZhdGlvbnMgZm9yIERNQSBmZW5jZSB3b3JrbG9hZHMuCj4+PiArCj4+PiArLSBUaGUgcmVzZXJ2 YXRpb24gYXBwcm9hY2ggY291bGQgYmUgZnVydGhlciByZWZpbmVkIGJ5IG9ubHkgcmVzZXJ2aW5n IHRoZQo+Pj4gKyAgaGFyZHdhcmUgcmVzb3VyY2VzIGZvciBETUEgZmVuY2Ugd29ya2xvYWRzIHdo ZW4gdGhleSBhcmUgaW4tZmxpZ2h0LiBUaGlzIG11c3QKPj4+ICsgIGNvdmVyIHRoZSB0aW1lIGZy b20gd2hlbiB0aGUgRE1BIGZlbmNlIGlzIHZpc2libGUgdG8gb3RoZXIgdGhyZWFkcyB1cCB0bwo+ Pj4gKyAgbW9tZW50IHdoZW4gZmVuY2UgaXMgY29tcGxldGVkIHRocm91Z2ggZG1hX2ZlbmNlX3Np Z25hbCgpLgo+Pj4gKwo+Pj4gKy0gQXMgYSBsYXN0IHJlc29ydCwgaWYgdGhlIGhhcmR3YXJlIHBy b3ZpZGVzIG5vIHVzZWZ1bCByZXNlcnZhdGlvbiBtZWNoYW5pY3MsCj4+PiArICBhbGwgd29ya2xv YWRzIG11c3QgYmUgZmx1c2hlZCBmcm9tIHRoZSBHUFUgd2hlbiBzd2l0Y2hpbmcgYmV0d2VlbiBq b2JzCj4+PiArICByZXF1aXJpbmcgRE1BIGZlbmNlcyBvciBqb2JzIHJlcXVpcmluZyBwYWdlIGZh dWx0IGhhbmRsaW5nOiBUaGlzIG1lYW5zIGFsbCBETUEKPj4+ICsgIGZlbmNlcyBtdXN0IGNvbXBs ZXRlIGJlZm9yZSBhIGNvbXB1dGUgam9iIHdpdGggcGFnZSBmYXVsdCBoYW5kbGluZyBjYW4gYmUK Pj4+ICsgIGluc2VydGVkIGludG8gdGhlIHNjaGVkdWxlciBxdWV1ZS4gQW5kIHZpY2UgdmVyc2Es IGJlZm9yZSBhIERNQSBmZW5jZSBjYW4gYmUKPj4+ICsgIG1hZGUgdmlzaWJsZSBhbnl3aGVyZSBp biB0aGUgc3lzdGVtLCBhbGwgY29tcHV0ZSB3b3JrbG9hZHMgbXVzdCBiZSBwcmVlbXB0ZWQKPj4+ ICsgIHRvIGd1YXJhbnRlZSBhbGwgcGVuZGluZyBHUFUgcGFnZSBmYXVsdHMgYXJlIGZsdXNoZWQu Cj4+PiArCj4+PiArLSBPbmx5IGEgZmFpcmx5IHRoZW9yZXRpY2FsIG9wdGlvbiB3b3VsZCBiZSB0 byB1bnRhbmdsZSB0aGVzZSBkZXBlbmRlbmNpZXMgd2hlbgo+Pj4gKyAgYWxsb2NhdGluZyBtZW1v cnkgdG8gcmVwYWlyIGhhcmR3YXJlIHBhZ2UgZmF1bHRzLCBlaXRoZXIgdGhyb3VnaCBzZXBhcmF0 ZQo+Pj4gKyAgbWVtb3J5IGJsb2NrcyBvciBydW50aW1lIHRyYWNraW5nIG9mIHRoZSBmdWxsIGRl cGVuZGVuY3kgZ3JhcGggb2YgYWxsIERNQQo+Pj4gKyAgZmVuY2VzLiBUaGlzIHJlc3VsdHMgdmVy eSB3aWRlIGltcGFjdCBvbiB0aGUga2VybmVsLCBzaW5jZSByZXNvbHZpbmcgdGhlIHBhZ2UKPj4+ ICsgIG9uIHRoZSBDUFUgc2lkZSBjYW4gaXRzZWxmIGludm9sdmUgYSBwYWdlIGZhdWx0LiBJdCBp cyBtdWNoIG1vcmUgZmVhc2libGUgYW5kCj4+PiArICByb2J1c3QgdG8gbGltaXQgdGhlIGltcGFj dCBvZiBoYW5kbGluZyBoYXJkd2FyZSBwYWdlIGZhdWx0cyB0byB0aGUgc3BlY2lmaWMKPj4+ICsg IGRyaXZlci4KPj4+ICsKPj4+ICtOb3RlIHRoYXQgd29ya2xvYWRzIHRoYXQgcnVuIG9uIGluZGVw ZW5kZW50IGhhcmR3YXJlIGxpa2UgY29weSBlbmdpbmVzIG9yIG90aGVyCj4+PiArR1BVcyBkbyBu b3QgaGF2ZSBhbnkgaW1wYWN0LiBUaGlzIGFsbG93cyB1cyB0byBrZWVwIHVzaW5nIERNQSBmZW5j ZXMgaW50ZXJuYWxseQo+Pj4gK2luIHRoZSBrZXJuZWwgZXZlbiBmb3IgcmVzb2x2aW5nIGhhcmR3 YXJlIHBhZ2UgZmF1bHRzLCBlLmcuIGJ5IHVzaW5nIGNvcHkKPj4+ICtlbmdpbmVzIHRvIGNsZWFy IG9yIGNvcHkgbWVtb3J5IG5lZWRlZCB0byByZXNvbHZlIHRoZSBwYWdlIGZhdWx0Lgo+Pj4gKwo+ Pj4gK0luIHNvbWUgd2F5cyB0aGlzIHBhZ2UgZmF1bHQgcHJvYmxlbSBpcyBhIHNwZWNpYWwgY2Fz ZSBvZiB0aGUgYEluZmluaXRlIERNQQo+Pj4gK0ZlbmNlc2AgZGlzY3Vzc2lvbnM6IEluZmluaXRl IGZlbmNlcyBmcm9tIGNvbXB1dGUgd29ya2xvYWRzIGFyZSBhbGxvd2VkIHRvCj4+PiArZGVwZW5k IG9uIERNQSBmZW5jZXMsIGJ1dCBub3QgdGhlIG90aGVyIHdheSBhcm91bmQuIEFuZCBub3QgZXZl biB0aGUgcGFnZSBmYXVsdAo+Pj4gK3Byb2JsZW0gaXMgbmV3LCBiZWNhdXNlIHNvbWUgb3RoZXIg Q1BVIHRocmVhZCBpbiB1c2Vyc3BhY2UgbWlnaHQKPj4+ICtoaXQgYSBwYWdlIGZhdWx0IHdoaWNo IGhvbGRzIHVwIGEgdXNlcnNwYWNlIGZlbmNlIC0gc3VwcG9ydGluZyBwYWdlIGZhdWx0cyBvbgo+ Pj4gK0dQVXMgZG9lc24ndCBhbnl0aGluZyBmdW5kYW1lbnRhbGx5IG5ldy4KPj4gVG8gbWUsIGlu IGdlbmVyYWwgdGhpcyBsb29rcyBnb29kLiBPbmUgdGhpbmcsIHRob3VnaCBpcyB0aGF0IGZvciBh IGZpcnN0Cj4+IHRpbWUgcmVhZGVyIGl0IG1pZ2h0IG5vdCBiZSB0b3RhbGx5IGNsZWFyIHdoYXQn cyBzcGVjaWFsIHdpdGggYSBjb21wdXRlCj4+IHdvcmtsb2FkLiBQZXJoYXBzIHNvbWUgY2xhcmlm aWNhdGlvbj8KPiBJbiB0aGUgZG9jcyB0aGlzIG5ldyBzZWN0aW9uIGlzIHJpZ2h0IGFmdGVyIHRo ZSBpbmZpbml0ZSBmZW5jZQo+IHNlY3Rpb24sIHdoaWNoIGdvZXMgdGhyb3VnaCB0aGlzIGtpbmQg b2Ygc3R1ZmYuIFNvIGl0J3Mgbm90IHNvIG11Y2gKPiAiY29tcHV0ZSB3b3JrbG9hZHMiIGJ1dCAi aW5maW5pdGUgZmVuY2VzIiwgd2hpY2ggSSB0aGluayBpcyBleHBsYWluZWQKPiBwbGVudHkgZW5v dWdoLgo+Ck9LLAo+PiBBbHNvIHNpbmNlIHRoZSBjdXJyZW50IGNyb3NzLWRyaXZlciBkbWFfZmVu Y2UgbG9ja2luZyBvcmRlciBpcwo+Pgo+PiAxKSBkbWFfcmVzdiAtPgo+PiAyKSBtZW1vcnlfYWxs b2NhdGlvbiAvIHJlY2xhaW0gLT4KPj4gMykgZG1hX2ZlbmNlX3dhaXQvY3JpdGljYWwKPj4KPj4g QW5kIHRoZSBsb2NraW5nIG9yZGVyIHJlcXVpcmVkIGZvciByZWNvdmVyYWJsZSBwYWdlZmF1bHQg aXMKPj4KPj4gYSkgZG1hX3Jlc3YgLT4KPj4gYikgZmVuY2Vfd2FpdC9jcml0aWNhbCAtPgo+PiBj KSBtZW1vcnlfYWxsb2NhdGlvbiAvIHJlY2xhaW0KPj4KPj4gKFBvc3NpYmx5IHdpdGggYSkgYW5k IGIpIGludGVyY2hhbmdlZCBhYm92ZSwgSXMgaXQgcG9zc2libGUgdG8gc2VydmljZSBhCj4+IHJl Y292ZXJhYmxlIHBhZ2VmYXVsdCB3aXRob3V0IHRha2luZyB0aGUgZG1hX3Jlc3YgbG9jaz8pCj4g SXQncyB3b3JzZSwgc2luY2UgdGhlIGxvY2sgb3JkZXIgd2UgY2FyZSBhYm91dCBpczoKPiAxKSBt bWFwX3NlbQo+IDIpIGRtYV9yZXN2Cj4gMykgcmVjbGFpbQo+IDQpIGRtYV9mZW5jZV93YWl0Cj4K PiBBbmQgZm9yIHRoaXMgbmljZSBicmF2ZSBuZXcgd29ybGQgb2YgdW5pZmllZCBzaGFyZWQgbWVt b3J5L2htbSwgd2UKPiByZWFsbHkgbmVlZCB0byBiZSBhYmxlIHRvIHJlc29sdmUgYXJiaXRyYXJ5 IGNwdSBzaWRlIHBhZ2UgZmF1bHRzICh3aXRoCj4gZml4dXBfdXNlcl9mYXVsdCgpIGxpa2UgdGhl IGlvbW11IGRyaXZlciBkb2VzIHRvbyBmb3IgUEFTSUQgbW9kZSkgdG8KPiBiZSBhYmxlIHRvIHNl cnZlIGdwdSBwYWdlIGZhdWx0cy4gU28gZXZlbiBpZiB3ZSB0YWtlIGRtYV9yZXN2Cj4gY29tcGxl dGVseSBvdXQgb2YgdGhlIHN5c3RlbSB3ZSBzdGlsbCBoYXZlOgo+Cj4gMSkgbW1hcF9zZW0KPiAy KSByZWNsYWltCj4gMykgZG1hX2ZlbmNlX3dhaXQKPgo+IFNvIHdlJ2QgYWxzbyBuZWVkIHRvIHRo cm93IG91dCBkbWFfZmVuY2Vfd2FpdCwgYW5kIGF0IHRoYXQgcG9pbnQgd2UncmUKPiBsb29raW5n IGF0IGEgbmV3IGdwdSBkcml2ZXIgc3RhY2suCj4KTWVhbmluZyB0aGF0IHRoZSBsb2NraW5nIG9y ZGVyIGZvciB3b3JrbG9hZHMgd2l0aCByZWNvdmVyYWJsZSBwYWdlIApmYXVsdHMgYmVjb21lczoK CmEpIGRtYV9mZW5jZV93YWl0L2NyaXRpY2FsCmIpIG1tYXBfc2VtCmMpIGRtYV9yZXN2CmQpIHJl Y2xhaW0KCndoaWNoIEkgYWdyZWUgd2UgY2FuJ3QgcmVhbGx5IHVzZSB3aXRoIHRoZSBjdXJyZW50 IHN0YWNrIHdoYXRldmVyIHdlIGRvIAp3aXRoIGRtYV9mZW5jZV93YWl0IHZzIHJlY2xhaW0uCgoK Pj4gSXQncyBjbGVhciB0aGF0IHRoZSBmZW5jZSBjcml0aWNhbCBzZWN0aW9uIGluIGIpIGlzIG5v dCBjb21wYXRpYmxlIHdpdGgKPj4gdGhlIGRtYV9mZW5jZSB3YWl0IGluIDMpIGFuZCB0aHVzIHRo ZSBtZW1vcnkgcmVzdHJpY3Rpb25zIGFyZSBuZWVkZWQuCj4+IEJ1dCBJIHRoaW5rIGdpdmVuIHRo ZSBtZW1vcnkgYWxsb2NhdGlvbiByZXN0cmljdGlvbnMgZm9yIHJlY292ZXJhYmxlCj4+IHBhZ2Vm YXVsdHMgSSBndWVzcyBhdCBzb21lIHBvaW50IHdlIG11c3QgYXNrIG91cnNlbHZlcyB3aHkgYXJl IHRoZXkKPj4gbmVjZXNzYXJ5IGFuZCB3aGF0J3MgdGhlIHByaWNlIHRvIGJlIHBhaWQgZm9yIGdl dHRpbmcgcmlkIG9mIHRoZW0sIGFuZAo+PiBkb2N1bWVudCBhbHNvIHRoYXQuICpJZiogaXQncyB0 aGUgY2FzZSB0aGF0IGl0IGFsbCBib2lscyBkb3duIHRvIHRoZSAyKQo+PiAtPiAzKSBsb2NraW5n IG9yZGVyIGFib3ZlLCBhbmQgdGhhdCdzIG1hbmRhdGVkICpvbmx5KiBieSB0aGUgZG1hX2ZlbmNl Cj4+IHdhaXQgaW4gdGhlIHVzZXJwdHIgbW11IG5vdGlmaWVycywgSSB0aGluayB0aGVzZSByZXN0 cmljdGlvbnMgYXJlIGEKPj4gcHJldHR5IGhpZ2ggcHJpY2UgdG8gcGF5LiBXb3VsZG4ndCBpdCBi ZSBwb3NzaWJsZSBub3cgdG8gcmVwbGFjZSB0aGF0Cj4+IGZlbmNlIHdhaXQgd2l0aCBlaXRoZXIg cGFnZSBwaW5uaW5nICh3aGljaCBub3cgaXMgY29oZXJlbnQgc2luY2UgNS45KSBvcgo+PiBwcmVl bXB0LWN0eCBmZW5jZXMgKyB1bnBpbm5lZCBwYWdlcyBpZiBhdmFpbGFibGUgYW5kIHRodXMgaW52 ZXJ0IHRoZSAyKQo+PiAtPiAzKSBsb2NraW5nIG9yZGVyPwo+IEl0J3Mgbm90IGp1c3QgdXNlcnB0 ciwgaXQncyBhbHNvIHNocmlua2Vycy4gbW1hcF9zZW0gcmVxdWlyZXMKPiBHRlBfS0VSTkVMIGFs bG9jYXRpb25zLCBzbyB0aGF0IGFscmVhZHkgZXhjbHVkZXMgb3VyIHNocmlua2VycyBpZiB3ZQo+ IHdhbnQgdGhpcy4gVGhhdCBtZWFucyBncHUgbWVtb3J5IGJlY29tZXMgcGlubmVkIHdoZW4gaXQn cyBtYW5hZ2VkIHdpdGgKPiBkbWFfZmVuY2UuIENocmlzdGlhbiBLw7ZuaWcganVzdCByZXdvcmtl ZCB0dG0gdG8gc3RvcCBkb2luZyB0aGF0LCB0bwo+IHJlbW92ZSB0aGUgaGFyZCBhbmQgZmFpcmx5 IGFyYml0cmFyeSAibWF4IDUwJSBvZiBzeXN0ZW0gbWVtb3J5IiBsaW1pdC4KCkV2ZW4gd2l0aCBz aHJpbmtlcnMsIGFuZCBhc3N1bWluZyB0aGVyZSBpcyBubyBndWFyYW50ZWUgd2UgY2FuIHByZWVt cHQsIApvbmUgY291bGQgdGFnIG1lbW9yeSAvIGJvcyBmb3IgcmVsZWFzZSBvbiBuZXh0IHJlc2Vy dmF0aW9uIC8gZG1hX2ZlbmNlIApzaWduYWwgd2hhdGV2ZXIgaGFwcGVucyBmaXJzdCwgd2hpY2gg d291bGQgbm90IGdpdmUgbWVtb3J5IGJhY2sgb24gCmRpcmVjdCByZWNsYWltLCBidXQgd2lsbCBl dmVudHVhbGx5IHJlbGVhc2UgaXQuIFdpbGwgbm90IGhlbHAgd2l0aCB0aGUgCm1tYXBfc2VtIGlz c3VlLCB0aG91Z2guCgoKPgo+Cj4gTm90ZSB0aGF0IGp1c3QgcHJlZW1wdC1jdHggZmVuY2VzIGFs b25lIGlzbid0IGVub3VnaCwgc2luY2UgeW91IGNvdWxkCj4gZW5kIHVwIHdpdGggc29tZXRoaW5n IGxpa2UgdGhpczoKPiAtIGNvbXB1dGUgd29ya2xvYWQgdXNpbmcgZ3B1IHBhZ2UgZmF1bHRzIGhh bmdzIGEgYWxsIG9mIHRoZQo+IGNvbXB1dGUvc2hhZGVyY29yZXMgb24gcGFnZSBmYXVsdHMsIHdl IGNhbid0IHByZWVtcHQKPiAtIGNvbmN1cnJlbnRseSB0aGVyZSdzIGEgM2Qgd29ya2xvYWQgcnVu bmluZywgd2hpY2ggYmVjYXVzZSBmaXhlZAo+IGZ1bmN0aW9uLCBhbmQgb25seSBwcmVlbXB0IGJl dHdlZW4gZHJhdyBjYWxscy4gaXQgaXMgc3R1Y2sgd2FpdGluZyBmb3IKPiBzb21lIHNoYWRlciBj b3JlcyB0byBiZWNvbWUgYXZhaWFibGUuIHRoaXMgaXMgcG9zc2libGUgYmVjYXVzZSBtb3N0Cj4g Z3B1cyBub3dhZGF5cyBoYXZlIHNlcGFyYXRlIGNvbW1hbmQgcXVldWVzIGZvciBjb21wdXRlLzNk IHdvcmtsb2Fkcwo+IC0gb3VyIGtlcm5lbCBwYWdlIGZhdWx0IGhhbmRsZXIgZm9yIHRoZSBjb21w dXRlIGpvYiB3YW50cyB0byBwcmVlbXB0Cj4gdGhlIDNkIHdvcmtsb2FkLCB3aGljaCB3b250IGhh cHBlbgo+IC0gZXZlcnlvbmUgaXMgZmlybWx5IHN0dWNrIGFuZCB0aGUgdXNlciBnZXRzIGFuZ3J5 ClllcywgcHJlZW1wdC1jdHggZmVuY2VzIHdvdWxkIGluZGVlZCBoYXZlIHRvIGJlIGd1YXJhbnRl ZWQgdG8gYmUgYWJsZSB0byAKcHJlZW1wdCB0byB3b3JrLCB1c2luZyBvbmUgb2YgdGhlIG9wdGlv bnMgZGVzY3JpYmVkIGFib3ZlLCBCdXQgaW4gCmdlbmVyYWwsIGludmVydGluZyByZWNsYWltIGFu ZCBkbWFfZmVuY2Vfd2FpdCB3b3VsZCBhY3R1YWxseSByZXNvbHZlIAp0aGlzIHBhcnRpY3VsYXIg c2l0dWF0aW9uLCBldmVuIGlmIGl0IGRvZXNuJ3QgaGVscCB3aXRoIHJlY292ZXJhYmxlIApwYWdl ZmF1bHRzIGR1ZSB0byBtbWFwX3NlbToKCi0ga2VybmVsIHBhZ2UgZmF1bHQgaGFuZGxlciBlbmRz IHVwIGluIHNocmlua2VyIHRhZ2dpbmcgM0Qgd29ya2xvYWQgCnJlc291cmNlcyBmb3IgcmVsZWFz ZQotIE1vdmVzIG9uIHRvIGFub3RoZXIgc2hyaW5rZXIgdGhhdCBzdWNjZWVkcyB0byByZWxlYXNl IGVub3VnaCBtZW1vcnkKLSBDb21wdXRlIHdvcmtsb2FkIHByb2NlZWRzCi0gM0Qgd29ya2xvYWQg cHJvY2VlZHMuCgouLkJ1dCBqdXN0IHdhbnRpbmcgdG8gZ2V0IHRoZSBmdWxsIHBpY3R1cmUgb2Yg d2hhdCB0aGUgdHJhZGVvZmZzIG9mIHRoaXMgCnJlYWxseSBhcmUuCgovVGhvbWFzCj4KPiBTbyBq dXN0IHJlcXVpcmluZyB0aGF0IGV2ZXJ5dGhpbmcgdXNlcyBwcmVlbXB0LWN0eCBmZW5jZXMgaXNu J3QgZW5vdWdoCj4gZHVlIHRvIHNoYXJlZCByZXNvdXJjZXMgcG9zc2libGUgYmxvY2tpbmcgcHJl ZW1wdGlvbiBldmVuIGFjcm9zcwo+IGVuZ2luZXMuIFBsdXMgd2UnZCBzdGlsbCBoYXZlIHRoZSBw cm9ibGVtIHRoYXQgZG1hX2ZlbmNlX3dhaXQgZnJvbQo+IHJlY2xhaW0gaXNuJ3QgYWxsb3dlZCwg cGlubmluZyBhbGwgdGhlIDNkIHdvcmtsb2FkIG1lbW9yeSBmb3IgZ29vZC4KPgo+IEFzaWRlOiBU aGlzIG1lYW5zIHRoYXQgZm9yIGNvbXB1dGUgd29ya2xvYWRzIHVzaW5nIHBhZ2UgZmF1bHRzIHdl Cj4gY2Fubm90IHVzZSBwcmVlbXB0LWN0eCBmZW5jZXMgZWl0aGVyLCBidXQgaW5zdGVhZCBtZW1v cnkgcmVjbGFpbSBoYXMKPiB0byBleGNsdXNpdmVseSB1c2UgcHRlIHphcHBpbmcgKGJvdGggc2hy aW5rZXIgYW5kIG1tdSBub3RpZmllcikuCj4KPiBDaGVlcnMsIERhbmllbApfX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0 CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3Rv cC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK