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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECBEEC4332F for ; Sat, 4 Nov 2023 03:44:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233999AbjKDDor (ORCPT ); Fri, 3 Nov 2023 23:44:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233666AbjKDDoq (ORCPT ); Fri, 3 Nov 2023 23:44:46 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7125D187 for ; Fri, 3 Nov 2023 20:43:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1699069436; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S1LrTjRfjBJLKAZKTPJ3e6IBQx9TBLxXp5gJn/UCemk=; b=BmkXAep27o8yWmezOL5z8AUS8FH+EzDwa5Y7kyCGQQ8/CovFZtChW93AwEWI3RHCkTUM0J IEjjOsRJx41+8Mfe8av3o/j9MF1oA/mmYArrQ45uqeoLvxnDmulMkMpPx0NxleFl1UKYKR pttQnrhhaw4rq22GtFa+4ZfgvuDKhRE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-679-uSNpMGNxPwW7gYHyU4CZ-g-1; Fri, 03 Nov 2023 23:43:51 -0400 X-MC-Unique: uSNpMGNxPwW7gYHyU4CZ-g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9A8C282401E; Sat, 4 Nov 2023 03:43:50 +0000 (UTC) Received: from fedora (unknown [10.72.120.13]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 59EFD2166B26; Sat, 4 Nov 2023 03:43:40 +0000 (UTC) Date: Sat, 4 Nov 2023 11:43:36 +0800 From: Ming Lei To: Ed Tsai =?utf-8?B?KOiUoeWul+i7kik=?= Cc: Will Shiu =?utf-8?B?KOioseaBreeRnCk=?= , Peter Wang =?utf-8?B?KOeOi+S/oeWPiyk=?= , "linux-block@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Alice Chao =?utf-8?B?KOi2meePruWdhyk=?= , "linux-mediatek@lists.infradead.org" , wsd_upstream , "axboe@kernel.dk" , Casper Li =?utf-8?B?KOadjuS4reamrik=?= , Chun-Hung Wu =?utf-8?B?KOW3q+mnv+Wujyk=?= , Powen Kao =?utf-8?B?KOmrmOS8r+aWhyk=?= , Naomi Chu =?utf-8?B?KOacseipoOeUsCk=?= , "linux-arm-kernel@lists.infradead.org" , Stanley Chu =?utf-8?B?KOacseWOn+mZnik=?= , "matthias.bgg@gmail.com" , "angelogioacchino.delregno@collabora.com" , ming.lei@redhat.com Subject: Re: [PATCH 1/1] block: Check the queue limit before bio submitting Message-ID: References: <20231025092255.27930-1-ed.tsai@mediatek.com> <64db8f5406571c2f89b70f852eb411320201abe6.camel@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org On Sat, Nov 04, 2023 at 01:11:02AM +0000, Ed Tsai (蔡宗軒) wrote: > On Sat, 2023-11-04 at 00:20 +0800, Ming Lei wrote: > > On Wed, Nov 01, 2023 at 02:23:26AM +0000, Ed Tsai (蔡宗軒) wrote: > > > On Wed, 2023-10-25 at 17:22 +0800, ed.tsai@mediatek.com wrote: > > > > From: Ed Tsai > > > > > > > > Referring to commit 07173c3ec276 ("block: enable multipage > > bvecs"), > > > > each bio_vec now holds more than one page, potentially exceeding > > > > 1MB in size and causing alignment issues with the queue limit. > > > > > > > > In a sequential read/write scenario, the file system maximizes > > the > > > > bio's capacity before submitting. However, misalignment with the > > > > queue limit can result in the bio being split into smaller I/O > > > > operations. > > > > > > > > For instance, assuming the maximum I/O size is set to 512KB and > > the > > > > memory is highly fragmented, resulting in each bio containing > > only > > > > one 2-pages bio_vec (i.e., bi_size = 1028KB). This would cause > > the > > > > bio to be split into two 512KB portions and one 4KB portion. As a > > > > result, the originally expected continuous large I/O operations > > are > > > > interspersed with many small I/O operations. > > > > > > > > To address this issue, this patch adds a check for the > > max_sectors > > > > before submitting the bio. This allows the upper layers to > > > > proactively > > > > detect and handle alignment issues. > > > > > > > > I performed the Antutu V10 Storage Test on a UFS 4.0 device, > > which > > > > resulted in a significant improvement in the Sequential test: > > > > > > > > Sequential Read (average of 5 rounds): > > > > Original: 3033.7 MB/sec > > > > Patched: 3520.9 MB/sec > > > > > > > > Sequential Write (average of 5 rounds): > > > > Original: 2225.4 MB/sec > > > > Patched: 2800.3 MB/sec > > > > > > > > Signed-off-by: Ed Tsai > > > > --- > > > > block/bio.c | 6 ++++++ > > > > 1 file changed, 6 insertions(+) > > > > > > > > diff --git a/block/bio.c b/block/bio.c > > > > index 816d412c06e9..a4a1f775b9ea 100644 > > > > --- a/block/bio.c > > > > +++ b/block/bio.c > > > > @@ -1227,6 +1227,7 @@ static int __bio_iov_iter_get_pages(struct > > bio > > > > *bio, struct iov_iter *iter) > > > > iov_iter_extraction_t extraction_flags = 0; > > > > unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt; > > > > unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt; > > > > +struct queue_limits *lim = &bdev_get_queue(bio->bi_bdev)- > > > > >limits; > > > > struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; > > > > struct page **pages = (struct page **)bv; > > > > ssize_t size, left; > > > > @@ -1275,6 +1276,11 @@ static int __bio_iov_iter_get_pages(struct > > bio > > > > *bio, struct iov_iter *iter) > > > > struct page *page = pages[i]; > > > > > > > > len = min_t(size_t, PAGE_SIZE - offset, left); > > > > +if (bio->bi_iter.bi_size + len > > > > > + lim->max_sectors << SECTOR_SHIFT) { > > > > +ret = left; > > > > +break; > > > > +} > > > > if (bio_op(bio) == REQ_OP_ZONE_APPEND) { > > > > ret = bio_iov_add_zone_append_page(bio, page, > > > > len, > > > > offset); > > > > -- > > > > 2.18.0 > > > > > > > > > > > > > Hi Jens, > > > > > > Just to clarify any potential confusion, I would like to provide > > > further details based on the assumed scenario mentioned above. > > > > > > When the upper layer continuously sends 1028KB full-sized bios for > > > sequential reads, the Block Layer sees the following sequence: > > > submit bio: size = 1028KB, start LBA = n > > > submit bio: size = 1028KB, start LBA = n + 1028KB > > > submit bio: size = 1028KB, start LBA = n + 2056KB > > > ... > > > > > > However, due to the queue limit restricting the I/O size to a > > maximum > > > of 512KB, the Block Layer splits into the following sequence: > > > submit bio: size = 512KB, start LBA = n > > > submit bio: size = 512KB, start LBA = n + 512KB > > > submit bio: size = 4KB, start LBA = n + 1024KB > > > submit bio: size = 512KB, start LBA = n + 1028KB > > > submit bio: size = 512KB, start LBA = n + 1540KB > > > submit bio: size = 4KB, start LBA = n + 2052KB > > > submit bio: size = 512KB, start LBA = n + 2056KB > > > submit bio: size = 512KB, start LBA = n + 2568KB > > > submit bio: size = 4KB, start LBA = n + 3080KB > > > ... > > > > > > The original expectation was for the storage to receive large, > > > contiguous requests. However, due to non-alignment, many small I/O > > > requests are generated. This problem is easily visible because the > > > user pages passed in are often allocated by the buddy system as > > order 0 > > > pages during page faults, resulting in highly non-contiguous > > memory. > > > > If order 0 page is added to bio, the multipage bvec becomes nop > > basically(256bvec holds 256 pages), then how can it make a difference > > for you? > > > > > > > > > > > As observed in the Antutu Sequential Read test below, it is similar > > to > > > the description above where the splitting caused by the queue limit > > > leaves small requests sandwiched in between: > > > > > > block_bio_queue: 8,32 R 86925864 + 2144 [Thread-51] > > > block_split: 8,32 R 86925864 / 86926888 [Thread-51] > > > block_split: 8,32 R 86926888 / 86927912 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86925864 + 1024 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86926888 + 1024 [Thread-51] > > > block_bio_queue: 8,32 R 86928008 + 2144 [Thread-51] > > > block_split: 8,32 R 86928008 / 86929032 [Thread-51] > > > block_split: 8,32 R 86929032 / 86930056 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86928008 + 1024 [Thread-51] > > > block_rq_issue: 8,32 R 49152 () 86927912 + 96 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86929032 + 1024 [Thread-51] > > > block_bio_queue: 8,32 R 86930152 + 2112 [Thread-51] > > > block_split: 8,32 R 86930152 / 86931176 [Thread-51] > > > block_split: 8,32 R 86931176 / 86932200 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86930152 + 1024 [Thread-51] > > > block_rq_issue: 8,32 R 49152 () 86930056 + 96 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86931176 + 1024 [Thread-51] > > > block_bio_queue: 8,32 R 86932264 + 2096 [Thread-51] > > > block_split: 8,32 R 86932264 / 86933288 [Thread-51] > > > block_split: 8,32 R 86933288 / 86934312 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86932264 + 1024 [Thread-51] > > > block_rq_issue: 8,32 R 32768 () 86932200 + 64 [Thread-51] > > > block_rq_issue: 8,32 R 524288 () 86933288 + 1024 [Thread-51] > > > > > > I simply prevents non-aligned situations in bio_iov_iter_get_pages. > > > > But there is still 4KB IO left if you limit max bio size is 512KB, > > then how does this 4KB IO finally go in case of 1028KB IO? > > > > > Besides making the upper layer application aware of the queue > > limit, I > > > would appreciate any other directions or suggestions you may have. > > > > The problem is related with IO size from application. > > > > If you send unaligned IO, you can't avoid the last IO with small > > size, no > > matter if block layer bio split is involved or not. Your patch just > > lets > > __bio_iov_iter_get_pages split the bio, and you still have 4KB left > > finally when application submits 1028KB, right? > > > > Then I don't understand why your patch improves sequential IO > > performance. > > > > Thanks, > > Ming > > > > The application performs I/O with a sufficitenly large I/O size, > causing it to constantly fill up and submit full bios. However, in the > iomap direct I/O scenario, pages are added to the bio one by one from > the user buffer. This typically triggers page faults, resulting in the > allocation of order 0 pages from the buddy system. > > The remaining amount of each order in the buddy system varies over > time. If there are not enough pages available in a particular order, > pages are split from higher orders. When pages are obtained from the > higher order, the user buffer may contain some small consecutive > patterns. > > In summary, the physical layout of the user buffer is unpredictable, > and when it contains some small consecutive patterns, the size of the > bio becomes randomly unaligned during filling. Yes, multipage bvec depends on physical layout of user buffer, but it doesn't affect bio size, which is decided by userspace, and the bvec page layout doesn't affect IO pattern. If userspace submits 1028K IO, the IO is split into 512K, 512K and 4K, no matter if each bvec includes how many pages. If userspace submits very large IO, such as 512M, which will be split into 1K bios with 512K size. You patch doesn't makes any difference actually from block layer viewpoint, such as: 1) dd if=/dev/ublkb0 of=/dev/null bs=1028k count=1 iflag=direct 2) observe IO pattern by the following bpftrace: kprobe:blk_mq_start_request { $rq = (struct request *)arg0; printf("%lu %16s %d %d: %s %s bio %lx-%lu\n", nsecs / 1000, comm, pid, cpu, ksym(reg("ip")), $rq->q->disk->disk_name, $rq->__sector, $rq->__data_len); } 3) no matter if your patch is applied or not, the following pattern is always observed: 117828811 dd 1475 0: blk_mq_start_request ublkb0 bio 0-524288 117828823 dd 1475 0: blk_mq_start_request ublkb0 bio 400-524288 117828825 dd 1475 0: blk_mq_start_request ublkb0 bio 800-4096 Similar pattern can be observed when running dd inside FS(xfs). > > This patch limits the bio to be filled up to the max_sectors. The > submission is an async operation, so once the bio is queued, it will > immediately return and continue filled and submit the next bio. bio split doesn't change this behavior too, the difference is just how many bios the upper layer(iomap) observed. Your patch just moves the split into upper layer, and iomap can see 3 bios with your patch when `dd bs=1028K`, and in vanilla tree, iomap just submits single bio with 1028K, block layer splits it into 512k, 512k, and 4k. So finally UFS driver observes same IO pattern. In short, please root cause why your patch improves performance, or please share your workloads, so we can observe the IO pattern and related mm/fs behavior and try to root cause it. Thanks, Ming 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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ECCD6C4332F for ; Sat, 4 Nov 2023 03:44:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Lztoto1KMRBEqdRkQIy9PcoH5azOZZB2oL6tUDq5es4=; b=JY+/tHi2YCPxkF yLQnQoTkD4pQGhJVr+kUaY3clHxqpNWjDpFS5VzZY1t6XmVGAzWUEMUUqkoO+iLR78Cx1NpsBmJIC I0m1BU1wKx/ufjfH6ok+5UKqHV25oE4TJ4rAuJwtEt1pNFzEDDizUMXCROTFzhcAph31Z6sRYZvgL 8i/JHaMeyzh5yp4D8dDxN9osNHCe4c5mnTFFe+MVB0y54NxtBsbnzC1ST+AyL2toJwd2Z6J4//pyL +2OM3Y5rUa5pHTD23iQMNulNauoKG3tZpOkNkO1wBviekNYHkwUQ4tDou6zDc2ogeZxmb9lmx1rOi 8iH3iA7SyCCUoivnJQfA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qz7Zn-00CZtk-36; Sat, 04 Nov 2023 03:44:00 +0000 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qz7Zk-00CZt6-0z for linux-arm-kernel@lists.infradead.org; Sat, 04 Nov 2023 03:43:58 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1699069435; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S1LrTjRfjBJLKAZKTPJ3e6IBQx9TBLxXp5gJn/UCemk=; b=Zm7MeFP9H+BvCka/Sr56nZta1ozLn4pM1eAbBFcMaJFM0OYPPki0wmumYs6d5/NWYRtM52 cDNUw5AYGhpuVF1ohZ45SwMkXveK+OLGdoaAAT2ZmSMHji876Q2QRUWzDgePeI46wPA+7W LzSRd/ls9yg3Q0YsrzGS2iyDp4GlZHg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-679-uSNpMGNxPwW7gYHyU4CZ-g-1; Fri, 03 Nov 2023 23:43:51 -0400 X-MC-Unique: uSNpMGNxPwW7gYHyU4CZ-g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9A8C282401E; Sat, 4 Nov 2023 03:43:50 +0000 (UTC) Received: from fedora (unknown [10.72.120.13]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 59EFD2166B26; Sat, 4 Nov 2023 03:43:40 +0000 (UTC) Date: Sat, 4 Nov 2023 11:43:36 +0800 From: Ming Lei To: Ed Tsai =?utf-8?B?KOiUoeWul+i7kik=?= Cc: Will Shiu =?utf-8?B?KOioseaBreeRnCk=?= , Peter Wang =?utf-8?B?KOeOi+S/oeWPiyk=?= , "linux-block@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Alice Chao =?utf-8?B?KOi2meePruWdhyk=?= , "linux-mediatek@lists.infradead.org" , wsd_upstream , "axboe@kernel.dk" , Casper Li =?utf-8?B?KOadjuS4reamrik=?= , Chun-Hung Wu =?utf-8?B?KOW3q+mnv+Wujyk=?= , Powen Kao =?utf-8?B?KOmrmOS8r+aWhyk=?= , Naomi Chu =?utf-8?B?KOacseipoOeUsCk=?= , "linux-arm-kernel@lists.infradead.org" , Stanley Chu =?utf-8?B?KOacseWOn+mZnik=?= , "matthias.bgg@gmail.com" , "angelogioacchino.delregno@collabora.com" , ming.lei@redhat.com Subject: Re: [PATCH 1/1] block: Check the queue limit before bio submitting Message-ID: References: <20231025092255.27930-1-ed.tsai@mediatek.com> <64db8f5406571c2f89b70f852eb411320201abe6.camel@mediatek.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231103_204356_414217_E38504E2 X-CRM114-Status: GOOD ( 54.28 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gU2F0LCBOb3YgMDQsIDIwMjMgYXQgMDE6MTE6MDJBTSArMDAwMCwgRWQgVHNhaSAo6JSh5a6X 6LuSKSB3cm90ZToKPiBPbiBTYXQsIDIwMjMtMTEtMDQgYXQgMDA6MjAgKzA4MDAsIE1pbmcgTGVp IHdyb3RlOgo+ID4gIE9uIFdlZCwgTm92IDAxLCAyMDIzIGF0IDAyOjIzOjI2QU0gKzAwMDAsIEVk IFRzYWkgKOiUoeWul+i7kikgd3JvdGU6Cj4gPiA+IE9uIFdlZCwgMjAyMy0xMC0yNSBhdCAxNzoy MiArMDgwMCwgZWQudHNhaUBtZWRpYXRlay5jb20gd3JvdGU6Cj4gPiA+ID4gRnJvbTogRWQgVHNh aSA8ZWQudHNhaUBtZWRpYXRlay5jb20+Cj4gPiA+ID4gCj4gPiA+ID4gUmVmZXJyaW5nIHRvIGNv bW1pdCAwNzE3M2MzZWMyNzYgKCJibG9jazogZW5hYmxlIG11bHRpcGFnZQo+ID4gYnZlY3MiKSwK PiA+ID4gPiBlYWNoIGJpb192ZWMgbm93IGhvbGRzIG1vcmUgdGhhbiBvbmUgcGFnZSwgcG90ZW50 aWFsbHkgZXhjZWVkaW5nCj4gPiA+ID4gMU1CIGluIHNpemUgYW5kIGNhdXNpbmcgYWxpZ25tZW50 IGlzc3VlcyB3aXRoIHRoZSBxdWV1ZSBsaW1pdC4KPiA+ID4gPiAKPiA+ID4gPiBJbiBhIHNlcXVl bnRpYWwgcmVhZC93cml0ZSBzY2VuYXJpbywgdGhlIGZpbGUgc3lzdGVtIG1heGltaXplcwo+ID4g dGhlCj4gPiA+ID4gYmlvJ3MgY2FwYWNpdHkgYmVmb3JlIHN1Ym1pdHRpbmcuIEhvd2V2ZXIsIG1p c2FsaWdubWVudCB3aXRoIHRoZQo+ID4gPiA+IHF1ZXVlIGxpbWl0IGNhbiByZXN1bHQgaW4gdGhl IGJpbyBiZWluZyBzcGxpdCBpbnRvIHNtYWxsZXIgSS9PCj4gPiA+ID4gb3BlcmF0aW9ucy4KPiA+ ID4gPiAKPiA+ID4gPiBGb3IgaW5zdGFuY2UsIGFzc3VtaW5nIHRoZSBtYXhpbXVtIEkvTyBzaXpl IGlzIHNldCB0byA1MTJLQiBhbmQKPiA+IHRoZQo+ID4gPiA+IG1lbW9yeSBpcyBoaWdobHkgZnJh Z21lbnRlZCwgcmVzdWx0aW5nIGluIGVhY2ggYmlvIGNvbnRhaW5pbmcKPiA+IG9ubHkKPiA+ID4g PiBvbmUgMi1wYWdlcyBiaW9fdmVjIChpLmUuLCBiaV9zaXplID0gMTAyOEtCKS4gVGhpcyB3b3Vs ZCBjYXVzZQo+ID4gdGhlCj4gPiA+ID4gYmlvIHRvIGJlIHNwbGl0IGludG8gdHdvIDUxMktCIHBv cnRpb25zIGFuZCBvbmUgNEtCIHBvcnRpb24uIEFzIGEKPiA+ID4gPiByZXN1bHQsIHRoZSBvcmln aW5hbGx5IGV4cGVjdGVkIGNvbnRpbnVvdXMgbGFyZ2UgSS9PIG9wZXJhdGlvbnMKPiA+IGFyZQo+ ID4gPiA+IGludGVyc3BlcnNlZCB3aXRoIG1hbnkgc21hbGwgSS9PIG9wZXJhdGlvbnMuCj4gPiA+ ID4gCj4gPiA+ID4gVG8gYWRkcmVzcyB0aGlzIGlzc3VlLCB0aGlzIHBhdGNoIGFkZHMgYSBjaGVj ayBmb3IgdGhlCj4gPiBtYXhfc2VjdG9ycwo+ID4gPiA+IGJlZm9yZSBzdWJtaXR0aW5nIHRoZSBi aW8uIFRoaXMgYWxsb3dzIHRoZSB1cHBlciBsYXllcnMgdG8KPiA+ID4gPiBwcm9hY3RpdmVseQo+ ID4gPiA+IGRldGVjdCBhbmQgaGFuZGxlIGFsaWdubWVudCBpc3N1ZXMuCj4gPiA+ID4gCj4gPiA+ ID4gSSBwZXJmb3JtZWQgdGhlIEFudHV0dSBWMTAgU3RvcmFnZSBUZXN0IG9uIGEgVUZTIDQuMCBk ZXZpY2UsCj4gPiB3aGljaAo+ID4gPiA+IHJlc3VsdGVkIGluIGEgc2lnbmlmaWNhbnQgaW1wcm92 ZW1lbnQgaW4gdGhlIFNlcXVlbnRpYWwgdGVzdDoKPiA+ID4gPiAKPiA+ID4gPiBTZXF1ZW50aWFs IFJlYWQgKGF2ZXJhZ2Ugb2YgNSByb3VuZHMpOgo+ID4gPiA+IE9yaWdpbmFsOiAzMDMzLjcgTUIv c2VjCj4gPiA+ID4gUGF0Y2hlZDogMzUyMC45IE1CL3NlYwo+ID4gPiA+IAo+ID4gPiA+IFNlcXVl bnRpYWwgV3JpdGUgKGF2ZXJhZ2Ugb2YgNSByb3VuZHMpOgo+ID4gPiA+IE9yaWdpbmFsOiAyMjI1 LjQgTUIvc2VjCj4gPiA+ID4gUGF0Y2hlZDogMjgwMC4zIE1CL3NlYwo+ID4gPiA+IAo+ID4gPiA+ IFNpZ25lZC1vZmYtYnk6IEVkIFRzYWkgPGVkLnRzYWlAbWVkaWF0ZWsuY29tPgo+ID4gPiA+IC0t LQo+ID4gPiA+ICBibG9jay9iaW8uYyB8IDYgKysrKysrCj4gPiA+ID4gIDEgZmlsZSBjaGFuZ2Vk LCA2IGluc2VydGlvbnMoKykKPiA+ID4gPiAKPiA+ID4gPiBkaWZmIC0tZ2l0IGEvYmxvY2svYmlv LmMgYi9ibG9jay9iaW8uYwo+ID4gPiA+IGluZGV4IDgxNmQ0MTJjMDZlOS4uYTRhMWY3NzViOWVh IDEwMDY0NAo+ID4gPiA+IC0tLSBhL2Jsb2NrL2Jpby5jCj4gPiA+ID4gKysrIGIvYmxvY2svYmlv LmMKPiA+ID4gPiBAQCAtMTIyNyw2ICsxMjI3LDcgQEAgc3RhdGljIGludCBfX2Jpb19pb3ZfaXRl cl9nZXRfcGFnZXMoc3RydWN0Cj4gPiBiaW8KPiA+ID4gPiAqYmlvLCBzdHJ1Y3QgaW92X2l0ZXIg Kml0ZXIpCj4gPiA+ID4gIGlvdl9pdGVyX2V4dHJhY3Rpb25fdCBleHRyYWN0aW9uX2ZsYWdzID0g MDsKPiA+ID4gPiAgdW5zaWduZWQgc2hvcnQgbnJfcGFnZXMgPSBiaW8tPmJpX21heF92ZWNzIC0g YmlvLT5iaV92Y250Owo+ID4gPiA+ICB1bnNpZ25lZCBzaG9ydCBlbnRyaWVzX2xlZnQgPSBiaW8t PmJpX21heF92ZWNzIC0gYmlvLT5iaV92Y250Owo+ID4gPiA+ICtzdHJ1Y3QgcXVldWVfbGltaXRz ICpsaW0gPSAmYmRldl9nZXRfcXVldWUoYmlvLT5iaV9iZGV2KS0KPiA+ID4gPiA+bGltaXRzOwo+ ID4gPiA+ICBzdHJ1Y3QgYmlvX3ZlYyAqYnYgPSBiaW8tPmJpX2lvX3ZlYyArIGJpby0+YmlfdmNu dDsKPiA+ID4gPiAgc3RydWN0IHBhZ2UgKipwYWdlcyA9IChzdHJ1Y3QgcGFnZSAqKilidjsKPiA+ ID4gPiAgc3NpemVfdCBzaXplLCBsZWZ0Owo+ID4gPiA+IEBAIC0xMjc1LDYgKzEyNzYsMTEgQEAg c3RhdGljIGludCBfX2Jpb19pb3ZfaXRlcl9nZXRfcGFnZXMoc3RydWN0Cj4gPiBiaW8KPiA+ID4g PiAqYmlvLCBzdHJ1Y3QgaW92X2l0ZXIgKml0ZXIpCj4gPiA+ID4gIHN0cnVjdCBwYWdlICpwYWdl ID0gcGFnZXNbaV07Cj4gPiA+ID4gIAo+ID4gPiA+ICBsZW4gPSBtaW5fdChzaXplX3QsIFBBR0Vf U0laRSAtIG9mZnNldCwgbGVmdCk7Cj4gPiA+ID4gK2lmIChiaW8tPmJpX2l0ZXIuYmlfc2l6ZSAr IGxlbiA+Cj4gPiA+ID4gKyAgICBsaW0tPm1heF9zZWN0b3JzIDw8IFNFQ1RPUl9TSElGVCkgewo+ ID4gPiA+ICtyZXQgPSBsZWZ0Owo+ID4gPiA+ICticmVhazsKPiA+ID4gPiArfQo+ID4gPiA+ICBp ZiAoYmlvX29wKGJpbykgPT0gUkVRX09QX1pPTkVfQVBQRU5EKSB7Cj4gPiA+ID4gIHJldCA9IGJp b19pb3ZfYWRkX3pvbmVfYXBwZW5kX3BhZ2UoYmlvLCBwYWdlLAo+ID4gPiA+IGxlbiwKPiA+ID4g PiAgb2Zmc2V0KTsKPiA+ID4gPiAtLSAKPiA+ID4gPiAyLjE4LjAKPiA+ID4gPiAKPiA+ID4gCj4g PiA+IAo+ID4gPiBIaSBKZW5zLAo+ID4gPiAKPiA+ID4gSnVzdCB0byBjbGFyaWZ5IGFueSBwb3Rl bnRpYWwgY29uZnVzaW9uLCBJIHdvdWxkIGxpa2UgdG8gcHJvdmlkZQo+ID4gPiBmdXJ0aGVyIGRl dGFpbHMgYmFzZWQgb24gdGhlIGFzc3VtZWQgc2NlbmFyaW8gbWVudGlvbmVkIGFib3ZlLgo+ID4g PiAKPiA+ID4gV2hlbiB0aGUgdXBwZXIgbGF5ZXIgY29udGludW91c2x5IHNlbmRzIDEwMjhLQiBm dWxsLXNpemVkIGJpb3MgZm9yCj4gPiA+IHNlcXVlbnRpYWwgcmVhZHMsIHRoZSBCbG9jayBMYXll ciBzZWVzIHRoZSBmb2xsb3dpbmcgc2VxdWVuY2U6Cj4gPiA+IHN1Ym1pdCBiaW86IHNpemUgPSAx MDI4S0IsIHN0YXJ0IExCQSA9IG4KPiA+ID4gc3VibWl0IGJpbzogc2l6ZSA9IDEwMjhLQiwgc3Rh cnQgTEJBID0gbiArIDEwMjhLQiAKPiA+ID4gc3VibWl0IGJpbzogc2l6ZSA9IDEwMjhLQiwgc3Rh cnQgTEJBID0gbiArIDIwNTZLQgo+ID4gPiAuLi4KPiA+ID4gCj4gPiA+IEhvd2V2ZXIsIGR1ZSB0 byB0aGUgcXVldWUgbGltaXQgcmVzdHJpY3RpbmcgdGhlIEkvTyBzaXplIHRvIGEKPiA+IG1heGlt dW0KPiA+ID4gb2YgNTEyS0IsIHRoZSBCbG9jayBMYXllciBzcGxpdHMgaW50byB0aGUgZm9sbG93 aW5nIHNlcXVlbmNlOgo+ID4gPiBzdWJtaXQgYmlvOiBzaXplID0gNTEyS0IsIHN0YXJ0IExCQSA9 IG4KPiA+ID4gc3VibWl0IGJpbzogc2l6ZSA9IDUxMktCLCBzdGFydCBMQkEgPSBuICsgIDUxMktC Cj4gPiA+IHN1Ym1pdCBiaW86IHNpemUgPSAgIDRLQiwgc3RhcnQgTEJBID0gbiArIDEwMjRLQgo+ ID4gPiBzdWJtaXQgYmlvOiBzaXplID0gNTEyS0IsIHN0YXJ0IExCQSA9IG4gKyAxMDI4S0IKPiA+ ID4gc3VibWl0IGJpbzogc2l6ZSA9IDUxMktCLCBzdGFydCBMQkEgPSBuICsgMTU0MEtCCj4gPiA+ IHN1Ym1pdCBiaW86IHNpemUgPSAgIDRLQiwgc3RhcnQgTEJBID0gbiArIDIwNTJLQgo+ID4gPiBz dWJtaXQgYmlvOiBzaXplID0gNTEyS0IsIHN0YXJ0IExCQSA9IG4gKyAyMDU2S0IKPiA+ID4gc3Vi bWl0IGJpbzogc2l6ZSA9IDUxMktCLCBzdGFydCBMQkEgPSBuICsgMjU2OEtCCj4gPiA+IHN1Ym1p dCBiaW86IHNpemUgPSAgIDRLQiwgc3RhcnQgTEJBID0gbiArIDMwODBLQgo+ID4gPiAuLi4KPiA+ ID4gCj4gPiA+IFRoZSBvcmlnaW5hbCBleHBlY3RhdGlvbiB3YXMgZm9yIHRoZSBzdG9yYWdlIHRv IHJlY2VpdmUgbGFyZ2UsCj4gPiA+IGNvbnRpZ3VvdXMgcmVxdWVzdHMuIEhvd2V2ZXIsIGR1ZSB0 byBub24tYWxpZ25tZW50LCBtYW55IHNtYWxsIEkvTwo+ID4gPiByZXF1ZXN0cyBhcmUgZ2VuZXJh dGVkLiBUaGlzIHByb2JsZW0gaXMgZWFzaWx5IHZpc2libGUgYmVjYXVzZSB0aGUKPiA+ID4gdXNl ciBwYWdlcyBwYXNzZWQgaW4gYXJlIG9mdGVuIGFsbG9jYXRlZCBieSB0aGUgYnVkZHkgc3lzdGVt IGFzCj4gPiBvcmRlciAwCj4gPiA+IHBhZ2VzIGR1cmluZyBwYWdlIGZhdWx0cywgcmVzdWx0aW5n IGluIGhpZ2hseSBub24tY29udGlndW91cwo+ID4gbWVtb3J5Lgo+ID4gCj4gPiBJZiBvcmRlciAw IHBhZ2UgaXMgYWRkZWQgdG8gYmlvLCB0aGUgbXVsdGlwYWdlIGJ2ZWMgYmVjb21lcyBub3AKPiA+ IGJhc2ljYWxseSgyNTZidmVjIGhvbGRzIDI1NiBwYWdlcyksIHRoZW4gaG93IGNhbiBpdCBtYWtl IGEgZGlmZmVyZW5jZQo+ID4gZm9yIHlvdT8KPiAKPiAKPiAKPiA+IAo+ID4gPiAKPiA+ID4gQXMg b2JzZXJ2ZWQgaW4gdGhlIEFudHV0dSBTZXF1ZW50aWFsIFJlYWQgdGVzdCBiZWxvdywgaXQgaXMg c2ltaWxhcgo+ID4gdG8KPiA+ID4gdGhlIGRlc2NyaXB0aW9uIGFib3ZlIHdoZXJlIHRoZSBzcGxp dHRpbmcgY2F1c2VkIGJ5IHRoZSBxdWV1ZSBsaW1pdAo+ID4gPiBsZWF2ZXMgc21hbGwgcmVxdWVz dHMgc2FuZHdpY2hlZCBpbiBiZXR3ZWVuOgo+ID4gPiAKPiA+ID4gYmxvY2tfYmlvX3F1ZXVlOiA4 LDMyIFIgODY5MjU4NjQgKyAyMTQ0IFtUaHJlYWQtNTFdCj4gPiA+IGJsb2NrX3NwbGl0OiA4LDMy IFIgODY5MjU4NjQgLyA4NjkyNjg4OCBbVGhyZWFkLTUxXQo+ID4gPiBibG9ja19zcGxpdDogOCwz MiBSIDg2OTI2ODg4IC8gODY5Mjc5MTIgW1RocmVhZC01MV0KPiA+ID4gYmxvY2tfcnFfaXNzdWU6 IDgsMzIgUiA1MjQyODggKCkgODY5MjU4NjQgKyAxMDI0IFtUaHJlYWQtNTFdCj4gPiA+IGJsb2Nr X3JxX2lzc3VlOiA4LDMyIFIgNTI0Mjg4ICgpIDg2OTI2ODg4ICsgMTAyNCBbVGhyZWFkLTUxXQo+ ID4gPiBibG9ja19iaW9fcXVldWU6IDgsMzIgUiA4NjkyODAwOCArIDIxNDQgW1RocmVhZC01MV0K PiA+ID4gYmxvY2tfc3BsaXQ6IDgsMzIgUiA4NjkyODAwOCAvIDg2OTI5MDMyIFtUaHJlYWQtNTFd Cj4gPiA+IGJsb2NrX3NwbGl0OiA4LDMyIFIgODY5MjkwMzIgLyA4NjkzMDA1NiBbVGhyZWFkLTUx XQo+ID4gPiBibG9ja19ycV9pc3N1ZTogOCwzMiBSIDUyNDI4OCAoKSA4NjkyODAwOCArIDEwMjQg W1RocmVhZC01MV0KPiA+ID4gYmxvY2tfcnFfaXNzdWU6IDgsMzIgUiA0OTE1MiAoKSA4NjkyNzkx MiArIDk2IFtUaHJlYWQtNTFdCj4gPiA+IGJsb2NrX3JxX2lzc3VlOiA4LDMyIFIgNTI0Mjg4ICgp IDg2OTI5MDMyICsgMTAyNCBbVGhyZWFkLTUxXQo+ID4gPiBibG9ja19iaW9fcXVldWU6IDgsMzIg UiA4NjkzMDE1MiArIDIxMTIgW1RocmVhZC01MV0KPiA+ID4gYmxvY2tfc3BsaXQ6IDgsMzIgUiA4 NjkzMDE1MiAvIDg2OTMxMTc2IFtUaHJlYWQtNTFdCj4gPiA+IGJsb2NrX3NwbGl0OiA4LDMyIFIg ODY5MzExNzYgLyA4NjkzMjIwMCBbVGhyZWFkLTUxXQo+ID4gPiBibG9ja19ycV9pc3N1ZTogOCwz MiBSIDUyNDI4OCAoKSA4NjkzMDE1MiArIDEwMjQgW1RocmVhZC01MV0KPiA+ID4gYmxvY2tfcnFf aXNzdWU6IDgsMzIgUiA0OTE1MiAoKSA4NjkzMDA1NiArIDk2IFtUaHJlYWQtNTFdCj4gPiA+IGJs b2NrX3JxX2lzc3VlOiA4LDMyIFIgNTI0Mjg4ICgpIDg2OTMxMTc2ICsgMTAyNCBbVGhyZWFkLTUx XQo+ID4gPiBibG9ja19iaW9fcXVldWU6IDgsMzIgUiA4NjkzMjI2NCArIDIwOTYgW1RocmVhZC01 MV0KPiA+ID4gYmxvY2tfc3BsaXQ6IDgsMzIgUiA4NjkzMjI2NCAvIDg2OTMzMjg4IFtUaHJlYWQt NTFdCj4gPiA+IGJsb2NrX3NwbGl0OiA4LDMyIFIgODY5MzMyODggLyA4NjkzNDMxMiBbVGhyZWFk LTUxXQo+ID4gPiBibG9ja19ycV9pc3N1ZTogOCwzMiBSIDUyNDI4OCAoKSA4NjkzMjI2NCArIDEw MjQgW1RocmVhZC01MV0KPiA+ID4gYmxvY2tfcnFfaXNzdWU6IDgsMzIgUiAzMjc2OCAoKSA4Njkz MjIwMCArIDY0IFtUaHJlYWQtNTFdCj4gPiA+IGJsb2NrX3JxX2lzc3VlOiA4LDMyIFIgNTI0Mjg4 ICgpIDg2OTMzMjg4ICsgMTAyNCBbVGhyZWFkLTUxXQo+ID4gPiAKPiA+ID4gSSBzaW1wbHkgcHJl dmVudHMgbm9uLWFsaWduZWQgc2l0dWF0aW9ucyBpbiBiaW9faW92X2l0ZXJfZ2V0X3BhZ2VzLgo+ ID4gCj4gPiBCdXQgdGhlcmUgaXMgc3RpbGwgNEtCIElPIGxlZnQgaWYgeW91IGxpbWl0IG1heCBi aW8gc2l6ZSBpcyA1MTJLQiwKPiA+IHRoZW4gaG93IGRvZXMgdGhpcyA0S0IgSU8gZmluYWxseSBn byBpbiBjYXNlIG9mIDEwMjhLQiBJTz8KPiA+IAo+ID4gPiBCZXNpZGVzIG1ha2luZyB0aGUgdXBw ZXIgbGF5ZXIgYXBwbGljYXRpb24gYXdhcmUgb2YgdGhlIHF1ZXVlCj4gPiBsaW1pdCwgSQo+ID4g PiB3b3VsZCBhcHByZWNpYXRlIGFueSBvdGhlciBkaXJlY3Rpb25zIG9yIHN1Z2dlc3Rpb25zIHlv dSBtYXkgaGF2ZS4KPiA+IAo+ID4gVGhlIHByb2JsZW0gaXMgcmVsYXRlZCB3aXRoIElPIHNpemUg ZnJvbSBhcHBsaWNhdGlvbi4KPiA+IAo+ID4gSWYgeW91IHNlbmQgdW5hbGlnbmVkIElPLCB5b3Ug Y2FuJ3QgYXZvaWQgdGhlIGxhc3QgSU8gd2l0aCBzbWFsbAo+ID4gc2l6ZSwgbm8KPiA+IG1hdHRl ciBpZiBibG9jayBsYXllciBiaW8gc3BsaXQgaXMgaW52b2x2ZWQgb3Igbm90LiBZb3VyIHBhdGNo IGp1c3QKPiA+IGxldHMKPiA+IF9fYmlvX2lvdl9pdGVyX2dldF9wYWdlcyBzcGxpdCB0aGUgYmlv LCBhbmQgeW91IHN0aWxsIGhhdmUgNEtCIGxlZnQKPiA+IGZpbmFsbHkgd2hlbiBhcHBsaWNhdGlv biBzdWJtaXRzIDEwMjhLQiwgcmlnaHQ/Cj4gPiAKPiA+IFRoZW4gSSBkb24ndCB1bmRlcnN0YW5k IHdoeSB5b3VyIHBhdGNoIGltcHJvdmVzIHNlcXVlbnRpYWwgSU8KPiA+IHBlcmZvcm1hbmNlLgo+ ID4gCj4gPiBUaGFua3MsCj4gPiBNaW5nCj4gPiAKPiAKPiBUaGUgYXBwbGljYXRpb24gcGVyZm9y bXMgSS9PIHdpdGggYSBzdWZmaWNpdGVubHkgbGFyZ2UgSS9PIHNpemUsCj4gY2F1c2luZyBpdCB0 byBjb25zdGFudGx5IGZpbGwgdXAgYW5kIHN1Ym1pdCBmdWxsIGJpb3MuIEhvd2V2ZXIsIGluIHRo ZQo+IGlvbWFwIGRpcmVjdCBJL08gc2NlbmFyaW8sIHBhZ2VzIGFyZSBhZGRlZCB0byB0aGUgYmlv IG9uZSBieSBvbmUgZnJvbQo+IHRoZSB1c2VyIGJ1ZmZlci4gVGhpcyB0eXBpY2FsbHkgdHJpZ2dl cnMgcGFnZSBmYXVsdHMsIHJlc3VsdGluZyBpbiB0aGUKPiBhbGxvY2F0aW9uIG9mIG9yZGVyIDAg cGFnZXMgZnJvbSB0aGUgYnVkZHkgc3lzdGVtLgo+IAo+IFRoZSByZW1haW5pbmcgYW1vdW50IG9m IGVhY2ggb3JkZXIgaW4gdGhlIGJ1ZGR5IHN5c3RlbSB2YXJpZXMgb3Zlcgo+IHRpbWUuIElmIHRo ZXJlIGFyZSBub3QgZW5vdWdoIHBhZ2VzIGF2YWlsYWJsZSBpbiBhIHBhcnRpY3VsYXIgb3JkZXIs Cj4gcGFnZXMgYXJlIHNwbGl0IGZyb20gaGlnaGVyIG9yZGVycy4gV2hlbiBwYWdlcyBhcmUgb2J0 YWluZWQgZnJvbSB0aGUKPiBoaWdoZXIgb3JkZXIsIHRoZSB1c2VyIGJ1ZmZlciBtYXkgY29udGFp biBzb21lIHNtYWxsIGNvbnNlY3V0aXZlCj4gcGF0dGVybnMuCj4gCj4gSW4gc3VtbWFyeSwgdGhl IHBoeXNpY2FsIGxheW91dCBvZiB0aGUgdXNlciBidWZmZXIgaXMgdW5wcmVkaWN0YWJsZSwKPiBh bmQgd2hlbiBpdCBjb250YWlucyBzb21lIHNtYWxsIGNvbnNlY3V0aXZlIHBhdHRlcm5zLCB0aGUg c2l6ZSBvZiB0aGUKPiBiaW8gYmVjb21lcyByYW5kb21seSB1bmFsaWduZWQgZHVyaW5nIGZpbGxp bmcuCgpZZXMsIG11bHRpcGFnZSBidmVjIGRlcGVuZHMgb24gcGh5c2ljYWwgbGF5b3V0IG9mIHVz ZXIgYnVmZmVyLCBidXQgaXQKZG9lc24ndCBhZmZlY3QgYmlvIHNpemUsIHdoaWNoIGlzIGRlY2lk ZWQgYnkgdXNlcnNwYWNlLCBhbmQgdGhlIGJ2ZWMKcGFnZSBsYXlvdXQgZG9lc24ndCBhZmZlY3Qg SU8gcGF0dGVybi4KCklmIHVzZXJzcGFjZSBzdWJtaXRzIDEwMjhLIElPLCB0aGUgSU8gaXMgc3Bs aXQgaW50byA1MTJLLCA1MTJLIGFuZCA0SywKbm8gbWF0dGVyIGlmIGVhY2ggYnZlYyBpbmNsdWRl cyBob3cgbWFueSBwYWdlcy4KCklmIHVzZXJzcGFjZSBzdWJtaXRzIHZlcnkgbGFyZ2UgSU8sIHN1 Y2ggYXMgNTEyTSwgd2hpY2ggd2lsbCBiZSBzcGxpdAppbnRvIDFLIGJpb3Mgd2l0aCA1MTJLIHNp emUuCgpZb3UgcGF0Y2ggZG9lc24ndCBtYWtlcyBhbnkgZGlmZmVyZW5jZSBhY3R1YWxseSBmcm9t IGJsb2NrIGxheWVyCnZpZXdwb2ludCwgc3VjaCBhczoKCjEpIGRkIGlmPS9kZXYvdWJsa2IwIG9m PS9kZXYvbnVsbCBicz0xMDI4ayBjb3VudD0xIGlmbGFnPWRpcmVjdAoKMikgb2JzZXJ2ZSBJTyBw YXR0ZXJuIGJ5IHRoZSBmb2xsb3dpbmcgYnBmdHJhY2U6CgprcHJvYmU6YmxrX21xX3N0YXJ0X3Jl cXVlc3QKewoJJHJxID0gKHN0cnVjdCByZXF1ZXN0ICopYXJnMDsKCglwcmludGYoIiVsdSAlMTZz ICVkICVkOiAlcyAlcyBiaW8gJWx4LSVsdVxuIiwKCQluc2VjcyAvIDEwMDAsICBjb21tLCBwaWQs IGNwdSwga3N5bShyZWcoImlwIikpLAoJCSRycS0+cS0+ZGlzay0+ZGlza19uYW1lLCAkcnEtPl9f c2VjdG9yLCAkcnEtPl9fZGF0YV9sZW4pOwp9CgozKSBubyBtYXR0ZXIgaWYgeW91ciBwYXRjaCBp cyBhcHBsaWVkIG9yIG5vdCwgdGhlIGZvbGxvd2luZyBwYXR0ZXJuCmlzIGFsd2F5cyBvYnNlcnZl ZDoKCjExNzgyODgxMSAgICAgICAgICAgICAgIGRkIDE0NzUgMDogYmxrX21xX3N0YXJ0X3JlcXVl c3QgdWJsa2IwIGJpbyAwLTUyNDI4OAoxMTc4Mjg4MjMgICAgICAgICAgICAgICBkZCAxNDc1IDA6 IGJsa19tcV9zdGFydF9yZXF1ZXN0IHVibGtiMCBiaW8gNDAwLTUyNDI4OAoxMTc4Mjg4MjUgICAg ICAgICAgICAgICBkZCAxNDc1IDA6IGJsa19tcV9zdGFydF9yZXF1ZXN0IHVibGtiMCBiaW8gODAw LTQwOTYKClNpbWlsYXIgcGF0dGVybiBjYW4gYmUgb2JzZXJ2ZWQgd2hlbiBydW5uaW5nIGRkIGlu c2lkZSBGUyh4ZnMpLgoKPiAKPiBUaGlzIHBhdGNoIGxpbWl0cyB0aGUgYmlvIHRvIGJlIGZpbGxl ZCB1cCB0byB0aGUgbWF4X3NlY3RvcnMuIFRoZQo+IHN1Ym1pc3Npb24gaXMgYW4gYXN5bmMgb3Bl cmF0aW9uLCBzbyBvbmNlIHRoZSBiaW8gaXMgcXVldWVkLCBpdCB3aWxsCj4gaW1tZWRpYXRlbHkg cmV0dXJuIGFuZCBjb250aW51ZSBmaWxsZWQgYW5kIHN1Ym1pdCB0aGUgbmV4dCBiaW8uCgpiaW8g c3BsaXQgZG9lc24ndCBjaGFuZ2UgdGhpcyBiZWhhdmlvciB0b28sIHRoZSBkaWZmZXJlbmNlIGlz IGp1c3QgaG93Cm1hbnkgYmlvcyB0aGUgdXBwZXIgbGF5ZXIoaW9tYXApIG9ic2VydmVkLgoKWW91 ciBwYXRjaCBqdXN0IG1vdmVzIHRoZSBzcGxpdCBpbnRvIHVwcGVyIGxheWVyLCBhbmQgaW9tYXAg Y2FuIHNlZQozIGJpb3Mgd2l0aCB5b3VyIHBhdGNoIHdoZW4gYGRkIGJzPTEwMjhLYCwgYW5kIGlu IHZhbmlsbGEgdHJlZSwgaW9tYXAKanVzdCBzdWJtaXRzIHNpbmdsZSBiaW8gd2l0aCAxMDI4Sywg YmxvY2sgbGF5ZXIgc3BsaXRzIGl0IGludG8KNTEyaywgNTEyaywgYW5kIDRrLiBTbyBmaW5hbGx5 IFVGUyBkcml2ZXIgb2JzZXJ2ZXMgc2FtZSBJTyBwYXR0ZXJuLgoKSW4gc2hvcnQsIHBsZWFzZSBy b290IGNhdXNlIHdoeSB5b3VyIHBhdGNoIGltcHJvdmVzIHBlcmZvcm1hbmNlLCBvcgpwbGVhc2Ug c2hhcmUgeW91ciB3b3JrbG9hZHMsIHNvIHdlIGNhbiBvYnNlcnZlIHRoZSBJTyBwYXR0ZXJuIGFu ZApyZWxhdGVkIG1tL2ZzIGJlaGF2aW9yIGFuZCB0cnkgdG8gcm9vdCBjYXVzZSBpdC4KCgpUaGFu a3MsCk1pbmcKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmlu ZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1hcm0ta2VybmVsCg==