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=-10.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,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 CA614C433E0 for ; Tue, 26 Jan 2021 19:22:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8F7EB22A84 for ; Tue, 26 Jan 2021 19:22:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728654AbhAZFrV (ORCPT ); Tue, 26 Jan 2021 00:47:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732297AbhAZCqs (ORCPT ); Mon, 25 Jan 2021 21:46:48 -0500 Received: from mail.kapsi.fi (mail.kapsi.fi [IPv6:2001:67c:1be8::25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F19BAC0613D6 for ; Mon, 25 Jan 2021 18:46:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: MIME-Version:Date:Message-ID:From:References:Cc:To:Subject:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=0AiauGDiGc0aqm9Js8Z08cj0Lke6k6BchWRBqlU0f68=; b=EPI4iBPFudZU67QHTHTNW9pcC0 65WCXXytDwRuuaxK6T0P1NhExdWVZ8s7Ysg/d/STgUMv4XNjE37EDFUK73vXlwjWoFx9eH6lCqULx pT6ox1oouKm0VkZrqr8k5XvbF6Pf0HviD0ozzbTWWpxTDWywAlnlY6ojuYbhZZua1M3/EXhYfNakI rL8RekyQKbqGFrKXM4694p964CZS7pPRTZXjagOfTSfHGq5P6Jvi4j3ytvWjzspIUQ/sZO7VTUztj I+hdnQYqJdNdeINVPitZIqvnI2u/It+pqiQE+dVEapu1x9xCiWLtYK097EOalersGdWl3RMu1mBpl D+Odvryw==; Received: from dsl-hkibng22-54f986-236.dhcp.inet.fi ([84.249.134.236] helo=[192.168.1.10]) by mail.kapsi.fi with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1l4EMi-0002kh-QK; Tue, 26 Jan 2021 04:46:00 +0200 Subject: Re: [PATCH v5 00/21] Host1x/TegraDRM UAPI To: Dmitry Osipenko , Mikko Perttunen , thierry.reding@gmail.com, jonathanh@nvidia.com, airlied@linux.ie, daniel@ffwll.ch Cc: linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org, talho@nvidia.com, bhuntsman@nvidia.com References: <20210111130019.3515669-1-mperttunen@nvidia.com> From: Mikko Perttunen Message-ID: <2f999b6d-d781-503a-78f4-d444bce72c58@kapsi.fi> Date: Tue, 26 Jan 2021 04:45:55 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 84.249.134.236 X-SA-Exim-Mail-From: cyndis@kapsi.fi X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org On 1/20/21 12:29 AM, Dmitry Osipenko wrote: > 11.01.2021 15:59, Mikko Perttunen пишет: >> Hi all, >> >> here's the fifth revision of the Host1x/TegraDRM UAPI proposal, >> containing primarily small bug fixes. It has also been >> rebased on top of recent linux-next. >> >> vaapi-tegra-driver has been updated to support the new UAPI >> as well as Tegra186: >> >> https://github.com/cyndis/vaapi-tegra-driver >> >> The `putsurface` program has been tested to work. >> >> The test suite for the new UAPI is available at >> https://github.com/cyndis/uapi-test >> >> The series can be also found in >> https://github.com/cyndis/linux/commits/work/host1x-uapi-v5. >> >> Older versions: >> v1: https://www.spinics.net/lists/linux-tegra/msg51000.html >> v2: https://www.spinics.net/lists/linux-tegra/msg53061.html >> v3: https://www.spinics.net/lists/linux-tegra/msg54370.html >> v4: https://www.spinics.net/lists/dri-devel/msg279897.html >> >> Thank you, >> Mikko > > The basic support for the v5 UAPI is added now to the Opentegra driver. > In overall UAPI works, but there are couple things that we need to > improve, I'll focus on them here. > > Problems > ======== > > 1. The channel map/unmap API needs some more thought. > > The main problem is a difficulty to track liveness of BOs and mappings. > The kernel driver refs BO for each mapping and userspace needs to track > both BO and its mappings together, it's too easy to make mistake and > leak BOs without noticing. > > 2. Host1x sync point UAPI should not be used for tracking DRM jobs. I > remember we discussed this previously, but this pops up again and I > don't remember where we ended previously. > > This creates unnecessary complexity for userspace. Userspace needs to > go through a lot of chores just to get a sync point and then to manage > it for the jobs. > > Nothing stops two different channels to reuse a single sync point and > use it for a job, fixing this will only add more complexity to the > kernel driver instead of removing it. > > 3. The signalling of DMA fences doesn't work properly in v5 apparently > because of the host1x waiter bug. I see that sync point interrupt > happens, but waiter callback isn't invoked. > > 4. The sync_file API is not very suitable for DRM purposes because of > -EMFILE "Too many open files", which I saw while was running x11perf. > It also adds complexity to userspace, instead of removing it. This > approach not suitable for DRM scheduler as well. > > 5. Sync points have a dirty hardware state when allocated / requested. > The special sync point reservation is meaningless in this case. > > 6. I found that the need to chop cmdstream into gathers is a bit > cumbersome for userspace of older SoCs which don't have h/w firewall. > Can we support option where all commands are collected into a single > dedicated cmdstream for a job? > > Possible solutions for the above problems > ========================================= > > 1. Stop to use concept of "channels". Switch to DRM context-only. > > Each DRM context should get access to all engines once DRM context is > created. Think of it like "when DRM context is opened, it opens a > channel for each engine". > > Then each DRM context will get one instance of mapping per-engine for > each BO. > > enum tegra_engine { > TEGRA_GR2D, > TEGRA_GR3D, > TEGRA_VIC, > ... > NUM_ENGINES > }; > > struct tegra_bo_mapping { > dma_addr_t ioaddr; > ... > }; > > struct tegra_bo { > ... > struct tegra_bo_mapping *hw_maps[NUM_ENGINES]; > }; > > Instead of DRM_IOCTL_TEGRA_CHANNEL_MAP we should have > DRM_IOCTL_TEGRA_GEM_MAP_TO_ENGINE, which will create a BO mapping for a > specified h/w engine. > > Once BO is closed, all its mappings should be closed too. This way > userspace doesn't need to track both BOs and mappings. > > Everything that userspace needs to do is: > > 1) Open DRM context > 2) Create GEM > 3) Map GEM to required hardware engines > 4) Submit job that uses GEM handle > 5) Close GEM > > If GEM wasn't mapped prior to the job's submission, then job will fail > because kernel driver won't resolve the IO mapping of the GEM. Perhaps we can instead change the reference counting such that if you close the GEM object, the mappings will be dropped as well automatically. > > 2. We will probably need a dedicated drm_tegra_submit_cmd for sync point > increments. The job's sync point will be allocated dynamically when job > is submitted. We will need a fag for the sync_incr and wait_syncpt > commands, saying "it's a job's sync point increment/wait" Negative. Like I have explained in previous discussions, with the current way the usage of hardware resources is much more deterministic and obvious. I disagree on the point that this is much more complicated for the userspace. Separating syncpoint and channel allocation is one of the primary motivations of this series for me. > > 3. We should use dma-fence API directly and waiter-shim should be > removed. It's great that you're already working on this. > > 4. Sync file shouldn't be needed for the part of DRM API which doesn't > interact with external non-DRM devices. We should use DRM syncobj for > everything related to DRM, it's a superior API over sync file, it's > suitable for DRM scheduler. Considering the issues with fileno limits, I suppose there is no other choice. Considering the recent NTSYNC proposal by Wine developers, maybe we should also have NTHANDLEs to get rid of restrictions of file descriptors. DRM syncobjs may have some advantages over sync files, but also disadvantages. They cannot be poll()ed, so they cannot be combined with waits for other resources. I'll look into this for v6. > > 5. The hardware state of sync points should be reset when sync point is > requested, not when host1x driver is initialized. This may be doable, but I don't think it is critical for this UAPI, so let's consider it after this series. The userspace should anyway not be able to assume the initial value of the syncpoint upon allocation. The kernel should set it to some high value to catch any issues related to wraparound. Also, this makes code more complicated since it now needs to ensure all waits on the syncpoint have completed before freeing the syncpoint, which can be nontrivial e.g. if the waiter is in a different virtual machine or some other device connected via PCIe (a real usecase). > > 6. We will need to allocate a host1x BO for a job's cmdstream and add a > restart command to the end of the job's stream. CDMA will jump into the > job's stream from push buffer. > > We could add a flag for that to drm_tegra_submit_cmd_gather, saying that > gather should be inlined into job's main cmdstream. > > This will remove a need to have a large push buffer that will easily > overflow, it's a real problem and upstream driver even has a bug where > it locks up on overflow. > > How it will look from CDMA perspective: > > PUSHBUF | > --------- > ... | | JOB | > | --------- | JOB GATHER | > RESTART ------> CMD | -------------- > | |GATHER -------> DATA | > ... <---------- RESTART| | | > | | | > Let me check if I understood you correctly: - You would like to have the job's cmdbuf have further GATHER opcodes that jump into smaller gathers? I assume this is needed because currently WAITs are placed into the pushbuffer, so the job will take a lot of space in the pushbuffer if there are a lot of waits (and GATHERs in between these waits)? If so, perhaps as a simpler alternative we could change the firewall to allow SETCLASS into HOST1X for waiting specifically, then userspace could just submit one big cmdbuf taking only little space in the pushbuffer? Although that would only allow direct ID/threshold waits. In any case, it seems that this can be added in a later patch, so we should omit it from this series for simplicity. If it is impossible for the userspace to deal with it, we could disable the firewall temporarily, or implement the above change in the firewall. > > What's missing > ============== > > 1. Explicit and implicit fencing isn't there yet, we need to support DRM > scheduler for that. > > 2. The "wait" command probably should be taught to take a syncobj handle > in order to populate it with a dma-fence by kernel driver once job is > submitted. This will give us intermediate fences of a job and allow > utilize the syncobj features like "wait until job is submitted to h/w > before starting to wait for timeout", which will be needed by userspace > when DRM scheduler will be supported. > > Miscellaneous > ============= > > 1. Please don't forget to bump driver version. This is important for > userspace. Sure. I didn't do it this time since it's backwards compatible and it's easy to detect if the new UAPI is available by checking for /dev/host1x. I can bump it in v6 if necessary. > > 2. Please use a proper kernel coding style, use checkpatch. > > # git format-patch -v5 ... > # ./scripts/checkpatch.pl --strict v5* Looks like I accidentally placed some spaces into firewall.c. Otherwise the warnings it prints do not look critical. > > 3. Kernel driver needs a rich error messages for each error condition > and it should dump submitted job when firewall fails. It's very tedious > to re-add it all each time when something doesn't work. Yes, that's true. Will take a look for v6. > > 4. Previously firewall was using the client's class if is_valid_class > wasn't specified in tegra_drm_client_ops, you changed it and now > firewall fails for GR3D because it doesn't have the is_valid_class() set > in the driver. See [1]. > > 5. The CDMA class should be restored to the class of a previous gather > after the wait command in submit_gathers() and not to the class of the > client. GR2D supports multiple classes. See [1]. Will take a look at these two for v6. > > [1] > https://github.com/grate-driver/linux/commit/024cba369c9c0e2762e9890068ff9944cb10c44f > Mikko 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=-10.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,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 F218AC433DB for ; Tue, 26 Jan 2021 02:46:07 +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 1793522AAA for ; Tue, 26 Jan 2021 02:46:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1793522AAA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kapsi.fi 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 CAE936E3CE; Tue, 26 Jan 2021 02:46:05 +0000 (UTC) Received: from mail.kapsi.fi (mail.kapsi.fi [IPv6:2001:67c:1be8::25]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4C4CB6E3CE for ; Tue, 26 Jan 2021 02:46:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: MIME-Version:Date:Message-ID:From:References:Cc:To:Subject:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=0AiauGDiGc0aqm9Js8Z08cj0Lke6k6BchWRBqlU0f68=; b=EPI4iBPFudZU67QHTHTNW9pcC0 65WCXXytDwRuuaxK6T0P1NhExdWVZ8s7Ysg/d/STgUMv4XNjE37EDFUK73vXlwjWoFx9eH6lCqULx pT6ox1oouKm0VkZrqr8k5XvbF6Pf0HviD0ozzbTWWpxTDWywAlnlY6ojuYbhZZua1M3/EXhYfNakI rL8RekyQKbqGFrKXM4694p964CZS7pPRTZXjagOfTSfHGq5P6Jvi4j3ytvWjzspIUQ/sZO7VTUztj I+hdnQYqJdNdeINVPitZIqvnI2u/It+pqiQE+dVEapu1x9xCiWLtYK097EOalersGdWl3RMu1mBpl D+Odvryw==; Received: from dsl-hkibng22-54f986-236.dhcp.inet.fi ([84.249.134.236] helo=[192.168.1.10]) by mail.kapsi.fi with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1l4EMi-0002kh-QK; Tue, 26 Jan 2021 04:46:00 +0200 Subject: Re: [PATCH v5 00/21] Host1x/TegraDRM UAPI To: Dmitry Osipenko , Mikko Perttunen , thierry.reding@gmail.com, jonathanh@nvidia.com, airlied@linux.ie, daniel@ffwll.ch References: <20210111130019.3515669-1-mperttunen@nvidia.com> From: Mikko Perttunen Message-ID: <2f999b6d-d781-503a-78f4-d444bce72c58@kapsi.fi> Date: Tue, 26 Jan 2021 04:45:55 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.1 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-SA-Exim-Connect-IP: 84.249.134.236 X-SA-Exim-Mail-From: cyndis@kapsi.fi X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false 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: linux-tegra@vger.kernel.org, talho@nvidia.com, bhuntsman@nvidia.com, dri-devel@lists.freedesktop.org Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" T24gMS8yMC8yMSAxMjoyOSBBTSwgRG1pdHJ5IE9zaXBlbmtvIHdyb3RlOgo+IDExLjAxLjIwMjEg MTU6NTksIE1pa2tvIFBlcnR0dW5lbiDQv9C40YjQtdGCOgo+PiBIaSBhbGwsCj4+Cj4+IGhlcmUn cyB0aGUgZmlmdGggcmV2aXNpb24gb2YgdGhlIEhvc3QxeC9UZWdyYURSTSBVQVBJIHByb3Bvc2Fs LAo+PiBjb250YWluaW5nIHByaW1hcmlseSBzbWFsbCBidWcgZml4ZXMuIEl0IGhhcyBhbHNvIGJl ZW4KPj4gcmViYXNlZCBvbiB0b3Agb2YgcmVjZW50IGxpbnV4LW5leHQuCj4+Cj4+IHZhYXBpLXRl Z3JhLWRyaXZlciBoYXMgYmVlbiB1cGRhdGVkIHRvIHN1cHBvcnQgdGhlIG5ldyBVQVBJCj4+IGFz IHdlbGwgYXMgVGVncmExODY6Cj4+Cj4+ICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9jeW5kaXMvdmFh cGktdGVncmEtZHJpdmVyCj4+Cj4+IFRoZSBgcHV0c3VyZmFjZWAgcHJvZ3JhbSBoYXMgYmVlbiB0 ZXN0ZWQgdG8gd29yay4KPj4KPj4gVGhlIHRlc3Qgc3VpdGUgZm9yIHRoZSBuZXcgVUFQSSBpcyBh dmFpbGFibGUgYXQKPj4gaHR0cHM6Ly9naXRodWIuY29tL2N5bmRpcy91YXBpLXRlc3QKPj4KPj4g VGhlIHNlcmllcyBjYW4gYmUgYWxzbyBmb3VuZCBpbgo+PiBodHRwczovL2dpdGh1Yi5jb20vY3lu ZGlzL2xpbnV4L2NvbW1pdHMvd29yay9ob3N0MXgtdWFwaS12NS4KPj4KPj4gT2xkZXIgdmVyc2lv bnM6Cj4+IHYxOiBodHRwczovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51eC10ZWdyYS9tc2c1 MTAwMC5odG1sCj4+IHYyOiBodHRwczovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51eC10ZWdy YS9tc2c1MzA2MS5odG1sCj4+IHYzOiBodHRwczovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51 eC10ZWdyYS9tc2c1NDM3MC5odG1sCj4+IHY0OiBodHRwczovL3d3dy5zcGluaWNzLm5ldC9saXN0 cy9kcmktZGV2ZWwvbXNnMjc5ODk3Lmh0bWwKPj4KPj4gVGhhbmsgeW91LAo+PiBNaWtrbwo+IAo+ IFRoZSBiYXNpYyBzdXBwb3J0IGZvciB0aGUgdjUgVUFQSSBpcyBhZGRlZCBub3cgdG8gdGhlIE9w ZW50ZWdyYSBkcml2ZXIuCj4gICBJbiBvdmVyYWxsIFVBUEkgd29ya3MsIGJ1dCB0aGVyZSBhcmUg Y291cGxlIHRoaW5ncyB0aGF0IHdlIG5lZWQgdG8KPiBpbXByb3ZlLCBJJ2xsIGZvY3VzIG9uIHRo ZW0gaGVyZS4KPiAKPiBQcm9ibGVtcwo+ID09PT09PT09Cj4gCj4gMS4gVGhlIGNoYW5uZWwgbWFw L3VubWFwIEFQSSBuZWVkcyBzb21lIG1vcmUgdGhvdWdodC4KPiAKPiBUaGUgbWFpbiBwcm9ibGVt IGlzIGEgZGlmZmljdWx0eSB0byB0cmFjayBsaXZlbmVzcyBvZiBCT3MgYW5kIG1hcHBpbmdzLgo+ ICAgVGhlIGtlcm5lbCBkcml2ZXIgcmVmcyBCTyBmb3IgZWFjaCBtYXBwaW5nIGFuZCB1c2Vyc3Bh Y2UgbmVlZHMgdG8gdHJhY2sKPiBib3RoIEJPIGFuZCBpdHMgbWFwcGluZ3MgdG9nZXRoZXIsIGl0 J3MgdG9vIGVhc3kgdG8gbWFrZSBtaXN0YWtlIGFuZAo+IGxlYWsgQk9zIHdpdGhvdXQgbm90aWNp bmcuCj4gCj4gMi4gSG9zdDF4IHN5bmMgcG9pbnQgVUFQSSBzaG91bGQgbm90IGJlIHVzZWQgZm9y IHRyYWNraW5nIERSTSBqb2JzLiAgSQo+IHJlbWVtYmVyIHdlIGRpc2N1c3NlZCB0aGlzIHByZXZp b3VzbHksIGJ1dCB0aGlzIHBvcHMgdXAgYWdhaW4gYW5kIEkKPiBkb24ndCByZW1lbWJlciB3aGVy ZSB3ZSBlbmRlZCBwcmV2aW91c2x5Lgo+IAo+IFRoaXMgY3JlYXRlcyB1bm5lY2Vzc2FyeSBjb21w bGV4aXR5IGZvciB1c2Vyc3BhY2UuICBVc2Vyc3BhY2UgbmVlZHMgdG8KPiBnbyB0aHJvdWdoIGEg bG90IG9mIGNob3JlcyBqdXN0IHRvIGdldCBhIHN5bmMgcG9pbnQgYW5kIHRoZW4gdG8gbWFuYWdl Cj4gaXQgZm9yIHRoZSBqb2JzLgo+IAo+IE5vdGhpbmcgc3RvcHMgdHdvIGRpZmZlcmVudCBjaGFu bmVscyB0byByZXVzZSBhIHNpbmdsZSBzeW5jIHBvaW50IGFuZAo+IHVzZSBpdCBmb3IgYSBqb2Is IGZpeGluZyB0aGlzIHdpbGwgb25seSBhZGQgbW9yZSBjb21wbGV4aXR5IHRvIHRoZQo+IGtlcm5l bCBkcml2ZXIgaW5zdGVhZCBvZiByZW1vdmluZyBpdC4KPiAKPiAzLiBUaGUgc2lnbmFsbGluZyBv ZiBETUEgZmVuY2VzIGRvZXNuJ3Qgd29yayBwcm9wZXJseSBpbiB2NSBhcHBhcmVudGx5Cj4gYmVj YXVzZSBvZiB0aGUgaG9zdDF4IHdhaXRlciBidWcuICBJIHNlZSB0aGF0IHN5bmMgcG9pbnQgaW50 ZXJydXB0Cj4gaGFwcGVucywgYnV0IHdhaXRlciBjYWxsYmFjayBpc24ndCBpbnZva2VkLgo+IAo+ IDQuIFRoZSBzeW5jX2ZpbGUgQVBJIGlzIG5vdCB2ZXJ5IHN1aXRhYmxlIGZvciBEUk0gcHVycG9z ZXMgYmVjYXVzZSBvZgo+IC1FTUZJTEUgIlRvbyBtYW55IG9wZW4gZmlsZXMiLCB3aGljaCBJIHNh dyB3aGlsZSB3YXMgcnVubmluZyB4MTFwZXJmLgo+IEl0IGFsc28gYWRkcyBjb21wbGV4aXR5IHRv IHVzZXJzcGFjZSwgaW5zdGVhZCBvZiByZW1vdmluZyBpdC4gIFRoaXMKPiBhcHByb2FjaCBub3Qg c3VpdGFibGUgZm9yIERSTSBzY2hlZHVsZXIgYXMgd2VsbC4KPiAKPiA1LiBTeW5jIHBvaW50cyBo YXZlIGEgZGlydHkgaGFyZHdhcmUgc3RhdGUgd2hlbiBhbGxvY2F0ZWQgLyByZXF1ZXN0ZWQuCj4g VGhlIHNwZWNpYWwgc3luYyBwb2ludCByZXNlcnZhdGlvbiBpcyBtZWFuaW5nbGVzcyBpbiB0aGlz IGNhc2UuCj4gCj4gNi4gSSBmb3VuZCB0aGF0IHRoZSBuZWVkIHRvIGNob3AgY21kc3RyZWFtIGlu dG8gZ2F0aGVycyBpcyBhIGJpdAo+IGN1bWJlcnNvbWUgZm9yIHVzZXJzcGFjZSBvZiBvbGRlciBT b0NzIHdoaWNoIGRvbid0IGhhdmUgaC93IGZpcmV3YWxsLgo+IENhbiB3ZSBzdXBwb3J0IG9wdGlv biB3aGVyZSBhbGwgY29tbWFuZHMgYXJlIGNvbGxlY3RlZCBpbnRvIGEgc2luZ2xlCj4gZGVkaWNh dGVkIGNtZHN0cmVhbSBmb3IgYSBqb2I/Cj4gCj4gUG9zc2libGUgc29sdXRpb25zIGZvciB0aGUg YWJvdmUgcHJvYmxlbXMKPiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PQo+IAo+IDEuIFN0b3AgdG8gdXNlIGNvbmNlcHQgb2YgImNoYW5uZWxzIi4gU3dpdGNoIHRvIERS TSBjb250ZXh0LW9ubHkuCj4gCj4gRWFjaCBEUk0gY29udGV4dCBzaG91bGQgZ2V0IGFjY2VzcyB0 byBhbGwgZW5naW5lcyBvbmNlIERSTSBjb250ZXh0IGlzCj4gY3JlYXRlZC4gIFRoaW5rIG9mIGl0 IGxpa2UgIndoZW4gRFJNIGNvbnRleHQgaXMgb3BlbmVkLCBpdCBvcGVucyBhCj4gY2hhbm5lbCBm b3IgZWFjaCBlbmdpbmUiLgo+IAo+IFRoZW4gZWFjaCBEUk0gY29udGV4dCB3aWxsIGdldCBvbmUg aW5zdGFuY2Ugb2YgbWFwcGluZyBwZXItZW5naW5lIGZvcgo+IGVhY2ggQk8uCj4gCj4gZW51bSB0 ZWdyYV9lbmdpbmUgewo+IAlURUdSQV9HUjJELAo+IAlURUdSQV9HUjNELAo+IAlURUdSQV9WSUMs Cj4gCS4uLgo+IAlOVU1fRU5HSU5FUwo+IH07Cj4gCj4gc3RydWN0IHRlZ3JhX2JvX21hcHBpbmcg ewo+IAlkbWFfYWRkcl90IGlvYWRkcjsKPiAJLi4uCj4gfTsKPiAKPiBzdHJ1Y3QgdGVncmFfYm8g ewo+IAkuLi4KPiAJc3RydWN0IHRlZ3JhX2JvX21hcHBpbmcgKmh3X21hcHNbTlVNX0VOR0lORVNd Owo+IH07Cj4gCj4gSW5zdGVhZCBvZiBEUk1fSU9DVExfVEVHUkFfQ0hBTk5FTF9NQVAgd2Ugc2hv dWxkIGhhdmUKPiBEUk1fSU9DVExfVEVHUkFfR0VNX01BUF9UT19FTkdJTkUsIHdoaWNoIHdpbGwg Y3JlYXRlIGEgQk8gbWFwcGluZyBmb3IgYQo+IHNwZWNpZmllZCBoL3cgZW5naW5lLgo+IAo+IE9u Y2UgQk8gaXMgY2xvc2VkLCBhbGwgaXRzIG1hcHBpbmdzIHNob3VsZCBiZSBjbG9zZWQgdG9vLiAg VGhpcyB3YXkKPiB1c2Vyc3BhY2UgZG9lc24ndCBuZWVkIHRvIHRyYWNrIGJvdGggQk9zIGFuZCBt YXBwaW5ncy4KPiAKPiBFdmVyeXRoaW5nIHRoYXQgdXNlcnNwYWNlIG5lZWRzIHRvIGRvIGlzOgo+ IAo+IAkxKSBPcGVuIERSTSBjb250ZXh0Cj4gCTIpIENyZWF0ZSBHRU0KPiAJMykgTWFwIEdFTSB0 byByZXF1aXJlZCBoYXJkd2FyZSBlbmdpbmVzCj4gCTQpIFN1Ym1pdCBqb2IgdGhhdCB1c2VzIEdF TSBoYW5kbGUKPiAJNSkgQ2xvc2UgR0VNCj4gCj4gSWYgR0VNIHdhc24ndCBtYXBwZWQgcHJpb3Ig dG8gdGhlIGpvYidzIHN1Ym1pc3Npb24sIHRoZW4gam9iIHdpbGwgZmFpbAo+IGJlY2F1c2Uga2Vy bmVsIGRyaXZlciB3b24ndCByZXNvbHZlIHRoZSBJTyBtYXBwaW5nIG9mIHRoZSBHRU0uClBlcmhh cHMgd2UgY2FuIGluc3RlYWQgY2hhbmdlIHRoZSByZWZlcmVuY2UgY291bnRpbmcgc3VjaCB0aGF0 IGlmIHlvdSAKY2xvc2UgdGhlIEdFTSBvYmplY3QsIHRoZSBtYXBwaW5ncyB3aWxsIGJlIGRyb3Bw ZWQgYXMgd2VsbCBhdXRvbWF0aWNhbGx5LgoKPiAKPiAyLiBXZSB3aWxsIHByb2JhYmx5IG5lZWQg YSBkZWRpY2F0ZWQgZHJtX3RlZ3JhX3N1Ym1pdF9jbWQgZm9yIHN5bmMgcG9pbnQKPiBpbmNyZW1l bnRzLiAgVGhlIGpvYidzIHN5bmMgcG9pbnQgd2lsbCBiZSBhbGxvY2F0ZWQgZHluYW1pY2FsbHkg d2hlbiBqb2IKPiBpcyBzdWJtaXR0ZWQuICBXZSB3aWxsIG5lZWQgYSBmYWcgZm9yIHRoZSBzeW5j X2luY3IgYW5kIHdhaXRfc3luY3B0Cj4gY29tbWFuZHMsIHNheWluZyAiaXQncyBhIGpvYidzIHN5 bmMgcG9pbnQgaW5jcmVtZW50L3dhaXQiCgpOZWdhdGl2ZS4gTGlrZSBJIGhhdmUgZXhwbGFpbmVk IGluIHByZXZpb3VzIGRpc2N1c3Npb25zLCB3aXRoIHRoZSAKY3VycmVudCB3YXkgdGhlIHVzYWdl IG9mIGhhcmR3YXJlIHJlc291cmNlcyBpcyBtdWNoIG1vcmUgZGV0ZXJtaW5pc3RpYyAKYW5kIG9i dmlvdXMuIEkgZGlzYWdyZWUgb24gdGhlIHBvaW50IHRoYXQgdGhpcyBpcyBtdWNoIG1vcmUgY29t cGxpY2F0ZWQgCmZvciB0aGUgdXNlcnNwYWNlLiBTZXBhcmF0aW5nIHN5bmNwb2ludCBhbmQgY2hh bm5lbCBhbGxvY2F0aW9uIGlzIG9uZSBvZiAKdGhlIHByaW1hcnkgbW90aXZhdGlvbnMgb2YgdGhp cyBzZXJpZXMgZm9yIG1lLgoKPiAKPiAzLiBXZSBzaG91bGQgdXNlIGRtYS1mZW5jZSBBUEkgZGly ZWN0bHkgYW5kIHdhaXRlci1zaGltIHNob3VsZCBiZQo+IHJlbW92ZWQuICBJdCdzIGdyZWF0IHRo YXQgeW91J3JlIGFscmVhZHkgd29ya2luZyBvbiB0aGlzLgo+IAo+IDQuIFN5bmMgZmlsZSBzaG91 bGRuJ3QgYmUgbmVlZGVkIGZvciB0aGUgcGFydCBvZiBEUk0gQVBJIHdoaWNoIGRvZXNuJ3QKPiBp bnRlcmFjdCB3aXRoIGV4dGVybmFsIG5vbi1EUk0gZGV2aWNlcy4gIFdlIHNob3VsZCB1c2UgRFJN IHN5bmNvYmogZm9yCj4gZXZlcnl0aGluZyByZWxhdGVkIHRvIERSTSwgaXQncyBhIHN1cGVyaW9y IEFQSSBvdmVyIHN5bmMgZmlsZSwgaXQncwo+IHN1aXRhYmxlIGZvciBEUk0gc2NoZWR1bGVyLgoK Q29uc2lkZXJpbmcgdGhlIGlzc3VlcyB3aXRoIGZpbGVubyBsaW1pdHMsIEkgc3VwcG9zZSB0aGVy ZSBpcyBubyBvdGhlciAKY2hvaWNlLiBDb25zaWRlcmluZyB0aGUgcmVjZW50IE5UU1lOQyBwcm9w b3NhbCBieSBXaW5lIGRldmVsb3BlcnMsIG1heWJlIAp3ZSBzaG91bGQgYWxzbyBoYXZlIE5USEFO RExFcyB0byBnZXQgcmlkIG9mIHJlc3RyaWN0aW9ucyBvZiBmaWxlIApkZXNjcmlwdG9ycy4gRFJN IHN5bmNvYmpzIG1heSBoYXZlIHNvbWUgYWR2YW50YWdlcyBvdmVyIHN5bmMgZmlsZXMsIGJ1dCAK YWxzbyBkaXNhZHZhbnRhZ2VzLiBUaGV5IGNhbm5vdCBiZSBwb2xsKCllZCwgc28gdGhleSBjYW5u b3QgYmUgY29tYmluZWQgCndpdGggd2FpdHMgZm9yIG90aGVyIHJlc291cmNlcy4KCkknbGwgbG9v ayBpbnRvIHRoaXMgZm9yIHY2LgoKPiAKPiA1LiBUaGUgaGFyZHdhcmUgc3RhdGUgb2Ygc3luYyBw b2ludHMgc2hvdWxkIGJlIHJlc2V0IHdoZW4gc3luYyBwb2ludCBpcwo+IHJlcXVlc3RlZCwgbm90 IHdoZW4gaG9zdDF4IGRyaXZlciBpcyBpbml0aWFsaXplZC4KClRoaXMgbWF5IGJlIGRvYWJsZSwg YnV0IEkgZG9uJ3QgdGhpbmsgaXQgaXMgY3JpdGljYWwgZm9yIHRoaXMgVUFQSSwgc28gCmxldCdz IGNvbnNpZGVyIGl0IGFmdGVyIHRoaXMgc2VyaWVzLgoKVGhlIHVzZXJzcGFjZSBzaG91bGQgYW55 d2F5IG5vdCBiZSBhYmxlIHRvIGFzc3VtZSB0aGUgaW5pdGlhbCB2YWx1ZSBvZiAKdGhlIHN5bmNw b2ludCB1cG9uIGFsbG9jYXRpb24uIFRoZSBrZXJuZWwgc2hvdWxkIHNldCBpdCB0byBzb21lIGhp Z2ggCnZhbHVlIHRvIGNhdGNoIGFueSBpc3N1ZXMgcmVsYXRlZCB0byB3cmFwYXJvdW5kLgoKQWxz bywgdGhpcyBtYWtlcyBjb2RlIG1vcmUgY29tcGxpY2F0ZWQgc2luY2UgaXQgbm93IG5lZWRzIHRv IGVuc3VyZSBhbGwgCndhaXRzIG9uIHRoZSBzeW5jcG9pbnQgaGF2ZSBjb21wbGV0ZWQgYmVmb3Jl IGZyZWVpbmcgdGhlIHN5bmNwb2ludCwgCndoaWNoIGNhbiBiZSBub250cml2aWFsIGUuZy4gaWYg dGhlIHdhaXRlciBpcyBpbiBhIGRpZmZlcmVudCB2aXJ0dWFsIAptYWNoaW5lIG9yIHNvbWUgb3Ro ZXIgZGV2aWNlIGNvbm5lY3RlZCB2aWEgUENJZSAoYSByZWFsIHVzZWNhc2UpLgoKPiAKPiA2LiBX ZSB3aWxsIG5lZWQgdG8gYWxsb2NhdGUgYSBob3N0MXggQk8gZm9yIGEgam9iJ3MgY21kc3RyZWFt IGFuZCBhZGQgYQo+IHJlc3RhcnQgY29tbWFuZCB0byB0aGUgZW5kIG9mIHRoZSBqb2IncyBzdHJl YW0uICBDRE1BIHdpbGwganVtcCBpbnRvIHRoZQo+IGpvYidzIHN0cmVhbSBmcm9tIHB1c2ggYnVm ZmVyLgo+IAo+IFdlIGNvdWxkIGFkZCBhIGZsYWcgZm9yIHRoYXQgdG8gZHJtX3RlZ3JhX3N1Ym1p dF9jbWRfZ2F0aGVyLCBzYXlpbmcgdGhhdAo+IGdhdGhlciBzaG91bGQgYmUgaW5saW5lZCBpbnRv IGpvYidzIG1haW4gY21kc3RyZWFtLgo+IAo+IFRoaXMgd2lsbCByZW1vdmUgYSBuZWVkIHRvIGhh dmUgYSBsYXJnZSBwdXNoIGJ1ZmZlciB0aGF0IHdpbGwgZWFzaWx5Cj4gb3ZlcmZsb3csIGl0J3Mg YSByZWFsIHByb2JsZW0gYW5kIHVwc3RyZWFtIGRyaXZlciBldmVuIGhhcyBhIGJ1ZyB3aGVyZQo+ IGl0IGxvY2tzIHVwIG9uIG92ZXJmbG93Lgo+IAo+IEhvdyBpdCB3aWxsIGxvb2sgZnJvbSBDRE1B IHBlcnNwZWN0aXZlOgo+IAo+IFBVU0hCVUYgfAo+IC0tLS0tLS0tLQo+IC4uLiAgICAgfCAgICAg IHwgSk9CICAgfAo+ICAgICAgICAgIHwgICAgICAtLS0tLS0tLS0gICAgICAgfCBKT0IgR0FUSEVS IHwKPiBSRVNUQVJUCS0tLS0tLT4gQ01EICAgIHwgICAgICAgLS0tLS0tLS0tLS0tLS0KPiAgICAg ICAgICB8ICAgICAgfEdBVEhFUiAtLS0tLS0tPiBEQVRBICAgICAgICB8Cj4gLi4uIDwtLS0tLS0t LS0tIFJFU1RBUlR8ICAgICAgIHwgICAgICAgICAgICB8Cj4gICAgICAgICAgfCAgICAgIHwgICAg ICAgfAo+IAoKTGV0IG1lIGNoZWNrIGlmIEkgdW5kZXJzdG9vZCB5b3UgY29ycmVjdGx5OgotIFlv dSB3b3VsZCBsaWtlIHRvIGhhdmUgdGhlIGpvYidzIGNtZGJ1ZiBoYXZlIGZ1cnRoZXIgR0FUSEVS IG9wY29kZXMgCnRoYXQganVtcCBpbnRvIHNtYWxsZXIgZ2F0aGVycz8KCkkgYXNzdW1lIHRoaXMg aXMgbmVlZGVkIGJlY2F1c2UgY3VycmVudGx5IFdBSVRzIGFyZSBwbGFjZWQgaW50byB0aGUgCnB1 c2hidWZmZXIsIHNvIHRoZSBqb2Igd2lsbCB0YWtlIGEgbG90IG9mIHNwYWNlIGluIHRoZSBwdXNo YnVmZmVyIGlmIAp0aGVyZSBhcmUgYSBsb3Qgb2Ygd2FpdHMgKGFuZCBHQVRIRVJzIGluIGJldHdl ZW4gdGhlc2Ugd2FpdHMpPwoKSWYgc28sIHBlcmhhcHMgYXMgYSBzaW1wbGVyIGFsdGVybmF0aXZl IHdlIGNvdWxkIGNoYW5nZSB0aGUgZmlyZXdhbGwgdG8gCmFsbG93IFNFVENMQVNTIGludG8gSE9T VDFYIGZvciB3YWl0aW5nIHNwZWNpZmljYWxseSwgdGhlbiB1c2Vyc3BhY2UgCmNvdWxkIGp1c3Qg c3VibWl0IG9uZSBiaWcgY21kYnVmIHRha2luZyBvbmx5IGxpdHRsZSBzcGFjZSBpbiB0aGUgCnB1 c2hidWZmZXI/IEFsdGhvdWdoIHRoYXQgd291bGQgb25seSBhbGxvdyBkaXJlY3QgSUQvdGhyZXNo b2xkIHdhaXRzLgoKSW4gYW55IGNhc2UsIGl0IHNlZW1zIHRoYXQgdGhpcyBjYW4gYmUgYWRkZWQg aW4gYSBsYXRlciBwYXRjaCwgc28gd2UgCnNob3VsZCBvbWl0IGl0IGZyb20gdGhpcyBzZXJpZXMg Zm9yIHNpbXBsaWNpdHkuIElmIGl0IGlzIGltcG9zc2libGUgZm9yIAp0aGUgdXNlcnNwYWNlIHRv IGRlYWwgd2l0aCBpdCwgd2UgY291bGQgZGlzYWJsZSB0aGUgZmlyZXdhbGwgCnRlbXBvcmFyaWx5 LCBvciBpbXBsZW1lbnQgdGhlIGFib3ZlIGNoYW5nZSBpbiB0aGUgZmlyZXdhbGwuCgo+IAo+IFdo YXQncyBtaXNzaW5nCj4gPT09PT09PT09PT09PT0KPiAKPiAxLiBFeHBsaWNpdCBhbmQgaW1wbGlj aXQgZmVuY2luZyBpc24ndCB0aGVyZSB5ZXQsIHdlIG5lZWQgdG8gc3VwcG9ydCBEUk0KPiBzY2hl ZHVsZXIgZm9yIHRoYXQuCj4gCj4gMi4gVGhlICJ3YWl0IiBjb21tYW5kIHByb2JhYmx5IHNob3Vs ZCBiZSB0YXVnaHQgdG8gdGFrZSBhIHN5bmNvYmogaGFuZGxlCj4gaW4gb3JkZXIgdG8gcG9wdWxh dGUgaXQgd2l0aCBhIGRtYS1mZW5jZSBieSBrZXJuZWwgZHJpdmVyIG9uY2Ugam9iIGlzCj4gc3Vi bWl0dGVkLiAgVGhpcyB3aWxsIGdpdmUgdXMgaW50ZXJtZWRpYXRlIGZlbmNlcyBvZiBhIGpvYiBh bmQgYWxsb3cKPiB1dGlsaXplIHRoZSBzeW5jb2JqIGZlYXR1cmVzIGxpa2UgIndhaXQgdW50aWwg am9iIGlzIHN1Ym1pdHRlZCB0byBoL3cKPiBiZWZvcmUgc3RhcnRpbmcgdG8gd2FpdCBmb3IgdGlt ZW91dCIsIHdoaWNoIHdpbGwgYmUgbmVlZGVkIGJ5IHVzZXJzcGFjZQo+IHdoZW4gRFJNIHNjaGVk dWxlciB3aWxsIGJlIHN1cHBvcnRlZC4KPiAKPiBNaXNjZWxsYW5lb3VzCj4gPT09PT09PT09PT09 PQo+IAo+IDEuIFBsZWFzZSBkb24ndCBmb3JnZXQgdG8gYnVtcCBkcml2ZXIgdmVyc2lvbi4gIFRo aXMgaXMgaW1wb3J0YW50IGZvcgo+IHVzZXJzcGFjZS4KClN1cmUuIEkgZGlkbid0IGRvIGl0IHRo aXMgdGltZSBzaW5jZSBpdCdzIGJhY2t3YXJkcyBjb21wYXRpYmxlIGFuZCBpdCdzIAplYXN5IHRv IGRldGVjdCBpZiB0aGUgbmV3IFVBUEkgaXMgYXZhaWxhYmxlIGJ5IGNoZWNraW5nIGZvciAvZGV2 L2hvc3QxeC4gCkkgY2FuIGJ1bXAgaXQgaW4gdjYgaWYgbmVjZXNzYXJ5LgoKPiAKPiAyLiBQbGVh c2UgdXNlIGEgcHJvcGVyIGtlcm5lbCBjb2Rpbmcgc3R5bGUsIHVzZSBjaGVja3BhdGNoLgo+IAo+ ICAgICAjIGdpdCBmb3JtYXQtcGF0Y2ggLXY1IC4uLgo+ICAgICAjIC4vc2NyaXB0cy9jaGVja3Bh dGNoLnBsIC0tc3RyaWN0IHY1KgoKTG9va3MgbGlrZSBJIGFjY2lkZW50YWxseSBwbGFjZWQgc29t ZSBzcGFjZXMgaW50byBmaXJld2FsbC5jLiBPdGhlcndpc2UgCnRoZSB3YXJuaW5ncyBpdCBwcmlu dHMgZG8gbm90IGxvb2sgY3JpdGljYWwuCgo+IAo+IDMuIEtlcm5lbCBkcml2ZXIgbmVlZHMgYSBy aWNoIGVycm9yIG1lc3NhZ2VzIGZvciBlYWNoIGVycm9yIGNvbmRpdGlvbgo+IGFuZCBpdCBzaG91 bGQgZHVtcCBzdWJtaXR0ZWQgam9iIHdoZW4gZmlyZXdhbGwgZmFpbHMuICBJdCdzIHZlcnkgdGVk aW91cwo+IHRvIHJlLWFkZCBpdCBhbGwgZWFjaCB0aW1lIHdoZW4gc29tZXRoaW5nIGRvZXNuJ3Qg d29yay4KClllcywgdGhhdCdzIHRydWUuIFdpbGwgdGFrZSBhIGxvb2sgZm9yIHY2LgoKPiAKPiA0 LiBQcmV2aW91c2x5IGZpcmV3YWxsIHdhcyB1c2luZyB0aGUgY2xpZW50J3MgY2xhc3MgaWYgaXNf dmFsaWRfY2xhc3MKPiB3YXNuJ3Qgc3BlY2lmaWVkIGluIHRlZ3JhX2RybV9jbGllbnRfb3BzLCB5 b3UgY2hhbmdlZCBpdCBhbmQgbm93Cj4gZmlyZXdhbGwgZmFpbHMgZm9yIEdSM0QgYmVjYXVzZSBp dCBkb2Vzbid0IGhhdmUgdGhlIGlzX3ZhbGlkX2NsYXNzKCkgc2V0Cj4gaW4gdGhlIGRyaXZlci4g IFNlZSBbMV0uCj4gCj4gNS4gVGhlIENETUEgY2xhc3Mgc2hvdWxkIGJlIHJlc3RvcmVkIHRvIHRo ZSBjbGFzcyBvZiBhIHByZXZpb3VzIGdhdGhlcgo+IGFmdGVyIHRoZSB3YWl0IGNvbW1hbmQgaW4g c3VibWl0X2dhdGhlcnMoKSBhbmQgbm90IHRvIHRoZSBjbGFzcyBvZiB0aGUKPiBjbGllbnQuICBH UjJEIHN1cHBvcnRzIG11bHRpcGxlIGNsYXNzZXMuICBTZWUgWzFdLgoKV2lsbCB0YWtlIGEgbG9v ayBhdCB0aGVzZSB0d28gZm9yIHY2LgoKPiAKPiBbMV0KPiBodHRwczovL2dpdGh1Yi5jb20vZ3Jh dGUtZHJpdmVyL2xpbnV4L2NvbW1pdC8wMjRjYmEzNjljOWMwZTI3NjJlOTg5MDA2OGZmOTk0NGNi MTBjNDRmCj4gCgpNaWtrbwpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3Rv cC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmkt ZGV2ZWwK