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.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,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 D7CD8C47088 for ; Wed, 26 May 2021 18:45:39 +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 A1EBD613BE for ; Wed, 26 May 2021 18:45:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A1EBD613BE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.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 CA0366E52D; Wed, 26 May 2021 18:45:38 +0000 (UTC) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6C0DF6E51B; Wed, 26 May 2021 18:45:37 +0000 (UTC) IronPort-SDR: 3b4jy5ieHGeCzT1W67Lf/p7Y0T2EpCc1+rQlV5Gz+HpunqAP3fS8GyJsfP8s4pizdiFB8YtG50 kk+7js8i4ldA== X-IronPort-AV: E=McAfee;i="6200,9189,9996"; a="202578146" X-IronPort-AV: E=Sophos;i="5.82,331,1613462400"; d="scan'208";a="202578146" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2021 11:45:36 -0700 IronPort-SDR: vdhqNw4TXpdZzzBwoRMFkaEQmhmFb/so97zL5sb5LCoRapW+berJZzxpuSSoQMkwhrqaYc06By gSd0KnGkfKRA== X-IronPort-AV: E=Sophos;i="5.82,331,1613462400"; d="scan'208";a="547325766" Received: from johnharr-mobl1.amr.corp.intel.com (HELO [10.209.66.193]) ([10.209.66.193]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2021 11:45:35 -0700 Subject: Re: [Intel-gfx] [RFC PATCH 60/97] drm/i915: Track 'serial' counts for virtual engines To: Tvrtko Ursulin , Matthew Brost References: <20210506191451.77768-1-matthew.brost@intel.com> <20210506191451.77768-61-matthew.brost@intel.com> <20210525175239.GA21324@sdutt-i7> <6f6a1266-fe48-9cf1-beba-0b4463000ca7@linux.intel.com> From: John Harrison Message-ID: <15643bd8-a270-a84d-3bd7-5376af7e378c@intel.com> Date: Wed, 26 May 2021 11:45:34 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.10.2 MIME-Version: 1.0 In-Reply-To: <6f6a1266-fe48-9cf1-beba-0b4463000ca7@linux.intel.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-GB 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: jason.ekstrand@intel.com, daniel.vetter@intel.com, intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On 5/26/2021 01:40, Tvrtko Ursulin wrote: > On 25/05/2021 18:52, Matthew Brost wrote: >> On Tue, May 25, 2021 at 11:16:12AM +0100, Tvrtko Ursulin wrote: >>> >>> On 06/05/2021 20:14, Matthew Brost wrote: >>>> From: John Harrison >>>> >>>> The serial number tracking of engines happens at the backend of >>>> request submission and was expecting to only be given physical >>>> engines. However, in GuC submission mode, the decomposition of virtual >>>> to physical engines does not happen in i915. Instead, requests are >>>> submitted to their virtual engine mask all the way through to the >>>> hardware (i.e. to GuC). This would mean that the heart beat code >>>> thinks the physical engines are idle due to the serial number not >>>> incrementing. >>>> >>>> This patch updates the tracking to decompose virtual engines into >>>> their physical constituents and tracks the request against each. This >>>> is not entirely accurate as the GuC will only be issuing the request >>>> to one physical engine. However, it is the best that i915 can do given >>>> that it has no knowledge of the GuC's scheduling decisions. >>> >>> Commit text sounds a bit defeatist. I think instead of making up the >>> serial >>> counts, which has downsides (could you please document in the commit >>> what >>> they are), we should think how to design things properly. >>> >> >> IMO, I don't think fixing serial counts is the scope of this series. We >> should focus on getting GuC submission in not cleaning up all the crap >> that is in the i915. Let's make a note of this though so we can revisit >> later. > > I will say again - commit message implies it is introducing an > unspecified downside by not fully fixing an also unspecified issue. It > is completely reasonable, and customary even, to ask for both to be > documented in the commit message. Not sure what exactly is 'unspecified'. I thought the commit message described both the problem (heartbeat not running when using virtual engines) and the result (heartbeat running on more engines than strictly necessary). But in greater detail... The serial number tracking is a hack for the heartbeat code to know whether an engine is busy or idle, and therefore whether it should be pinged for aliveness. Whenever a submission is made to an engine, the serial number is incremented. The heartbeat code keeps a copy of the value. If the value has changed, the engine is busy and needs to be pinged. This works fine for execlist mode where virtual engine decomposition is done inside i915. It fails miserably for GuC mode where the decomposition is done by the hardware. The reason being that the heartbeat code only looks at physical engines but the serial count is only incremented on the virtual engine. Thus, the heartbeat sees everything as idle and does not ping. This patch decomposes the virtual engines for the sake of incrementing the serial count on each sub-engine in order to keep the heartbeat code happy. The downside is that now the heartbeat sees all sub-engines as busy rather than only the one the submission actually ends up on. There really isn't much that can be done about that. The heartbeat code is in i915 not GuC, the scheduler is in GuC not i915. The only way to improve it is to either move the heartbeat code into GuC as well and completely disable the i915 side, or add some way for i915 to interrogate GuC as to which engines are or are not active. Technically, we do have both. GuC has (or at least had) an option to force a context switch on every execution quantum pre-emption. However, that is much, much, more heavy weight than the heartbeat. For the latter, we do (almost) have the engine usage statistics for PMU and such like. I'm not sure how much effort it would be to wire that up to the heartbeat code instead of using the serial count. In short, the serial count is ever so slightly inefficient in that it causes heartbeat pings on engines which are idle. On the other hand, it is way more efficient and simpler than the current alternatives. Does that answer the questions? John. > > If we are abandoning the normal review process someone please say so I > don't waste my time reading it. > > Regards, > > Tvrtko > >> Matt >> >>> Regards, >>> >>> Tvrtko >>> >>>> Signed-off-by: John Harrison >>>> Signed-off-by: Matthew Brost >>>> --- >>>>    drivers/gpu/drm/i915/gt/intel_engine_types.h     |  2 ++ >>>>    .../gpu/drm/i915/gt/intel_execlists_submission.c |  6 ++++++ >>>>    drivers/gpu/drm/i915/gt/intel_ring_submission.c  |  6 ++++++ >>>>    drivers/gpu/drm/i915/gt/mock_engine.c            |  6 ++++++ >>>>    .../gpu/drm/i915/gt/uc/intel_guc_submission.c    | 16 >>>> ++++++++++++++++ >>>>    drivers/gpu/drm/i915/i915_request.c              |  4 +++- >>>>    6 files changed, 39 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h >>>> b/drivers/gpu/drm/i915/gt/intel_engine_types.h >>>> index 86302e6d86b2..e2b5cda6dbc4 100644 >>>> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h >>>> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h >>>> @@ -389,6 +389,8 @@ struct intel_engine_cs { >>>>        void        (*park)(struct intel_engine_cs *engine); >>>>        void        (*unpark)(struct intel_engine_cs *engine); >>>> +    void        (*bump_serial)(struct intel_engine_cs *engine); >>>> + >>>>        void        (*set_default_submission)(struct intel_engine_cs >>>> *engine); >>>>        const struct intel_context_ops *cops; >>>> diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c >>>> b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c >>>> index ae12d7f19ecd..02880ea5d693 100644 >>>> --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c >>>> +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c >>>> @@ -3199,6 +3199,11 @@ static void execlists_release(struct >>>> intel_engine_cs *engine) >>>>        lrc_fini_wa_ctx(engine); >>>>    } >>>> +static void execlist_bump_serial(struct intel_engine_cs *engine) >>>> +{ >>>> +    engine->serial++; >>>> +} >>>> + >>>>    static void >>>>    logical_ring_default_vfuncs(struct intel_engine_cs *engine) >>>>    { >>>> @@ -3208,6 +3213,7 @@ logical_ring_default_vfuncs(struct >>>> intel_engine_cs *engine) >>>>        engine->cops = &execlists_context_ops; >>>>        engine->request_alloc = execlists_request_alloc; >>>> +    engine->bump_serial = execlist_bump_serial; >>>>        engine->reset.prepare = execlists_reset_prepare; >>>>        engine->reset.rewind = execlists_reset_rewind; >>>> diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c >>>> b/drivers/gpu/drm/i915/gt/intel_ring_submission.c >>>> index 14aa31879a37..39dd7c4ed0a9 100644 >>>> --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c >>>> +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c >>>> @@ -1045,6 +1045,11 @@ static void setup_irq(struct intel_engine_cs >>>> *engine) >>>>        } >>>>    } >>>> +static void ring_bump_serial(struct intel_engine_cs *engine) >>>> +{ >>>> +    engine->serial++; >>>> +} >>>> + >>>>    static void setup_common(struct intel_engine_cs *engine) >>>>    { >>>>        struct drm_i915_private *i915 = engine->i915; >>>> @@ -1064,6 +1069,7 @@ static void setup_common(struct >>>> intel_engine_cs *engine) >>>>        engine->cops = &ring_context_ops; >>>>        engine->request_alloc = ring_request_alloc; >>>> +    engine->bump_serial = ring_bump_serial; >>>>        /* >>>>         * Using a global execution timeline; the previous final >>>> breadcrumb is >>>> diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c >>>> b/drivers/gpu/drm/i915/gt/mock_engine.c >>>> index bd005c1b6fd5..97b10fd60b55 100644 >>>> --- a/drivers/gpu/drm/i915/gt/mock_engine.c >>>> +++ b/drivers/gpu/drm/i915/gt/mock_engine.c >>>> @@ -292,6 +292,11 @@ static void mock_engine_release(struct >>>> intel_engine_cs *engine) >>>>        intel_engine_fini_retire(engine); >>>>    } >>>> +static void mock_bump_serial(struct intel_engine_cs *engine) >>>> +{ >>>> +    engine->serial++; >>>> +} >>>> + >>>>    struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, >>>>                        const char *name, >>>>                        int id) >>>> @@ -318,6 +323,7 @@ struct intel_engine_cs *mock_engine(struct >>>> drm_i915_private *i915, >>>>        engine->base.cops = &mock_context_ops; >>>>        engine->base.request_alloc = mock_request_alloc; >>>> +    engine->base.bump_serial = mock_bump_serial; >>>>        engine->base.emit_flush = mock_emit_flush; >>>>        engine->base.emit_fini_breadcrumb = mock_emit_breadcrumb; >>>>        engine->base.submit_request = mock_submit_request; >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> index dc79d287c50a..f0e5731bcef6 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> @@ -1500,6 +1500,20 @@ static void guc_release(struct >>>> intel_engine_cs *engine) >>>>        lrc_fini_wa_ctx(engine); >>>>    } >>>> +static void guc_bump_serial(struct intel_engine_cs *engine) >>>> +{ >>>> +    engine->serial++; >>>> +} >>>> + >>>> +static void virtual_guc_bump_serial(struct intel_engine_cs *engine) >>>> +{ >>>> +    struct intel_engine_cs *e; >>>> +    intel_engine_mask_t tmp, mask = engine->mask; >>>> + >>>> +    for_each_engine_masked(e, engine->gt, mask, tmp) >>>> +        e->serial++; >>>> +} >>>> + >>>>    static void guc_default_vfuncs(struct intel_engine_cs *engine) >>>>    { >>>>        /* Default vfuncs which can be overridden by each engine. */ >>>> @@ -1508,6 +1522,7 @@ static void guc_default_vfuncs(struct >>>> intel_engine_cs *engine) >>>>        engine->cops = &guc_context_ops; >>>>        engine->request_alloc = guc_request_alloc; >>>> +    engine->bump_serial = guc_bump_serial; >>>>        engine->sched_engine->schedule = i915_schedule; >>>> @@ -1843,6 +1858,7 @@ guc_create_virtual(struct intel_engine_cs >>>> **siblings, unsigned int count) >>>>        ve->base.cops = &virtual_guc_context_ops; >>>>        ve->base.request_alloc = guc_request_alloc; >>>> +    ve->base.bump_serial = virtual_guc_bump_serial; >>>>        ve->base.submit_request = guc_submit_request; >>>> diff --git a/drivers/gpu/drm/i915/i915_request.c >>>> b/drivers/gpu/drm/i915/i915_request.c >>>> index 9542a5baa45a..127d60b36422 100644 >>>> --- a/drivers/gpu/drm/i915/i915_request.c >>>> +++ b/drivers/gpu/drm/i915/i915_request.c >>>> @@ -692,7 +692,9 @@ bool __i915_request_submit(struct i915_request >>>> *request) >>>>                         request->ring->vaddr + request->postfix); >>>>        trace_i915_request_execute(request); >>>> -    engine->serial++; >>>> +    if (engine->bump_serial) >>>> +        engine->bump_serial(engine); >>>> + >>>>        result = true; >>>>        GEM_BUG_ON(test_bit(I915_FENCE_FLAG_ACTIVE, >>>> &request->fence.flags)); >>>> > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx 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.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,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 B4440C47089 for ; Wed, 26 May 2021 18:45:43 +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 79F4D613BF for ; Wed, 26 May 2021 18:45:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 79F4D613BF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0CAB26E542; Wed, 26 May 2021 18:45:39 +0000 (UTC) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6C0DF6E51B; Wed, 26 May 2021 18:45:37 +0000 (UTC) IronPort-SDR: 3b4jy5ieHGeCzT1W67Lf/p7Y0T2EpCc1+rQlV5Gz+HpunqAP3fS8GyJsfP8s4pizdiFB8YtG50 kk+7js8i4ldA== X-IronPort-AV: E=McAfee;i="6200,9189,9996"; a="202578146" X-IronPort-AV: E=Sophos;i="5.82,331,1613462400"; d="scan'208";a="202578146" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2021 11:45:36 -0700 IronPort-SDR: vdhqNw4TXpdZzzBwoRMFkaEQmhmFb/so97zL5sb5LCoRapW+berJZzxpuSSoQMkwhrqaYc06By gSd0KnGkfKRA== X-IronPort-AV: E=Sophos;i="5.82,331,1613462400"; d="scan'208";a="547325766" Received: from johnharr-mobl1.amr.corp.intel.com (HELO [10.209.66.193]) ([10.209.66.193]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2021 11:45:35 -0700 To: Tvrtko Ursulin , Matthew Brost References: <20210506191451.77768-1-matthew.brost@intel.com> <20210506191451.77768-61-matthew.brost@intel.com> <20210525175239.GA21324@sdutt-i7> <6f6a1266-fe48-9cf1-beba-0b4463000ca7@linux.intel.com> From: John Harrison Message-ID: <15643bd8-a270-a84d-3bd7-5376af7e378c@intel.com> Date: Wed, 26 May 2021 11:45:34 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.10.2 MIME-Version: 1.0 In-Reply-To: <6f6a1266-fe48-9cf1-beba-0b4463000ca7@linux.intel.com> Content-Language: en-GB Subject: Re: [Intel-gfx] [RFC PATCH 60/97] drm/i915: Track 'serial' counts for virtual engines X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jason.ekstrand@intel.com, daniel.vetter@intel.com, intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" T24gNS8yNi8yMDIxIDAxOjQwLCBUdnJ0a28gVXJzdWxpbiB3cm90ZToKPiBPbiAyNS8wNS8yMDIx IDE4OjUyLCBNYXR0aGV3IEJyb3N0IHdyb3RlOgo+PiBPbiBUdWUsIE1heSAyNSwgMjAyMSBhdCAx MToxNjoxMkFNICswMTAwLCBUdnJ0a28gVXJzdWxpbiB3cm90ZToKPj4+Cj4+PiBPbiAwNi8wNS8y MDIxIDIwOjE0LCBNYXR0aGV3IEJyb3N0IHdyb3RlOgo+Pj4+IEZyb206IEpvaG4gSGFycmlzb24g PEpvaG4uQy5IYXJyaXNvbkBJbnRlbC5jb20+Cj4+Pj4KPj4+PiBUaGUgc2VyaWFsIG51bWJlciB0 cmFja2luZyBvZiBlbmdpbmVzIGhhcHBlbnMgYXQgdGhlIGJhY2tlbmQgb2YKPj4+PiByZXF1ZXN0 IHN1Ym1pc3Npb24gYW5kIHdhcyBleHBlY3RpbmcgdG8gb25seSBiZSBnaXZlbiBwaHlzaWNhbAo+ Pj4+IGVuZ2luZXMuIEhvd2V2ZXIsIGluIEd1QyBzdWJtaXNzaW9uIG1vZGUsIHRoZSBkZWNvbXBv c2l0aW9uIG9mIHZpcnR1YWwKPj4+PiB0byBwaHlzaWNhbCBlbmdpbmVzIGRvZXMgbm90IGhhcHBl biBpbiBpOTE1LiBJbnN0ZWFkLCByZXF1ZXN0cyBhcmUKPj4+PiBzdWJtaXR0ZWQgdG8gdGhlaXIg dmlydHVhbCBlbmdpbmUgbWFzayBhbGwgdGhlIHdheSB0aHJvdWdoIHRvIHRoZQo+Pj4+IGhhcmR3 YXJlIChpLmUuIHRvIEd1QykuIFRoaXMgd291bGQgbWVhbiB0aGF0IHRoZSBoZWFydCBiZWF0IGNv ZGUKPj4+PiB0aGlua3MgdGhlIHBoeXNpY2FsIGVuZ2luZXMgYXJlIGlkbGUgZHVlIHRvIHRoZSBz ZXJpYWwgbnVtYmVyIG5vdAo+Pj4+IGluY3JlbWVudGluZy4KPj4+Pgo+Pj4+IFRoaXMgcGF0Y2gg dXBkYXRlcyB0aGUgdHJhY2tpbmcgdG8gZGVjb21wb3NlIHZpcnR1YWwgZW5naW5lcyBpbnRvCj4+ Pj4gdGhlaXIgcGh5c2ljYWwgY29uc3RpdHVlbnRzIGFuZCB0cmFja3MgdGhlIHJlcXVlc3QgYWdh aW5zdCBlYWNoLiBUaGlzCj4+Pj4gaXMgbm90IGVudGlyZWx5IGFjY3VyYXRlIGFzIHRoZSBHdUMg d2lsbCBvbmx5IGJlIGlzc3VpbmcgdGhlIHJlcXVlc3QKPj4+PiB0byBvbmUgcGh5c2ljYWwgZW5n aW5lLiBIb3dldmVyLCBpdCBpcyB0aGUgYmVzdCB0aGF0IGk5MTUgY2FuIGRvIGdpdmVuCj4+Pj4g dGhhdCBpdCBoYXMgbm8ga25vd2xlZGdlIG9mIHRoZSBHdUMncyBzY2hlZHVsaW5nIGRlY2lzaW9u cy4KPj4+Cj4+PiBDb21taXQgdGV4dCBzb3VuZHMgYSBiaXQgZGVmZWF0aXN0LiBJIHRoaW5rIGlu c3RlYWQgb2YgbWFraW5nIHVwIHRoZSAKPj4+IHNlcmlhbAo+Pj4gY291bnRzLCB3aGljaCBoYXMg ZG93bnNpZGVzIChjb3VsZCB5b3UgcGxlYXNlIGRvY3VtZW50IGluIHRoZSBjb21taXQgCj4+PiB3 aGF0Cj4+PiB0aGV5IGFyZSksIHdlIHNob3VsZCB0aGluayBob3cgdG8gZGVzaWduIHRoaW5ncyBw cm9wZXJseS4KPj4+Cj4+Cj4+IElNTywgSSBkb24ndCB0aGluayBmaXhpbmcgc2VyaWFsIGNvdW50 cyBpcyB0aGUgc2NvcGUgb2YgdGhpcyBzZXJpZXMuIFdlCj4+IHNob3VsZCBmb2N1cyBvbiBnZXR0 aW5nIEd1QyBzdWJtaXNzaW9uIGluIG5vdCBjbGVhbmluZyB1cCBhbGwgdGhlIGNyYXAKPj4gdGhh dCBpcyBpbiB0aGUgaTkxNS4gTGV0J3MgbWFrZSBhIG5vdGUgb2YgdGhpcyB0aG91Z2ggc28gd2Ug Y2FuIHJldmlzaXQKPj4gbGF0ZXIuCj4KPiBJIHdpbGwgc2F5IGFnYWluIC0gY29tbWl0IG1lc3Nh Z2UgaW1wbGllcyBpdCBpcyBpbnRyb2R1Y2luZyBhbiAKPiB1bnNwZWNpZmllZCBkb3duc2lkZSBi eSBub3QgZnVsbHkgZml4aW5nIGFuIGFsc28gdW5zcGVjaWZpZWQgaXNzdWUuIEl0IAo+IGlzIGNv bXBsZXRlbHkgcmVhc29uYWJsZSwgYW5kIGN1c3RvbWFyeSBldmVuLCB0byBhc2sgZm9yIGJvdGgg dG8gYmUgCj4gZG9jdW1lbnRlZCBpbiB0aGUgY29tbWl0IG1lc3NhZ2UuCk5vdCBzdXJlIHdoYXQg ZXhhY3RseSBpcyAndW5zcGVjaWZpZWQnLiBJIHRob3VnaHQgdGhlIGNvbW1pdCBtZXNzYWdlIApk ZXNjcmliZWQgYm90aCB0aGUgcHJvYmxlbSAoaGVhcnRiZWF0IG5vdCBydW5uaW5nIHdoZW4gdXNp bmcgdmlydHVhbCAKZW5naW5lcykgYW5kIHRoZSByZXN1bHQgKGhlYXJ0YmVhdCBydW5uaW5nIG9u IG1vcmUgZW5naW5lcyB0aGFuIHN0cmljdGx5IApuZWNlc3NhcnkpLiBCdXQgaW4gZ3JlYXRlciBk ZXRhaWwuLi4KClRoZSBzZXJpYWwgbnVtYmVyIHRyYWNraW5nIGlzIGEgaGFjayBmb3IgdGhlIGhl YXJ0YmVhdCBjb2RlIHRvIGtub3cgCndoZXRoZXIgYW4gZW5naW5lIGlzIGJ1c3kgb3IgaWRsZSwg YW5kIHRoZXJlZm9yZSB3aGV0aGVyIGl0IHNob3VsZCBiZSAKcGluZ2VkIGZvciBhbGl2ZW5lc3Mu IFdoZW5ldmVyIGEgc3VibWlzc2lvbiBpcyBtYWRlIHRvIGFuIGVuZ2luZSwgdGhlIApzZXJpYWwg bnVtYmVyIGlzIGluY3JlbWVudGVkLiBUaGUgaGVhcnRiZWF0IGNvZGUga2VlcHMgYSBjb3B5IG9m IHRoZSAKdmFsdWUuIElmIHRoZSB2YWx1ZSBoYXMgY2hhbmdlZCwgdGhlIGVuZ2luZSBpcyBidXN5 IGFuZCBuZWVkcyB0byBiZSBwaW5nZWQuCgpUaGlzIHdvcmtzIGZpbmUgZm9yIGV4ZWNsaXN0IG1v ZGUgd2hlcmUgdmlydHVhbCBlbmdpbmUgZGVjb21wb3NpdGlvbiBpcyAKZG9uZSBpbnNpZGUgaTkx NS4gSXQgZmFpbHMgbWlzZXJhYmx5IGZvciBHdUMgbW9kZSB3aGVyZSB0aGUgCmRlY29tcG9zaXRp b24gaXMgZG9uZSBieSB0aGUgaGFyZHdhcmUuIFRoZSByZWFzb24gYmVpbmcgdGhhdCB0aGUgCmhl YXJ0YmVhdCBjb2RlIG9ubHkgbG9va3MgYXQgcGh5c2ljYWwgZW5naW5lcyBidXQgdGhlIHNlcmlh bCBjb3VudCBpcyAKb25seSBpbmNyZW1lbnRlZCBvbiB0aGUgdmlydHVhbCBlbmdpbmUuIFRodXMs IHRoZSBoZWFydGJlYXQgc2VlcyAKZXZlcnl0aGluZyBhcyBpZGxlIGFuZCBkb2VzIG5vdCBwaW5n LgoKVGhpcyBwYXRjaCBkZWNvbXBvc2VzIHRoZSB2aXJ0dWFsIGVuZ2luZXMgZm9yIHRoZSBzYWtl IG9mIGluY3JlbWVudGluZyAKdGhlIHNlcmlhbCBjb3VudCBvbiBlYWNoIHN1Yi1lbmdpbmUgaW4g b3JkZXIgdG8ga2VlcCB0aGUgaGVhcnRiZWF0IGNvZGUgCmhhcHB5LiBUaGUgZG93bnNpZGUgaXMg dGhhdCBub3cgdGhlIGhlYXJ0YmVhdCBzZWVzIGFsbCBzdWItZW5naW5lcyBhcyAKYnVzeSByYXRo ZXIgdGhhbiBvbmx5IHRoZSBvbmUgdGhlIHN1Ym1pc3Npb24gYWN0dWFsbHkgZW5kcyB1cCBvbi4g VGhlcmUgCnJlYWxseSBpc24ndCBtdWNoIHRoYXQgY2FuIGJlIGRvbmUgYWJvdXQgdGhhdC4gVGhl IGhlYXJ0YmVhdCBjb2RlIGlzIGluIAppOTE1IG5vdCBHdUMsIHRoZSBzY2hlZHVsZXIgaXMgaW4g R3VDIG5vdCBpOTE1LiBUaGUgb25seSB3YXkgdG8gaW1wcm92ZSAKaXQgaXMgdG8gZWl0aGVyIG1v dmUgdGhlIGhlYXJ0YmVhdCBjb2RlIGludG8gR3VDIGFzIHdlbGwgYW5kIGNvbXBsZXRlbHkgCmRp c2FibGUgdGhlIGk5MTUgc2lkZSwgb3IgYWRkIHNvbWUgd2F5IGZvciBpOTE1IHRvIGludGVycm9n YXRlIEd1QyBhcyB0byAKd2hpY2ggZW5naW5lcyBhcmUgb3IgYXJlIG5vdCBhY3RpdmUuIFRlY2hu aWNhbGx5LCB3ZSBkbyBoYXZlIGJvdGguIEd1QyAKaGFzIChvciBhdCBsZWFzdCBoYWQpIGFuIG9w dGlvbiB0byBmb3JjZSBhIGNvbnRleHQgc3dpdGNoIG9uIGV2ZXJ5IApleGVjdXRpb24gcXVhbnR1 bSBwcmUtZW1wdGlvbi4gSG93ZXZlciwgdGhhdCBpcyBtdWNoLCBtdWNoLCBtb3JlIGhlYXZ5IAp3 ZWlnaHQgdGhhbiB0aGUgaGVhcnRiZWF0LiBGb3IgdGhlIGxhdHRlciwgd2UgZG8gKGFsbW9zdCkg aGF2ZSB0aGUgCmVuZ2luZSB1c2FnZSBzdGF0aXN0aWNzIGZvciBQTVUgYW5kIHN1Y2ggbGlrZS4g SSdtIG5vdCBzdXJlIGhvdyBtdWNoIAplZmZvcnQgaXQgd291bGQgYmUgdG8gd2lyZSB0aGF0IHVw IHRvIHRoZSBoZWFydGJlYXQgY29kZSBpbnN0ZWFkIG9mIAp1c2luZyB0aGUgc2VyaWFsIGNvdW50 LgoKSW4gc2hvcnQsIHRoZSBzZXJpYWwgY291bnQgaXMgZXZlciBzbyBzbGlnaHRseSBpbmVmZmlj aWVudCBpbiB0aGF0IGl0IApjYXVzZXMgaGVhcnRiZWF0IHBpbmdzIG9uIGVuZ2luZXMgd2hpY2gg YXJlIGlkbGUuIE9uIHRoZSBvdGhlciBoYW5kLCBpdCAKaXMgd2F5IG1vcmUgZWZmaWNpZW50IGFu ZCBzaW1wbGVyIHRoYW4gdGhlIGN1cnJlbnQgYWx0ZXJuYXRpdmVzLgoKRG9lcyB0aGF0IGFuc3dl ciB0aGUgcXVlc3Rpb25zPwoKSm9obi4KCgo+Cj4gSWYgd2UgYXJlIGFiYW5kb25pbmcgdGhlIG5v cm1hbCByZXZpZXcgcHJvY2VzcyBzb21lb25lIHBsZWFzZSBzYXkgc28gSSAKPiBkb24ndCB3YXN0 ZSBteSB0aW1lIHJlYWRpbmcgaXQuCj4KPiBSZWdhcmRzLAo+Cj4gVHZydGtvCj4KPj4gTWF0dAo+ Pgo+Pj4gUmVnYXJkcywKPj4+Cj4+PiBUdnJ0a28KPj4+Cj4+Pj4gU2lnbmVkLW9mZi1ieTogSm9o biBIYXJyaXNvbiA8Sm9obi5DLkhhcnJpc29uQEludGVsLmNvbT4KPj4+PiBTaWduZWQtb2ZmLWJ5 OiBNYXR0aGV3IEJyb3N0IDxtYXR0aGV3LmJyb3N0QGludGVsLmNvbT4KPj4+PiAtLS0KPj4+PiDC oMKgIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2VuZ2luZV90eXBlcy5owqDCoMKgwqAg fMKgIDIgKysKPj4+PiDCoMKgIC4uLi9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZXhlY2xpc3RzX3N1 Ym1pc3Npb24uYyB8wqAgNiArKysrKysKPj4+PiDCoMKgIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0 L2ludGVsX3Jpbmdfc3VibWlzc2lvbi5jwqAgfMKgIDYgKysrKysrCj4+Pj4gwqDCoCBkcml2ZXJz L2dwdS9kcm0vaTkxNS9ndC9tb2NrX2VuZ2luZS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqAg NiArKysrKysKPj4+PiDCoMKgIC4uLi9ncHUvZHJtL2k5MTUvZ3QvdWMvaW50ZWxfZ3VjX3N1Ym1p c3Npb24uY8KgwqDCoCB8IDE2IAo+Pj4+ICsrKysrKysrKysrKysrKysKPj4+PiDCoMKgIGRyaXZl cnMvZ3B1L2RybS9pOTE1L2k5MTVfcmVxdWVzdC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg fMKgIDQgKysrLQo+Pj4+IMKgwqAgNiBmaWxlcyBjaGFuZ2VkLCAzOSBpbnNlcnRpb25zKCspLCAx IGRlbGV0aW9uKC0pCj4+Pj4KPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUv Z3QvaW50ZWxfZW5naW5lX3R5cGVzLmggCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9p bnRlbF9lbmdpbmVfdHlwZXMuaAo+Pj4+IGluZGV4IDg2MzAyZTZkODZiMi4uZTJiNWNkYTZkYmM0 IDEwMDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2VuZ2luZV90 eXBlcy5oCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZW5naW5lX3R5 cGVzLmgKPj4+PiBAQCAtMzg5LDYgKzM4OSw4IEBAIHN0cnVjdCBpbnRlbF9lbmdpbmVfY3Mgewo+ Pj4+IMKgwqDCoMKgwqDCoCB2b2lkwqDCoMKgwqDCoMKgwqAgKCpwYXJrKShzdHJ1Y3QgaW50ZWxf ZW5naW5lX2NzICplbmdpbmUpOwo+Pj4+IMKgwqDCoMKgwqDCoCB2b2lkwqDCoMKgwqDCoMKgwqAg KCp1bnBhcmspKHN0cnVjdCBpbnRlbF9lbmdpbmVfY3MgKmVuZ2luZSk7Cj4+Pj4gK8KgwqDCoCB2 b2lkwqDCoMKgwqDCoMKgwqAgKCpidW1wX3NlcmlhbCkoc3RydWN0IGludGVsX2VuZ2luZV9jcyAq ZW5naW5lKTsKPj4+PiArCj4+Pj4gwqDCoMKgwqDCoMKgIHZvaWTCoMKgwqDCoMKgwqDCoCAoKnNl dF9kZWZhdWx0X3N1Ym1pc3Npb24pKHN0cnVjdCBpbnRlbF9lbmdpbmVfY3MgCj4+Pj4gKmVuZ2lu ZSk7Cj4+Pj4gwqDCoMKgwqDCoMKgIGNvbnN0IHN0cnVjdCBpbnRlbF9jb250ZXh0X29wcyAqY29w czsKPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZXhlY2xp c3RzX3N1Ym1pc3Npb24uYyAKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2V4 ZWNsaXN0c19zdWJtaXNzaW9uLmMKPj4+PiBpbmRleCBhZTEyZDdmMTllY2QuLjAyODgwZWE1ZDY5 MyAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9leGVjbGlz dHNfc3VibWlzc2lvbi5jCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxf ZXhlY2xpc3RzX3N1Ym1pc3Npb24uYwo+Pj4+IEBAIC0zMTk5LDYgKzMxOTksMTEgQEAgc3RhdGlj IHZvaWQgZXhlY2xpc3RzX3JlbGVhc2Uoc3RydWN0IAo+Pj4+IGludGVsX2VuZ2luZV9jcyAqZW5n aW5lKQo+Pj4+IMKgwqDCoMKgwqDCoCBscmNfZmluaV93YV9jdHgoZW5naW5lKTsKPj4+PiDCoMKg IH0KPj4+PiArc3RhdGljIHZvaWQgZXhlY2xpc3RfYnVtcF9zZXJpYWwoc3RydWN0IGludGVsX2Vu Z2luZV9jcyAqZW5naW5lKQo+Pj4+ICt7Cj4+Pj4gK8KgwqDCoCBlbmdpbmUtPnNlcmlhbCsrOwo+ Pj4+ICt9Cj4+Pj4gKwo+Pj4+IMKgwqAgc3RhdGljIHZvaWQKPj4+PiDCoMKgIGxvZ2ljYWxfcmlu Z19kZWZhdWx0X3ZmdW5jcyhzdHJ1Y3QgaW50ZWxfZW5naW5lX2NzICplbmdpbmUpCj4+Pj4gwqDC oCB7Cj4+Pj4gQEAgLTMyMDgsNiArMzIxMyw3IEBAIGxvZ2ljYWxfcmluZ19kZWZhdWx0X3ZmdW5j cyhzdHJ1Y3QgCj4+Pj4gaW50ZWxfZW5naW5lX2NzICplbmdpbmUpCj4+Pj4gwqDCoMKgwqDCoMKg IGVuZ2luZS0+Y29wcyA9ICZleGVjbGlzdHNfY29udGV4dF9vcHM7Cj4+Pj4gwqDCoMKgwqDCoMKg IGVuZ2luZS0+cmVxdWVzdF9hbGxvYyA9IGV4ZWNsaXN0c19yZXF1ZXN0X2FsbG9jOwo+Pj4+ICvC oMKgwqAgZW5naW5lLT5idW1wX3NlcmlhbCA9IGV4ZWNsaXN0X2J1bXBfc2VyaWFsOwo+Pj4+IMKg wqDCoMKgwqDCoCBlbmdpbmUtPnJlc2V0LnByZXBhcmUgPSBleGVjbGlzdHNfcmVzZXRfcHJlcGFy ZTsKPj4+PiDCoMKgwqDCoMKgwqAgZW5naW5lLT5yZXNldC5yZXdpbmQgPSBleGVjbGlzdHNfcmVz ZXRfcmV3aW5kOwo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRl bF9yaW5nX3N1Ym1pc3Npb24uYyAKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVs X3Jpbmdfc3VibWlzc2lvbi5jCj4+Pj4gaW5kZXggMTRhYTMxODc5YTM3Li4zOWRkN2M0ZWQwYTkg MTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfcmluZ19zdWJt aXNzaW9uLmMKPj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9yaW5nX3N1 Ym1pc3Npb24uYwo+Pj4+IEBAIC0xMDQ1LDYgKzEwNDUsMTEgQEAgc3RhdGljIHZvaWQgc2V0dXBf aXJxKHN0cnVjdCBpbnRlbF9lbmdpbmVfY3MgCj4+Pj4gKmVuZ2luZSkKPj4+PiDCoMKgwqDCoMKg wqAgfQo+Pj4+IMKgwqAgfQo+Pj4+ICtzdGF0aWMgdm9pZCByaW5nX2J1bXBfc2VyaWFsKHN0cnVj dCBpbnRlbF9lbmdpbmVfY3MgKmVuZ2luZSkKPj4+PiArewo+Pj4+ICvCoMKgwqAgZW5naW5lLT5z ZXJpYWwrKzsKPj4+PiArfQo+Pj4+ICsKPj4+PiDCoMKgIHN0YXRpYyB2b2lkIHNldHVwX2NvbW1v bihzdHJ1Y3QgaW50ZWxfZW5naW5lX2NzICplbmdpbmUpCj4+Pj4gwqDCoCB7Cj4+Pj4gwqDCoMKg wqDCoMKgIHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1ID0gZW5naW5lLT5pOTE1Owo+Pj4+ IEBAIC0xMDY0LDYgKzEwNjksNyBAQCBzdGF0aWMgdm9pZCBzZXR1cF9jb21tb24oc3RydWN0IAo+ Pj4+IGludGVsX2VuZ2luZV9jcyAqZW5naW5lKQo+Pj4+IMKgwqDCoMKgwqDCoCBlbmdpbmUtPmNv cHMgPSAmcmluZ19jb250ZXh0X29wczsKPj4+PiDCoMKgwqDCoMKgwqAgZW5naW5lLT5yZXF1ZXN0 X2FsbG9jID0gcmluZ19yZXF1ZXN0X2FsbG9jOwo+Pj4+ICvCoMKgwqAgZW5naW5lLT5idW1wX3Nl cmlhbCA9IHJpbmdfYnVtcF9zZXJpYWw7Cj4+Pj4gwqDCoMKgwqDCoMKgIC8qCj4+Pj4gwqDCoMKg wqDCoMKgwqAgKiBVc2luZyBhIGdsb2JhbCBleGVjdXRpb24gdGltZWxpbmU7IHRoZSBwcmV2aW91 cyBmaW5hbCAKPj4+PiBicmVhZGNydW1iIGlzCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1 L2RybS9pOTE1L2d0L21vY2tfZW5naW5lLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9n dC9tb2NrX2VuZ2luZS5jCj4+Pj4gaW5kZXggYmQwMDVjMWI2ZmQ1Li45N2IxMGZkNjBiNTUgMTAw NjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvbW9ja19lbmdpbmUuYwo+Pj4+ ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L21vY2tfZW5naW5lLmMKPj4+PiBAQCAtMjky LDYgKzI5MiwxMSBAQCBzdGF0aWMgdm9pZCBtb2NrX2VuZ2luZV9yZWxlYXNlKHN0cnVjdCAKPj4+ PiBpbnRlbF9lbmdpbmVfY3MgKmVuZ2luZSkKPj4+PiDCoMKgwqDCoMKgwqAgaW50ZWxfZW5naW5l X2ZpbmlfcmV0aXJlKGVuZ2luZSk7Cj4+Pj4gwqDCoCB9Cj4+Pj4gK3N0YXRpYyB2b2lkIG1vY2tf YnVtcF9zZXJpYWwoc3RydWN0IGludGVsX2VuZ2luZV9jcyAqZW5naW5lKQo+Pj4+ICt7Cj4+Pj4g K8KgwqDCoCBlbmdpbmUtPnNlcmlhbCsrOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+IMKgwqAgc3RydWN0 IGludGVsX2VuZ2luZV9jcyAqbW9ja19lbmdpbmUoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5 MTUsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29u c3QgY2hhciAqbmFtZSwKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBpbnQgaWQpCj4+Pj4gQEAgLTMxOCw2ICszMjMsNyBAQCBzdHJ1Y3QgaW50ZWxfZW5n aW5lX2NzICptb2NrX2VuZ2luZShzdHJ1Y3QgCj4+Pj4gZHJtX2k5MTVfcHJpdmF0ZSAqaTkxNSwK Pj4+PiDCoMKgwqDCoMKgwqAgZW5naW5lLT5iYXNlLmNvcHMgPSAmbW9ja19jb250ZXh0X29wczsK Pj4+PiDCoMKgwqDCoMKgwqAgZW5naW5lLT5iYXNlLnJlcXVlc3RfYWxsb2MgPSBtb2NrX3JlcXVl c3RfYWxsb2M7Cj4+Pj4gK8KgwqDCoCBlbmdpbmUtPmJhc2UuYnVtcF9zZXJpYWwgPSBtb2NrX2J1 bXBfc2VyaWFsOwo+Pj4+IMKgwqDCoMKgwqDCoCBlbmdpbmUtPmJhc2UuZW1pdF9mbHVzaCA9IG1v Y2tfZW1pdF9mbHVzaDsKPj4+PiDCoMKgwqDCoMKgwqAgZW5naW5lLT5iYXNlLmVtaXRfZmluaV9i cmVhZGNydW1iID0gbW9ja19lbWl0X2JyZWFkY3J1bWI7Cj4+Pj4gwqDCoMKgwqDCoMKgIGVuZ2lu ZS0+YmFzZS5zdWJtaXRfcmVxdWVzdCA9IG1vY2tfc3VibWl0X3JlcXVlc3Q7Cj4+Pj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L3VjL2ludGVsX2d1Y19zdWJtaXNzaW9uLmMg Cj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC91Yy9pbnRlbF9ndWNfc3VibWlzc2lvbi5j Cj4+Pj4gaW5kZXggZGM3OWQyODdjNTBhLi5mMGU1NzMxYmNlZjYgMTAwNjQ0Cj4+Pj4gLS0tIGEv ZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvdWMvaW50ZWxfZ3VjX3N1Ym1pc3Npb24uYwo+Pj4+ICsr KyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L3VjL2ludGVsX2d1Y19zdWJtaXNzaW9uLmMKPj4+ PiBAQCAtMTUwMCw2ICsxNTAwLDIwIEBAIHN0YXRpYyB2b2lkIGd1Y19yZWxlYXNlKHN0cnVjdCAK Pj4+PiBpbnRlbF9lbmdpbmVfY3MgKmVuZ2luZSkKPj4+PiDCoMKgwqDCoMKgwqAgbHJjX2Zpbmlf d2FfY3R4KGVuZ2luZSk7Cj4+Pj4gwqDCoCB9Cj4+Pj4gK3N0YXRpYyB2b2lkIGd1Y19idW1wX3Nl cmlhbChzdHJ1Y3QgaW50ZWxfZW5naW5lX2NzICplbmdpbmUpCj4+Pj4gK3sKPj4+PiArwqDCoMKg IGVuZ2luZS0+c2VyaWFsKys7Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK3N0YXRpYyB2b2lkIHZpcnR1 YWxfZ3VjX2J1bXBfc2VyaWFsKHN0cnVjdCBpbnRlbF9lbmdpbmVfY3MgKmVuZ2luZSkKPj4+PiAr ewo+Pj4+ICvCoMKgwqAgc3RydWN0IGludGVsX2VuZ2luZV9jcyAqZTsKPj4+PiArwqDCoMKgIGlu dGVsX2VuZ2luZV9tYXNrX3QgdG1wLCBtYXNrID0gZW5naW5lLT5tYXNrOwo+Pj4+ICsKPj4+PiAr wqDCoMKgIGZvcl9lYWNoX2VuZ2luZV9tYXNrZWQoZSwgZW5naW5lLT5ndCwgbWFzaywgdG1wKQo+ Pj4+ICvCoMKgwqDCoMKgwqDCoCBlLT5zZXJpYWwrKzsKPj4+PiArfQo+Pj4+ICsKPj4+PiDCoMKg IHN0YXRpYyB2b2lkIGd1Y19kZWZhdWx0X3ZmdW5jcyhzdHJ1Y3QgaW50ZWxfZW5naW5lX2NzICpl bmdpbmUpCj4+Pj4gwqDCoCB7Cj4+Pj4gwqDCoMKgwqDCoMKgIC8qIERlZmF1bHQgdmZ1bmNzIHdo aWNoIGNhbiBiZSBvdmVycmlkZGVuIGJ5IGVhY2ggZW5naW5lLiAqLwo+Pj4+IEBAIC0xNTA4LDYg KzE1MjIsNyBAQCBzdGF0aWMgdm9pZCBndWNfZGVmYXVsdF92ZnVuY3Moc3RydWN0IAo+Pj4+IGlu dGVsX2VuZ2luZV9jcyAqZW5naW5lKQo+Pj4+IMKgwqDCoMKgwqDCoCBlbmdpbmUtPmNvcHMgPSAm Z3VjX2NvbnRleHRfb3BzOwo+Pj4+IMKgwqDCoMKgwqDCoCBlbmdpbmUtPnJlcXVlc3RfYWxsb2Mg PSBndWNfcmVxdWVzdF9hbGxvYzsKPj4+PiArwqDCoMKgIGVuZ2luZS0+YnVtcF9zZXJpYWwgPSBn dWNfYnVtcF9zZXJpYWw7Cj4+Pj4gwqDCoMKgwqDCoMKgIGVuZ2luZS0+c2NoZWRfZW5naW5lLT5z Y2hlZHVsZSA9IGk5MTVfc2NoZWR1bGU7Cj4+Pj4gQEAgLTE4NDMsNiArMTg1OCw3IEBAIGd1Y19j cmVhdGVfdmlydHVhbChzdHJ1Y3QgaW50ZWxfZW5naW5lX2NzIAo+Pj4+ICoqc2libGluZ3MsIHVu c2lnbmVkIGludCBjb3VudCkKPj4+PiDCoMKgwqDCoMKgwqAgdmUtPmJhc2UuY29wcyA9ICZ2aXJ0 dWFsX2d1Y19jb250ZXh0X29wczsKPj4+PiDCoMKgwqDCoMKgwqAgdmUtPmJhc2UucmVxdWVzdF9h bGxvYyA9IGd1Y19yZXF1ZXN0X2FsbG9jOwo+Pj4+ICvCoMKgwqAgdmUtPmJhc2UuYnVtcF9zZXJp YWwgPSB2aXJ0dWFsX2d1Y19idW1wX3NlcmlhbDsKPj4+PiDCoMKgwqDCoMKgwqAgdmUtPmJhc2Uu c3VibWl0X3JlcXVlc3QgPSBndWNfc3VibWl0X3JlcXVlc3Q7Cj4+Pj4gZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfcmVxdWVzdC5jIAo+Pj4+IGIvZHJpdmVycy9ncHUvZHJt L2k5MTUvaTkxNV9yZXF1ZXN0LmMKPj4+PiBpbmRleCA5NTQyYTViYWE0NWEuLjEyN2Q2MGIzNjQy MiAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X3JlcXVlc3QuYwo+ Pj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfcmVxdWVzdC5jCj4+Pj4gQEAgLTY5 Miw3ICs2OTIsOSBAQCBib29sIF9faTkxNV9yZXF1ZXN0X3N1Ym1pdChzdHJ1Y3QgaTkxNV9yZXF1 ZXN0IAo+Pj4+ICpyZXF1ZXN0KQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgcmVxdWVzdC0+cmluZy0+dmFkZHIgKyByZXF1ZXN0LT5wb3N0Zml4KTsK Pj4+PiDCoMKgwqDCoMKgwqAgdHJhY2VfaTkxNV9yZXF1ZXN0X2V4ZWN1dGUocmVxdWVzdCk7Cj4+ Pj4gLcKgwqDCoCBlbmdpbmUtPnNlcmlhbCsrOwo+Pj4+ICvCoMKgwqAgaWYgKGVuZ2luZS0+YnVt cF9zZXJpYWwpCj4+Pj4gK8KgwqDCoMKgwqDCoMKgIGVuZ2luZS0+YnVtcF9zZXJpYWwoZW5naW5l KTsKPj4+PiArCj4+Pj4gwqDCoMKgwqDCoMKgIHJlc3VsdCA9IHRydWU7Cj4+Pj4gwqDCoMKgwqDC oMKgIEdFTV9CVUdfT04odGVzdF9iaXQoSTkxNV9GRU5DRV9GTEFHX0FDVElWRSwgCj4+Pj4gJnJl cXVlc3QtPmZlbmNlLmZsYWdzKSk7Cj4+Pj4KPiBfX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwo+IEludGVsLWdmeCBtYWlsaW5nIGxpc3QKPiBJbnRlbC1nZnhA bGlzdHMuZnJlZWRlc2t0b3Aub3JnCj4gaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFp bG1hbi9saXN0aW5mby9pbnRlbC1nZngKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fCkludGVsLWdmeCBtYWlsaW5nIGxpc3QKSW50ZWwtZ2Z4QGxpc3RzLmZy ZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3Rp bmZvL2ludGVsLWdmeAo=