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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 D3B2FC11F66 for ; Mon, 28 Jun 2021 19:14:55 +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 7C8D461C92 for ; Mon, 28 Jun 2021 19:14:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7C8D461C92 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.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 C57036E520; Mon, 28 Jun 2021 19:14:53 +0000 (UTC) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id E77616E134; Mon, 28 Jun 2021 19:14:51 +0000 (UTC) X-IronPort-AV: E=McAfee;i="6200,9189,10029"; a="205012172" X-IronPort-AV: E=Sophos;i="5.83,306,1616482800"; d="scan'208";a="205012172" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2021 12:14:51 -0700 X-IronPort-AV: E=Sophos;i="5.83,306,1616482800"; d="scan'208";a="488996130" Received: from danielmi-mobl2.ger.corp.intel.com (HELO [10.249.254.242]) ([10.249.254.242]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2021 12:14:49 -0700 Message-ID: Subject: Re: [Intel-gfx] [PATCH v3 2/5] drm/i915/gem: Introduce a selftest for the gem object migrate functionality From: Thomas =?ISO-8859-1?Q?Hellstr=F6m?= To: "Ruhl, Michael J" , "intel-gfx@lists.freedesktop.org" , "dri-devel@lists.freedesktop.org" Date: Mon, 28 Jun 2021 21:14:47 +0200 In-Reply-To: <1cd06e51484c44a985e4a467007d1752@intel.com> References: <20210628144626.76126-1-thomas.hellstrom@linux.intel.com> <20210628144626.76126-3-thomas.hellstrom@linux.intel.com> <1cd06e51484c44a985e4a467007d1752@intel.com> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.40.1 (3.40.1-1.fc34) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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: "Auld, Matthew" Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On Mon, 2021-06-28 at 18:53 +0000, Ruhl, Michael J wrote: > > -----Original Message----- > > From: Intel-gfx On Behalf > > Of > > Thomas Hellström > > Sent: Monday, June 28, 2021 10:46 AM > > To: intel-gfx@lists.freedesktop.org; > > dri-devel@lists.freedesktop.org > > Cc: Thomas Hellström ; Auld, > > Matthew > > > > Subject: [Intel-gfx] [PATCH v3 2/5] drm/i915/gem: Introduce a > > selftest for the > > gem object migrate functionality > > > > From: Matthew Auld > > > > A selftest for the gem object migrate functionality. Slightly > > adapted > > from the original by Matthew to the new interface and new fill blit > > code. > > > > Co-developed-by: Thomas Hellström > > > > Signed-off-by: Thomas Hellström > > Signed-off-by: Matthew Auld > > --- > > drivers/gpu/drm/i915/gem/i915_gem_object.c    |   1 + > > .../drm/i915/gem/selftests/i915_gem_migrate.c | 237 > > ++++++++++++++++++ > > .../drm/i915/selftests/i915_live_selftests.h  |   1 + > > 3 files changed, 239 insertions(+) > > create mode 100644 > > drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c > > b/drivers/gpu/drm/i915/gem/i915_gem_object.c > > index 1c18be067b58..ff147fd59874 100644 > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c > > @@ -649,6 +649,7 @@ static const struct drm_gem_object_funcs > > i915_gem_object_funcs = { > > #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) > > #include "selftests/huge_gem_object.c" > > #include "selftests/huge_pages.c" > > +#include "selftests/i915_gem_migrate.c" > > #include "selftests/i915_gem_object.c" > > #include "selftests/i915_gem_coherency.c" > > #endif > > diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c > > b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c > > new file mode 100644 > > index 000000000000..a437b66f64d9 > > --- /dev/null > > +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c > > @@ -0,0 +1,237 @@ > > +// SPDX-License-Identifier: MIT > > +/* > > + * Copyright © 2020-2021 Intel Corporation > > + */ > > + > > +#include "gt/intel_migrate.h" > > + > > +static int igt_smem_create_migrate(void *arg) > > +{ > > +       struct intel_gt *gt = arg; > > +       struct drm_i915_private *i915 = gt->i915; > > +       struct drm_i915_gem_object *obj; > > +       struct i915_gem_ww_ctx ww; > > +       int err = 0; > > + > > +       /* Switch object backing-store on create */ > > +       obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0); > > +       if (IS_ERR(obj)) > > +               return PTR_ERR(obj); > > + > > +       for_i915_gem_ww(&ww, err, true) { > > +               err = i915_gem_object_lock(obj, &ww); > > +               if (err) > > +                       continue; > > + > > +               if (!i915_gem_object_can_migrate(obj, > > INTEL_REGION_SMEM)) { > > +                       err = -EINVAL; > > +                       continue; > > +               } > > + > > +               err = i915_gem_object_migrate(obj, &ww, > > INTEL_REGION_SMEM); > > +               if (err) > > +                       continue; > > + > > +               err = i915_gem_object_pin_pages(obj); > > +               if (err) > > +                       continue; > > + > > +               if (i915_gem_object_can_migrate(obj, > > INTEL_REGION_LMEM)) > > +                       err = -EINVAL; > > + > > +               i915_gem_object_unpin_pages(obj); > > +       } > > +       i915_gem_object_put(obj); > > + > > +       return err; > > +} > > + > > +static int igt_lmem_create_migrate(void *arg) > > +{ > > +       struct intel_gt *gt = arg; > > +       struct drm_i915_private *i915 = gt->i915; > > +       struct drm_i915_gem_object *obj; > > +       struct i915_gem_ww_ctx ww; > > +       int err = 0; > > + > > +       /* Switch object backing-store on create */ > > +       obj = i915_gem_object_create_shmem(i915, PAGE_SIZE); > > +       if (IS_ERR(obj)) > > +               return PTR_ERR(obj); > > + > > +       for_i915_gem_ww(&ww, err, true) { > > +               err = i915_gem_object_lock(obj, &ww); > > +               if (err) > > +                       continue; > > + > > +               if (!i915_gem_object_can_migrate(obj, > > INTEL_REGION_LMEM)) { > > +                       err = -EINVAL; > > +                       continue; > > +               } > > + > > +               err = i915_gem_object_migrate(obj, &ww, > > INTEL_REGION_LMEM); > > +               if (err) > > +                       continue; > > + > > +               err = i915_gem_object_pin_pages(obj); > > +               if (err) > > +                       continue; > > + > > +               if (i915_gem_object_can_migrate(obj, > > INTEL_REGION_SMEM)) > > +                       err = -EINVAL; > > + > > +               i915_gem_object_unpin_pages(obj); > > +       } > > +       i915_gem_object_put(obj); > > + > > +       return err; > > +} > > + > > +static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, > > +                                 struct drm_i915_gem_object *obj) > > +{ > > +       int err; > > + > > +       err = i915_gem_object_lock(obj, ww); > > +       if (err) > > +               return err; > > + > > +       err = i915_gem_object_wait(obj, > > +                                  I915_WAIT_INTERRUPTIBLE | > > +                                  I915_WAIT_PRIORITY | > > +                                  I915_WAIT_ALL, > > +                                  MAX_SCHEDULE_TIMEOUT); > > +       if (err) > > +               return err; > > + > > +       if (i915_gem_object_is_lmem(obj)) { > > +               if (!i915_gem_object_can_migrate(obj, > > INTEL_REGION_SMEM)) { > > I don't see any  testing of the parameter num_allowed. > > Is that done somewhere else? > > Mike That's a user-space submitted parameter only, dictating what region the object is allowed in when bound to the GPU. It's not exercised in this selftest. Thanks, Thomas 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 10B1AC11F65 for ; Mon, 28 Jun 2021 19:14:55 +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 9B90F61C92 for ; Mon, 28 Jun 2021 19:14:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9B90F61C92 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.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 48DA16E134; Mon, 28 Jun 2021 19:14:53 +0000 (UTC) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id E77616E134; Mon, 28 Jun 2021 19:14:51 +0000 (UTC) X-IronPort-AV: E=McAfee;i="6200,9189,10029"; a="205012172" X-IronPort-AV: E=Sophos;i="5.83,306,1616482800"; d="scan'208";a="205012172" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2021 12:14:51 -0700 X-IronPort-AV: E=Sophos;i="5.83,306,1616482800"; d="scan'208";a="488996130" Received: from danielmi-mobl2.ger.corp.intel.com (HELO [10.249.254.242]) ([10.249.254.242]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2021 12:14:49 -0700 Message-ID: From: Thomas =?ISO-8859-1?Q?Hellstr=F6m?= To: "Ruhl, Michael J" , "intel-gfx@lists.freedesktop.org" , "dri-devel@lists.freedesktop.org" Date: Mon, 28 Jun 2021 21:14:47 +0200 In-Reply-To: <1cd06e51484c44a985e4a467007d1752@intel.com> References: <20210628144626.76126-1-thomas.hellstrom@linux.intel.com> <20210628144626.76126-3-thomas.hellstrom@linux.intel.com> <1cd06e51484c44a985e4a467007d1752@intel.com> User-Agent: Evolution 3.40.1 (3.40.1-1.fc34) MIME-Version: 1.0 Subject: Re: [Intel-gfx] [PATCH v3 2/5] drm/i915/gem: Introduce a selftest for the gem object migrate functionality 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: "Auld, Matthew" Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" T24gTW9uLCAyMDIxLTA2LTI4IGF0IDE4OjUzICswMDAwLCBSdWhsLCBNaWNoYWVsIEogd3JvdGU6 Cj4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQo+ID4gRnJvbTogSW50ZWwtZ2Z4IDxpbnRl bC1nZngtYm91bmNlc0BsaXN0cy5mcmVlZGVza3RvcC5vcmc+IE9uIEJlaGFsZgo+ID4gT2YKPiA+ IFRob21hcyBIZWxsc3Ryw7ZtCj4gPiBTZW50OiBNb25kYXksIEp1bmUgMjgsIDIwMjEgMTA6NDYg QU0KPiA+IFRvOiBpbnRlbC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnOyAgIAo+ID4gZHJpLWRl dmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwo+ID4gQ2M6IFRob21hcyBIZWxsc3Ryw7ZtIDx0aG9t YXMuaGVsbHN0cm9tQGxpbnV4LmludGVsLmNvbT47IEF1bGQsCj4gPiBNYXR0aGV3Cj4gPiA8bWF0 dGhldy5hdWxkQGludGVsLmNvbT4KPiA+IFN1YmplY3Q6IFtJbnRlbC1nZnhdIFtQQVRDSCB2MyAy LzVdIGRybS9pOTE1L2dlbTogSW50cm9kdWNlIGEKPiA+IHNlbGZ0ZXN0IGZvciB0aGUKPiA+IGdl bSBvYmplY3QgbWlncmF0ZSBmdW5jdGlvbmFsaXR5Cj4gPiAKPiA+IEZyb206IE1hdHRoZXcgQXVs ZCA8bWF0dGhldy5hdWxkQGludGVsLmNvbT4KPiA+IAo+ID4gQSBzZWxmdGVzdCBmb3IgdGhlIGdl bSBvYmplY3QgbWlncmF0ZSBmdW5jdGlvbmFsaXR5LiBTbGlnaHRseQo+ID4gYWRhcHRlZAo+ID4g ZnJvbSB0aGUgb3JpZ2luYWwgYnkgTWF0dGhldyB0byB0aGUgbmV3IGludGVyZmFjZSBhbmQgbmV3 IGZpbGwgYmxpdAo+ID4gY29kZS4KPiA+IAo+ID4gQ28tZGV2ZWxvcGVkLWJ5OiBUaG9tYXMgSGVs bHN0csO2bQo+ID4gPHRob21hcy5oZWxsc3Ryb21AbGludXguaW50ZWwuY29tPgo+ID4gU2lnbmVk LW9mZi1ieTogVGhvbWFzIEhlbGxzdHLDtm0gPHRob21hcy5oZWxsc3Ryb21AbGludXguaW50ZWwu Y29tPgo+ID4gU2lnbmVkLW9mZi1ieTogTWF0dGhldyBBdWxkIDxtYXR0aGV3LmF1bGRAaW50ZWwu Y29tPgo+ID4gLS0tCj4gPiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1fb2JqZWN0 LmPCoMKgwqAgfMKgwqAgMSArCj4gPiAuLi4vZHJtL2k5MTUvZ2VtL3NlbGZ0ZXN0cy9pOTE1X2dl bV9taWdyYXRlLmMgfCAyMzcKPiA+ICsrKysrKysrKysrKysrKysrKwo+ID4gLi4uL2RybS9pOTE1 L3NlbGZ0ZXN0cy9pOTE1X2xpdmVfc2VsZnRlc3RzLmjCoCB8wqDCoCAxICsKPiA+IDMgZmlsZXMg Y2hhbmdlZCwgMjM5IGluc2VydGlvbnMoKykKPiA+IGNyZWF0ZSBtb2RlIDEwMDY0NAo+ID4gZHJp dmVycy9ncHUvZHJtL2k5MTUvZ2VtL3NlbGZ0ZXN0cy9pOTE1X2dlbV9taWdyYXRlLmMKPiA+IAo+ ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9vYmplY3Qu Ywo+ID4gYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1fb2JqZWN0LmMKPiA+IGlu ZGV4IDFjMThiZTA2N2I1OC4uZmYxNDdmZDU5ODc0IDEwMDY0NAo+ID4gLS0tIGEvZHJpdmVycy9n cHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX29iamVjdC5jCj4gPiArKysgYi9kcml2ZXJzL2dwdS9k cm0vaTkxNS9nZW0vaTkxNV9nZW1fb2JqZWN0LmMKPiA+IEBAIC02NDksNiArNjQ5LDcgQEAgc3Rh dGljIGNvbnN0IHN0cnVjdCBkcm1fZ2VtX29iamVjdF9mdW5jcwo+ID4gaTkxNV9nZW1fb2JqZWN0 X2Z1bmNzID0gewo+ID4gI2lmIElTX0VOQUJMRUQoQ09ORklHX0RSTV9JOTE1X1NFTEZURVNUKQo+ ID4gI2luY2x1ZGUgInNlbGZ0ZXN0cy9odWdlX2dlbV9vYmplY3QuYyIKPiA+ICNpbmNsdWRlICJz ZWxmdGVzdHMvaHVnZV9wYWdlcy5jIgo+ID4gKyNpbmNsdWRlICJzZWxmdGVzdHMvaTkxNV9nZW1f bWlncmF0ZS5jIgo+ID4gI2luY2x1ZGUgInNlbGZ0ZXN0cy9pOTE1X2dlbV9vYmplY3QuYyIKPiA+ ICNpbmNsdWRlICJzZWxmdGVzdHMvaTkxNV9nZW1fY29oZXJlbmN5LmMiCj4gPiAjZW5kaWYKPiA+ IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vc2VsZnRlc3RzL2k5MTVfZ2Vt X21pZ3JhdGUuYwo+ID4gYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vc2VsZnRlc3RzL2k5MTVf Z2VtX21pZ3JhdGUuYwo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiA+IGluZGV4IDAwMDAwMDAw MDAwMC4uYTQzN2I2NmY2NGQ5Cj4gPiAtLS0gL2Rldi9udWxsCj4gPiArKysgYi9kcml2ZXJzL2dw dS9kcm0vaTkxNS9nZW0vc2VsZnRlc3RzL2k5MTVfZ2VtX21pZ3JhdGUuYwo+ID4gQEAgLTAsMCAr MSwyMzcgQEAKPiA+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCj4gPiArLyoKPiA+ ICsgKiBDb3B5cmlnaHQgwqkgMjAyMC0yMDIxIEludGVsIENvcnBvcmF0aW9uCj4gPiArICovCj4g PiArCj4gPiArI2luY2x1ZGUgImd0L2ludGVsX21pZ3JhdGUuaCIKPiA+ICsKPiA+ICtzdGF0aWMg aW50IGlndF9zbWVtX2NyZWF0ZV9taWdyYXRlKHZvaWQgKmFyZykKPiA+ICt7Cj4gPiArwqDCoMKg wqDCoMKgwqBzdHJ1Y3QgaW50ZWxfZ3QgKmd0ID0gYXJnOwo+ID4gK8KgwqDCoMKgwqDCoMKgc3Ry dWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUgPSBndC0+aTkxNTsKPiA+ICvCoMKgwqDCoMKgwqDC oHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmo7Cj4gPiArwqDCoMKgwqDCoMKgwqBzdHJ1 Y3QgaTkxNV9nZW1fd3dfY3R4IHd3Owo+ID4gK8KgwqDCoMKgwqDCoMKgaW50IGVyciA9IDA7Cj4g PiArCj4gPiArwqDCoMKgwqDCoMKgwqAvKiBTd2l0Y2ggb2JqZWN0IGJhY2tpbmctc3RvcmUgb24g Y3JlYXRlICovCj4gPiArwqDCoMKgwqDCoMKgwqBvYmogPSBpOTE1X2dlbV9vYmplY3RfY3JlYXRl X2xtZW0oaTkxNSwgUEFHRV9TSVpFLCAwKTsKPiA+ICvCoMKgwqDCoMKgwqDCoGlmIChJU19FUlIo b2JqKSkKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqByZXR1cm4gUFRSX0VSUihv YmopOwo+ID4gKwo+ID4gK8KgwqDCoMKgwqDCoMKgZm9yX2k5MTVfZ2VtX3d3KCZ3dywgZXJyLCB0 cnVlKSB7Cj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgZXJyID0gaTkxNV9nZW1f b2JqZWN0X2xvY2sob2JqLCAmd3cpOwo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oGlmIChlcnIpCj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoGNvbnRpbnVlOwo+ID4gKwo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGlm ICghaTkxNV9nZW1fb2JqZWN0X2Nhbl9taWdyYXRlKG9iaiwKPiA+IElOVEVMX1JFR0lPTl9TTUVN KSkgewo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBl cnIgPSAtRUlOVkFMOwo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqBjb250aW51ZTsKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB9Cj4g PiArCj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgZXJyID0gaTkxNV9nZW1fb2Jq ZWN0X21pZ3JhdGUob2JqLCAmd3csCj4gPiBJTlRFTF9SRUdJT05fU01FTSk7Cj4gPiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaWYgKGVycikKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgY29udGludWU7Cj4gPiArCj4gPiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgZXJyID0gaTkxNV9nZW1fb2JqZWN0X3Bpbl9wYWdlcyhvYmop Owo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGlmIChlcnIpCj4gPiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGNvbnRpbnVlOwo+ID4gKwo+ ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGlmIChpOTE1X2dlbV9vYmplY3RfY2Fu X21pZ3JhdGUob2JqLAo+ID4gSU5URUxfUkVHSU9OX0xNRU0pKQo+ID4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBlcnIgPSAtRUlOVkFMOwo+ID4gKwo+ID4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGk5MTVfZ2VtX29iamVjdF91bnBpbl9wYWdl cyhvYmopOwo+ID4gK8KgwqDCoMKgwqDCoMKgfQo+ID4gK8KgwqDCoMKgwqDCoMKgaTkxNV9nZW1f b2JqZWN0X3B1dChvYmopOwo+ID4gKwo+ID4gK8KgwqDCoMKgwqDCoMKgcmV0dXJuIGVycjsKPiA+ ICt9Cj4gPiArCj4gPiArc3RhdGljIGludCBpZ3RfbG1lbV9jcmVhdGVfbWlncmF0ZSh2b2lkICph cmcpCj4gPiArewo+ID4gK8KgwqDCoMKgwqDCoMKgc3RydWN0IGludGVsX2d0ICpndCA9IGFyZzsK PiA+ICvCoMKgwqDCoMKgwqDCoHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1ID0gZ3QtPmk5 MTU7Cj4gPiArwqDCoMKgwqDCoMKgwqBzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCAqb2JqOwo+ ID4gK8KgwqDCoMKgwqDCoMKgc3RydWN0IGk5MTVfZ2VtX3d3X2N0eCB3dzsKPiA+ICvCoMKgwqDC oMKgwqDCoGludCBlcnIgPSAwOwo+ID4gKwo+ID4gK8KgwqDCoMKgwqDCoMKgLyogU3dpdGNoIG9i amVjdCBiYWNraW5nLXN0b3JlIG9uIGNyZWF0ZSAqLwo+ID4gK8KgwqDCoMKgwqDCoMKgb2JqID0g aTkxNV9nZW1fb2JqZWN0X2NyZWF0ZV9zaG1lbShpOTE1LCBQQUdFX1NJWkUpOwo+ID4gK8KgwqDC oMKgwqDCoMKgaWYgKElTX0VSUihvYmopKQo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoHJldHVybiBQVFJfRVJSKG9iaik7Cj4gPiArCj4gPiArwqDCoMKgwqDCoMKgwqBmb3JfaTkx NV9nZW1fd3coJnd3LCBlcnIsIHRydWUpIHsKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqBlcnIgPSBpOTE1X2dlbV9vYmplY3RfbG9jayhvYmosICZ3dyk7Cj4gPiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgaWYgKGVycikKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgY29udGludWU7Cj4gPiArCj4gPiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgaWYgKCFpOTE1X2dlbV9vYmplY3RfY2FuX21pZ3JhdGUob2JqLAo+ ID4gSU5URUxfUkVHSU9OX0xNRU0pKSB7Cj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoGVyciA9IC1FSU5WQUw7Cj4gPiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGNvbnRpbnVlOwo+ID4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoH0KPiA+ICsKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqBlcnIgPSBpOTE1X2dlbV9vYmplY3RfbWlncmF0ZShvYmosICZ3dywKPiA+IElOVEVMX1JFR0lP Tl9MTUVNKTsKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBpZiAoZXJyKQo+ID4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBjb250aW51ZTsK PiA+ICsKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBlcnIgPSBpOTE1X2dlbV9v YmplY3RfcGluX3BhZ2VzKG9iaik7Cj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg aWYgKGVycikKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgY29udGludWU7Cj4gPiArCj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaWYg KGk5MTVfZ2VtX29iamVjdF9jYW5fbWlncmF0ZShvYmosCj4gPiBJTlRFTF9SRUdJT05fU01FTSkp Cj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGVyciA9 IC1FSU5WQUw7Cj4gPiArCj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaTkxNV9n ZW1fb2JqZWN0X3VucGluX3BhZ2VzKG9iaik7Cj4gPiArwqDCoMKgwqDCoMKgwqB9Cj4gPiArwqDC oMKgwqDCoMKgwqBpOTE1X2dlbV9vYmplY3RfcHV0KG9iaik7Cj4gPiArCj4gPiArwqDCoMKgwqDC oMKgwqByZXR1cm4gZXJyOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IGxtZW1fcGFnZXNf bWlncmF0ZV9vbmUoc3RydWN0IGk5MTVfZ2VtX3d3X2N0eCAqd3csCj4gPiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1 Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCAqb2JqKQo+ID4gK3sKPiA+ICvCoMKgwqDCoMKgwqDCoGlu dCBlcnI7Cj4gPiArCj4gPiArwqDCoMKgwqDCoMKgwqBlcnIgPSBpOTE1X2dlbV9vYmplY3RfbG9j ayhvYmosIHd3KTsKPiA+ICvCoMKgwqDCoMKgwqDCoGlmIChlcnIpCj4gPiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgcmV0dXJuIGVycjsKPiA+ICsKPiA+ICvCoMKgwqDCoMKgwqDCoGVy ciA9IGk5MTVfZ2VtX29iamVjdF93YWl0KG9iaiwKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSTkxNV9XQUlUX0lO VEVSUlVQVElCTEUgfAo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJOTE1X1dBSVRfUFJJT1JJVFkgfAo+ID4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBJOTE1X1dBSVRfQUxMLAo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBNQVhfU0NIRURVTEVfVElNRU9V VCk7Cj4gPiArwqDCoMKgwqDCoMKgwqBpZiAoZXJyKQo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoHJldHVybiBlcnI7Cj4gPiArCj4gPiArwqDCoMKgwqDCoMKgwqBpZiAoaTkxNV9n ZW1fb2JqZWN0X2lzX2xtZW0ob2JqKSkgewo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoGlmICghaTkxNV9nZW1fb2JqZWN0X2Nhbl9taWdyYXRlKG9iaiwKPiA+IElOVEVMX1JFR0lP Tl9TTUVNKSkgewo+IAo+IEkgZG9uJ3Qgc2VlIGFuecKgIHRlc3Rpbmcgb2YgdGhlIHBhcmFtZXRl ciBudW1fYWxsb3dlZC4KPiAKPiBJcyB0aGF0IGRvbmUgc29tZXdoZXJlIGVsc2U/Cj4gCj4gTWlr ZQoKVGhhdCdzIGEgdXNlci1zcGFjZSBzdWJtaXR0ZWQgcGFyYW1ldGVyIG9ubHksIGRpY3RhdGlu ZyB3aGF0IHJlZ2lvbiB0aGUKb2JqZWN0IGlzIGFsbG93ZWQgaW4gd2hlbiBib3VuZCB0byB0aGUg R1BVLiBJdCdzIG5vdCBleGVyY2lzZWQgaW4gdGhpcwpzZWxmdGVzdC4KClRoYW5rcywKVGhvbWFz CgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KSW50ZWwt Z2Z4IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vaW50ZWwtZ2Z4Cg==