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=-9.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT 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 9775BC43381 for ; Wed, 20 Mar 2019 15:48:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6FE3B2186A for ; Wed, 20 Mar 2019 15:48:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727225AbfCTPsr (ORCPT ); Wed, 20 Mar 2019 11:48:47 -0400 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:40701 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727012AbfCTPsm (ORCPT ); Wed, 20 Mar 2019 11:48:42 -0400 X-Originating-IP: 90.88.33.153 Received: from localhost.localdomain (aaubervilliers-681-1-92-153.w90-88.abo.wanadoo.fr [90.88.33.153]) (Authenticated sender: paul.kocialkowski@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id F25D32000A; Wed, 20 Mar 2019 15:48:38 +0000 (UTC) From: Paul Kocialkowski To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Maarten Lankhorst , Maxime Ripard , Sean Paul , David Airlie , Daniel Vetter , Eric Anholt , Eben Upton , Thomas Petazzoni , Paul Kocialkowski Subject: [PATCH v2 2/2] drm/vc4: Allocated/liberate the binner BO at firstopen/lastclose Date: Wed, 20 Mar 2019 16:48:09 +0100 Message-Id: <20190320154809.14823-3-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190320154809.14823-1-paul.kocialkowski@bootlin.com> References: <20190320154809.14823-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The binner BO is a pre-requisite to GPU operations, so we must ensure that it is always allocated when the GPU is in use. Currently, we are allocating it at probe time and liberating/allocating it during runtime pm cycles. First, since the binner buffer is only required for GPU rendering, it's a waste to allocate it when the driver probes since internal users of the driver (such as fbcon) won't try to use the GPU. Move the allocation/liberation to the firstopen/lastclose instead to only allocate it when userspace has opened the device and adapt the IRQ handler to return early when no binner BO was allocated yet. Second, because the buffer is allocated from the same pool as other GPU buffers, we might run into a situation where we are out of memory at runtime resume. This causes the binner BO allocation to fail and results in all subsequent operations to fail, resulting in a major hang in userspace. As a result, keep the buffer alive during runtime pm. Signed-off-by: Paul Kocialkowski --- drivers/gpu/drm/vc4/vc4_drv.c | 26 ++++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_irq.c | 3 +++ drivers/gpu/drm/vc4/vc4_v3d.c | 15 +-------------- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 3227706700f9..605dc50613e3 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -134,6 +134,30 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) kfree(vc4file); } +static int vc4_firstopen(struct drm_device *drm) +{ + struct vc4_dev *vc4 = to_vc4_dev(drm); + int ret; + + if (!vc4->bin_bo) { + ret = vc4_allocate_bin_bo(drm); + if (ret) + return ret; + } + + return 0; +} + +static void vc4_lastclose(struct drm_device *drm) +{ + struct vc4_dev *vc4 = to_vc4_dev(drm); + + if (vc4->bin_bo) { + drm_gem_object_put_unlocked(&vc4->bin_bo->base.base); + vc4->bin_bo = NULL; + } +} + static const struct vm_operations_struct vc4_vm_ops = { .fault = vc4_fault, .open = drm_gem_vm_open, @@ -180,6 +204,8 @@ static struct drm_driver vc4_drm_driver = { DRIVER_SYNCOBJ), .open = vc4_open, .postclose = vc4_close, + .firstopen = vc4_firstopen, + .lastclose = vc4_lastclose, .irq_handler = vc4_irq, .irq_preinstall = vc4_irq_preinstall, .irq_postinstall = vc4_irq_postinstall, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 7a3c093e7443..f52bb21e9885 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -808,6 +808,7 @@ extern struct platform_driver vc4_v3d_driver; int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); int vc4_v3d_get_bin_slot(struct vc4_dev *vc4); +int vc4_allocate_bin_bo(struct drm_device *drm); /* vc4_validate.c */ int diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 4cd2ccfe15f4..efaba2b02f6c 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c @@ -64,6 +64,9 @@ vc4_overflow_mem_work(struct work_struct *work) struct vc4_exec_info *exec; unsigned long irqflags; + if (!bo) + return; + bin_bo_slot = vc4_v3d_get_bin_slot(vc4); if (bin_bo_slot < 0) { DRM_ERROR("Couldn't allocate binner overflow mem\n"); diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index e47e29426078..e04a51a75f01 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -218,7 +218,7 @@ int vc4_v3d_get_bin_slot(struct vc4_dev *vc4) * overall CMA pool before they make scenes complicated enough to run * out of bin space. */ -static int vc4_allocate_bin_bo(struct drm_device *drm) +int vc4_allocate_bin_bo(struct drm_device *drm) { struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_v3d *v3d = vc4->v3d; @@ -303,9 +303,6 @@ static int vc4_v3d_runtime_suspend(struct device *dev) vc4_irq_uninstall(vc4->dev); - drm_gem_object_put_unlocked(&vc4->bin_bo->base.base); - vc4->bin_bo = NULL; - clk_disable_unprepare(v3d->clk); return 0; @@ -317,10 +314,6 @@ static int vc4_v3d_runtime_resume(struct device *dev) struct vc4_dev *vc4 = v3d->vc4; int ret; - ret = vc4_allocate_bin_bo(vc4->dev); - if (ret) - return ret; - ret = clk_prepare_enable(v3d->clk); if (ret != 0) return ret; @@ -384,12 +377,6 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) if (ret != 0) return ret; - ret = vc4_allocate_bin_bo(drm); - if (ret) { - clk_disable_unprepare(v3d->clk); - return ret; - } - /* Reset the binner overflow address/size at setup, to be sure * we don't reuse an old one. */ -- 2.21.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paul Kocialkowski Subject: [PATCH v2 2/2] drm/vc4: Allocated/liberate the binner BO at firstopen/lastclose Date: Wed, 20 Mar 2019 16:48:09 +0100 Message-ID: <20190320154809.14823-3-paul.kocialkowski@bootlin.com> References: <20190320154809.14823-1-paul.kocialkowski@bootlin.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1F4C789FF7 for ; Wed, 20 Mar 2019 15:48:41 +0000 (UTC) In-Reply-To: <20190320154809.14823-1-paul.kocialkowski@bootlin.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Thomas Petazzoni , Maxime Ripard , Eben Upton , Paul Kocialkowski , David Airlie , Sean Paul List-Id: dri-devel@lists.freedesktop.org VGhlIGJpbm5lciBCTyBpcyBhIHByZS1yZXF1aXNpdGUgdG8gR1BVIG9wZXJhdGlvbnMsIHNvIHdl IG11c3QgZW5zdXJlCnRoYXQgaXQgaXMgYWx3YXlzIGFsbG9jYXRlZCB3aGVuIHRoZSBHUFUgaXMg aW4gdXNlLiBDdXJyZW50bHksIHdlIGFyZQphbGxvY2F0aW5nIGl0IGF0IHByb2JlIHRpbWUgYW5k IGxpYmVyYXRpbmcvYWxsb2NhdGluZyBpdCBkdXJpbmcgcnVudGltZQpwbSBjeWNsZXMuCgpGaXJz dCwgc2luY2UgdGhlIGJpbm5lciBidWZmZXIgaXMgb25seSByZXF1aXJlZCBmb3IgR1BVIHJlbmRl cmluZywgaXQncwphIHdhc3RlIHRvIGFsbG9jYXRlIGl0IHdoZW4gdGhlIGRyaXZlciBwcm9iZXMg c2luY2UgaW50ZXJuYWwgdXNlcnMgb2YKdGhlIGRyaXZlciAoc3VjaCBhcyBmYmNvbikgd29uJ3Qg dHJ5IHRvIHVzZSB0aGUgR1BVLgoKTW92ZSB0aGUgYWxsb2NhdGlvbi9saWJlcmF0aW9uIHRvIHRo ZSBmaXJzdG9wZW4vbGFzdGNsb3NlIGluc3RlYWQgdG8Kb25seSBhbGxvY2F0ZSBpdCB3aGVuIHVz ZXJzcGFjZSBoYXMgb3BlbmVkIHRoZSBkZXZpY2UgYW5kIGFkYXB0IHRoZSBJUlEKaGFuZGxlciB0 byByZXR1cm4gZWFybHkgd2hlbiBubyBiaW5uZXIgQk8gd2FzIGFsbG9jYXRlZCB5ZXQuCgpTZWNv bmQsIGJlY2F1c2UgdGhlIGJ1ZmZlciBpcyBhbGxvY2F0ZWQgZnJvbSB0aGUgc2FtZSBwb29sIGFz IG90aGVyIEdQVQpidWZmZXJzLCB3ZSBtaWdodCBydW4gaW50byBhIHNpdHVhdGlvbiB3aGVyZSB3 ZSBhcmUgb3V0IG9mIG1lbW9yeSBhdApydW50aW1lIHJlc3VtZS4gVGhpcyBjYXVzZXMgdGhlIGJp bm5lciBCTyBhbGxvY2F0aW9uIHRvIGZhaWwgYW5kIHJlc3VsdHMKaW4gYWxsIHN1YnNlcXVlbnQg b3BlcmF0aW9ucyB0byBmYWlsLCByZXN1bHRpbmcgaW4gYSBtYWpvciBoYW5nIGluCnVzZXJzcGFj ZS4KCkFzIGEgcmVzdWx0LCBrZWVwIHRoZSBidWZmZXIgYWxpdmUgZHVyaW5nIHJ1bnRpbWUgcG0u CgpTaWduZWQtb2ZmLWJ5OiBQYXVsIEtvY2lhbGtvd3NraSA8cGF1bC5rb2NpYWxrb3dza2lAYm9v dGxpbi5jb20+Ci0tLQogZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHJ2LmMgfCAyNiArKysrKysr KysrKysrKysrKysrKysrKysrKwogZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHJ2LmggfCAgMSAr CiBkcml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9pcnEuYyB8ICAzICsrKwogZHJpdmVycy9ncHUvZHJt L3ZjNC92YzRfdjNkLmMgfCAxNSArLS0tLS0tLS0tLS0tLS0KIDQgZmlsZXMgY2hhbmdlZCwgMzEg aW5zZXJ0aW9ucygrKSwgMTQgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUv ZHJtL3ZjNC92YzRfZHJ2LmMgYi9kcml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9kcnYuYwppbmRleCAz MjI3NzA2NzAwZjkuLjYwNWRjNTA2MTNlMyAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3Zj NC92YzRfZHJ2LmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHJ2LmMKQEAgLTEzNCw2 ICsxMzQsMzAgQEAgc3RhdGljIHZvaWQgdmM0X2Nsb3NlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYs IHN0cnVjdCBkcm1fZmlsZSAqZmlsZSkKIAlrZnJlZSh2YzRmaWxlKTsKIH0KIAorc3RhdGljIGlu dCB2YzRfZmlyc3RvcGVuKHN0cnVjdCBkcm1fZGV2aWNlICpkcm0pCit7CisJc3RydWN0IHZjNF9k ZXYgKnZjNCA9IHRvX3ZjNF9kZXYoZHJtKTsKKwlpbnQgcmV0OworCisJaWYgKCF2YzQtPmJpbl9i bykgeworCQlyZXQgPSB2YzRfYWxsb2NhdGVfYmluX2JvKGRybSk7CisJCWlmIChyZXQpCisJCQly ZXR1cm4gcmV0OworCX0KKworCXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCB2YzRfbGFzdGNs b3NlKHN0cnVjdCBkcm1fZGV2aWNlICpkcm0pCit7CisJc3RydWN0IHZjNF9kZXYgKnZjNCA9IHRv X3ZjNF9kZXYoZHJtKTsKKworCWlmICh2YzQtPmJpbl9ibykgeworCQlkcm1fZ2VtX29iamVjdF9w dXRfdW5sb2NrZWQoJnZjNC0+YmluX2JvLT5iYXNlLmJhc2UpOworCQl2YzQtPmJpbl9ibyA9IE5V TEw7CisJfQorfQorCiBzdGF0aWMgY29uc3Qgc3RydWN0IHZtX29wZXJhdGlvbnNfc3RydWN0IHZj NF92bV9vcHMgPSB7CiAJLmZhdWx0ID0gdmM0X2ZhdWx0LAogCS5vcGVuID0gZHJtX2dlbV92bV9v cGVuLApAQCAtMTgwLDYgKzIwNCw4IEBAIHN0YXRpYyBzdHJ1Y3QgZHJtX2RyaXZlciB2YzRfZHJt X2RyaXZlciA9IHsKIAkJCSAgICBEUklWRVJfU1lOQ09CSiksCiAJLm9wZW4gPSB2YzRfb3BlbiwK IAkucG9zdGNsb3NlID0gdmM0X2Nsb3NlLAorCS5maXJzdG9wZW4gPSB2YzRfZmlyc3RvcGVuLAor CS5sYXN0Y2xvc2UgPSB2YzRfbGFzdGNsb3NlLAogCS5pcnFfaGFuZGxlciA9IHZjNF9pcnEsCiAJ LmlycV9wcmVpbnN0YWxsID0gdmM0X2lycV9wcmVpbnN0YWxsLAogCS5pcnFfcG9zdGluc3RhbGwg PSB2YzRfaXJxX3Bvc3RpbnN0YWxsLApkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92 YzRfZHJ2LmggYi9kcml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9kcnYuaAppbmRleCA3YTNjMDkzZTc0 NDMuLmY1MmJiMjFlOTg4NSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHJ2 LmgKKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHJ2LmgKQEAgLTgwOCw2ICs4MDgsNyBA QCBleHRlcm4gc3RydWN0IHBsYXRmb3JtX2RyaXZlciB2YzRfdjNkX2RyaXZlcjsKIGludCB2YzRf djNkX2RlYnVnZnNfaWRlbnQoc3RydWN0IHNlcV9maWxlICptLCB2b2lkICp1bnVzZWQpOwogaW50 IHZjNF92M2RfZGVidWdmc19yZWdzKHN0cnVjdCBzZXFfZmlsZSAqbSwgdm9pZCAqdW51c2VkKTsK IGludCB2YzRfdjNkX2dldF9iaW5fc2xvdChzdHJ1Y3QgdmM0X2RldiAqdmM0KTsKK2ludCB2YzRf YWxsb2NhdGVfYmluX2JvKHN0cnVjdCBkcm1fZGV2aWNlICpkcm0pOwogCiAvKiB2YzRfdmFsaWRh dGUuYyAqLwogaW50CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9pcnEuYyBi L2RyaXZlcnMvZ3B1L2RybS92YzQvdmM0X2lycS5jCmluZGV4IDRjZDJjY2ZlMTVmNC4uZWZhYmEy YjAyZjZjIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9pcnEuYworKysgYi9k cml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9pcnEuYwpAQCAtNjQsNiArNjQsOSBAQCB2YzRfb3ZlcmZs b3dfbWVtX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQogCXN0cnVjdCB2YzRfZXhlY19p bmZvICpleGVjOwogCXVuc2lnbmVkIGxvbmcgaXJxZmxhZ3M7CiAKKwlpZiAoIWJvKQorCQlyZXR1 cm47CisKIAliaW5fYm9fc2xvdCA9IHZjNF92M2RfZ2V0X2Jpbl9zbG90KHZjNCk7CiAJaWYgKGJp bl9ib19zbG90IDwgMCkgewogCQlEUk1fRVJST1IoIkNvdWxkbid0IGFsbG9jYXRlIGJpbm5lciBv dmVyZmxvdyBtZW1cbiIpOwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfdjNk LmMgYi9kcml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF92M2QuYwppbmRleCBlNDdlMjk0MjYwNzguLmUw NGE1MWE3NWYwMSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfdjNkLmMKKysr IGIvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfdjNkLmMKQEAgLTIxOCw3ICsyMTgsNyBAQCBpbnQg dmM0X3YzZF9nZXRfYmluX3Nsb3Qoc3RydWN0IHZjNF9kZXYgKnZjNCkKICAqIG92ZXJhbGwgQ01B IHBvb2wgYmVmb3JlIHRoZXkgbWFrZSBzY2VuZXMgY29tcGxpY2F0ZWQgZW5vdWdoIHRvIHJ1bgog ICogb3V0IG9mIGJpbiBzcGFjZS4KICAqLwotc3RhdGljIGludCB2YzRfYWxsb2NhdGVfYmluX2Jv KHN0cnVjdCBkcm1fZGV2aWNlICpkcm0pCitpbnQgdmM0X2FsbG9jYXRlX2Jpbl9ibyhzdHJ1Y3Qg ZHJtX2RldmljZSAqZHJtKQogewogCXN0cnVjdCB2YzRfZGV2ICp2YzQgPSB0b192YzRfZGV2KGRy bSk7CiAJc3RydWN0IHZjNF92M2QgKnYzZCA9IHZjNC0+djNkOwpAQCAtMzAzLDkgKzMwMyw2IEBA IHN0YXRpYyBpbnQgdmM0X3YzZF9ydW50aW1lX3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQog CiAJdmM0X2lycV91bmluc3RhbGwodmM0LT5kZXYpOwogCi0JZHJtX2dlbV9vYmplY3RfcHV0X3Vu bG9ja2VkKCZ2YzQtPmJpbl9iby0+YmFzZS5iYXNlKTsKLQl2YzQtPmJpbl9ibyA9IE5VTEw7Ci0K IAljbGtfZGlzYWJsZV91bnByZXBhcmUodjNkLT5jbGspOwogCiAJcmV0dXJuIDA7CkBAIC0zMTcs MTAgKzMxNCw2IEBAIHN0YXRpYyBpbnQgdmM0X3YzZF9ydW50aW1lX3Jlc3VtZShzdHJ1Y3QgZGV2 aWNlICpkZXYpCiAJc3RydWN0IHZjNF9kZXYgKnZjNCA9IHYzZC0+dmM0OwogCWludCByZXQ7CiAK LQlyZXQgPSB2YzRfYWxsb2NhdGVfYmluX2JvKHZjNC0+ZGV2KTsKLQlpZiAocmV0KQotCQlyZXR1 cm4gcmV0OwotCiAJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKHYzZC0+Y2xrKTsKIAlpZiAocmV0 ICE9IDApCiAJCXJldHVybiByZXQ7CkBAIC0zODQsMTIgKzM3Nyw2IEBAIHN0YXRpYyBpbnQgdmM0 X3YzZF9iaW5kKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZSAqbWFzdGVyLCB2b2lk ICpkYXRhKQogCWlmIChyZXQgIT0gMCkKIAkJcmV0dXJuIHJldDsKIAotCXJldCA9IHZjNF9hbGxv Y2F0ZV9iaW5fYm8oZHJtKTsKLQlpZiAocmV0KSB7Ci0JCWNsa19kaXNhYmxlX3VucHJlcGFyZSh2 M2QtPmNsayk7Ci0JCXJldHVybiByZXQ7Ci0JfQotCiAJLyogUmVzZXQgdGhlIGJpbm5lciBvdmVy ZmxvdyBhZGRyZXNzL3NpemUgYXQgc2V0dXAsIHRvIGJlIHN1cmUKIAkgKiB3ZSBkb24ndCByZXVz ZSBhbiBvbGQgb25lLgogCSAqLwotLSAKMi4yMS4wCgpfX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBs aXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1h bi9saXN0aW5mby9kcmktZGV2ZWw=