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=-0.9 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 71C76C3A5A9 for ; Mon, 4 May 2020 14:28:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 47D562075B for ; Mon, 4 May 2020 14:28:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="J3RmePcR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729018AbgEDO2y (ORCPT ); Mon, 4 May 2020 10:28:54 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:47696 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728641AbgEDO2y (ORCPT ); Mon, 4 May 2020 10:28:54 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 044EHbo1063496; Mon, 4 May 2020 14:18:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=content-type : mime-version : subject : from : in-reply-to : date : cc : content-transfer-encoding : message-id : references : to; s=corp-2020-01-29; bh=94tGbpbZfrGPx3PEjMKqajez4HYY6/WnYiRMTWfEfxw=; b=J3RmePcR8ShrP9iW8ROqyeXm145NYHpekoIbMSM0ekGOLfQtOEQ9ulAhaiGKtTVU0IMz iXxjbhxvn6qw003ElQAWZ9WP3F8Vw+Vy4VkO4kmXsMnzQFNNV1SrB2VbUcpEwQqZgIaw J+O/3cKNbFh3/CTBRhm90ZSjP+U8dECBFINzMOWqhMCeajnrd8mWsRBQxkUnta0uPHDd NYaoSF4UpCOWgSeKdPJ08KijlEwwtdUI9iDA3NuCXd+aD6iR6quaXFlRAgowHt/vprhP GSxUJlILuylz/MHb4/Fz3jSbnsQ8gn9/KQ1onFL9+flK+ht+2anuRncWCAYMZGzMw7Md 0A== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2130.oracle.com with ESMTP id 30s09qy6kp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 04 May 2020 14:18:10 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 044E5Vqi062768; Mon, 4 May 2020 14:18:09 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserp3020.oracle.com with ESMTP id 30sjnasb8u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 04 May 2020 14:18:09 +0000 Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id 044EHxd0000815; Mon, 4 May 2020 14:17:59 GMT Received: from [192.168.0.159] (/108.20.144.72) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 04 May 2020 07:17:59 -0700 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: [PATCH v10 0/5] Add NUMA-awareness to qspinlock From: Alex Kogan In-Reply-To: <20200403205930.1707-1-alex.kogan@oracle.com> Date: Mon, 4 May 2020 10:17:56 -0400 Cc: linux@armlinux.org.uk, Ingo Molnar , Will Deacon , Arnd Bergmann , linux-arch@vger.kernel.org, linux-arm-kernel , linux-kernel@vger.kernel.org, Thomas Gleixner , Borislav Petkov , hpa@zytor.com, x86@kernel.org, Hanjun Guo , Jan Glauber , Steven Sistare , Daniel Jordan , dave.dice@oracle.com, Alex Kogan Content-Transfer-Encoding: quoted-printable Message-Id: <6DE89034-0388-4F62-A75D-898EE53D45A7@oracle.com> References: <20200403205930.1707-1-alex.kogan@oracle.com> To: Peter Zijlstra , Waiman Long X-Mailer: Apple Mail (2.3445.104.11) X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9610 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 adultscore=0 phishscore=0 mlxlogscore=999 bulkscore=0 malwarescore=0 spamscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005040118 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9610 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 spamscore=0 adultscore=0 clxscore=1011 suspectscore=0 priorityscore=1501 malwarescore=0 mlxlogscore=999 phishscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005040118 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Peter, Longman (and everyone on this list), Hope you are doing well. I was wondering whether you have had a chance to review this series, and have any further comments. Thanks, =E2=80=94 Alex > On Apr 3, 2020, at 4:59 PM, Alex Kogan wrote: >=20 > Changes from v9: > ---------------- >=20 > - Revise the series based on Peter's version, adopting names, style, = etc. >=20 > - Add a new patch that allows to prioritize certain threads (e.g., in=20= > irq and nmi contexts) and avoids moving them between waiting queues, > based on the suggestion by Longman. >=20 > - Drop the shuffle reduction optimization from the series (new = performance > data did not justify it). >=20 > - Do not call cna_init_nodes() as an early_initcall (call it from=20 > cna_configure_spin_lock_slowpath() instead), based on the comment from=20= > Longman. >=20 >=20 > Summary > ------- >=20 > Lock throughput can be increased by handing a lock to a waiter on the > same NUMA node as the lock holder, provided care is taken to avoid > starvation of waiters on other NUMA nodes. This patch introduces CNA > (compact NUMA-aware lock) as the slow path for qspinlock. It is > enabled through a configuration option (NUMA_AWARE_SPINLOCKS). >=20 > CNA is a NUMA-aware version of the MCS lock. Spinning threads are > organized in two queues, a primary queue for threads running on the = same > node as the current lock holder, and a secondary queue for threads > running on other nodes. Threads store the ID of the node on which > they are running in their queue nodes. After acquiring the MCS lock = and > before acquiring the spinlock, the lock holder scans the primary queue > looking for a thread running on the same node (pre-scan). If found = (call > it thread T), all threads in the primary queue between the current = lock > holder and T are moved to the end of the secondary queue. If such T > is not found, we make another scan of the primary queue after = acquiring=20 > the spinlock when unlocking the MCS lock (post-scan), starting at the > node where pre-scan stopped. If both scans fail to find such T, the > MCS lock is passed to the first thread in the secondary queue. If the > secondary queue is empty, the MCS lock is passed to the next thread in = the > primary queue. To avoid starvation of threads in the secondary queue, = those > threads are moved back to the head of the primary queue after a = certain > number of intra-node lock hand-offs. Lastly, certain threads (e.g., in > in irq and nmi contexts) are given a preferential treatment -- the = scan > stops when such a thread is found, effectively never moving those = threads=20 > into the secondary queue. >=20 > More details are available at https://arxiv.org/abs/1810.05600. >=20 > We have done some performance evaluation with the locktorture module > as well as with several benchmarks from the will-it-scale repo. > The following locktorture results are from an Oracle X5-4 server > (four Intel Xeon E7-8895 v3 @ 2.60GHz sockets with 18 hyperthreaded > cores each). Each number represents an average (over 25 runs) of the > total number of ops (x10^7) reported at the end of each run. The=20 > standard deviation is also reported in (), and in general is about 3% > from the average. The 'stock' kernel is v5.6.0-rc6, > commit 5ad0ec0b8652, compiled in the default configuration.=20 > 'patch-CNA' is the modified kernel with NUMA_AWARE_SPINLOCKS set;=20 > the speedup is calculated dividing 'patch-CNA' by 'stock'. >=20 > #thr stock patch-CNA speedup (patch-CNA/stock) > 1 2.702 (0.100) 2.712 (0.122) 1.003 > 2 3.691 (0.162) 3.672 (0.138) 0.995 > 4 4.285 (0.108) 4.256 (0.124) 0.993 > 8 5.117 (0.133) 5.972 (0.258) 1.167 > 16 6.273 (0.196) 7.628 (0.274) 1.216 > 32 6.757 (0.122) 8.544 (0.225) 1.264 > 36 6.761 (0.091) 8.691 (0.170) 1.285 > 72 6.569 (0.132) 9.280 (0.225) 1.413 > 108 6.167 (0.112) 9.410 (0.171) 1.526 > 142 5.901 (0.117) 9.415 (0.211) 1.595 >=20 > The following tables contain throughput results (ops/us) from the same > setup for will-it-scale/open1_threads:=20 >=20 > #thr stock patch-CNA speedup (patch-CNA/stock) > 1 0.511 (0.002) 0.525 (0.003) 1.027 > 2 0.774 (0.018) 0.769 (0.017) 0.993 > 4 1.352 (0.023) 1.372 (0.032) 1.014 > 8 1.675 (0.090) 1.660 (0.136) 0.991 > 16 1.665 (0.114) 1.583 (0.092) 0.951 > 32 0.966 (0.038) 1.637 (0.087) 1.694 > 36 0.973 (0.066) 1.570 (0.081) 1.613 > 72 0.844 (0.040) 1.620 (0.091) 1.919 > 108 0.836 (0.040) 1.670 (0.084) 1.999 > 142 0.799 (0.043) 1.699 (0.087) 2.127 >=20 > and will-it-scale/lock2_threads: >=20 > #thr stock patch-CNA speedup (patch-CNA/stock) > 1 1.581 (0.004) 1.576 (0.007) 0.997 > 2 2.699 (0.059) 2.687 (0.067) 0.996 > 4 5.240 (0.234) 5.155 (0.252) 0.984 > 8 4.370 (0.241) 4.111 (0.342) 0.941 > 16 4.152 (0.112) 4.113 (0.164) 0.991 > 32 2.579 (0.099) 4.099 (0.127) 1.589 > 36 2.604 (0.066) 4.005 (0.104) 1.538 > 72 2.028 (0.091) 4.024 (0.112) 1.984 > 108 2.079 (0.106) 3.997 (0.093) 1.923 > 142 1.858 (0.103) 3.955 (0.109) 2.129 >=20 > Our evaluation shows that CNA also improves performance of user=20 > applications that have hot pthread mutexes. Those mutexes are=20 > blocking, and waiting threads park and unpark via the futex=20 > mechanism in the kernel. Given that kernel futex chains, which > are hashed by the mutex address, are each protected by a=20 > chain-specific spin lock, the contention on a user-mode mutex=20 > translates into contention on a kernel level spinlock.=20 >=20 > Here are the results for the leveldb =E2=80=98readrandom=E2=80=99 = benchmark: >=20 > #thr stock patch-CNA speedup (patch-CNA/stock) > 1 0.530 (0.013) 0.533 (0.011) 1.006 > 2 0.839 (0.043) 0.847 (0.031) 1.010 > 4 0.758 (0.021) 0.764 (0.018) 1.008 > 8 0.677 (0.022) 0.682 (0.016) 1.008 > 16 0.714 (0.023) 0.814 (0.027) 1.140 > 32 0.765 (0.040) 1.168 (0.032) 1.527 > 36 0.706 (0.023) 1.139 (0.066) 1.614 > 72 0.624 (0.017) 1.184 (0.026) 1.898 > 108 0.605 (0.013) 1.147 (0.023) 1.894 > 142 0.593 (0.012) 1.131 (0.019) 1.908 >=20 > Further comments are welcome and appreciated. >=20 > Alex Kogan (5): > locking/qspinlock: Rename mcs lock/unlock macros and make them more > generic > locking/qspinlock: Refactor the qspinlock slow path > locking/qspinlock: Introduce CNA into the slow path of qspinlock > locking/qspinlock: Introduce starvation avoidance into CNA > locking/qspinlock: Avoid moving certain threads between waiting = queues > in CNA >=20 > .../admin-guide/kernel-parameters.txt | 18 + > arch/arm/include/asm/mcs_spinlock.h | 6 +- > arch/x86/Kconfig | 20 + > arch/x86/include/asm/qspinlock.h | 6 + > arch/x86/kernel/alternative.c | 2 + > include/asm-generic/mcs_spinlock.h | 4 +- > kernel/locking/mcs_spinlock.h | 20 +- > kernel/locking/qspinlock.c | 82 +++- > kernel/locking/qspinlock_cna.h | 407 ++++++++++++++++++ > kernel/locking/qspinlock_paravirt.h | 2 +- > 10 files changed, 544 insertions(+), 23 deletions(-) > create mode 100644 kernel/locking/qspinlock_cna.h >=20 > --=20 > 2.21.1 (Apple Git-122.3) >=20 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Kogan Subject: Re: [PATCH v10 0/5] Add NUMA-awareness to qspinlock Date: Mon, 4 May 2020 10:17:56 -0400 Message-ID: <6DE89034-0388-4F62-A75D-898EE53D45A7@oracle.com> References: <20200403205930.1707-1-alex.kogan@oracle.com> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20200403205930.1707-1-alex.kogan@oracle.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane-mx.org@lists.infradead.org To: Peter Zijlstra , Waiman Long Cc: linux-arch@vger.kernel.org, Hanjun Guo , Arnd Bergmann , dave.dice@oracle.com, Jan Glauber , x86@kernel.org, Will Deacon , linux@armlinux.org.uk, linux-kernel@vger.kernel.org, Ingo Molnar , Borislav Petkov , hpa@zytor.com, Alex Kogan , Steven Sistare , Thomas Gleixner , Daniel Jordan , linux-arm-kernel List-Id: linux-arch.vger.kernel.org SGksIFBldGVyLCBMb25nbWFuIChhbmQgZXZlcnlvbmUgb24gdGhpcyBsaXN0KSwKCkhvcGUgeW91 IGFyZSBkb2luZyB3ZWxsLgoKSSB3YXMgd29uZGVyaW5nIHdoZXRoZXIgeW91IGhhdmUgaGFkIGEg Y2hhbmNlIHRvIHJldmlldyB0aGlzIHNlcmllcywKYW5kIGhhdmUgYW55IGZ1cnRoZXIgY29tbWVu dHMuCgpUaGFua3MsCuKAlCBBbGV4Cgo+IE9uIEFwciAzLCAyMDIwLCBhdCA0OjU5IFBNLCBBbGV4 IEtvZ2FuIDxhbGV4LmtvZ2FuQG9yYWNsZS5jb20+IHdyb3RlOgo+IAo+IENoYW5nZXMgZnJvbSB2 OToKPiAtLS0tLS0tLS0tLS0tLS0tCj4gCj4gLSBSZXZpc2UgdGhlIHNlcmllcyBiYXNlZCBvbiBQ ZXRlcidzIHZlcnNpb24sIGFkb3B0aW5nIG5hbWVzLCBzdHlsZSwgZXRjLgo+IAo+IC0gQWRkIGEg bmV3IHBhdGNoIHRoYXQgYWxsb3dzIHRvIHByaW9yaXRpemUgY2VydGFpbiB0aHJlYWRzIChlLmcu LCBpbiAKPiBpcnEgYW5kIG5taSBjb250ZXh0cykgYW5kIGF2b2lkcyBtb3ZpbmcgdGhlbSBiZXR3 ZWVuIHdhaXRpbmcgcXVldWVzLAo+IGJhc2VkIG9uIHRoZSBzdWdnZXN0aW9uIGJ5IExvbmdtYW4u Cj4gCj4gLSBEcm9wIHRoZSBzaHVmZmxlIHJlZHVjdGlvbiBvcHRpbWl6YXRpb24gZnJvbSB0aGUg c2VyaWVzIChuZXcgcGVyZm9ybWFuY2UKPiBkYXRhIGRpZCBub3QganVzdGlmeSBpdCkuCj4gCj4g LSBEbyBub3QgY2FsbCBjbmFfaW5pdF9ub2RlcygpIGFzIGFuIGVhcmx5X2luaXRjYWxsIChjYWxs IGl0IGZyb20gCj4gY25hX2NvbmZpZ3VyZV9zcGluX2xvY2tfc2xvd3BhdGgoKSBpbnN0ZWFkKSwg YmFzZWQgb24gdGhlIGNvbW1lbnQgZnJvbSAKPiBMb25nbWFuLgo+IAo+IAo+IFN1bW1hcnkKPiAt LS0tLS0tCj4gCj4gTG9jayB0aHJvdWdocHV0IGNhbiBiZSBpbmNyZWFzZWQgYnkgaGFuZGluZyBh IGxvY2sgdG8gYSB3YWl0ZXIgb24gdGhlCj4gc2FtZSBOVU1BIG5vZGUgYXMgdGhlIGxvY2sgaG9s ZGVyLCBwcm92aWRlZCBjYXJlIGlzIHRha2VuIHRvIGF2b2lkCj4gc3RhcnZhdGlvbiBvZiB3YWl0 ZXJzIG9uIG90aGVyIE5VTUEgbm9kZXMuIFRoaXMgcGF0Y2ggaW50cm9kdWNlcyBDTkEKPiAoY29t cGFjdCBOVU1BLWF3YXJlIGxvY2spIGFzIHRoZSBzbG93IHBhdGggZm9yIHFzcGlubG9jay4gSXQg aXMKPiBlbmFibGVkIHRocm91Z2ggYSBjb25maWd1cmF0aW9uIG9wdGlvbiAoTlVNQV9BV0FSRV9T UElOTE9DS1MpLgo+IAo+IENOQSBpcyBhIE5VTUEtYXdhcmUgdmVyc2lvbiBvZiB0aGUgTUNTIGxv Y2suIFNwaW5uaW5nIHRocmVhZHMgYXJlCj4gb3JnYW5pemVkIGluIHR3byBxdWV1ZXMsIGEgcHJp bWFyeSBxdWV1ZSBmb3IgdGhyZWFkcyBydW5uaW5nIG9uIHRoZSBzYW1lCj4gbm9kZSBhcyB0aGUg Y3VycmVudCBsb2NrIGhvbGRlciwgYW5kIGEgc2Vjb25kYXJ5IHF1ZXVlIGZvciB0aHJlYWRzCj4g cnVubmluZyBvbiBvdGhlciBub2Rlcy4gVGhyZWFkcyBzdG9yZSB0aGUgSUQgb2YgdGhlIG5vZGUg b24gd2hpY2gKPiB0aGV5IGFyZSBydW5uaW5nIGluIHRoZWlyIHF1ZXVlIG5vZGVzLiBBZnRlciBh Y3F1aXJpbmcgdGhlIE1DUyBsb2NrIGFuZAo+IGJlZm9yZSBhY3F1aXJpbmcgdGhlIHNwaW5sb2Nr LCB0aGUgbG9jayBob2xkZXIgc2NhbnMgdGhlIHByaW1hcnkgcXVldWUKPiBsb29raW5nIGZvciBh IHRocmVhZCBydW5uaW5nIG9uIHRoZSBzYW1lIG5vZGUgKHByZS1zY2FuKS4gSWYgZm91bmQgKGNh bGwKPiBpdCB0aHJlYWQgVCksIGFsbCB0aHJlYWRzIGluIHRoZSBwcmltYXJ5IHF1ZXVlIGJldHdl ZW4gdGhlIGN1cnJlbnQgbG9jawo+IGhvbGRlciBhbmQgVCBhcmUgbW92ZWQgdG8gdGhlIGVuZCBv ZiB0aGUgc2Vjb25kYXJ5IHF1ZXVlLiAgSWYgc3VjaCBUCj4gaXMgbm90IGZvdW5kLCB3ZSBtYWtl IGFub3RoZXIgc2NhbiBvZiB0aGUgcHJpbWFyeSBxdWV1ZSBhZnRlciBhY3F1aXJpbmcgCj4gdGhl IHNwaW5sb2NrIHdoZW4gdW5sb2NraW5nIHRoZSBNQ1MgbG9jayAocG9zdC1zY2FuKSwgc3RhcnRp bmcgYXQgdGhlCj4gbm9kZSB3aGVyZSBwcmUtc2NhbiBzdG9wcGVkLiBJZiBib3RoIHNjYW5zIGZh aWwgdG8gZmluZCBzdWNoIFQsIHRoZQo+IE1DUyBsb2NrIGlzIHBhc3NlZCB0byB0aGUgZmlyc3Qg dGhyZWFkIGluIHRoZSBzZWNvbmRhcnkgcXVldWUuIElmIHRoZQo+IHNlY29uZGFyeSBxdWV1ZSBp cyBlbXB0eSwgdGhlIE1DUyBsb2NrIGlzIHBhc3NlZCB0byB0aGUgbmV4dCB0aHJlYWQgaW4gdGhl Cj4gcHJpbWFyeSBxdWV1ZS4gVG8gYXZvaWQgc3RhcnZhdGlvbiBvZiB0aHJlYWRzIGluIHRoZSBz ZWNvbmRhcnkgcXVldWUsIHRob3NlCj4gdGhyZWFkcyBhcmUgbW92ZWQgYmFjayB0byB0aGUgaGVh ZCBvZiB0aGUgcHJpbWFyeSBxdWV1ZSBhZnRlciBhIGNlcnRhaW4KPiBudW1iZXIgb2YgaW50cmEt bm9kZSBsb2NrIGhhbmQtb2Zmcy4gTGFzdGx5LCBjZXJ0YWluIHRocmVhZHMgKGUuZy4sIGluCj4g aW4gaXJxIGFuZCBubWkgY29udGV4dHMpIGFyZSBnaXZlbiBhIHByZWZlcmVudGlhbCB0cmVhdG1l bnQgLS0gdGhlIHNjYW4KPiBzdG9wcyB3aGVuIHN1Y2ggYSB0aHJlYWQgaXMgZm91bmQsIGVmZmVj dGl2ZWx5IG5ldmVyIG1vdmluZyB0aG9zZSB0aHJlYWRzIAo+IGludG8gdGhlIHNlY29uZGFyeSBx dWV1ZS4KPiAKPiBNb3JlIGRldGFpbHMgYXJlIGF2YWlsYWJsZSBhdCBodHRwczovL2FyeGl2Lm9y Zy9hYnMvMTgxMC4wNTYwMC4KPiAKPiBXZSBoYXZlIGRvbmUgc29tZSBwZXJmb3JtYW5jZSBldmFs dWF0aW9uIHdpdGggdGhlIGxvY2t0b3J0dXJlIG1vZHVsZQo+IGFzIHdlbGwgYXMgd2l0aCBzZXZl cmFsIGJlbmNobWFya3MgZnJvbSB0aGUgd2lsbC1pdC1zY2FsZSByZXBvLgo+IFRoZSBmb2xsb3dp bmcgbG9ja3RvcnR1cmUgcmVzdWx0cyBhcmUgZnJvbSBhbiBPcmFjbGUgWDUtNCBzZXJ2ZXIKPiAo Zm91ciBJbnRlbCBYZW9uIEU3LTg4OTUgdjMgQCAyLjYwR0h6IHNvY2tldHMgd2l0aCAxOCBoeXBl cnRocmVhZGVkCj4gY29yZXMgZWFjaCkuIEVhY2ggbnVtYmVyIHJlcHJlc2VudHMgYW4gYXZlcmFn ZSAob3ZlciAyNSBydW5zKSBvZiB0aGUKPiB0b3RhbCBudW1iZXIgb2Ygb3BzICh4MTBeNykgcmVw b3J0ZWQgYXQgdGhlIGVuZCBvZiBlYWNoIHJ1bi4gVGhlIAo+IHN0YW5kYXJkIGRldmlhdGlvbiBp cyBhbHNvIHJlcG9ydGVkIGluICgpLCBhbmQgaW4gZ2VuZXJhbCBpcyBhYm91dCAzJQo+IGZyb20g dGhlIGF2ZXJhZ2UuIFRoZSAnc3RvY2snIGtlcm5lbCBpcyB2NS42LjAtcmM2LAo+IGNvbW1pdCA1 YWQwZWMwYjg2NTIsIGNvbXBpbGVkIGluIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uIAo+ICdw YXRjaC1DTkEnIGlzIHRoZSBtb2RpZmllZCBrZXJuZWwgd2l0aCBOVU1BX0FXQVJFX1NQSU5MT0NL UyBzZXQ7IAo+IHRoZSBzcGVlZHVwIGlzIGNhbGN1bGF0ZWQgZGl2aWRpbmcgJ3BhdGNoLUNOQScg YnkgJ3N0b2NrJy4KPiAKPiAjdGhyICAJIHN0b2NrICAgICAgICBwYXRjaC1DTkEgICBzcGVlZHVw IChwYXRjaC1DTkEvc3RvY2spCj4gIDEgIDIuNzAyICgwLjEwMCkgIDIuNzEyICgwLjEyMikgIDEu MDAzCj4gIDIgIDMuNjkxICgwLjE2MikgIDMuNjcyICgwLjEzOCkgIDAuOTk1Cj4gIDQgIDQuMjg1 ICgwLjEwOCkgIDQuMjU2ICgwLjEyNCkgIDAuOTkzCj4gIDggIDUuMTE3ICgwLjEzMykgIDUuOTcy ICgwLjI1OCkgIDEuMTY3Cj4gMTYgIDYuMjczICgwLjE5NikgIDcuNjI4ICgwLjI3NCkgIDEuMjE2 Cj4gMzIgIDYuNzU3ICgwLjEyMikgIDguNTQ0ICgwLjIyNSkgIDEuMjY0Cj4gMzYgIDYuNzYxICgw LjA5MSkgIDguNjkxICgwLjE3MCkgIDEuMjg1Cj4gNzIgIDYuNTY5ICgwLjEzMikgIDkuMjgwICgw LjIyNSkgIDEuNDEzCj4gMTA4ICA2LjE2NyAoMC4xMTIpICA5LjQxMCAoMC4xNzEpICAxLjUyNgo+ IDE0MiAgNS45MDEgKDAuMTE3KSAgOS40MTUgKDAuMjExKSAgMS41OTUKPiAKPiBUaGUgZm9sbG93 aW5nIHRhYmxlcyBjb250YWluIHRocm91Z2hwdXQgcmVzdWx0cyAob3BzL3VzKSBmcm9tIHRoZSBz YW1lCj4gc2V0dXAgZm9yIHdpbGwtaXQtc2NhbGUvb3BlbjFfdGhyZWFkczogCj4gCj4gI3RociAg CSBzdG9jayAgICAgICAgcGF0Y2gtQ05BICAgc3BlZWR1cCAocGF0Y2gtQ05BL3N0b2NrKQo+ICAx ICAwLjUxMSAoMC4wMDIpICAwLjUyNSAoMC4wMDMpICAxLjAyNwo+ICAyICAwLjc3NCAoMC4wMTgp ICAwLjc2OSAoMC4wMTcpICAwLjk5Mwo+ICA0ICAxLjM1MiAoMC4wMjMpICAxLjM3MiAoMC4wMzIp ICAxLjAxNAo+ICA4ICAxLjY3NSAoMC4wOTApICAxLjY2MCAoMC4xMzYpICAwLjk5MQo+IDE2ICAx LjY2NSAoMC4xMTQpICAxLjU4MyAoMC4wOTIpICAwLjk1MQo+IDMyICAwLjk2NiAoMC4wMzgpICAx LjYzNyAoMC4wODcpICAxLjY5NAo+IDM2ICAwLjk3MyAoMC4wNjYpICAxLjU3MCAoMC4wODEpICAx LjYxMwo+IDcyICAwLjg0NCAoMC4wNDApICAxLjYyMCAoMC4wOTEpICAxLjkxOQo+IDEwOCAgMC44 MzYgKDAuMDQwKSAgMS42NzAgKDAuMDg0KSAgMS45OTkKPiAxNDIgIDAuNzk5ICgwLjA0MykgIDEu Njk5ICgwLjA4NykgIDIuMTI3Cj4gCj4gYW5kIHdpbGwtaXQtc2NhbGUvbG9jazJfdGhyZWFkczoK PiAKPiAjdGhyICAJIHN0b2NrICAgICAgICBwYXRjaC1DTkEgICBzcGVlZHVwIChwYXRjaC1DTkEv c3RvY2spCj4gIDEgIDEuNTgxICgwLjAwNCkgIDEuNTc2ICgwLjAwNykgIDAuOTk3Cj4gIDIgIDIu Njk5ICgwLjA1OSkgIDIuNjg3ICgwLjA2NykgIDAuOTk2Cj4gIDQgIDUuMjQwICgwLjIzNCkgIDUu MTU1ICgwLjI1MikgIDAuOTg0Cj4gIDggIDQuMzcwICgwLjI0MSkgIDQuMTExICgwLjM0MikgIDAu OTQxCj4gMTYgIDQuMTUyICgwLjExMikgIDQuMTEzICgwLjE2NCkgIDAuOTkxCj4gMzIgIDIuNTc5 ICgwLjA5OSkgIDQuMDk5ICgwLjEyNykgIDEuNTg5Cj4gMzYgIDIuNjA0ICgwLjA2NikgIDQuMDA1 ICgwLjEwNCkgIDEuNTM4Cj4gNzIgIDIuMDI4ICgwLjA5MSkgIDQuMDI0ICgwLjExMikgIDEuOTg0 Cj4gMTA4ICAyLjA3OSAoMC4xMDYpICAzLjk5NyAoMC4wOTMpICAxLjkyMwo+IDE0MiAgMS44NTgg KDAuMTAzKSAgMy45NTUgKDAuMTA5KSAgMi4xMjkKPiAKPiBPdXIgZXZhbHVhdGlvbiBzaG93cyB0 aGF0IENOQSBhbHNvIGltcHJvdmVzIHBlcmZvcm1hbmNlIG9mIHVzZXIgCj4gYXBwbGljYXRpb25z IHRoYXQgaGF2ZSBob3QgcHRocmVhZCBtdXRleGVzLiBUaG9zZSBtdXRleGVzIGFyZSAKPiBibG9j a2luZywgYW5kIHdhaXRpbmcgdGhyZWFkcyBwYXJrIGFuZCB1bnBhcmsgdmlhIHRoZSBmdXRleCAK PiBtZWNoYW5pc20gaW4gdGhlIGtlcm5lbC4gR2l2ZW4gdGhhdCBrZXJuZWwgZnV0ZXggY2hhaW5z LCB3aGljaAo+IGFyZSBoYXNoZWQgYnkgdGhlIG11dGV4IGFkZHJlc3MsIGFyZSBlYWNoIHByb3Rl Y3RlZCBieSBhIAo+IGNoYWluLXNwZWNpZmljIHNwaW4gbG9jaywgdGhlIGNvbnRlbnRpb24gb24g YSB1c2VyLW1vZGUgbXV0ZXggCj4gdHJhbnNsYXRlcyBpbnRvIGNvbnRlbnRpb24gb24gYSBrZXJu ZWwgbGV2ZWwgc3BpbmxvY2suIAo+IAo+IEhlcmUgYXJlIHRoZSByZXN1bHRzIGZvciB0aGUgbGV2 ZWxkYiDigJhyZWFkcmFuZG9t4oCZIGJlbmNobWFyazoKPiAKPiAjdGhyICAJIHN0b2NrICAgICAg ICBwYXRjaC1DTkEgICBzcGVlZHVwIChwYXRjaC1DTkEvc3RvY2spCj4gIDEgIDAuNTMwICgwLjAx MykgIDAuNTMzICgwLjAxMSkgIDEuMDA2Cj4gIDIgIDAuODM5ICgwLjA0MykgIDAuODQ3ICgwLjAz MSkgIDEuMDEwCj4gIDQgIDAuNzU4ICgwLjAyMSkgIDAuNzY0ICgwLjAxOCkgIDEuMDA4Cj4gIDgg IDAuNjc3ICgwLjAyMikgIDAuNjgyICgwLjAxNikgIDEuMDA4Cj4gMTYgIDAuNzE0ICgwLjAyMykg IDAuODE0ICgwLjAyNykgIDEuMTQwCj4gMzIgIDAuNzY1ICgwLjA0MCkgIDEuMTY4ICgwLjAzMikg IDEuNTI3Cj4gMzYgIDAuNzA2ICgwLjAyMykgIDEuMTM5ICgwLjA2NikgIDEuNjE0Cj4gNzIgIDAu NjI0ICgwLjAxNykgIDEuMTg0ICgwLjAyNikgIDEuODk4Cj4gMTA4ICAwLjYwNSAoMC4wMTMpICAx LjE0NyAoMC4wMjMpICAxLjg5NAo+IDE0MiAgMC41OTMgKDAuMDEyKSAgMS4xMzEgKDAuMDE5KSAg MS45MDgKPiAKPiBGdXJ0aGVyIGNvbW1lbnRzIGFyZSB3ZWxjb21lIGFuZCBhcHByZWNpYXRlZC4K PiAKPiBBbGV4IEtvZ2FuICg1KToKPiAgbG9ja2luZy9xc3BpbmxvY2s6IFJlbmFtZSBtY3MgbG9j ay91bmxvY2sgbWFjcm9zIGFuZCBtYWtlIHRoZW0gbW9yZQo+ICAgIGdlbmVyaWMKPiAgbG9ja2lu Zy9xc3BpbmxvY2s6IFJlZmFjdG9yIHRoZSBxc3BpbmxvY2sgc2xvdyBwYXRoCj4gIGxvY2tpbmcv cXNwaW5sb2NrOiBJbnRyb2R1Y2UgQ05BIGludG8gdGhlIHNsb3cgcGF0aCBvZiBxc3BpbmxvY2sK PiAgbG9ja2luZy9xc3BpbmxvY2s6IEludHJvZHVjZSBzdGFydmF0aW9uIGF2b2lkYW5jZSBpbnRv IENOQQo+ICBsb2NraW5nL3FzcGlubG9jazogQXZvaWQgbW92aW5nIGNlcnRhaW4gdGhyZWFkcyBi ZXR3ZWVuIHdhaXRpbmcgcXVldWVzCj4gICAgaW4gQ05BCj4gCj4gLi4uL2FkbWluLWd1aWRlL2tl cm5lbC1wYXJhbWV0ZXJzLnR4dCAgICAgICAgIHwgIDE4ICsKPiBhcmNoL2FybS9pbmNsdWRlL2Fz bS9tY3Nfc3BpbmxvY2suaCAgICAgICAgICAgfCAgIDYgKy0KPiBhcmNoL3g4Ni9LY29uZmlnICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgMjAgKwo+IGFyY2gveDg2L2luY2x1ZGUvYXNt L3FzcGlubG9jay5oICAgICAgICAgICAgICB8ICAgNiArCj4gYXJjaC94ODYva2VybmVsL2FsdGVy bmF0aXZlLmMgICAgICAgICAgICAgICAgIHwgICAyICsKPiBpbmNsdWRlL2FzbS1nZW5lcmljL21j c19zcGlubG9jay5oICAgICAgICAgICAgfCAgIDQgKy0KPiBrZXJuZWwvbG9ja2luZy9tY3Nfc3Bp bmxvY2suaCAgICAgICAgICAgICAgICAgfCAgMjAgKy0KPiBrZXJuZWwvbG9ja2luZy9xc3Bpbmxv Y2suYyAgICAgICAgICAgICAgICAgICAgfCAgODIgKysrLQo+IGtlcm5lbC9sb2NraW5nL3FzcGlu bG9ja19jbmEuaCAgICAgICAgICAgICAgICB8IDQwNyArKysrKysrKysrKysrKysrKysKPiBrZXJu ZWwvbG9ja2luZy9xc3BpbmxvY2tfcGFyYXZpcnQuaCAgICAgICAgICAgfCAgIDIgKy0KPiAxMCBm aWxlcyBjaGFuZ2VkLCA1NDQgaW5zZXJ0aW9ucygrKSwgMjMgZGVsZXRpb25zKC0pCj4gY3JlYXRl IG1vZGUgMTAwNjQ0IGtlcm5lbC9sb2NraW5nL3FzcGlubG9ja19jbmEuaAo+IAo+IC0tIAo+IDIu MjEuMSAoQXBwbGUgR2l0LTEyMi4zKQo+IAoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFy bS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9t YWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK