From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.0 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27508C43603 for ; Wed, 11 Dec 2019 11:14:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D974F214AF for ; Wed, 11 Dec 2019 11:14:54 +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="KN/NdJZB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727851AbfLKLOy (ORCPT ); Wed, 11 Dec 2019 06:14:54 -0500 Received: from esa1.hc3370-68.iphmx.com ([216.71.145.142]:22399 "EHLO esa1.hc3370-68.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727469AbfLKLOx (ORCPT ); Wed, 11 Dec 2019 06:14:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1576062892; h=date:from:to:cc:subject:message-id:references: mime-version:content-transfer-encoding:in-reply-to; bh=Js+KXVZu0C18q/pPZwN6y53cJHe5c921qavIhxSbNr0=; b=KN/NdJZBHKvsOTj9enYihaSSbrUQ9P9/oxUxur35BCT1RgBWyRFgMyrD 9pUWeUNfAvKIJ0es99iT30FYNb+6Ym0nY4JtPMi5OOX+/kEv774IEqt88 8MU4hKzLFtvKzP7SrtJH4cSlqMmW6mtfvtFPpZSDGjg05iwREqOic2WId w=; Authentication-Results: esa1.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 (esa1.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=esa1.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa1.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=esa1.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 (esa1.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=esa1.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: E1SgW5d/JwjFrVJ4rG46aG2mxrt+Z9vE+P4acKp8Lh42xK/bQFGNRypqf2fT9YkW7PLI8xIBPz z6po0exRV2hbTI43CIoh3Xbdrez9/AzsmRjlJfcTkOrpPKfGFP3ky389luPc0n7G8uNTntQ9Ip GacmHMNpXXX62Bt7DAY0JO9WxnexhCc+njV5MJVGPHVxk7dqfky2jd8JKpQbrjATP5MrrgqkXO Jnl2i9FjGa4XBtpxyBP0e2uCc3U1U10bMTk0rj2/Ja9WIiWfZ2KLEvnBtf02J0itS4853l2/Ob iok= X-SBRS: 2.7 X-MesageID: 9645192 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,301,1571716800"; d="scan'208";a="9645192" Date: Wed, 11 Dec 2019 12:14:44 +0100 From: Roger Pau =?iso-8859-1?Q?Monn=E9?= To: SeongJae Park CC: , , , , , , , SeongJae Park Subject: Re: Re: [PATCH v5 2/2] xen/blkback: Squeeze page pools if a memory pressure is detected Message-ID: <20191211111444.GL980@Air-de-Roger> References: <20191210110432.GG980@Air-de-Roger> <20191211040812.12354-1-sj38.park@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20191211040812.12354-1-sj38.park@gmail.com> 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 Hello, I see that you have already sent v6, for future iterations can you please wait until the conversation on the previous version has been settled? I'm still replying to your replies to v5, and hence you should hold off sending v6 until we get some kind of conclusion/agreement. On Wed, Dec 11, 2019 at 05:08:12AM +0100, SeongJae Park wrote: > On Tue, 10 Dec 2019 12:04:32 +0100 "Roger Pau Monné" 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. > > Right, the problem can occur only if it is mis-configured so that the frontend > running guests can attach a large number of devices which is enough to cause > the memory pressure. I tried to explain it in below paragraph, but seems above > paragraph is a little bit confusing. I will wordsmith the sentence in the next > version. I would word it along these lines: "Host administrators can cause memory pressure in blkback by attaching a large number of block devices and inducing I/O." > > > > > 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. > > Thank you for great suggestions, I will apply those. > > > > > > > > > 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. > > Good point! I will add the note. > > > > > > 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 While this is useful, it's kind of too verbose IMO. If you need to do this kind of performance comparisons I would recommend using ministat (available at least on Debian and FreeBSD) in order to plot the results and give the std deviation and statistical difference given a confidence level. The output of ministat can be pasted in the commit message, since it's a text based tool. > > > > > > 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. > > Yes, agree that. My test is just a minimal check for my environment. I will > note the points and concerns in the commit message. I'm afraid that just adding a note about this concerns is not enough. We should make sure that this change doesn't regress the current performance of fast storage backends, and hence I have to ask you to test with null_blk or a fast storage and provide the figures. > > > > > 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. > > Yes, as Paul also pointed out and suggested, we should consider a structural > solution in a big picture. Until the big change is ready, this simple solution > would work as a point fix. Getting a proper solution would be my preference, in the mean time I guess it's fine to accept such a bodge, as it's pretty small and non-intrusive. 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=-2.0 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 438E5C43603 for ; Wed, 11 Dec 2019 11:15:07 +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 004BE214AF for ; Wed, 11 Dec 2019 11:15:06 +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="Gj2PilRE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 004BE214AF 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 1iezxH-0007rz-E0; Wed, 11 Dec 2019 11:14:55 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iezxF-0007rs-UE for xen-devel@lists.xenproject.org; Wed, 11 Dec 2019 11:14:54 +0000 X-Inumbo-ID: 73c4fce8-1c07-11ea-8b06-12813bfff9fa Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 73c4fce8-1c07-11ea-8b06-12813bfff9fa; Wed, 11 Dec 2019 11:14:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1576062893; h=date:from:to:cc:subject:message-id:references: mime-version:content-transfer-encoding:in-reply-to; bh=Js+KXVZu0C18q/pPZwN6y53cJHe5c921qavIhxSbNr0=; b=Gj2PilREgeKGoQ2GIwT19LgLeWGmqYaRT+EceznVV7KCKzjPszbWxe/r gqhEXP0EQJKLRVZ0khTAItB82EGYe+I4NeYal5ZFpx4YgDZJKWeQPCleA Hi2U3n4TGYxOm6bEdXOout07Fp8oX+FoMa0jPdwW2YoKgjRsoP8/dRO7j Y=; Authentication-Results: esa1.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 (esa1.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=esa1.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa1.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=esa1.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 (esa1.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=esa1.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: E1SgW5d/JwjFrVJ4rG46aG2mxrt+Z9vE+P4acKp8Lh42xK/bQFGNRypqf2fT9YkW7PLI8xIBPz z6po0exRV2hbTI43CIoh3Xbdrez9/AzsmRjlJfcTkOrpPKfGFP3ky389luPc0n7G8uNTntQ9Ip GacmHMNpXXX62Bt7DAY0JO9WxnexhCc+njV5MJVGPHVxk7dqfky2jd8JKpQbrjATP5MrrgqkXO Jnl2i9FjGa4XBtpxyBP0e2uCc3U1U10bMTk0rj2/Ja9WIiWfZ2KLEvnBtf02J0itS4853l2/Ob iok= X-SBRS: 2.7 X-MesageID: 9645192 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,301,1571716800"; d="scan'208";a="9645192" Date: Wed, 11 Dec 2019 12:14:44 +0100 From: Roger Pau =?iso-8859-1?Q?Monn=E9?= To: SeongJae Park Message-ID: <20191211111444.GL980@Air-de-Roger> References: <20191210110432.GG980@Air-de-Roger> <20191211040812.12354-1-sj38.park@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191211040812.12354-1-sj38.park@gmail.com> 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" SGVsbG8sCgpJIHNlZSB0aGF0IHlvdSBoYXZlIGFscmVhZHkgc2VudCB2NiwgZm9yIGZ1dHVyZSBp dGVyYXRpb25zIGNhbiB5b3UKcGxlYXNlIHdhaXQgdW50aWwgdGhlIGNvbnZlcnNhdGlvbiBvbiB0 aGUgcHJldmlvdXMgdmVyc2lvbiBoYXMgYmVlbgpzZXR0bGVkPwoKSSdtIHN0aWxsIHJlcGx5aW5n IHRvIHlvdXIgcmVwbGllcyB0byB2NSwgYW5kIGhlbmNlIHlvdSBzaG91bGQgaG9sZCBvZmYKc2Vu ZGluZyB2NiB1bnRpbCB3ZSBnZXQgc29tZSBraW5kIG9mIGNvbmNsdXNpb24vYWdyZWVtZW50LgoK T24gV2VkLCBEZWMgMTEsIDIwMTkgYXQgMDU6MDg6MTJBTSArMDEwMCwgU2VvbmdKYWUgUGFyayB3 cm90ZToKPiBPbiBUdWUsIDEwIERlYyAyMDE5IDEyOjA0OjMyICswMTAwICJSb2dlciBQYXUgTW9u bsOpIiA8cm9nZXIucGF1QGNpdHJpeC5jb20+IHdyb3RlOgo+IAo+ID4gPiBFYWNoIGBibGtpZmAg aGFzIGEgZnJlZSBwYWdlcyBwb29sIGZvciB0aGUgZ3JhbnQgbWFwcGluZy4gIFRoZSBzaXplIG9m Cj4gPiA+IHRoZSBwb29sIHN0YXJ0cyBmcm9tIHplcm8gYW5kIGJlIGluY3JlYXNlZCBvbiBkZW1h bmQgd2hpbGUgcHJvY2Vzc2luZwo+ID4gPiB0aGUgSS9PIHJlcXVlc3RzLiAgSWYgY3VycmVudCBJ L08gcmVxdWVzdHMgaGFuZGxpbmcgaXMgZmluaXNoZWQgb3IgMTAwCj4gPiA+IG1pbGxpc2Vjb25k cyBoYXMgcGFzc2VkIHNpbmNlIGxhc3QgSS9PIHJlcXVlc3RzIGhhbmRsaW5nLCBpdCBjaGVja3Mg YW5kCj4gPiA+IHNocmlua3MgdGhlIHBvb2wgdG8gbm90IGV4Y2VlZCB0aGUgc2l6ZSBsaW1pdCwg YG1heF9idWZmZXJfcGFnZXNgLgo+ID4gPiAKPiA+ID4gVGhlcmVmb3JlLCBgYmxrZnJvbnRgIHJ1 bm5pbmcgZ3Vlc3RzIGNhbiBjYXVzZSBhIG1lbW9yeSBwcmVzc3VyZSBpbiB0aGUKPiA+ID4gYGJs a2JhY2tgIHJ1bm5pbmcgZ3Vlc3QgYnkgYXR0YWNoaW5nIGEgbGFyZ2UgbnVtYmVyIG9mIGJsb2Nr IGRldmljZXMgYW5kCj4gPiA+IGluZHVjaW5nIEkvTy4KPiA+IAo+ID4gSG0sIEkgZG9uJ3QgdGhp bmsgdGhpcyBpcyBhY3R1YWxseSB0cnVlLiBibGtmcm9udCBjYW5ub3QgYXR0YWNoIGFuCj4gPiBh cmJpdHJhcnkgbnVtYmVyIG9mIGRldmljZXMsIGJsa2Zyb250IGlzIGp1c3QgYSBmcm9udGVuZCBm b3IgYSBkZXZpY2UKPiA+IHRoYXQncyBpbnN0YW50aWF0ZWQgYnkgdGhlIFhlbiB0b29sc3RhY2ss IHNvIGl0J3MgdGhlIHRvb2xzdGFjayB0aGUgb25lCj4gPiB0aGF0IGNvbnRyb2xzIHRoZSBhbW91 bnQgb2YgUFYgYmxvY2sgZGV2aWNlcy4KPiAKPiBSaWdodCwgdGhlIHByb2JsZW0gY2FuIG9jY3Vy IG9ubHkgaWYgaXQgaXMgbWlzLWNvbmZpZ3VyZWQgc28gdGhhdCB0aGUgZnJvbnRlbmQKPiBydW5u aW5nIGd1ZXN0cyBjYW4gYXR0YWNoIGEgbGFyZ2UgbnVtYmVyIG9mIGRldmljZXMgd2hpY2ggaXMg ZW5vdWdoIHRvIGNhdXNlCj4gdGhlIG1lbW9yeSBwcmVzc3VyZS4gIEkgdHJpZWQgdG8gZXhwbGFp biBpdCBpbiBiZWxvdyBwYXJhZ3JhcGgsIGJ1dCBzZWVtcyBhYm92ZQo+IHBhcmFncmFwaCBpcyBh IGxpdHRsZSBiaXQgY29uZnVzaW5nLiAgSSB3aWxsIHdvcmRzbWl0aCB0aGUgc2VudGVuY2UgaW4g dGhlIG5leHQKPiB2ZXJzaW9uLgoKSSB3b3VsZCB3b3JkIGl0IGFsb25nIHRoZXNlIGxpbmVzOgoK Ikhvc3QgYWRtaW5pc3RyYXRvcnMgY2FuIGNhdXNlIG1lbW9yeSBwcmVzc3VyZSBpbiBibGtiYWNr IGJ5IGF0dGFjaGluZwphIGxhcmdlIG51bWJlciBvZiBibG9jayBkZXZpY2VzIGFuZCBpbmR1Y2lu ZyBJL08uIgoKPiA+IAo+ID4gPiBTeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIGF2b2lkIHN1Y2gg cHJvYmxlbWF0aWMKPiA+ID4gc2l0dWF0aW9ucyBieSBsaW1pdGluZyB0aGUgbWF4aW11bSBudW1i ZXIgb2YgZGV2aWNlcyBlYWNoIGd1ZXN0IGNhbgo+ID4gPiBhdHRhY2guICBIb3dldmVyLCBmaW5k aW5nIHRoZSBvcHRpbWFsIGxpbWl0IGlzIG5vdCBzbyBlYXN5LiAgSW1wcm9wZXIKPiA+ID4gc2V0 IG9mIHRoZSBsaW1pdCBjYW4gcmVzdWx0cyBpbiB0aGUgbWVtb3J5IHByZXNzdXJlIG9yIGEgcmVz b3VyY2UKPiA+ID4gdW5kZXJ1dGlsaXphdGlvbi4gIFRoaXMgY29tbWl0IGF2b2lkcyBzdWNoIHBy b2JsZW1hdGljIHNpdHVhdGlvbnMgYnkKPiA+ID4gc3F1ZWV6aW5nIHRoZSBwb29scyAocmV0dXJu cyBldmVyeSBmcmVlIHBhZ2UgaW4gdGhlIHBvb2wgdG8gdGhlIHN5c3RlbSkKPiA+ID4gZm9yIGEg d2hpbGUgKHVzZXJzIGNhbiBzZXQgdGhpcyBkdXJhdGlvbiB2aWEgYSBtb2R1bGUgcGFyYW1ldGVy KSBpZiBhCj4gPiA+IG1lbW9yeSBwcmVzc3VyZSBpcyBkZXRlY3RlZC4KPiA+ID4gCj4gPiA+IERp c2N1c3Npb25zCj4gPiA+ID09PT09PT09PT09Cj4gPiA+IAo+ID4gPiBUaGUgYGJsa2JhY2tgJ3Mg b3JpZ2luYWwgc2hyaW5raW5nIG1lY2hhbmlzbSByZXR1cm5zIG9ubHkgcGFnZXMgaW4gdGhlCj4g PiA+IHBvb2wsIHdoaWNoIGFyZSBub3QgY3VycmVudGx5IGJlIHVzZWQgYnkgYGJsa2JhY2tgLCB0 byB0aGUgc3lzdGVtLiAgSW4KPiA+ID4gb3RoZXIgd29yZHMsIHRoZSBwYWdlcyBhcmUgbm90IG1h cHBlZCB3aXRoIGZvcmVpZ24gcGFnZXMuICBCZWNhdXNlIHRoaXMKPiA+ICAgICAgICAgICAgICAg ICAgICAgICAgIF4gdGhhdCAgICAgICAgICAgICAgIF4gZ3JhbnRlZAo+ID4gPiBjb21taXQgaXMg Y2hhbmdpbmcgb25seSB0aGUgc2hyaW5rIGxpbWl0IGJ1dCB1c2VzIHRoZSBtZWNoYW5pc20gYXMg aXMsCj4gPiA+IHRoaXMgY29tbWl0IGRvZXMgbm90IGludHJvZHVjZSBpbXByb3BlciBtYXBwaW5n cyByZWxhdGVkIHNlY3VyaXR5Cj4gPiA+IGlzc3Vlcy4KPiA+IAo+ID4gVGhhdCBsYXN0IHNlbnRl bmNlIGlzIGhhcmQgdG8gcGFyc2UuIEkgdGhpbmsgc29tZXRoaW5nIGxpa2U6Cj4gPiAKPiA+ICJC ZWNhdXNlIHRoaXMgY29tbWl0IGlzIGNoYW5naW5nIG9ubHkgdGhlIHNocmluayBsaW1pdCBidXQg c3RpbGwgdXNlcyB0aGUKPiA+IHNhbWUgZnJlZWluZyBtZWNoYW5pc20gaXQgZG9lcyBub3QgdG91 Y2ggcGFnZXMgd2hpY2ggYXJlIGN1cnJlbnRseQo+ID4gbWFwcGluZyBncmFudHMuIgo+ID4gCj4g PiA+IAo+ID4gPiBPbmNlIGEgbWVtb3J5IHByZXNzdXJlIGlzIGRldGVjdGVkLCB0aGlzIGNvbW1p dCBrZWVwcyB0aGUgc3F1ZWV6aW5nCj4gPiA+IGxpbWl0IGZvciBhIHVzZXItc3BlY2lmaWVkIHRp bWUgZHVyYXRpb24uICBUaGUgZHVyYXRpb24gc2hvdWxkIGJlCj4gPiA+IG5laXRoZXIgdG9vIGxv bmcgbm9yIHRvbyBzaG9ydC4gIElmIGl0IGlzIHRvbyBsb25nLCB0aGUgc3F1ZWV6aW5nCj4gPiA+ IGluY3VycmluZyBvdmVyaGVhZCBjYW4gcmVkdWNlIHRoZSBJL08gcGVyZm9ybWFuY2UuICBJZiBp dCBpcyB0b28gc2hvcnQsCj4gPiA+IGBibGtiYWNrYCB3aWxsIG5vdCBmcmVlIGVub3VnaCBwYWdl cyB0byByZWR1Y2UgdGhlIG1lbW9yeSBwcmVzc3VyZS4KPiA+ID4gVGhpcyBjb21taXQgc2V0cyB0 aGUgdmFsdWUgYXMgYDEwIG1pbGxpc2Vjb25kc2AgYnkgZGVmYXVsdCBiZWNhdXNlIGl0IGlzCj4g PiA+IGEgc2hvcnQgdGltZSBpbiB0ZXJtcyBvZiBJL08gd2hpbGUgaXQgaXMgYSBsb25nIHRpbWUg aW4gdGVybXMgb2YgbWVtb3J5Cj4gPiA+IG9wZXJhdGlvbnMuICBBbHNvLCBhcyB0aGUgb3JpZ2lu YWwgc2hyaW5raW5nIG1lY2hhbmlzbSB3b3JrcyBmb3IgYXQKPiA+ID4gbGVhc3QgZXZlcnkgMTAw IG1pbGxpc2Vjb25kcywgdGhpcyBjb3VsZCBiZSBhIHNvbWV3aGF0IHJlYXNvbmFibGUKPiA+ID4g Y2hvaWNlLiAgSSBhbHNvIHRlc3RlZCBvdGhlciBkdXJhdGlvbnMgKHJlZmVyIHRvIHRoZSBiZWxv dyBzZWN0aW9uIGZvcgo+ID4gPiBtb3JlIGRldGFpbHMpIGFuZCBjb25maXJtZWQgdGhhdCAxMCBt aWxsaXNlY29uZHMgaXMgdGhlIG9uZSB0aGF0IHdvcmtzCj4gPiA+IGJlc3Qgd2l0aCB0aGUgdGVz dC4gIFRoYXQgc2FpZCwgdGhlIHByb3BlciBkdXJhdGlvbiBkZXBlbmRzIG9uIGFjdHVhbAo+ID4g PiBjb25maWd1cmF0aW9ucyBhbmQgd29ya2xvYWRzLiAgVGhhdCdzIHdoeSB0aGlzIGNvbW1pdCBp cyBhbGxvd2luZyB1c2Vycwo+ID4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBeIGFsbG93cwo+ID4gPiB0byBzZXQgaXQgYXMgdGhlaXIgb3B0 aW1hbCB2YWx1ZSB2aWEgdGhlIG1vZHVsZSBwYXJhbWV0ZXIuCj4gPiAKPiA+IC4uLiB0byBzZXQg dGhlIGR1cmF0aW9uIGFzIGEgbW9kdWxlIHBhcmFtZXRlci4KPiAKPiBUaGFuayB5b3UgZm9yIGdy ZWF0IHN1Z2dlc3Rpb25zLCBJIHdpbGwgYXBwbHkgdGhvc2UuCj4gCj4gPiAKPiA+ID4gCj4gPiA+ IE1lbW9yeSBQcmVzc3VyZSBUZXN0Cj4gPiA+ID09PT09PT09PT09PT09PT09PT09Cj4gPiA+IAo+ ID4gPiBUbyBzaG93IGhvdyB0aGlzIGNvbW1pdCBmaXhlcyB0aGUgbWVtb3J5IHByZXNzdXJlIHNp dHVhdGlvbiB3ZWxsLCBJCj4gPiA+IGNvbmZpZ3VyZWQgYSB0ZXN0IGVudmlyb25tZW50IG9uIGEg eGVuLXJ1bm5pbmcgdmlydHVhbGl6YXRpb24gc3lzdGVtLgo+ID4gPiBPbiB0aGUgYGJsa2Zyb250 YCBydW5uaW5nIGd1ZXN0IGluc3RhbmNlcywgSSBhdHRhY2ggYSBsYXJnZSBudW1iZXIgb2YKPiA+ ID4gbmV0d29yay1iYWNrZWQgdm9sdW1lIGRldmljZXMgYW5kIGluZHVjZSBJL08gdG8gdGhvc2Uu ICBNZWFud2hpbGUsIEkKPiA+ID4gbWVhc3VyZSB0aGUgbnVtYmVyIG9mIHBhZ2VzIHRoYXQgc3dh cHBlZCBpbiBhbmQgb3V0IG9uIHRoZSBgYmxrYmFja2AKPiA+ID4gcnVubmluZyBndWVzdC4gIFRo ZSB0ZXN0IHJhbiB0d2ljZSwgb25jZSBmb3IgdGhlIGBibGtiYWNrYCBiZWZvcmUgdGhpcwo+ID4g PiBjb21taXQgYW5kIG9uY2UgZm9yIHRoYXQgYWZ0ZXIgdGhpcyBjb21taXQuICBBcyBzaG93biBi ZWxvdywgdGhpcyBjb21taXQKPiA+ID4gaGFzIGRyYW1hdGljYWxseSByZWR1Y2VkIHRoZSBtZW1v cnkgcHJlc3N1cmU6Cj4gPiA+IAo+ID4gPiAgICAgICAgICAgICAgICAgcHN3cGluICBwc3dwb3V0 Cj4gPiAKPiA+IEkgYXNzdW1lIHBzd3BpbiBtZWFucyAncGFnZXMgc3dhcHBlZCBpbicgYW5kIHBz d3BvdXQgJ3BhZ2VzIHN3YXBwZWQKPiA+IG91dCcuIE1pZ2h0IGJlIGdvb2QgdG8gYWRkIGEgbm90 ZSB0byB0aGF0IGVmZmVjdC4KPiAKPiBHb29kIHBvaW50ISAgSSB3aWxsIGFkZCB0aGUgbm90ZS4K PiAKPiA+IAo+ID4gPiAgICAgYmVmb3JlICAgICAgNzYsNjcyICAxODUsNzk5Cj4gPiA+ICAgICBh ZnRlciAgICAgICAgICAyMTIgICAgMywzMjUKPiA+ID4gCj4gPiA+IE9wdGltYWwgQWdncmVzc2l2 ZSBTaHJpbmtpbmcgRHVyYXRpb24KPiA+ID4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLQo+ID4gPiAKPiA+ID4gVG8gZmluZCBhIGJlc3Qgc3F1ZWV6aW5nIGR1cmF0aW9uLCBJ IHJlcGVhdGVkIHRoZSB0ZXN0IHdpdGggdGhyZWUKPiA+ID4gZGlmZmVyZW50IGR1cmF0aW9ucyAo MW1zLCAxMG1zLCBhbmQgMTAwbXMpLiAgVGhlIHJlc3VsdHMgYXJlIGFzIGJlbG93Ogo+ID4gPiAK PiA+ID4gICAgIGR1cmF0aW9uICAgIHBzd3BpbiAgcHN3cG91dAo+ID4gPiAgICAgMSAgICAgICAg ICAgODUyICAgICA2LDQyNAo+ID4gPiAgICAgMTAgICAgICAgICAgMjEyICAgICAzLDMyNQo+ID4g PiAgICAgMTAwICAgICAgICAgMjAzICAgICAzLDM0MAo+ID4gPiAKPiA+ID4gQXMgZXhwZWN0ZWQs IHRoZSBtZW1vcnkgcHJlc3N1cmUgaGFzIGRlY3JlYXNlZCBhcyB0aGUgZHVyYXRpb24gaXMKPiA+ ID4gaW5jcmVhc2VkLCBidXQgdGhlIHJlZHVjdGlvbiBzdG9wcGVkIGZyb20gdGhlIGAxMG1zYC4g IEJhc2VkIG9uIHRoaXMKPiA+ID4gcmVzdWx0cywgSSBjaG9zZSB0aGUgZGVmYXVsdCBkdXJhdGlv biBhcyAxMG1zLgo+ID4gPiAKPiA+ID4gUGVyZm9ybWFuY2UgT3ZlcmhlYWQgVGVzdAo+ID4gPiA9 PT09PT09PT09PT09PT09PT09PT09PT09Cj4gPiA+IAo+ID4gPiBUaGlzIGNvbW1pdCBjb3VsZCBp bmN1ciBJL08gcGVyZm9ybWFuY2UgZGVncmFkYXRpb24gdW5kZXIgc2V2ZXJlIG1lbW9yeQo+ID4g PiBwcmVzc3VyZSBiZWNhdXNlIHRoZSBzcXVlZXppbmcgd2lsbCByZXF1aXJlIG1vcmUgcGFnZSBh bGxvY2F0aW9ucyBwZXIKPiA+ID4gSS9PLiAgVG8gc2hvdyB0aGUgb3ZlcmhlYWQsIEkgYXJ0aWZp Y2lhbGx5IG1hZGUgYSB3b3JzdC1jYXNlIHNxdWVlemluZwo+ID4gPiBzaXR1YXRpb24gYW5kIG1l YXN1cmVkIHRoZSBJL08gcGVyZm9ybWFuY2Ugb2YgYSBgYmxrZnJvbnRgIHJ1bm5pbmcKPiA+ID4g Z3Vlc3QuCj4gPiA+IAo+ID4gPiBGb3IgdGhlIGFydGlmaWNpYWwgc3F1ZWV6aW5nLCBJIHNldCB0 aGUgYGJsa2JhY2subWF4X2J1ZmZlcl9wYWdlc2AgdXNpbmcKPiA+ID4gdGhlIGAvc3lzL21vZHVs ZS94ZW5fYmxrYmFjay9wYXJhbWV0ZXJzL21heF9idWZmZXJfcGFnZXNgIGZpbGUuICBXZSBzZXQK PiA+ID4gdGhlIHZhbHVlIHRvIGAxMDI0YCBhbmQgYDBgLiAgVGhlIGAxMDI0YCBpcyB0aGUgZGVm YXVsdCB2YWx1ZS4gIFNldHRpbmcKPiA+ID4gdGhlIHZhbHVlIGFzIGAwYCBpcyBzYW1lIHRvIGEg c2l0dWF0aW9uIGRvaW5nIHRoZSBzcXVlZXppbmcgYWx3YXlzCj4gPiA+ICh3b3JzdC1jYXNlKS4K PiA+ID4gCj4gPiA+IEZvciB0aGUgSS9PIHBlcmZvcm1hbmNlIG1lYXN1cmVtZW50LCBJIHVzZSBh IHNpbXBsZSBgZGRgIGNvbW1hbmQuCj4gPiA+IAo+ID4gPiBEZWZhdWx0IFBlcmZvcm1hbmNlCj4g PiA+IC0tLS0tLS0tLS0tLS0tLS0tLS0KPiA+ID4gCj4gPiA+ICAgICBbZG9tMF0jIGVjaG8gMTAy NCA+IC9zeXMvbW9kdWxlL3hlbl9ibGtiYWNrL3BhcmFtZXRlcnMvbWF4X2J1ZmZlcl9wYWdlcwo+ ID4gPiAgICAgW2luc3RhbmNlXSQgZm9yIGkgaW4gezEuLjV9OyBkbyBkZCBpZj0vZGV2L3plcm8g b2Y9ZmlsZSBicz00ayBjb3VudD0kKCgyNTYqNTEyKSk7IHN5bmM7IGRvbmUKPiA+ID4gICAgIDEz MTA3MiswIHJlY29yZHMgaW4KPiA+ID4gICAgIDEzMTA3MiswIHJlY29yZHMgb3V0Cj4gPiA+ICAg ICA1MzY4NzA5MTIgYnl0ZXMgKDUzNyBNQikgY29waWVkLCAxMS43MjU3IHMsIDQ1LjggTUIvcwo+ ID4gPiAgICAgMTMxMDcyKzAgcmVjb3JkcyBpbgo+ID4gPiAgICAgMTMxMDcyKzAgcmVjb3JkcyBv dXQKPiA+ID4gICAgIDUzNjg3MDkxMiBieXRlcyAoNTM3IE1CKSBjb3BpZWQsIDEzLjg4Mjcgcywg MzguNyBNQi9zCj4gPiA+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gPiA+ICAgICAxMzEwNzIr MCByZWNvcmRzIG91dAo+ID4gPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIpIGNvcGllZCwg MTMuODc4MSBzLCAzOC43IE1CL3MKPiA+ID4gICAgIDEzMTA3MiswIHJlY29yZHMgaW4KPiA+ID4g ICAgIDEzMTA3MiswIHJlY29yZHMgb3V0Cj4gPiA+ICAgICA1MzY4NzA5MTIgYnl0ZXMgKDUzNyBN QikgY29waWVkLCAxMy44NzM3IHMsIDM4LjcgTUIvcwo+ID4gPiAgICAgMTMxMDcyKzAgcmVjb3Jk cyBpbgo+ID4gPiAgICAgMTMxMDcyKzAgcmVjb3JkcyBvdXQKPiA+ID4gICAgIDUzNjg3MDkxMiBi eXRlcyAoNTM3IE1CKSBjb3BpZWQsIDEzLjg3MDIgcywgMzguNyBNQi9zCgpXaGlsZSB0aGlzIGlz IHVzZWZ1bCwgaXQncyBraW5kIG9mIHRvbyB2ZXJib3NlIElNTy4gSWYgeW91IG5lZWQgdG8gZG8K dGhpcyBraW5kIG9mIHBlcmZvcm1hbmNlIGNvbXBhcmlzb25zIEkgd291bGQgcmVjb21tZW5kIHVz aW5nIG1pbmlzdGF0CihhdmFpbGFibGUgYXQgbGVhc3Qgb24gRGViaWFuIGFuZCBGcmVlQlNEKSBp biBvcmRlciB0byBwbG90IHRoZQpyZXN1bHRzIGFuZCBnaXZlIHRoZSBzdGQgZGV2aWF0aW9uIGFu ZCBzdGF0aXN0aWNhbCBkaWZmZXJlbmNlIGdpdmVuIGEKY29uZmlkZW5jZSBsZXZlbC4KClRoZSBv dXRwdXQgb2YgbWluaXN0YXQgY2FuIGJlIHBhc3RlZCBpbiB0aGUgY29tbWl0IG1lc3NhZ2UsIHNp bmNlIGl0J3MKYSB0ZXh0IGJhc2VkIHRvb2wuCgo+ID4gPiAKPiA+ID4gV29yc3QtY2FzZSBQZXJm b3JtYW5jZQo+ID4gPiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4gPiA+IAo+ID4gPiAgICAgW2Rv bTBdIyBlY2hvIDAgPiAvc3lzL21vZHVsZS94ZW5fYmxrYmFjay9wYXJhbWV0ZXJzL21heF9idWZm ZXJfcGFnZXMKPiA+ID4gICAgIFtpbnN0YW5jZV0kIGZvciBpIGluIHsxLi41fTsgZG8gZGQgaWY9 L2Rldi96ZXJvIG9mPWZpbGUgYnM9NGsgY291bnQ9JCgoMjU2KjUxMikpOyBzeW5jOyBkb25lCj4g PiA+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gPiA+ICAgICAxMzEwNzIrMCByZWNvcmRzIG91 dAo+ID4gPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIpIGNvcGllZCwgMTEuNzI1NyBzLCA0 NS44IE1CL3MKPiA+ID4gICAgIDEzMTA3MiswIHJlY29yZHMgaW4KPiA+ID4gICAgIDEzMTA3Misw IHJlY29yZHMgb3V0Cj4gPiA+ICAgICA1MzY4NzA5MTIgYnl0ZXMgKDUzNyBNQikgY29waWVkLCAx My44NzggcywgMzguNyBNQi9zCj4gPiA+ICAgICAxMzEwNzIrMCByZWNvcmRzIGluCj4gPiA+ICAg ICAxMzEwNzIrMCByZWNvcmRzIG91dAo+ID4gPiAgICAgNTM2ODcwOTEyIGJ5dGVzICg1MzcgTUIp IGNvcGllZCwgMTMuODc0NiBzLCAzOC43IE1CL3MKPiA+ID4gICAgIDEzMTA3MiswIHJlY29yZHMg aW4KPiA+ID4gICAgIDEzMTA3MiswIHJlY29yZHMgb3V0Cj4gPiA+ICAgICA1MzY4NzA5MTIgYnl0 ZXMgKDUzNyBNQikgY29waWVkLCAxMy44Nzg2IHMsIDM4LjcgTUIvcwo+ID4gPiAgICAgMTMxMDcy KzAgcmVjb3JkcyBpbgo+ID4gPiAgICAgMTMxMDcyKzAgcmVjb3JkcyBvdXQKPiA+ID4gICAgIDUz Njg3MDkxMiBieXRlcyAoNTM3IE1CKSBjb3BpZWQsIDEzLjg3NDkgcywgMzguNyBNQi9zCj4gPiA+ IAo+ID4gPiBJbiBzaG9ydCwgZXZlbiB3b3JzdCBjYXNlIHNxdWVlemluZyBtYWtlcyBubyB2aXNp YmxlIHBlcmZvcm1hbmNlCj4gPiA+IGRlZ3JhZGF0aW9uLgo+ID4gCj4gPiBJIHdvdWxkIGFyZ3Vl IHRoYXQgd2l0aCBhIH40ME1CL3MgdGhyb3VnaHB1dCB5b3Ugd29uJ3Qgc2VlIGFueQo+ID4gcGVy Zm9ybWFuY2UgZGlmZmVyZW5jZSBhdCBhbGwgcmVnYXJkbGVzcyBvZiB0aGUgc2l6ZSBvZiB0aGUg cG9vbCBvZgo+ID4gZnJlZSBwYWdlcyBvciB0aGUgYW1vdW50IG9mIHBlcnNpc3RlbnQgZ3JhbnRz IGJlY2F1c2UgdGhlIGJvdHRsZW5lY2sgaXMKPiA+IG9uIHRoZSBzdG9yYWdlIHBlcmZvcm1hbmNl IGl0c2VsZi4KPiA+IAo+ID4gWW91IG5lZWQgdG8gdGVzdCB0aGlzIHVzaW5nIG51bGxibGsgb3Ig c29tZSBraW5kIG9mIGZhc3Qgc3RvcmFnZSwgb3IKPiA+IGVsc2UgdGhlIGFib3ZlIGZpZ3VyZXMg YXJlIG5vdCBnb2luZyB0byByZWZsZWN0IGFueSBjaGFuZ2VzIHlvdSBtYWtlCj4gPiBiZWNhdXNl IHRoZXkgYXJlIGhpZGRlbiBieSB0aGUgcG9vciBwZXJmb3JtYW5jZSBvZiB0aGUgdW5kZXJseWlu Zwo+ID4gc3RvcmFnZS4KPiAKPiBZZXMsIGFncmVlIHRoYXQuICBNeSB0ZXN0IGlzIGp1c3QgYSBt aW5pbWFsIGNoZWNrIGZvciBteSBlbnZpcm9ubWVudC4gIEkgd2lsbAo+IG5vdGUgdGhlIHBvaW50 cyBhbmQgY29uY2VybnMgaW4gdGhlIGNvbW1pdCBtZXNzYWdlLgoKSSdtIGFmcmFpZCB0aGF0IGp1 c3QgYWRkaW5nIGEgbm90ZSBhYm91dCB0aGlzIGNvbmNlcm5zIGlzIG5vdCBlbm91Z2guCgpXZSBz aG91bGQgbWFrZSBzdXJlIHRoYXQgdGhpcyBjaGFuZ2UgZG9lc24ndCByZWdyZXNzIHRoZSBjdXJy ZW50CnBlcmZvcm1hbmNlIG9mIGZhc3Qgc3RvcmFnZSBiYWNrZW5kcywgYW5kIGhlbmNlIEkgaGF2 ZSB0byBhc2sgeW91IHRvCnRlc3Qgd2l0aCBudWxsX2JsayBvciBhIGZhc3Qgc3RvcmFnZSBhbmQg cHJvdmlkZSB0aGUgZmlndXJlcy4KCj4gPiAKPiA+ID4gSSB0aGluayB0aGlzIGlzIGR1ZSB0byB0 aGUgc2xvdyBzcGVlZCBvZiB0aGUgSS9PLiAgSW4KPiA+ID4gb3RoZXIgd29yZHMsIHRoZSBhZGRp dGlvbmFsIHBhZ2UgYWxsb2NhdGlvbiBvdmVyaGVhZCBpcyBoaWRkZW4gdW5kZXIgdGhlCj4gPiA+ IG11Y2ggc2xvd2VyIEkvTyBsYXRlbmN5Lgo+ID4gPiAKPiA+ID4gTmV2ZXJ0aGVsZXNzLCBwbGVh c2V0IG5vdGUgdGhhdCB0aGlzIGlzIGp1c3QgYSB2ZXJ5IHNpbXBsZSBhbmQgbWluaW1hbAo+ID4g PiB0ZXN0Lgo+ID4gCj4gPiBJIHdvdWxkIGxpa2UgdG8gYWRkIHRoYXQgSU1PIHRoaXMgaXMgcGFw ZXJpbmcgb3ZlciBhbiBleGlzdGluZyBpc3N1ZSwKPiA+IHdoaWNoIGlzIGhvdyBwYWdlcyB0byBi ZSB1c2VkIHRvIG1hcCBncmFudHMgYXJlIGFsbG9jYXRlZC4gR3JhbnQKPiA+IG1hcHBpbmdzIF9z aG91bGRuJ3RfIGNvbnN1bWUgUkFNIHBhZ2VzIGluIHRoZSBmaXJzdCBwbGFjZSwgYW5kIElJUkMK PiA+IHRoZSBmYWN0IHRoYXQgdGhleSBkbyBpcyBiZWNhdXNlIExpbnV4IGJhbGxvb25zIG91dCBt ZW1vcnkgaW4gb3JkZXIgdG8KPiA+IHJlLXVzZSB0aG9zZSBwYWdlcyB0byBtYXAgZ3JhbnRzIGFu ZCBoYXZlIGEgdmFsaWQgcGFnZSBzdHJ1Y3QuCj4gPiAKPiA+IEEgd2F5IHRvIHNvbHZlIHRoaXMg d291bGQgYmUgdG8gaG90cGx1ZyBhIGZha2UgbWVtb3J5IHJlZ2lvbiBhbmQgdXNlCj4gPiBpdCBp biBvcmRlciB0byBtYXAgZ3JhbnQgcGFnZXMsIHdpdGhvdXQgaGF2aW5nIHRvIGJhbGxvb24gb3V0 IFJBTQo+ID4gcmVnaW9ucy4gQXQgdGhlIGVuZCBvZiBkYXkgb24gYSBQViBkb21haW4gbWFwcGlu ZyBhIGdyYW50IHNob3VsZCBqdXN0Cj4gPiByZXF1aXJlIHZpcnR1YWwgYWRkcmVzcyBzcGFjZS4K PiA+IAo+ID4gVGhpcyBpcyBnb2luZyB0byBnZXQgZXZlbiB3b3JzZSBmb3IgUFZIIHRoYXQgcmVx dWlyZXMgYSBwaHlzaWNhbCBtZW1vcnkKPiA+IGFkZHJlc3MgaW4gb3JkZXIgdG8gbWFwIGEgZ3Jh bnQsIGJ1dCB0aGF0J3MgYW5vdGhlciBzdG9yeS4KPiAKPiBZZXMsIGFzIFBhdWwgYWxzbyBwb2lu dGVkIG91dCBhbmQgc3VnZ2VzdGVkLCB3ZSBzaG91bGQgY29uc2lkZXIgYSBzdHJ1Y3R1cmFsCj4g c29sdXRpb24gaW4gYSBiaWcgcGljdHVyZS4gIFVudGlsIHRoZSBiaWcgY2hhbmdlIGlzIHJlYWR5 LCB0aGlzIHNpbXBsZSBzb2x1dGlvbgo+IHdvdWxkIHdvcmsgYXMgYSBwb2ludCBmaXguCgpHZXR0 aW5nIGEgcHJvcGVyIHNvbHV0aW9uIHdvdWxkIGJlIG15IHByZWZlcmVuY2UsIGluIHRoZSBtZWFu IHRpbWUgSQpndWVzcyBpdCdzIGZpbmUgdG8gYWNjZXB0IHN1Y2ggYSBib2RnZSwgYXMgaXQncyBw cmV0dHkgc21hbGwgYW5kCm5vbi1pbnRydXNpdmUuCgpUaGFua3MsIFJvZ2VyLgoKX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVsIG1haWxpbmcg bGlzdApYZW4tZGV2ZWxAbGlzdHMueGVucHJvamVjdC5vcmcKaHR0cHM6Ly9saXN0cy54ZW5wcm9q ZWN0Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL3hlbi1kZXZlbA==