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=-8.1 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, 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 A3B77C2D0BF for ; Tue, 10 Dec 2019 11:04:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 62E2C2073D for ; Tue, 10 Dec 2019 11:04:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="hFd/VNWP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727149AbfLJLEm (ORCPT ); Tue, 10 Dec 2019 06:04:42 -0500 Received: from esa6.hc3370-68.iphmx.com ([216.71.155.175]:6084 "EHLO esa6.hc3370-68.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727018AbfLJLEm (ORCPT ); Tue, 10 Dec 2019 06:04:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1575975881; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=eM9GJhYmgntlMtTD+75XtmeukkZf/oCk8wIREKff2H4=; b=hFd/VNWPMglqcJwQCqIkmnms0+ybC3sDqi9PYkT2Y8Z5UfynNO0FSHhs ULL3sbsMSFqM/g6NwoWQuNCEY21gHZ1od85HONNRy4Ew9TFOmiCnB8Zyt CwdS2hr/Rdpk6aLOATaAvtaapeYFfPPpPNSEt+lOZt+nP8dW36JRDjf8Y 8=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=roger.pau@citrix.com; spf=Pass smtp.mailfrom=roger.pau@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of roger.pau@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of roger.pau@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: 9NmFtmBaQa/YevSgNyWFN4SYb4s0qJ0+o7kXfLOEohSi05nK3qKNNI6cWkOmOBP3WoxXRl6CUR hTdhntcws6D0XdAcAaFBbIhPChSmidxXRRyR0d+ecQQtbrYBf79ZGRD2y/p9TP+WdAolc7jCk/ ob6+XUtrnHaWmWbjSUt4GaNZMUuOJoFfebUSLOn689ywemALYsGuGxnRLoiQYnf2+r+uuRBeIe FCdz7/CA231Fn4ymQRJDuV7H62knKYw9L4N/Eqxsd/E3dpQR/ZD7uO4uBuxjBYJkZWZk2BrVEh wxE= X-SBRS: 2.7 X-MesageID: 9859319 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,299,1571716800"; d="scan'208";a="9859319" Date: Tue, 10 Dec 2019 12:04:32 +0100 From: Roger Pau =?iso-8859-1?Q?Monn=E9?= To: SeongJae Park CC: , , , , , , , SeongJae Park Subject: Re: [PATCH v5 2/2] xen/blkback: Squeeze page pools if a memory pressure is detected Message-ID: <20191210110432.GG980@Air-de-Roger> References: <20191210080628.5264-1-sjpark@amazon.de> <20191210080628.5264-3-sjpark@amazon.de> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20191210080628.5264-3-sjpark@amazon.de> User-Agent: Mutt/1.12.2 (2019-09-21) X-ClientProxiedBy: AMSPEX02CAS02.citrite.net (10.69.22.113) To AMSPEX02CL03.citrite.net (10.69.22.127) Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org On Tue, Dec 10, 2019 at 08:06:28AM +0000, SeongJae Park wrote: > Each `blkif` has a free pages pool for the grant mapping. The size of > the pool starts from zero and be increased on demand while processing > the I/O requests. If current I/O requests handling is finished or 100 > milliseconds has passed since last I/O requests handling, it checks and > shrinks the pool to not exceed the size limit, `max_buffer_pages`. > > Therefore, `blkfront` running guests can cause a memory pressure in the > `blkback` running guest by attaching a large number of block devices and > inducing I/O. Hm, I don't think this is actually true. blkfront cannot attach an arbitrary number of devices, blkfront is just a frontend for a device that's instantiated by the Xen toolstack, so it's the toolstack the one that controls the amount of PV block devices. > System administrators can avoid such problematic > situations by limiting the maximum number of devices each guest can > attach. However, finding the optimal limit is not so easy. Improper > set of the limit can results in the memory pressure or a resource > underutilization. This commit avoids such problematic situations by > squeezing the pools (returns every free page in the pool to the system) > for a while (users can set this duration via a module parameter) if a > memory pressure is detected. > > Discussions > =========== > > The `blkback`'s original shrinking mechanism returns only pages in the > pool, which are not currently be used by `blkback`, to the system. In > other words, the pages are not mapped with foreign pages. Because this ^ that ^ granted > commit is changing only the shrink limit but uses the mechanism as is, > this commit does not introduce improper mappings related security > issues. That last sentence is hard to parse. I think something like: "Because this commit is changing only the shrink limit but still uses the same freeing mechanism it does not touch pages which are currently mapping grants." > > Once a memory pressure is detected, this commit keeps the squeezing > limit for a user-specified time duration. The duration should be > neither too long nor too short. If it is too long, the squeezing > incurring overhead can reduce the I/O performance. If it is too short, > `blkback` will not free enough pages to reduce the memory pressure. > This commit sets the value as `10 milliseconds` by default because it is > a short time in terms of I/O while it is a long time in terms of memory > operations. Also, as the original shrinking mechanism works for at > least every 100 milliseconds, this could be a somewhat reasonable > choice. I also tested other durations (refer to the below section for > more details) and confirmed that 10 milliseconds is the one that works > best with the test. That said, the proper duration depends on actual > configurations and workloads. That's why this commit is allowing users ^ allows > to set it as their optimal value via the module parameter. ... to set the duration as a module parameter. > > Memory Pressure Test > ==================== > > To show how this commit fixes the memory pressure situation well, I > configured a test environment on a xen-running virtualization system. > On the `blkfront` running guest instances, I attach a large number of > network-backed volume devices and induce I/O to those. Meanwhile, I > measure the number of pages that swapped in and out on the `blkback` > running guest. The test ran twice, once for the `blkback` before this > commit and once for that after this commit. As shown below, this commit > has dramatically reduced the memory pressure: > > pswpin pswpout I assume pswpin means 'pages swapped in' and pswpout 'pages swapped out'. Might be good to add a note to that effect. > before 76,672 185,799 > after 212 3,325 > > Optimal Aggressive Shrinking Duration > ------------------------------------- > > To find a best squeezing duration, I repeated the test with three > different durations (1ms, 10ms, and 100ms). The results are as below: > > duration pswpin pswpout > 1 852 6,424 > 10 212 3,325 > 100 203 3,340 > > As expected, the memory pressure has decreased as the duration is > increased, but the reduction stopped from the `10ms`. Based on this > results, I chose the default duration as 10ms. > > Performance Overhead Test > ========================= > > This commit could incur I/O performance degradation under severe memory > pressure because the squeezing will require more page allocations per > I/O. To show the overhead, I artificially made a worst-case squeezing > situation and measured the I/O performance of a `blkfront` running > guest. > > For the artificial squeezing, I set the `blkback.max_buffer_pages` using > the `/sys/module/xen_blkback/parameters/max_buffer_pages` file. We set > the value to `1024` and `0`. The `1024` is the default value. Setting > the value as `0` is same to a situation doing the squeezing always > (worst-case). > > For the I/O performance measurement, I use a simple `dd` command. > > Default Performance > ------------------- > > [dom0]# echo 1024 > /sys/module/xen_blkback/parameters/max_buffer_pages > [instance]$ for i in {1..5}; do dd if=/dev/zero of=file bs=4k count=$((256*512)); sync; done > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 11.7257 s, 45.8 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8827 s, 38.7 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8781 s, 38.7 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8737 s, 38.7 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8702 s, 38.7 MB/s > > Worst-case Performance > ---------------------- > > [dom0]# echo 0 > /sys/module/xen_blkback/parameters/max_buffer_pages > [instance]$ for i in {1..5}; do dd if=/dev/zero of=file bs=4k count=$((256*512)); sync; done > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 11.7257 s, 45.8 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.878 s, 38.7 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8746 s, 38.7 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8786 s, 38.7 MB/s > 131072+0 records in > 131072+0 records out > 536870912 bytes (537 MB) copied, 13.8749 s, 38.7 MB/s > > In short, even worst case squeezing makes no visible performance > degradation. I would argue that with a ~40MB/s throughput you won't see any performance difference at all regardless of the size of the pool of free pages or the amount of persistent grants because the bottleneck is on the storage performance itself. You need to test this using nullblk or some kind of fast storage, or else the above figures are not going to reflect any changes you make because they are hidden by the poor performance of the underlying storage. > I think this is due to the slow speed of the I/O. In > other words, the additional page allocation overhead is hidden under the > much slower I/O latency. > > Nevertheless, pleaset note that this is just a very simple and minimal > test. I would like to add that IMO this is papering over an existing issue, which is how pages to be used to map grants are allocated. Grant mappings _shouldn't_ consume RAM pages in the first place, and IIRC the fact that they do is because Linux balloons out memory in order to re-use those pages to map grants and have a valid page struct. A way to solve this would be to hotplug a fake memory region and use it in order to map grant pages, without having to balloon out RAM regions. At the end of day on a PV domain mapping a grant should just require virtual address space. This is going to get even worse for PVH that requires a physical memory address in order to map a grant, but that's another story. > > Reviewed-by: Juergen Gross > Signed-off-by: SeongJae Park > --- > drivers/block/xen-blkback/blkback.c | 23 +++++++++++++++++++++-- > drivers/block/xen-blkback/common.h | 1 + > drivers/block/xen-blkback/xenbus.c | 3 ++- > 3 files changed, 24 insertions(+), 3 deletions(-) > > diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c > index fd1e19f1a49f..4d4dba7ea721 100644 > --- a/drivers/block/xen-blkback/blkback.c > +++ b/drivers/block/xen-blkback/blkback.c > @@ -142,6 +142,22 @@ static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt) > HZ * xen_blkif_pgrant_timeout); > } > > +/* Once a memory pressure is detected, squeeze free page pools for a while. */ > +static int xen_blkif_buffer_squeeze_duration_ms = 10; unsigned? You can likely drop the xen_blkif prefix since this is a static variable. > +module_param_named(buffer_squeeze_duration_ms, > + xen_blkif_buffer_squeeze_duration_ms, int, 0644); > +MODULE_PARM_DESC(buffer_squeeze_duration_ms, > +"Duration in ms to squeeze pages buffer when a memory pressure is detected"); > + > +static unsigned long xen_blk_buffer_squeeze_end; > + > +unsigned xen_blkbk_reclaim(struct xenbus_device *dev) > +{ > + xen_blk_buffer_squeeze_end = jiffies + > + msecs_to_jiffies(xen_blkif_buffer_squeeze_duration_ms); > + return 0; > +} > + > static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page) > { > unsigned long flags; > @@ -656,8 +672,11 @@ int xen_blkif_schedule(void *arg) > ring->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL); > } > > - /* Shrink if we have more than xen_blkif_max_buffer_pages */ > - shrink_free_pagepool(ring, xen_blkif_max_buffer_pages); > + /* Shrink the free pages pool if it is too large. */ > + if (time_before(jiffies, xen_blk_buffer_squeeze_end)) > + shrink_free_pagepool(ring, 0); > + else > + shrink_free_pagepool(ring, xen_blkif_max_buffer_pages); > > if (log_stats && time_after(jiffies, ring->st_print)) > print_stats(ring); > diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h > index 1d3002d773f7..c0334cda79fe 100644 > --- a/drivers/block/xen-blkback/common.h > +++ b/drivers/block/xen-blkback/common.h > @@ -383,6 +383,7 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id); > int xen_blkif_schedule(void *arg); > int xen_blkif_purge_persistent(void *arg); > void xen_blkbk_free_caches(struct xen_blkif_ring *ring); > +unsigned xen_blkbk_reclaim(struct xenbus_device *dev); > > int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, > struct backend_info *be, int state); > diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c > index b90dbcd99c03..de49a09e6933 100644 > --- a/drivers/block/xen-blkback/xenbus.c > +++ b/drivers/block/xen-blkback/xenbus.c > @@ -1115,7 +1115,8 @@ static struct xenbus_driver xen_blkbk_driver = { > .ids = xen_blkbk_ids, > .probe = xen_blkbk_probe, > .remove = xen_blkbk_remove, > - .otherend_changed = frontend_changed > + .otherend_changed = frontend_changed, > + .reclaim = xen_blkbk_reclaim While at it please add the ending comma so that new addition don't have to modify the previous line. Thanks, Roger. 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=-8.1 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, 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 262A4C43603 for ; Tue, 10 Dec 2019 11:05:04 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (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 DEE8F20663 for ; Tue, 10 Dec 2019 11:05:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="hFd/VNWP" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DEE8F20663 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iedJs-0003a2-PO; Tue, 10 Dec 2019 11:04:44 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iedJr-0003Zw-H8 for xen-devel@lists.xenproject.org; Tue, 10 Dec 2019 11:04:43 +0000 X-Inumbo-ID: dd6c8b0a-1b3c-11ea-a1e1-bc764e2007e4 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id dd6c8b0a-1b3c-11ea-a1e1-bc764e2007e4; Tue, 10 Dec 2019 11:04:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1575975881; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=eM9GJhYmgntlMtTD+75XtmeukkZf/oCk8wIREKff2H4=; b=hFd/VNWPMglqcJwQCqIkmnms0+ybC3sDqi9PYkT2Y8Z5UfynNO0FSHhs ULL3sbsMSFqM/g6NwoWQuNCEY21gHZ1od85HONNRy4Ew9TFOmiCnB8Zyt CwdS2hr/Rdpk6aLOATaAvtaapeYFfPPpPNSEt+lOZt+nP8dW36JRDjf8Y 8=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=roger.pau@citrix.com; spf=Pass smtp.mailfrom=roger.pau@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of roger.pau@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of roger.pau@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: 9NmFtmBaQa/YevSgNyWFN4SYb4s0qJ0+o7kXfLOEohSi05nK3qKNNI6cWkOmOBP3WoxXRl6CUR hTdhntcws6D0XdAcAaFBbIhPChSmidxXRRyR0d+ecQQtbrYBf79ZGRD2y/p9TP+WdAolc7jCk/ ob6+XUtrnHaWmWbjSUt4GaNZMUuOJoFfebUSLOn689ywemALYsGuGxnRLoiQYnf2+r+uuRBeIe FCdz7/CA231Fn4ymQRJDuV7H62knKYw9L4N/Eqxsd/E3dpQR/ZD7uO4uBuxjBYJkZWZk2BrVEh wxE= X-SBRS: 2.7 X-MesageID: 9859319 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,299,1571716800"; d="scan'208";a="9859319" Date: Tue, 10 Dec 2019 12:04:32 +0100 From: Roger Pau =?iso-8859-1?Q?Monn=E9?= To: SeongJae Park Message-ID: <20191210110432.GG980@Air-de-Roger> References: <20191210080628.5264-1-sjpark@amazon.de> <20191210080628.5264-3-sjpark@amazon.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191210080628.5264-3-sjpark@amazon.de> User-Agent: Mutt/1.12.2 (2019-09-21) X-ClientProxiedBy: AMSPEX02CAS02.citrite.net (10.69.22.113) To AMSPEX02CL03.citrite.net (10.69.22.127) Subject: Re: [Xen-devel] [PATCH v5 2/2] xen/blkback: Squeeze page pools if a memory pressure is detected X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: axboe@kernel.dk, sjpark@amazon.com, konrad.wilk@oracle.com, pdurrant@amazon.com, SeongJae Park , linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, xen-devel@lists.xenproject.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" T24gVHVlLCBEZWMgMTAsIDIwMTkgYXQgMDg6MDY6MjhBTSArMDAwMCwgU2VvbmdKYWUgUGFyayB3 cm90ZToKPiBFYWNoIGBibGtpZmAgaGFzIGEgZnJlZSBwYWdlcyBwb29sIGZvciB0aGUgZ3JhbnQg bWFwcGluZy4gIFRoZSBzaXplIG9mCj4gdGhlIHBvb2wgc3RhcnRzIGZyb20gemVybyBhbmQgYmUg aW5jcmVhc2VkIG9uIGRlbWFuZCB3aGlsZSBwcm9jZXNzaW5nCj4gdGhlIEkvTyByZXF1ZXN0cy4g IElmIGN1cnJlbnQgSS9PIHJlcXVlc3RzIGhhbmRsaW5nIGlzIGZpbmlzaGVkIG9yIDEwMAo+IG1p bGxpc2Vjb25kcyBoYXMgcGFzc2VkIHNpbmNlIGxhc3QgSS9PIHJlcXVlc3RzIGhhbmRsaW5nLCBp dCBjaGVja3MgYW5kCj4gc2hyaW5rcyB0aGUgcG9vbCB0byBub3QgZXhjZWVkIHRoZSBzaXplIGxp bWl0LCBgbWF4X2J1ZmZlcl9wYWdlc2AuCj4gCj4gVGhlcmVmb3JlLCBgYmxrZnJvbnRgIHJ1bm5p bmcgZ3Vlc3RzIGNhbiBjYXVzZSBhIG1lbW9yeSBwcmVzc3VyZSBpbiB0aGUKPiBgYmxrYmFja2Ag cnVubmluZyBndWVzdCBieSBhdHRhY2hpbmcgYSBsYXJnZSBudW1iZXIgb2YgYmxvY2sgZGV2aWNl cyBhbmQKPiBpbmR1Y2luZyBJL08uCgpIbSwgSSBkb24ndCB0aGluayB0aGlzIGlzIGFjdHVhbGx5 IHRydWUuIGJsa2Zyb250IGNhbm5vdCBhdHRhY2ggYW4KYXJiaXRyYXJ5IG51bWJlciBvZiBkZXZp Y2VzLCBibGtmcm9udCBpcyBqdXN0IGEgZnJvbnRlbmQgZm9yIGEgZGV2aWNlCnRoYXQncyBpbnN0 YW50aWF0ZWQgYnkgdGhlIFhlbiB0b29sc3RhY2ssIHNvIGl0J3MgdGhlIHRvb2xzdGFjayB0aGUg b25lCnRoYXQgY29udHJvbHMgdGhlIGFtb3VudCBvZiBQViBibG9jayBkZXZpY2VzLgoKPiBTeXN0 ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIGF2b2lkIHN1Y2ggcHJvYmxlbWF0aWMKPiBzaXR1YXRpb25z IGJ5IGxpbWl0aW5nIHRoZSBtYXhpbXVtIG51bWJlciBvZiBkZXZpY2VzIGVhY2ggZ3Vlc3QgY2Fu Cj4gYXR0YWNoLiAgSG93ZXZlciwgZmluZGluZyB0aGUgb3B0aW1hbCBsaW1pdCBpcyBub3Qgc28g ZWFzeS4gIEltcHJvcGVyCj4gc2V0IG9mIHRoZSBsaW1pdCBjYW4gcmVzdWx0cyBpbiB0aGUgbWVt b3J5IHByZXNzdXJlIG9yIGEgcmVzb3VyY2UKPiB1bmRlcnV0aWxpemF0aW9uLiAgVGhpcyBjb21t aXQgYXZvaWRzIHN1Y2ggcHJvYmxlbWF0aWMgc2l0dWF0aW9ucyBieQo+IHNxdWVlemluZyB0aGUg cG9vbHMgKHJldHVybnMgZXZlcnkgZnJlZSBwYWdlIGluIHRoZSBwb29sIHRvIHRoZSBzeXN0ZW0p Cj4gZm9yIGEgd2hpbGUgKHVzZXJzIGNhbiBzZXQgdGhpcyBkdXJhdGlvbiB2aWEgYSBtb2R1bGUg cGFyYW1ldGVyKSBpZiBhCj4gbWVtb3J5IHByZXNzdXJlIGlzIGRldGVjdGVkLgo+IAo+IERpc2N1 c3Npb25zCj4gPT09PT09PT09PT0KPiAKPiBUaGUgYGJsa2JhY2tgJ3Mgb3JpZ2luYWwgc2hyaW5r aW5nIG1lY2hhbmlzbSByZXR1cm5zIG9ubHkgcGFnZXMgaW4gdGhlCj4gcG9vbCwgd2hpY2ggYXJl IG5vdCBjdXJyZW50bHkgYmUgdXNlZCBieSBgYmxrYmFja2AsIHRvIHRoZSBzeXN0ZW0uICBJbgo+ IG90aGVyIHdvcmRzLCB0aGUgcGFnZXMgYXJlIG5vdCBtYXBwZWQgd2l0aCBmb3JlaWduIHBhZ2Vz LiAgQmVjYXVzZSB0aGlzCiAgICAgICAgICAgICAgICAgICAgICAgIF4gdGhhdCAgICAgICAgICAg ICAgIF4gZ3JhbnRlZAo+IGNvbW1pdCBpcyBjaGFuZ2luZyBvbmx5IHRoZSBzaHJpbmsgbGltaXQg YnV0IHVzZXMgdGhlIG1lY2hhbmlzbSBhcyBpcywKPiB0aGlzIGNvbW1pdCBkb2VzIG5vdCBpbnRy b2R1Y2UgaW1wcm9wZXIgbWFwcGluZ3MgcmVsYXRlZCBzZWN1cml0eQo+IGlzc3Vlcy4KClRoYXQg bGFzdCBzZW50ZW5jZSBpcyBoYXJkIHRvIHBhcnNlLiBJIHRoaW5rIHNvbWV0aGluZyBsaWtlOgoK IkJlY2F1c2UgdGhpcyBjb21taXQgaXMgY2hhbmdpbmcgb25seSB0aGUgc2hyaW5rIGxpbWl0IGJ1 dCBzdGlsbCB1c2VzIHRoZQpzYW1lIGZyZWVpbmcgbWVjaGFuaXNtIGl0IGRvZXMgbm90IHRvdWNo IHBhZ2VzIHdoaWNoIGFyZSBjdXJyZW50bHkKbWFwcGluZyBncmFudHMuIgoKPiAKPiBPbmNlIGEg bWVtb3J5IHByZXNzdXJlIGlzIGRldGVjdGVkLCB0aGlzIGNvbW1pdCBrZWVwcyB0aGUgc3F1ZWV6 aW5nCj4gbGltaXQgZm9yIGEgdXNlci1zcGVjaWZpZWQgdGltZSBkdXJhdGlvbi4gIFRoZSBkdXJh dGlvbiBzaG91bGQgYmUKPiBuZWl0aGVyIHRvbyBsb25nIG5vciB0b28gc2hvcnQuICBJZiBpdCBp cyB0b28gbG9uZywgdGhlIHNxdWVlemluZwo+IGluY3VycmluZyBvdmVyaGVhZCBjYW4gcmVkdWNl IHRoZSBJL08gcGVyZm9ybWFuY2UuICBJZiBpdCBpcyB0b28gc2hvcnQsCj4gYGJsa2JhY2tgIHdp bGwgbm90IGZyZWUgZW5vdWdoIHBhZ2VzIHRvIHJlZHVjZSB0aGUgbWVtb3J5IHByZXNzdXJlLgo+ IFRoaXMgY29tbWl0IHNldHMgdGhlIHZhbHVlIGFzIGAxMCBtaWxsaXNlY29uZHNgIGJ5IGRlZmF1 bHQgYmVjYXVzZSBpdCBpcwo+IGEgc2hvcnQgdGltZSBpbiB0ZXJtcyBvZiBJL08gd2hpbGUgaXQg aXMgYSBsb25nIHRpbWUgaW4gdGVybXMgb2YgbWVtb3J5Cj4gb3BlcmF0aW9ucy4gIEFsc28sIGFz IHRoZSBvcmlnaW5hbCBzaHJpbmtpbmcgbWVjaGFuaXNtIHdvcmtzIGZvciBhdAo+IGxlYXN0IGV2 ZXJ5IDEwMCBtaWxsaXNlY29uZHMsIHRoaXMgY291bGQgYmUgYSBzb21ld2hhdCByZWFzb25hYmxl Cj4gY2hvaWNlLiAgSSBhbHNvIHRlc3RlZCBvdGhlciBkdXJhdGlvbnMgKHJlZmVyIHRvIHRoZSBi ZWxvdyBzZWN0aW9uIGZvcgo+IG1vcmUgZGV0YWlscykgYW5kIGNvbmZpcm1lZCB0aGF0IDEwIG1p bGxpc2Vjb25kcyBpcyB0aGUgb25lIHRoYXQgd29ya3MKPiBiZXN0IHdpdGggdGhlIHRlc3QuICBU aGF0IHNhaWQsIHRoZSBwcm9wZXIgZHVyYXRpb24gZGVwZW5kcyBvbiBhY3R1YWwKPiBjb25maWd1 cmF0aW9ucyBhbmQgd29ya2xvYWRzLiAgVGhhdCdzIHdoeSB0aGlzIGNvbW1pdCBpcyBhbGxvd2lu ZyB1c2VycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIF4gYWxsb3dzCj4gdG8gc2V0IGl0IGFzIHRoZWlyIG9wdGltYWwgdmFsdWUgdmlhIHRo ZSBtb2R1bGUgcGFyYW1ldGVyLgoKLi4uIHRvIHNldCB0aGUgZHVyYXRpb24gYXMgYSBtb2R1bGUg cGFyYW1ldGVyLgoKPiAKPiBNZW1vcnkgUHJlc3N1cmUgVGVzdAo+ID09PT09PT09PT09PT09PT09 PT09Cj4gCj4gVG8gc2hvdyBob3cgdGhpcyBjb21taXQgZml4ZXMgdGhlIG1lbW9yeSBwcmVzc3Vy ZSBzaXR1YXRpb24gd2VsbCwgSQo+IGNvbmZpZ3VyZWQgYSB0ZXN0IGVudmlyb25tZW50IG9uIGEg eGVuLXJ1bm5pbmcgdmlydHVhbGl6YXRpb24gc3lzdGVtLgo+IE9uIHRoZSBgYmxrZnJvbnRgIHJ1 bm5pbmcgZ3Vlc3QgaW5zdGFuY2VzLCBJIGF0dGFjaCBhIGxhcmdlIG51bWJlciBvZgo+IG5ldHdv cmstYmFja2VkIHZvbHVtZSBkZXZpY2VzIGFuZCBpbmR1Y2UgSS9PIHRvIHRob3NlLiAgTWVhbndo aWxlLCBJCj4gbWVhc3VyZSB0aGUgbnVtYmVyIG9mIHBhZ2VzIHRoYXQgc3dhcHBlZCBpbiBhbmQg b3V0IG9uIHRoZSBgYmxrYmFja2AKPiBydW5uaW5nIGd1ZXN0LiAgVGhlIHRlc3QgcmFuIHR3aWNl LCBvbmNlIGZvciB0aGUgYGJsa2JhY2tgIGJlZm9yZSB0aGlzCj4gY29tbWl0IGFuZCBvbmNlIGZv ciB0aGF0IGFmdGVyIHRoaXMgY29tbWl0LiAgQXMgc2hvd24gYmVsb3csIHRoaXMgY29tbWl0Cj4g aGFzIGRyYW1hdGljYWxseSByZWR1Y2VkIHRoZSBtZW1vcnkgcHJlc3N1cmU6Cj4gCj4gICAgICAg ICAgICAgICAgIHBzd3BpbiAgcHN3cG91dAoKSSBhc3N1bWUgcHN3cGluIG1lYW5zICdwYWdlcyBz d2FwcGVkIGluJyBhbmQgcHN3cG91dCAncGFnZXMgc3dhcHBlZApvdXQnLiBNaWdodCBiZSBnb29k IHRvIGFkZCBhIG5vdGUgdG8gdGhhdCBlZmZlY3QuCgo+ICAgICBiZWZvcmUgICAgICA3Niw2NzIg IDE4NSw3OTkKPiAgICAgYWZ0ZXIgICAgICAgICAgMjEyICAgIDMsMzI1Cj4gCj4gT3B0aW1hbCBB Z2dyZXNzaXZlIFNocmlua2luZyBEdXJhdGlvbgo+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0KPiAKPiBUbyBmaW5kIGEgYmVzdCBzcXVlZXppbmcgZHVyYXRpb24sIEkgcmVw ZWF0ZWQgdGhlIHRlc3Qgd2l0aCB0aHJlZQo+IGRpZmZlcmVudCBkdXJhdGlvbnMgKDFtcywgMTBt cywgYW5kIDEwMG1zKS4gIFRoZSByZXN1bHRzIGFyZSBhcyBiZWxvdzoKPiAKPiAgICAgZHVyYXRp b24gICAgcHN3cGluICBwc3dwb3V0Cj4gICAgIDEgICAgICAgICAgIDg1MiAgICAgNiw0MjQKPiAg ICAgMTAgICAgICAgICAgMjEyICAgICAzLDMyNQo+ICAgICAxMDAgICAgICAgICAyMDMgICAgIDMs MzQwCj4gCj4gQXMgZXhwZWN0ZWQsIHRoZSBtZW1vcnkgcHJlc3N1cmUgaGFzIGRlY3JlYXNlZCBh cyB0aGUgZHVyYXRpb24gaXMKPiBpbmNyZWFzZWQsIGJ1dCB0aGUgcmVkdWN0aW9uIHN0b3BwZWQg ZnJvbSB0aGUgYDEwbXNgLiAgQmFzZWQgb24gdGhpcwo+IHJlc3VsdHMsIEkgY2hvc2UgdGhlIGRl ZmF1bHQgZHVyYXRpb24gYXMgMTBtcy4KPiAKPiBQZXJmb3JtYW5jZSBPdmVyaGVhZCBUZXN0Cj4g PT09PT09PT09PT09PT09PT09PT09PT09PQo+IAo+IFRoaXMgY29tbWl0IGNvdWxkIGluY3VyIEkv TyBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbiB1bmRlciBzZXZlcmUgbWVtb3J5Cj4gcHJlc3N1cmUg YmVjYXVzZSB0aGUgc3F1ZWV6aW5nIHdpbGwgcmVxdWlyZSBtb3JlIHBhZ2UgYWxsb2NhdGlvbnMg cGVyCj4gSS9PLiAgVG8gc2hvdyB0aGUgb3ZlcmhlYWQsIEkgYXJ0aWZpY2lhbGx5IG1hZGUgYSB3 b3JzdC1jYXNlIHNxdWVlemluZwo+IHNpdHVhdGlvbiBhbmQgbWVhc3VyZWQgdGhlIEkvTyBwZXJm b3JtYW5jZSBvZiBhIGBibGtmcm9udGAgcnVubmluZwo+IGd1ZXN0Lgo+IAo+IEZvciB0aGUgYXJ0 aWZpY2lhbCBzcXVlZXppbmcsIEkgc2V0IHRoZSBgYmxrYmFjay5tYXhfYnVmZmVyX3BhZ2VzYCB1 c2luZwo+IHRoZSBgL3N5cy9tb2R1bGUveGVuX2Jsa2JhY2svcGFyYW1ldGVycy9tYXhfYnVmZmVy X3BhZ2VzYCBmaWxlLiAgV2Ugc2V0Cj4gdGhlIHZhbHVlIHRvIGAxMDI0YCBhbmQgYDBgLiAgVGhl IGAxMDI0YCBpcyB0aGUgZGVmYXVsdCB2YWx1ZS4gIFNldHRpbmcKPiB0aGUgdmFsdWUgYXMgYDBg IGlzIHNhbWUgdG8gYSBzaXR1YXRpb24gZG9pbmcgdGhlIHNxdWVlemluZyBhbHdheXMKPiAod29y c3QtY2FzZSkuCj4gCj4gRm9yIHRoZSBJL08gcGVyZm9ybWFuY2UgbWVhc3VyZW1lbnQsIEkgdXNl IGEgc2ltcGxlIGBkZGAgY29tbWFuZC4KPiAKPiBEZWZhdWx0IFBlcmZvcm1hbmNlCj4gLS0tLS0t LS0tLS0tLS0tLS0tLQo+IAo+ICAgICBbZG9tMF0jIGVjaG8gMTAyNCA+IC9zeXMvbW9kdWxlL3hl bl9ibGtiYWNrL3BhcmFtZXRlcnMvbWF4X2J1ZmZlcl9wYWdlcwo+ICAgICBbaW5zdGFuY2VdJCBm b3IgaSBpbiB7MS4uNX07IGRvIGRkIGlmPS9kZXYvemVybyBvZj1maWxlIGJzPTRrIGNvdW50PSQo KDI1Nio1MTIpKTsgc3luYzsgZG9uZQo+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gICAgIDEz MTA3MiswIHJlY29yZHMgb3V0Cj4gICAgIDUzNjg3MDkxMiBieXRlcyAoNTM3IE1CKSBjb3BpZWQs IDExLjcyNTcgcywgNDUuOCBNQi9zCj4gICAgIDEzMTA3MiswIHJlY29yZHMgaW4KPiAgICAgMTMx MDcyKzAgcmVjb3JkcyBvdXQKPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIpIGNvcGllZCwg MTMuODgyNyBzLCAzOC43IE1CL3MKPiAgICAgMTMxMDcyKzAgcmVjb3JkcyBpbgo+ICAgICAxMzEw NzIrMCByZWNvcmRzIG91dAo+ICAgICA1MzY4NzA5MTIgYnl0ZXMgKDUzNyBNQikgY29waWVkLCAx My44NzgxIHMsIDM4LjcgTUIvcwo+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gICAgIDEzMTA3 MiswIHJlY29yZHMgb3V0Cj4gICAgIDUzNjg3MDkxMiBieXRlcyAoNTM3IE1CKSBjb3BpZWQsIDEz Ljg3MzcgcywgMzguNyBNQi9zCj4gICAgIDEzMTA3MiswIHJlY29yZHMgaW4KPiAgICAgMTMxMDcy KzAgcmVjb3JkcyBvdXQKPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIpIGNvcGllZCwgMTMu ODcwMiBzLCAzOC43IE1CL3MKPiAKPiBXb3JzdC1jYXNlIFBlcmZvcm1hbmNlCj4gLS0tLS0tLS0t LS0tLS0tLS0tLS0tLQo+IAo+ICAgICBbZG9tMF0jIGVjaG8gMCA+IC9zeXMvbW9kdWxlL3hlbl9i bGtiYWNrL3BhcmFtZXRlcnMvbWF4X2J1ZmZlcl9wYWdlcwo+ICAgICBbaW5zdGFuY2VdJCBmb3Ig aSBpbiB7MS4uNX07IGRvIGRkIGlmPS9kZXYvemVybyBvZj1maWxlIGJzPTRrIGNvdW50PSQoKDI1 Nio1MTIpKTsgc3luYzsgZG9uZQo+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gICAgIDEzMTA3 MiswIHJlY29yZHMgb3V0Cj4gICAgIDUzNjg3MDkxMiBieXRlcyAoNTM3IE1CKSBjb3BpZWQsIDEx LjcyNTcgcywgNDUuOCBNQi9zCj4gICAgIDEzMTA3MiswIHJlY29yZHMgaW4KPiAgICAgMTMxMDcy KzAgcmVjb3JkcyBvdXQKPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIpIGNvcGllZCwgMTMu ODc4IHMsIDM4LjcgTUIvcwo+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gICAgIDEzMTA3Misw IHJlY29yZHMgb3V0Cj4gICAgIDUzNjg3MDkxMiBieXRlcyAoNTM3IE1CKSBjb3BpZWQsIDEzLjg3 NDYgcywgMzguNyBNQi9zCj4gICAgIDEzMTA3MiswIHJlY29yZHMgaW4KPiAgICAgMTMxMDcyKzAg cmVjb3JkcyBvdXQKPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIpIGNvcGllZCwgMTMuODc4 NiBzLCAzOC43IE1CL3MKPiAgICAgMTMxMDcyKzAgcmVjb3JkcyBpbgo+ICAgICAxMzEwNzIrMCBy ZWNvcmRzIG91dAo+ICAgICA1MzY4NzA5MTIgYnl0ZXMgKDUzNyBNQikgY29waWVkLCAxMy44NzQ5 IHMsIDM4LjcgTUIvcwo+IAo+IEluIHNob3J0LCBldmVuIHdvcnN0IGNhc2Ugc3F1ZWV6aW5nIG1h a2VzIG5vIHZpc2libGUgcGVyZm9ybWFuY2UKPiBkZWdyYWRhdGlvbi4KCkkgd291bGQgYXJndWUg dGhhdCB3aXRoIGEgfjQwTUIvcyB0aHJvdWdocHV0IHlvdSB3b24ndCBzZWUgYW55CnBlcmZvcm1h bmNlIGRpZmZlcmVuY2UgYXQgYWxsIHJlZ2FyZGxlc3Mgb2YgdGhlIHNpemUgb2YgdGhlIHBvb2wg b2YKZnJlZSBwYWdlcyBvciB0aGUgYW1vdW50IG9mIHBlcnNpc3RlbnQgZ3JhbnRzIGJlY2F1c2Ug dGhlIGJvdHRsZW5lY2sgaXMKb24gdGhlIHN0b3JhZ2UgcGVyZm9ybWFuY2UgaXRzZWxmLgoKWW91 IG5lZWQgdG8gdGVzdCB0aGlzIHVzaW5nIG51bGxibGsgb3Igc29tZSBraW5kIG9mIGZhc3Qgc3Rv cmFnZSwgb3IKZWxzZSB0aGUgYWJvdmUgZmlndXJlcyBhcmUgbm90IGdvaW5nIHRvIHJlZmxlY3Qg YW55IGNoYW5nZXMgeW91IG1ha2UKYmVjYXVzZSB0aGV5IGFyZSBoaWRkZW4gYnkgdGhlIHBvb3Ig cGVyZm9ybWFuY2Ugb2YgdGhlIHVuZGVybHlpbmcKc3RvcmFnZS4KCj4gSSB0aGluayB0aGlzIGlz IGR1ZSB0byB0aGUgc2xvdyBzcGVlZCBvZiB0aGUgSS9PLiAgSW4KPiBvdGhlciB3b3JkcywgdGhl IGFkZGl0aW9uYWwgcGFnZSBhbGxvY2F0aW9uIG92ZXJoZWFkIGlzIGhpZGRlbiB1bmRlciB0aGUK PiBtdWNoIHNsb3dlciBJL08gbGF0ZW5jeS4KPiAKPiBOZXZlcnRoZWxlc3MsIHBsZWFzZXQgbm90 ZSB0aGF0IHRoaXMgaXMganVzdCBhIHZlcnkgc2ltcGxlIGFuZCBtaW5pbWFsCj4gdGVzdC4KCkkg d291bGQgbGlrZSB0byBhZGQgdGhhdCBJTU8gdGhpcyBpcyBwYXBlcmluZyBvdmVyIGFuIGV4aXN0 aW5nIGlzc3VlLAp3aGljaCBpcyBob3cgcGFnZXMgdG8gYmUgdXNlZCB0byBtYXAgZ3JhbnRzIGFy ZSBhbGxvY2F0ZWQuIEdyYW50Cm1hcHBpbmdzIF9zaG91bGRuJ3RfIGNvbnN1bWUgUkFNIHBhZ2Vz IGluIHRoZSBmaXJzdCBwbGFjZSwgYW5kIElJUkMKdGhlIGZhY3QgdGhhdCB0aGV5IGRvIGlzIGJl Y2F1c2UgTGludXggYmFsbG9vbnMgb3V0IG1lbW9yeSBpbiBvcmRlciB0bwpyZS11c2UgdGhvc2Ug cGFnZXMgdG8gbWFwIGdyYW50cyBhbmQgaGF2ZSBhIHZhbGlkIHBhZ2Ugc3RydWN0LgoKQSB3YXkg dG8gc29sdmUgdGhpcyB3b3VsZCBiZSB0byBob3RwbHVnIGEgZmFrZSBtZW1vcnkgcmVnaW9uIGFu ZCB1c2UKaXQgaW4gb3JkZXIgdG8gbWFwIGdyYW50IHBhZ2VzLCB3aXRob3V0IGhhdmluZyB0byBi YWxsb29uIG91dCBSQU0KcmVnaW9ucy4gQXQgdGhlIGVuZCBvZiBkYXkgb24gYSBQViBkb21haW4g bWFwcGluZyBhIGdyYW50IHNob3VsZCBqdXN0CnJlcXVpcmUgdmlydHVhbCBhZGRyZXNzIHNwYWNl LgoKVGhpcyBpcyBnb2luZyB0byBnZXQgZXZlbiB3b3JzZSBmb3IgUFZIIHRoYXQgcmVxdWlyZXMg YSBwaHlzaWNhbCBtZW1vcnkKYWRkcmVzcyBpbiBvcmRlciB0byBtYXAgYSBncmFudCwgYnV0IHRo YXQncyBhbm90aGVyIHN0b3J5LgoKPiAKPiBSZXZpZXdlZC1ieTogSnVlcmdlbiBHcm9zcyA8amdy b3NzQHN1c2UuY29tPgo+IFNpZ25lZC1vZmYtYnk6IFNlb25nSmFlIFBhcmsgPHNqcGFya0BhbWF6 b24uZGU+Cj4gLS0tCj4gIGRyaXZlcnMvYmxvY2sveGVuLWJsa2JhY2svYmxrYmFjay5jIHwgMjMg KysrKysrKysrKysrKysrKysrKysrLS0KPiAgZHJpdmVycy9ibG9jay94ZW4tYmxrYmFjay9jb21t b24uaCAgfCAgMSArCj4gIGRyaXZlcnMvYmxvY2sveGVuLWJsa2JhY2sveGVuYnVzLmMgIHwgIDMg KystCj4gIDMgZmlsZXMgY2hhbmdlZCwgMjQgaW5zZXJ0aW9ucygrKSwgMyBkZWxldGlvbnMoLSkK PiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ibG9jay94ZW4tYmxrYmFjay9ibGtiYWNrLmMgYi9k cml2ZXJzL2Jsb2NrL3hlbi1ibGtiYWNrL2Jsa2JhY2suYwo+IGluZGV4IGZkMWUxOWYxYTQ5Zi4u NGQ0ZGJhN2VhNzIxIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvYmxvY2sveGVuLWJsa2JhY2svYmxr YmFjay5jCj4gKysrIGIvZHJpdmVycy9ibG9jay94ZW4tYmxrYmFjay9ibGtiYWNrLmMKPiBAQCAt MTQyLDYgKzE0MiwyMiBAQCBzdGF0aWMgaW5saW5lIGJvb2wgcGVyc2lzdGVudF9nbnRfdGltZW91 dChzdHJ1Y3QgcGVyc2lzdGVudF9nbnQgKnBlcnNpc3RlbnRfZ250KQo+ICAJCUhaICogeGVuX2Js a2lmX3BncmFudF90aW1lb3V0KTsKPiAgfQo+ICAKPiArLyogT25jZSBhIG1lbW9yeSBwcmVzc3Vy ZSBpcyBkZXRlY3RlZCwgc3F1ZWV6ZSBmcmVlIHBhZ2UgcG9vbHMgZm9yIGEgd2hpbGUuICovCj4g K3N0YXRpYyBpbnQgeGVuX2Jsa2lmX2J1ZmZlcl9zcXVlZXplX2R1cmF0aW9uX21zID0gMTA7Cgp1 bnNpZ25lZD8KCllvdSBjYW4gbGlrZWx5IGRyb3AgdGhlIHhlbl9ibGtpZiBwcmVmaXggc2luY2Ug dGhpcyBpcyBhIHN0YXRpYwp2YXJpYWJsZS4KCj4gK21vZHVsZV9wYXJhbV9uYW1lZChidWZmZXJf c3F1ZWV6ZV9kdXJhdGlvbl9tcywKPiArCQl4ZW5fYmxraWZfYnVmZmVyX3NxdWVlemVfZHVyYXRp b25fbXMsIGludCwgMDY0NCk7Cj4gK01PRFVMRV9QQVJNX0RFU0MoYnVmZmVyX3NxdWVlemVfZHVy YXRpb25fbXMsCj4gKyJEdXJhdGlvbiBpbiBtcyB0byBzcXVlZXplIHBhZ2VzIGJ1ZmZlciB3aGVu IGEgbWVtb3J5IHByZXNzdXJlIGlzIGRldGVjdGVkIik7Cj4gKwo+ICtzdGF0aWMgdW5zaWduZWQg bG9uZyB4ZW5fYmxrX2J1ZmZlcl9zcXVlZXplX2VuZDsKPiArCj4gK3Vuc2lnbmVkIHhlbl9ibGti a19yZWNsYWltKHN0cnVjdCB4ZW5idXNfZGV2aWNlICpkZXYpCj4gK3sKPiArCXhlbl9ibGtfYnVm ZmVyX3NxdWVlemVfZW5kID0gamlmZmllcyArCj4gKwkJbXNlY3NfdG9famlmZmllcyh4ZW5fYmxr aWZfYnVmZmVyX3NxdWVlemVfZHVyYXRpb25fbXMpOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4g IHN0YXRpYyBpbmxpbmUgaW50IGdldF9mcmVlX3BhZ2Uoc3RydWN0IHhlbl9ibGtpZl9yaW5nICpy aW5nLCBzdHJ1Y3QgcGFnZSAqKnBhZ2UpCj4gIHsKPiAgCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4g QEAgLTY1Niw4ICs2NzIsMTEgQEAgaW50IHhlbl9ibGtpZl9zY2hlZHVsZSh2b2lkICphcmcpCj4g IAkJCXJpbmctPm5leHRfbHJ1ID0gamlmZmllcyArIG1zZWNzX3RvX2ppZmZpZXMoTFJVX0lOVEVS VkFMKTsKPiAgCQl9Cj4gIAo+IC0JCS8qIFNocmluayBpZiB3ZSBoYXZlIG1vcmUgdGhhbiB4ZW5f YmxraWZfbWF4X2J1ZmZlcl9wYWdlcyAqLwo+IC0JCXNocmlua19mcmVlX3BhZ2Vwb29sKHJpbmcs IHhlbl9ibGtpZl9tYXhfYnVmZmVyX3BhZ2VzKTsKPiArCQkvKiBTaHJpbmsgdGhlIGZyZWUgcGFn ZXMgcG9vbCBpZiBpdCBpcyB0b28gbGFyZ2UuICovCj4gKwkJaWYgKHRpbWVfYmVmb3JlKGppZmZp ZXMsIHhlbl9ibGtfYnVmZmVyX3NxdWVlemVfZW5kKSkKPiArCQkJc2hyaW5rX2ZyZWVfcGFnZXBv b2wocmluZywgMCk7Cj4gKwkJZWxzZQo+ICsJCQlzaHJpbmtfZnJlZV9wYWdlcG9vbChyaW5nLCB4 ZW5fYmxraWZfbWF4X2J1ZmZlcl9wYWdlcyk7Cj4gIAo+ICAJCWlmIChsb2dfc3RhdHMgJiYgdGlt ZV9hZnRlcihqaWZmaWVzLCByaW5nLT5zdF9wcmludCkpCj4gIAkJCXByaW50X3N0YXRzKHJpbmcp Owo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Jsb2NrL3hlbi1ibGtiYWNrL2NvbW1vbi5oIGIvZHJp dmVycy9ibG9jay94ZW4tYmxrYmFjay9jb21tb24uaAo+IGluZGV4IDFkMzAwMmQ3NzNmNy4uYzAz MzRjZGE3OWZlIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvYmxvY2sveGVuLWJsa2JhY2svY29tbW9u LmgKPiArKysgYi9kcml2ZXJzL2Jsb2NrL3hlbi1ibGtiYWNrL2NvbW1vbi5oCj4gQEAgLTM4Myw2 ICszODMsNyBAQCBpcnFyZXR1cm5fdCB4ZW5fYmxraWZfYmVfaW50KGludCBpcnEsIHZvaWQgKmRl dl9pZCk7Cj4gIGludCB4ZW5fYmxraWZfc2NoZWR1bGUodm9pZCAqYXJnKTsKPiAgaW50IHhlbl9i bGtpZl9wdXJnZV9wZXJzaXN0ZW50KHZvaWQgKmFyZyk7Cj4gIHZvaWQgeGVuX2Jsa2JrX2ZyZWVf Y2FjaGVzKHN0cnVjdCB4ZW5fYmxraWZfcmluZyAqcmluZyk7Cj4gK3Vuc2lnbmVkIHhlbl9ibGti a19yZWNsYWltKHN0cnVjdCB4ZW5idXNfZGV2aWNlICpkZXYpOwo+ICAKPiAgaW50IHhlbl9ibGti a19mbHVzaF9kaXNrY2FjaGUoc3RydWN0IHhlbmJ1c190cmFuc2FjdGlvbiB4YnQsCj4gIAkJCSAg ICAgIHN0cnVjdCBiYWNrZW5kX2luZm8gKmJlLCBpbnQgc3RhdGUpOwo+IGRpZmYgLS1naXQgYS9k cml2ZXJzL2Jsb2NrL3hlbi1ibGtiYWNrL3hlbmJ1cy5jIGIvZHJpdmVycy9ibG9jay94ZW4tYmxr YmFjay94ZW5idXMuYwo+IGluZGV4IGI5MGRiY2Q5OWMwMy4uZGU0OWEwOWU2OTMzIDEwMDY0NAo+ IC0tLSBhL2RyaXZlcnMvYmxvY2sveGVuLWJsa2JhY2sveGVuYnVzLmMKPiArKysgYi9kcml2ZXJz L2Jsb2NrL3hlbi1ibGtiYWNrL3hlbmJ1cy5jCj4gQEAgLTExMTUsNyArMTExNSw4IEBAIHN0YXRp YyBzdHJ1Y3QgeGVuYnVzX2RyaXZlciB4ZW5fYmxrYmtfZHJpdmVyID0gewo+ICAJLmlkcyAgPSB4 ZW5fYmxrYmtfaWRzLAo+ICAJLnByb2JlID0geGVuX2Jsa2JrX3Byb2JlLAo+ICAJLnJlbW92ZSA9 IHhlbl9ibGtia19yZW1vdmUsCj4gLQkub3RoZXJlbmRfY2hhbmdlZCA9IGZyb250ZW5kX2NoYW5n ZWQKPiArCS5vdGhlcmVuZF9jaGFuZ2VkID0gZnJvbnRlbmRfY2hhbmdlZCwKPiArCS5yZWNsYWlt ID0geGVuX2Jsa2JrX3JlY2xhaW0KCldoaWxlIGF0IGl0IHBsZWFzZSBhZGQgdGhlIGVuZGluZyBj b21tYSBzbyB0aGF0IG5ldyBhZGRpdGlvbiBkb24ndApoYXZlIHRvIG1vZGlmeSB0aGUgcHJldmlv dXMgbGluZS4KClRoYW5rcywgUm9nZXIuCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fXwpYZW4tZGV2ZWwgbWFpbGluZyBsaXN0Clhlbi1kZXZlbEBsaXN0cy54 ZW5wcm9qZWN0Lm9yZwpodHRwczovL2xpc3RzLnhlbnByb2plY3Qub3JnL21haWxtYW4vbGlzdGlu Zm8veGVuLWRldmVs