From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dmitry Osipenko Subject: Re: [RFC] Host1x/TegraDRM UAPI (drm_tegra_submit_command) Date: Mon, 29 Jun 2020 03:00:05 +0300 Message-ID: <3f0d2e08-aa0b-9048-c22d-8f3d3106cdff@gmail.com> References: <9b06b7ec-f952-2561-7afb-5653514cd5d3@kapsi.fi> <19b7b295-30fa-8897-02f3-3c3b8f2a0e53@kapsi.fi> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Return-path: In-Reply-To: <19b7b295-30fa-8897-02f3-3c3b8f2a0e53-/1wQRMveznE@public.gmane.org> Content-Language: en-US Sender: linux-tegra-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Mikko Perttunen , Thierry Reding , Jon Hunter , David Airlie , Daniel Vetter , sumit.semwal-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org, gustavo-THi1TnShQwVAfugRpC6u6w@public.gmane.org Cc: "linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , dri-devel , talho-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org, bhuntsman-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org, Erik Faye-Lund List-Id: linux-tegra@vger.kernel.org 28.06.2020 13:28, Mikko Perttunen пишет: > On 6/28/20 1:32 AM, Dmitry Osipenko wrote: >> 23.06.2020 15:09, Mikko Perttunen пишет: >>> /* Command is an opcode gather from a GEM handle */ >>> #define DRM_TEGRA_SUBMIT_COMMAND_GATHER             0 >>> /* Command is an opcode gather from a user pointer */ >>> #define DRM_TEGRA_SUBMIT_COMMAND_GATHER_UPTR        1 >>> /* Command is a wait for syncpt fence completion */ >>> #define DRM_TEGRA_SUBMIT_COMMAND_WAIT_SYNCPT        2 >>> /* Command is a wait for SYNC_FILE FD completion */ >>> #define DRM_TEGRA_SUBMIT_COMMAND_WAIT_SYNC_FILE     3 >>> /* Command is a wait for DRM syncobj completion */ >>> #define DRM_TEGRA_SUBMIT_COMMAND_WAIT_SYNCOBJ       4 >>> >>> /* >>>   * Allow driver to skip command execution if engine >>>   * was not accessed by another channel between >>>   * submissions. >>>   */ >>> #define DRM_TEGRA_SUBMIT_CONTEXT_SETUP                        (1<<0) >>> >>> struct drm_tegra_submit_command { >>>          __u16 type; >>>          __u16 flags; >> >> Shouldn't the "packed" attribute be needed if a non-32bit aligned fields >> are used? > > I guess we should change these to u32 for consistency. > >> >>>          union { >>>                  struct { >>>                      /* GEM handle */ >>>                      __u32 handle; >>> >>>                      /* >>>                       * Offset into GEM object in bytes. >>>                       * Must be aligned by 4. >>>                       */ >>>                      __u64 offset; >> >> 64bits for a gather offset is a bit too much, in most cases gathers are >> under 4K. >> >> u32 should be more than enough (maybe even u16 if offset is given in a >> dword granularity). > > I guess this can be changed to u32, though I don't think there is any > particularly pressing reason not to use u64. > > In any case, I think we concluded that we'll drop the GEM gather command > for now. Sure, I commented this just in a case, for the future :) >> >>>                      /* >>>                       * Length of gather in bytes. >>>                       * Must be aligned by 4. >>>                       */ >>>                      __u64 length; >> >> u32/16 >> >>>                  } gather; >> >>>                  struct { >>>                          __u32 reserved[1]; >>> >>>                          /* >>>                           * Pointer to gather data. >>>                           * Must be aligned by 4 bytes. >>>                           */ >>>                          __u64 base; >>>                          /* >>>                           * Length of gather in bytes. >>>                           * Must be aligned by 4. >>>                           */ >>>                          __u64 length; >>>                  } gather_uptr; >> >> What about to inline the UPTR gather data and relocs into the >> drm_tegra_submit_command[] buffer: >> >> struct drm_tegra_submit_command { >>     struct { >>         u16 num_words; >>         u16 num_relocs; >> >>         gather_data[]; >>         drm_tegra_submit_relocation relocs[]; >>     } gather_uptr; >> }; >> >> struct drm_tegra_channel_submit { >>          __u32 num_syncpt_incrs; >>          __u32 syncpt_idx; >> >>          __u64 commands_ptr; >>     __u32 commands_size; >> ... >> }; >> >> struct drm_tegra_submit_command example[] = { >>     cmd.gather_uptr{}, >>     ... >>     gather_data[], >>     gather_relocs[], >>     cmd.wait_syncpt{}, >>     ... >> }; >> >> This way we will have only a single copy_from_user() for the whole >> cmdstream, which should be more efficient to do and nicer from both >> userspace and kernel perspectives in regards to forming and parsing the >> commands. >> > > I'm not sure I agree it being nicer with regard to forming and parsing > - Can you actually place multiple unsized arrays in a struct without > pointers? No :) But there are no unsized arrays here. The parser will read first command and then move pointer to the next command based on size of the parsed command. > - gather_data's length is a multiple of 4, and so since we have u64's in > drm_tegra_submit_relocation, alignment needs to be taken care of > manually, both when forming and kernel needs to validate it while > parsing. Depending on number of words in the gather, padding would need > to be inserted. We could swap the two around but it still feels more > brittle. Yes, there will be unaligned reads on ARM64, but I don't think it's a problem. Isn't it? > Also, if we read the gather from a separate address, userspace doesn't > necessarily need to know the length of the gather (and number of relocs) > upfront, so it's easier to have a builder pattern without needing to > copy things later. Usually there are 2-3 relocs per gather, so userspace could simply maintain a fixed-sized static buffer for the relocs (say 32 relocs). Once gather is sliced by userspace, the stashed relocs will be appended to the comands buffer and next gather will be formed. The relocs copying doesn't really costs anything for userspace, the price is incomparable with the cost of UPTR copying of each gather for the kernel. Well, the UPTR copying isn't expensive, but if there is a single copy for the whole IOCTL, then it's even much better! > If we allow direct page mappings for gathers later, a separate address > would make things also a little bit easier. For direct page mappings > userspace would need to keep the opcode data unchanged while the job is > being executed, so userspace could keep an arena where the gathers are > placed, and refer to segments of that, instead of having to keep the > drm_tegra_submit_commands alive. Okay, what about to have a single UPTR buffer for all gathers of a job? struct drm_tegra_channel_submit { u64 commands_ptr; u64 gathers_ptr; u32 commands_size; u32 gathers_size; ... }; struct drm_tegra_submit_command { ... union { struct { /* * Length of gather in bytes. * Must be aligned by 4. */ __u32 length; } gather_uptr; }; }; Now we have a single UPTR gather that could be sliced into sub-gathers during of job's submission and also the whole data could be copied at once by kernel driver for the parsing purposes. The userspace will have to preallocate a large-enough buffer upfront for the gathers. If it runs out of space in the buffer, then it should reallocate a larger buffer. Nice and simple :) 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=-2.3 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no 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 3C992C433E1 for ; Mon, 29 Jun 2020 06:51: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 137F0206E9 for ; Mon, 29 Jun 2020 06:51:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FmAQHIEf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 137F0206E9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com 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 E4B0C6E3E1; Mon, 29 Jun 2020 06:50:59 +0000 (UTC) Received: from mail-lj1-x244.google.com (mail-lj1-x244.google.com [IPv6:2a00:1450:4864:20::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5FA7C6E3CB for ; Mon, 29 Jun 2020 00:00:09 +0000 (UTC) Received: by mail-lj1-x244.google.com with SMTP id f8so3815963ljc.2 for ; Sun, 28 Jun 2020 17:00:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=qAx5VBPEoxfFFPCSdYQxL6J6HVE4Hnow+vGJgzv15sY=; b=FmAQHIEfgtywOIBM/e66H03h9Bdrd6+WwTxtAH1TnMFfBkZS6KHycOcTuBMR4HWpq0 1z5z1C1CEwrKCMMYDrOux8ESdlODUaNw/ZNm3O4iIG3UdOnl0qNZuUgV9hvC+vzgODAt edbtlZXQoL30MkfbWBLSIiBmKHO2pNJa1sUURUw02J47Bgo7jryLWMikH/fuMScKEeBl k6/Q3usSgWM58pR77AeEtoMJZ0EO9sEPjDBKGG3leaWx6w/Y31+2nAZMmRWsBj1kIzfS 32InlqwRHpKcTwbQHfVIYO7vW1nZW5nIteyVMaH/DvLh5waLvHVKyVmIhqPDfC/P+wTZ WTVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=qAx5VBPEoxfFFPCSdYQxL6J6HVE4Hnow+vGJgzv15sY=; b=dYReEpVuOLUH+6bojHSDZmZIIU1kwv2wbvJ/hHKa0N1HdpzokNM03yazjLie931WO6 L7cLa2XTzdKGr8H6L9SbyyPPswZ5/O5la+pAaANe2Uuy35VNPTx4/XRh8AG94yBCQIRk T07LHmddb9cQhqizgN+LMv5rPhBTV63BtPSZuDXaOAyjo5Nfiz6NwqUjhfU61UnMIx79 AmC+G9z1pbV+1z7B/cHEOy/aFD7l1ibs9HrGQzjYdQ1how617zUS5Xgqk30ofvsb7tb4 ofjxyuYcT2P/5MHiVbR8RtjoMVs+eZPwp2xe1LaR92+NooiismGIlSuzyO3j2MVkkl5o Xngg== X-Gm-Message-State: AOAM533QJv+GsjkW3x8KosxEraLFYCcsGejHtaBAyQR1yhaKQjOStitI 2hqpbYLSZ9tJHUmX3dJIBHk= X-Google-Smtp-Source: ABdhPJySmIlHXzYAwVEeD+3MpSFOk/QoIfClC/+Bvn+1toqG2cWU2FqnlmB6N2IyvkoRDvpukx73rQ== X-Received: by 2002:a2e:9dd8:: with SMTP id x24mr7130504ljj.304.1593388807666; Sun, 28 Jun 2020 17:00:07 -0700 (PDT) Received: from [192.168.2.145] (79-139-237-54.dynamic.spd-mgts.ru. [79.139.237.54]) by smtp.googlemail.com with ESMTPSA id n3sm1573659ljc.114.2020.06.28.17.00.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 28 Jun 2020 17:00:06 -0700 (PDT) Subject: Re: [RFC] Host1x/TegraDRM UAPI (drm_tegra_submit_command) To: Mikko Perttunen , Thierry Reding , Jon Hunter , David Airlie , Daniel Vetter , sumit.semwal@linaro.org, gustavo@padovan.org References: <9b06b7ec-f952-2561-7afb-5653514cd5d3@kapsi.fi> <19b7b295-30fa-8897-02f3-3c3b8f2a0e53@kapsi.fi> From: Dmitry Osipenko Message-ID: <3f0d2e08-aa0b-9048-c22d-8f3d3106cdff@gmail.com> Date: Mon, 29 Jun 2020 03:00:05 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <19b7b295-30fa-8897-02f3-3c3b8f2a0e53@kapsi.fi> Content-Language: en-US X-Mailman-Approved-At: Mon, 29 Jun 2020 06:50:54 +0000 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 , Erik Faye-Lund Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" MjguMDYuMjAyMCAxMzoyOCwgTWlra28gUGVydHR1bmVuINC/0LjRiNC10YI6Cj4gT24gNi8yOC8y MCAxOjMyIEFNLCBEbWl0cnkgT3NpcGVua28gd3JvdGU6Cj4+IDIzLjA2LjIwMjAgMTU6MDksIE1p a2tvIFBlcnR0dW5lbiDQv9C40YjQtdGCOgo+Pj4gLyogQ29tbWFuZCBpcyBhbiBvcGNvZGUgZ2F0 aGVyIGZyb20gYSBHRU0gaGFuZGxlICovCj4+PiAjZGVmaW5lIERSTV9URUdSQV9TVUJNSVRfQ09N TUFORF9HQVRIRVLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMAo+Pj4gLyogQ29tbWFuZCBpcyBh biBvcGNvZGUgZ2F0aGVyIGZyb20gYSB1c2VyIHBvaW50ZXIgKi8KPj4+ICNkZWZpbmUgRFJNX1RF R1JBX1NVQk1JVF9DT01NQU5EX0dBVEhFUl9VUFRSwqDCoMKgwqDCoMKgwqAgMQo+Pj4gLyogQ29t bWFuZCBpcyBhIHdhaXQgZm9yIHN5bmNwdCBmZW5jZSBjb21wbGV0aW9uICovCj4+PiAjZGVmaW5l IERSTV9URUdSQV9TVUJNSVRfQ09NTUFORF9XQUlUX1NZTkNQVMKgwqDCoMKgwqDCoMKgIDIKPj4+ IC8qIENvbW1hbmQgaXMgYSB3YWl0IGZvciBTWU5DX0ZJTEUgRkQgY29tcGxldGlvbiAqLwo+Pj4g I2RlZmluZSBEUk1fVEVHUkFfU1VCTUlUX0NPTU1BTkRfV0FJVF9TWU5DX0ZJTEXCoMKgwqDCoCAz Cj4+PiAvKiBDb21tYW5kIGlzIGEgd2FpdCBmb3IgRFJNIHN5bmNvYmogY29tcGxldGlvbiAqLwo+ Pj4gI2RlZmluZSBEUk1fVEVHUkFfU1VCTUlUX0NPTU1BTkRfV0FJVF9TWU5DT0JKwqDCoMKgwqDC oMKgIDQKPj4+Cj4+PiAvKgo+Pj4gwqDCoCogQWxsb3cgZHJpdmVyIHRvIHNraXAgY29tbWFuZCBl eGVjdXRpb24gaWYgZW5naW5lCj4+PiDCoMKgKiB3YXMgbm90IGFjY2Vzc2VkIGJ5IGFub3RoZXIg Y2hhbm5lbCBiZXR3ZWVuCj4+PiDCoMKgKiBzdWJtaXNzaW9ucy4KPj4+IMKgwqAqLwo+Pj4gI2Rl ZmluZSBEUk1fVEVHUkFfU1VCTUlUX0NPTlRFWFRfU0VUVVDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgxPDwwKQo+Pj4KPj4+IHN0cnVjdCBkcm1fdGVncmFf c3VibWl0X2NvbW1hbmQgewo+Pj4gwqDCoMKgwqDCoMKgwqDCoCBfX3UxNiB0eXBlOwo+Pj4gwqDC oMKgwqDCoMKgwqDCoCBfX3UxNiBmbGFnczsKPj4KPj4gU2hvdWxkbid0IHRoZSAicGFja2VkIiBh dHRyaWJ1dGUgYmUgbmVlZGVkIGlmIGEgbm9uLTMyYml0IGFsaWduZWQgZmllbGRzCj4+IGFyZSB1 c2VkPwo+IAo+IEkgZ3Vlc3Mgd2Ugc2hvdWxkIGNoYW5nZSB0aGVzZSB0byB1MzIgZm9yIGNvbnNp c3RlbmN5Lgo+IAo+Pgo+Pj4gwqDCoMKgwqDCoMKgwqDCoCB1bmlvbiB7Cj4+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3Qgewo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAvKiBHRU0gaGFuZGxlICovCj4+PiDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9fdTMyIGhhbmRsZTsKPj4+Cj4+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIC8qCj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKiBPZmZzZXQgaW50byBHRU0gb2JqZWN0IGluIGJ5dGVz Lgo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICogTXVzdCBi ZSBhbGlnbmVkIGJ5IDQuCj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgKi8KPj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgX191 NjQgb2Zmc2V0Owo+Pgo+PiA2NGJpdHMgZm9yIGEgZ2F0aGVyIG9mZnNldCBpcyBhIGJpdCB0b28g bXVjaCwgaW4gbW9zdCBjYXNlcyBnYXRoZXJzIGFyZQo+PiB1bmRlciA0Sy4KPj4KPj4gdTMyIHNo b3VsZCBiZSBtb3JlIHRoYW4gZW5vdWdoIChtYXliZSBldmVuIHUxNiBpZiBvZmZzZXQgaXMgZ2l2 ZW4gaW4gYQo+PiBkd29yZCBncmFudWxhcml0eSkuCj4gCj4gSSBndWVzcyB0aGlzIGNhbiBiZSBj aGFuZ2VkIHRvIHUzMiwgdGhvdWdoIEkgZG9uJ3QgdGhpbmsgdGhlcmUgaXMgYW55Cj4gcGFydGlj dWxhcmx5IHByZXNzaW5nIHJlYXNvbiBub3QgdG8gdXNlIHU2NC4KPiAKPiBJbiBhbnkgY2FzZSwg SSB0aGluayB3ZSBjb25jbHVkZWQgdGhhdCB3ZSdsbCBkcm9wIHRoZSBHRU0gZ2F0aGVyIGNvbW1h bmQKPiBmb3Igbm93LgoKU3VyZSwgSSBjb21tZW50ZWQgdGhpcyBqdXN0IGluIGEgY2FzZSwgZm9y IHRoZSBmdXR1cmUgOikKCj4+Cj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIC8qCj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg KiBMZW5ndGggb2YgZ2F0aGVyIGluIGJ5dGVzLgo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgICogTXVzdCBiZSBhbGlnbmVkIGJ5IDQuCj4+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKi8KPj4+IMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgX191NjQgbGVuZ3RoOwo+Pgo+PiB1MzIvMTYKPj4KPj4+ IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0gZ2F0aGVyOwo+Pgo+Pj4gwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RydWN0IHsKPj4+IMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBfX3UzMiByZXNlcnZlZFsxXTsKPj4+Cj4+ PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgLyoKPj4+ IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICogUG9p bnRlciB0byBnYXRoZXIgZGF0YS4KPj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgICogTXVzdCBiZSBhbGlnbmVkIGJ5IDQgYnl0ZXMuCj4+PiDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqLwo+Pj4gwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9fdTY0IGJhc2U7 Cj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgLyoK Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICog TGVuZ3RoIG9mIGdhdGhlciBpbiBieXRlcy4KPj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICogTXVzdCBiZSBhbGlnbmVkIGJ5IDQuCj4+PiDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqLwo+Pj4gwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9fdTY0IGxlbmd0 aDsKPj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0gZ2F0aGVyX3VwdHI7Cj4+ Cj4+IFdoYXQgYWJvdXQgdG8gaW5saW5lIHRoZSBVUFRSIGdhdGhlciBkYXRhIGFuZCByZWxvY3Mg aW50byB0aGUKPj4gZHJtX3RlZ3JhX3N1Ym1pdF9jb21tYW5kW10gYnVmZmVyOgo+Pgo+PiBzdHJ1 Y3QgZHJtX3RlZ3JhX3N1Ym1pdF9jb21tYW5kIHsKPj4gwqDCoMKgwqBzdHJ1Y3Qgewo+PiDCoMKg wqDCoMKgwqDCoCB1MTYgbnVtX3dvcmRzOwo+PiDCoMKgwqDCoMKgwqDCoCB1MTYgbnVtX3JlbG9j czsKPj4KPj4gwqDCoMKgwqDCoMKgwqAgZ2F0aGVyX2RhdGFbXTsKPj4gwqDCoMKgwqDCoMKgwqAg ZHJtX3RlZ3JhX3N1Ym1pdF9yZWxvY2F0aW9uIHJlbG9jc1tdOwo+PiDCoMKgwqDCoH0gZ2F0aGVy X3VwdHI7Cj4+IH07Cj4+Cj4+IHN0cnVjdCBkcm1fdGVncmFfY2hhbm5lbF9zdWJtaXQgewo+PiDC oMKgwqDCoMKgwqDCoMKgIF9fdTMyIG51bV9zeW5jcHRfaW5jcnM7Cj4+IMKgwqDCoMKgwqDCoMKg wqAgX191MzIgc3luY3B0X2lkeDsKPj4KPj4gwqDCoMKgwqDCoMKgwqDCoCBfX3U2NCBjb21tYW5k c19wdHI7Cj4+IMKgwqDCoMKgX191MzIgY29tbWFuZHNfc2l6ZTsKPj4gLi4uCj4+IH07Cj4+Cj4+ IHN0cnVjdCBkcm1fdGVncmFfc3VibWl0X2NvbW1hbmQgZXhhbXBsZVtdID0gewo+PiDCoMKgwqDC oGNtZC5nYXRoZXJfdXB0cnt9LAo+PiDCoMKgwqDCoC4uLgo+PiDCoMKgwqDCoGdhdGhlcl9kYXRh W10sCj4+IMKgwqDCoMKgZ2F0aGVyX3JlbG9jc1tdLAo+PiDCoMKgwqDCoGNtZC53YWl0X3N5bmNw dHt9LAo+PiDCoMKgwqDCoC4uLgo+PiB9Owo+Pgo+PiBUaGlzIHdheSB3ZSB3aWxsIGhhdmUgb25s eSBhIHNpbmdsZSBjb3B5X2Zyb21fdXNlcigpIGZvciB0aGUgd2hvbGUKPj4gY21kc3RyZWFtLCB3 aGljaCBzaG91bGQgYmUgbW9yZSBlZmZpY2llbnQgdG8gZG8gYW5kIG5pY2VyIGZyb20gYm90aAo+ PiB1c2Vyc3BhY2UgYW5kIGtlcm5lbCBwZXJzcGVjdGl2ZXMgaW4gcmVnYXJkcyB0byBmb3JtaW5n IGFuZCBwYXJzaW5nIHRoZQo+PiBjb21tYW5kcy4KPj4KPiAKPiBJJ20gbm90IHN1cmUgSSBhZ3Jl ZSBpdCBiZWluZyBuaWNlciB3aXRoIHJlZ2FyZCB0byBmb3JtaW5nIGFuZCBwYXJzaW5nCj4gLSBD YW4geW91IGFjdHVhbGx5IHBsYWNlIG11bHRpcGxlIHVuc2l6ZWQgYXJyYXlzIGluIGEgc3RydWN0 IHdpdGhvdXQKPiBwb2ludGVycz8KCk5vIDopIEJ1dCB0aGVyZSBhcmUgbm8gdW5zaXplZCBhcnJh eXMgaGVyZS4gVGhlIHBhcnNlciB3aWxsIHJlYWQgZmlyc3QKY29tbWFuZCBhbmQgdGhlbiBtb3Zl IHBvaW50ZXIgdG8gdGhlIG5leHQgY29tbWFuZCBiYXNlZCBvbiBzaXplIG9mIHRoZQpwYXJzZWQg Y29tbWFuZC4KCj4gLSBnYXRoZXJfZGF0YSdzIGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIDQsIGFu ZCBzbyBzaW5jZSB3ZSBoYXZlIHU2NCdzIGluCj4gZHJtX3RlZ3JhX3N1Ym1pdF9yZWxvY2F0aW9u LCBhbGlnbm1lbnQgbmVlZHMgdG8gYmUgdGFrZW4gY2FyZSBvZgo+IG1hbnVhbGx5LCBib3RoIHdo ZW4gZm9ybWluZyBhbmQga2VybmVsIG5lZWRzIHRvIHZhbGlkYXRlIGl0IHdoaWxlCj4gcGFyc2lu Zy4gRGVwZW5kaW5nIG9uIG51bWJlciBvZiB3b3JkcyBpbiB0aGUgZ2F0aGVyLCBwYWRkaW5nIHdv dWxkIG5lZWQKPiB0byBiZSBpbnNlcnRlZC4gV2UgY291bGQgc3dhcCB0aGUgdHdvIGFyb3VuZCBi dXQgaXQgc3RpbGwgZmVlbHMgbW9yZQo+IGJyaXR0bGUuCgpZZXMsIHRoZXJlIHdpbGwgYmUgdW5h bGlnbmVkIHJlYWRzIG9uIEFSTTY0LCBidXQgSSBkb24ndCB0aGluayBpdCdzIGEKcHJvYmxlbS4g SXNuJ3QgaXQ/Cgo+IEFsc28sIGlmIHdlIHJlYWQgdGhlIGdhdGhlciBmcm9tIGEgc2VwYXJhdGUg YWRkcmVzcywgdXNlcnNwYWNlIGRvZXNuJ3QKPiBuZWNlc3NhcmlseSBuZWVkIHRvIGtub3cgdGhl IGxlbmd0aCBvZiB0aGUgZ2F0aGVyIChhbmQgbnVtYmVyIG9mIHJlbG9jcykKPiB1cGZyb250LCBz byBpdCdzIGVhc2llciB0byBoYXZlIGEgYnVpbGRlciBwYXR0ZXJuIHdpdGhvdXQgbmVlZGluZyB0 bwo+IGNvcHkgdGhpbmdzIGxhdGVyLgoKVXN1YWxseSB0aGVyZSBhcmUgMi0zIHJlbG9jcyBwZXIg Z2F0aGVyLCBzbyB1c2Vyc3BhY2UgY291bGQgc2ltcGx5Cm1haW50YWluIGEgZml4ZWQtc2l6ZWQg c3RhdGljIGJ1ZmZlciBmb3IgdGhlIHJlbG9jcyAoc2F5IDMyIHJlbG9jcykuCk9uY2UgZ2F0aGVy IGlzIHNsaWNlZCBieSB1c2Vyc3BhY2UsIHRoZSBzdGFzaGVkIHJlbG9jcyB3aWxsIGJlIGFwcGVu ZGVkCnRvIHRoZSBjb21hbmRzIGJ1ZmZlciBhbmQgbmV4dCBnYXRoZXIgd2lsbCBiZSBmb3JtZWQu CgpUaGUgcmVsb2NzIGNvcHlpbmcgZG9lc24ndCByZWFsbHkgY29zdHMgYW55dGhpbmcgZm9yIHVz ZXJzcGFjZSwgdGhlCnByaWNlIGlzIGluY29tcGFyYWJsZSB3aXRoIHRoZSBjb3N0IG9mIFVQVFIg Y29weWluZyBvZiBlYWNoIGdhdGhlciBmb3IKdGhlIGtlcm5lbC4KCldlbGwsIHRoZSBVUFRSIGNv cHlpbmcgaXNuJ3QgZXhwZW5zaXZlLCBidXQgaWYgdGhlcmUgaXMgYSBzaW5nbGUgY29weQpmb3Ig dGhlIHdob2xlIElPQ1RMLCB0aGVuIGl0J3MgZXZlbiBtdWNoIGJldHRlciEKCj4gSWYgd2UgYWxs b3cgZGlyZWN0IHBhZ2UgbWFwcGluZ3MgZm9yIGdhdGhlcnMgbGF0ZXIsIGEgc2VwYXJhdGUgYWRk cmVzcwo+IHdvdWxkIG1ha2UgdGhpbmdzIGFsc28gYSBsaXR0bGUgYml0IGVhc2llci4gRm9yIGRp cmVjdCBwYWdlIG1hcHBpbmdzCj4gdXNlcnNwYWNlIHdvdWxkIG5lZWQgdG8ga2VlcCB0aGUgb3Bj b2RlIGRhdGEgdW5jaGFuZ2VkIHdoaWxlIHRoZSBqb2IgaXMKPiBiZWluZyBleGVjdXRlZCwgc28g dXNlcnNwYWNlIGNvdWxkIGtlZXAgYW4gYXJlbmEgd2hlcmUgdGhlIGdhdGhlcnMgYXJlCj4gcGxh Y2VkLCBhbmQgcmVmZXIgdG8gc2VnbWVudHMgb2YgdGhhdCwgaW5zdGVhZCBvZiBoYXZpbmcgdG8g a2VlcCB0aGUKPiBkcm1fdGVncmFfc3VibWl0X2NvbW1hbmRzIGFsaXZlLgoKT2theSwgd2hhdCBh Ym91dCB0byBoYXZlIGEgc2luZ2xlIFVQVFIgYnVmZmVyIGZvciBhbGwgZ2F0aGVycyBvZiBhIGpv Yj8KCnN0cnVjdCBkcm1fdGVncmFfY2hhbm5lbF9zdWJtaXQgewoJdTY0IGNvbW1hbmRzX3B0cjsK CXU2NCBnYXRoZXJzX3B0cjsKCgl1MzIgY29tbWFuZHNfc2l6ZTsKCXUzMiBnYXRoZXJzX3NpemU7 CgkuLi4KfTsKCnN0cnVjdCBkcm1fdGVncmFfc3VibWl0X2NvbW1hbmQgewoJLi4uCiAgICAgICAg dW5pb24gewogICAgICAgICAgICAgICAgc3RydWN0IHsKICAgICAgICAgICAgICAgICAgICAgICAg LyoKICAgICAgICAgICAgICAgICAgICAgICAgICogTGVuZ3RoIG9mIGdhdGhlciBpbiBieXRlcy4K ICAgICAgICAgICAgICAgICAgICAgICAgICogTXVzdCBiZSBhbGlnbmVkIGJ5IDQuCiAgICAgICAg ICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBfX3UzMiBsZW5ndGg7 CiAgICAgICAgICAgICAgICB9IGdhdGhlcl91cHRyOwoJfTsKfTsKCk5vdyB3ZSBoYXZlIGEgc2lu Z2xlIFVQVFIgZ2F0aGVyIHRoYXQgY291bGQgYmUgc2xpY2VkIGludG8gc3ViLWdhdGhlcnMKZHVy aW5nIG9mIGpvYidzIHN1Ym1pc3Npb24gYW5kIGFsc28gdGhlIHdob2xlIGRhdGEgY291bGQgYmUg Y29waWVkIGF0Cm9uY2UgYnkga2VybmVsIGRyaXZlciBmb3IgdGhlIHBhcnNpbmcgcHVycG9zZXMu CgpUaGUgdXNlcnNwYWNlIHdpbGwgaGF2ZSB0byBwcmVhbGxvY2F0ZSBhIGxhcmdlLWVub3VnaCBi dWZmZXIgdXBmcm9udCBmb3IKdGhlIGdhdGhlcnMuIElmIGl0IHJ1bnMgb3V0IG9mIHNwYWNlIGlu IHRoZSBidWZmZXIsIHRoZW4gaXQgc2hvdWxkCnJlYWxsb2NhdGUgYSBsYXJnZXIgYnVmZmVyLiBO aWNlIGFuZCBzaW1wbGUgOikKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0 b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJp LWRldmVsCg==