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 27F0FFF8875 for ; Thu, 30 Apr 2026 04:05:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:Message-Id:Date:Subject:Cc:To:From:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=snB875P95SUbpGSGDIAQLGtDYkvzFzItmsNJKMa2UQ4=; b=GliLs1EG+GkV12rTQyDeEBGSvD 0tB5T4UsnFQQtEnCXaihgVZt/6o4Uc6dUg5n6sny3S63VL7KmiJVDrHwlI7g2uSIBxdN4neHAoldQ P6y2mHSIHISsnW6q6bkrJyKTC/j45LeQavGxosXitKHMQhqdqmoajkAG4AsOjix5LZNAonhKYE64a TW0zSCraF83HC/smd5tkFSQtyniBv5+kVreQ2JjT155PQF0vZ8xHICi6yf6imhyR9NflHIc4Zii+A p8rH+is1SZQTBO5hE9imas+SC0UrWF8mqLGwjbwBwuETIhgUnELi3/PB5kszDExKE18VnrWp+z2SX 5SkD97WQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wIIe0-00000004ck2-0Wtj; Thu, 30 Apr 2026 04:04:56 +0000 Received: from tor.source.kernel.org ([2600:3c04:e001:324:0:1991:8:25]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wIIdy-00000004cjo-3dVa; Thu, 30 Apr 2026 04:04:55 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id 9FF0960582; Thu, 30 Apr 2026 04:04:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E6B0C2BCB8; Thu, 30 Apr 2026 04:04:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777521893; bh=SQbc6yap3IwxIjf5vkMZhpQlq9soeHHQjAS0yGku44k=; h=From:To:Cc:Subject:Date:From; b=XmywiKhuyr1+iRfR3PHU6v9GONpwVAKCcc0eTlQU9yjUnF6uRHR/EBTZ/UN8UVVVB kG/ZtEEtVbHvFaU+7KcGKU5U2/IzqdlsTRcV5sdP0HYPRqvAozZqjFb0EOASauV2xC xUaKzad/uIF07HjedFILdewu7IjvV/gAtfxZbzVm8Kt/pEV3hdCFjBHz3/a9JeCr35 5oYSoSs/WSqmNPs15idDrhOJSsG7WKscp9W5QVhlflYcPmOPSGHTGSFBqz1kz4GAV0 apuUfkjNj3pyaP8/fgBFyApKG9AU7GKaHlnxXjL4Jva5JTKwRj7lbU5sCFB18KTvNd ycxSlp7jRcFKg== From: "Barry Song (Xiaomi)" To: akpm@linux-foundation.org, linux-mm@kvack.org, willy@infradead.org Cc: david@kernel.org, ljs@kernel.org, liam@infradead.org, vbabka@kernel.org, rppt@kernel.org, surenb@google.com, mhocko@suse.com, jack@suse.cz, pfalcato@suse.de, wanglian@kylinos.cn, chentao@kylinos.cn, lianux.mm@gmail.com, kunwu.chan@gmail.com, liyangouwen1@oppo.com, chrisl@kernel.org, kasong@tencent.com, shikemeng@huaweicloud.com, nphamcs@gmail.com, bhe@redhat.com, youngjun.park@lge.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, "Barry Song (Xiaomi)" Subject: [PATCH v2 0/5] mm: reduce mmap_lock contention and improve page fault performance Date: Thu, 30 Apr 2026 12:04:22 +0800 Message-Id: <20260430040427.4672-1-baohua@kernel.org> X-Mailer: git-send-email 2.39.3 (Apple Git-146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Oven observed most mmap_lock contention and priority inversion come from page fault retries after waiting for I/O completion. Oven subsequently raised the following idea: There is no need to always fall back to mmap_lock when the per-VMA lock is released only to wait for the page cache to become ready. On a page fault retry, the per-VMA lock can still be reused. We believe the same should also apply to anonymous folios. However, there is a case where I/O has completed but we fail to acquire the folio lock because a concurrent thread may be installing PTEs for the folio. This is expected to be short-lived, so retrying the page fault is unnecessary. This patchset handles two cases: (1) If we need to wait for I/O completion, we still drop the per-VMA lock, as current page fault handling already does. Holding it for too long may introduce various priority inversion issues on mobile devices. After I/O completes, we retry the page fault with the per-VMA lock, rather than falling back to mmap_lock. (2) If I/O has already completed and the folio is up to date, the wait is likely due to a concurrent PTE installation. In this case, we keep the per-VMA lock and avoid retrying the page fault. With (1), the dramatically reduced mmap_lock contention leads to a significant improvement in Douyin performance. Oven’s data is shown below. Douyin (the Chinese version of TikTok) warm start on a smartphone with 8GB RAM. == mmap_lock Acquisitions And Wait Time == Metric Before (Avg) After (Avg) Change ------------------------------------------------------------------------ Read Lock Count 20,010 5,719 -71.42% Read Total Wait (us) 10,695,877 408,436 -96.18% Read Avg Wait (us) 534.00 71.00 -86.70% Write Lock Count 838 909 +8.47% Write Total Wait (us) 501,293 97,633 -80.52% Write Avg Wait (us) 598.00 107.00 -82.11% == Read Lock Waiting Time Distribution of mmap_lock == Range (us) Before (Avg) After (Avg) Change ------------------------------------------------------------------------ [0, 1) 9,927 4,286 -56.82% [1, 10) 9,179 1,327 -85.54% [10, 100) 191 88 -53.93% [100, 1000) 57 6 -89.47% [1000, 10000) 328 9 -97.26% [10000, 100000) 328 6 -98.17% [100000, 1000000) 0 0 N/A [1000000, +) 0 0 N/A == Write Lock Waiting Time Distribution of mmap_lock == Range (us) Before (Avg) After (Avg) Change ------------------------------------------------------------------------ [0, 1) 250 300 +20.00% [1, 10) 483 556 +15.11% [10, 100) 52 41 -21.15% [100, 1000) 12 5 -58.33% [1000, 10000) 22 4 -81.82% [10000, 100000) 16 1 -93.75% [100000, 1000000) 0 0 N/A [1000000, +) 0 0 N/A After the optimization, the number of read lock acquisitions is significantly reduced, and both lock waiting time and tail latency are dramatically improved. Kunwu and Lian also developed a model to capture the situation described by Matthew [1], where a memcg with limited memory may fail to make progress. This happens because after I/O is initiated on the first page fault, the folios may be reclaimed by the time of the retry, leaving the workload with little or no forward progress. A stress setup made by Kunwu and Lian as follows: * 256-core x86 system * 500 threads continuously faulting on 16MB files The model was running within a memcg with limited memory, as shown below: systemd-run --scope -p MemoryHigh=1G -p MemoryMax=1.2G -p MemorySwapMax=0 \ --unit=mmap-thrash-$$ ./mmap_lock & \ TEST_PID=$! The reproducer code is shown below: #define THREADS 500 #define FILE_SIZE (16 * 1024 * 1024) /* 16MB */ static _Atomic int g_stop = 0; #define RUN_SECONDS 600 struct worker_arg { long id; uint64_t *counts; }; void *worker(void *arg) { struct worker_arg *wa = (struct worker_arg *)arg; long id = wa->id; char path[64]; uint64_t local_rounds = 0; snprintf(path, sizeof(path), "./test_file_%d_%ld.dat", getpid(), id); int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd < 0) return NULL; if (ftruncate(fd, FILE_SIZE) < 0) { close(fd); return NULL; } while (!atomic_load_explicit(&g_stop, memory_order_relaxed)) { char *f_map = mmap(NULL, FILE_SIZE, PROT_READ, MAP_SHARED, fd, 0); if (f_map != MAP_FAILED) { /* Pure page cache thrashing */ for (int i = 0; i < FILE_SIZE; i += 4096) { volatile unsigned char c = (unsigned char)f_map[i]; (void)c; } munmap(f_map, FILE_SIZE); local_rounds++; } } wa->counts[id] = local_rounds; close(fd); unlink(path); return NULL; } int main(void) { printf("Pure File Thrashing Started. PID: %d\n", getpid()); pthread_t t[THREADS]; uint64_t local_counts[THREADS]; memset(local_counts, 0, sizeof(local_counts)); struct worker_arg args[THREADS]; for (long i = 0; i < THREADS; i++) { args[i].id = i; args[i].counts = local_counts; pthread_create(&t[i], NULL, worker, &args[i]); } sleep(RUN_SECONDS); atomic_store_explicit(&g_stop, 1, memory_order_relaxed); for (int i = 0; i < THREADS; i++) pthread_join(t[i], NULL); uint64_t total = 0; for (int i = 0; i < THREADS; i++) total += local_counts[i]; printf("Total rounds : %llu\n", (unsigned long long)total); printf("Throughput : %.2f rounds/sec\n", (double)total / RUN_SECONDS); return 0; } They also added temporary counters in page fault retries [2]: - RETRY_IO_MISS : folio not present after I/O completion - RETRY_MMAP_DROP : retry fallback due to waiting for I/O Their results are as follows: | Case | Total Rounds | Throughput | Miss/Drop(%) | RETRY_MMAP_DROP | RETRY_IO_MISS | | ------------------- | ------------ | ---------- | ------------ | --------------- | ------------- | | Baseline (Run 1) | 22,711 | 37.85 /s | 45.04 | 970,078 | 436,956 | | Baseline (Run 2) | 23,530 | 39.22 /s | 44.96 | 972,043 | 437,077 | | With Series (Run A) | 54,428 | 90.71 /s | 1.69 | 1,204,124 | 20,398 | | With Series (Run B) | 35,949 | 59.91 /s | 0.03 | 327,023 | 99 | Without this series, nearly half of the retries fail to observe completed I/O results, leading to significant CPU and I/O waste. With the finer- grained VMA lock, faulting threads avoid the heavily contended mmap_lock during retries and are therefore able to complete the page fault. With (2), there is a clear improvement in swap-in bandwidth in a model with five threads issuing MADV_PAGEOUT-based swap-outs and five threads performing swap-ins on a 100MB anonymous mmap VMA. #define SIZE (100 * 1024 * 1024) #define PAGE_SIZE 4096 #define WRITER_THREADS 5 #define READER_THREADS 5 #define RUN_SECONDS 30 static uint8_t *buf; static atomic_ulong pageout_rounds = 0; static atomic_ulong swapin_rounds = 0; static atomic_int stop_flag = 0; static void *pageout_thread(void *arg) { (void)arg; while (!atomic_load(&stop_flag)) { if (madvise(buf, SIZE, MADV_PAGEOUT) == 0) { atomic_fetch_add(&pageout_rounds, 1); } } return NULL; } static void *reader_thread(void *arg) { (void)arg; volatile uint64_t sum = 0; while (!atomic_load(&stop_flag)) { for (size_t i = 0; i < SIZE; i += PAGE_SIZE) { sum += buf[i]; } /* One full pass over 100MB, counted as one swap-in round (approximate) */ atomic_fetch_add(&swapin_rounds, 1); } return NULL; } int main(void) { pthread_t writers[WRITER_THREADS]; pthread_t readers[READER_THREADS]; buf = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (buf == MAP_FAILED) { exit(EXIT_FAILURE); } memset(buf, 0, SIZE); for (int i = 0; i < WRITER_THREADS; i++) { if (pthread_create(&writers[i], NULL, pageout_thread, NULL) != 0) { perror("pthread_create"); exit(EXIT_FAILURE); } } for (int i = 0; i < READER_THREADS; i++) { if (pthread_create(&readers[i], NULL, reader_thread, NULL) != 0) { perror("pthread_create"); exit(EXIT_FAILURE); } } sleep(RUN_SECONDS); atomic_store(&stop_flag, 1); for (int i = 0; i < WRITER_THREADS; i++) pthread_join(writers[i], NULL); for (int i = 0; i < READER_THREADS; i++) pthread_join(readers[i], NULL); printf("=== Result (30s) ===\n"); printf("Pageout rounds: %lu\n", pageout_rounds); printf("Swap-in rounds (approx): %lu\n", swapin_rounds); munmap(buf, SIZE); return 0; } W/o patches: === Result (30s) === Pageout rounds: 1324847 Swap-in rounds (approx): 874 W/patches: === Result (30s) === Pageout rounds: 1330550 Swap-in rounds (approx): 1017 [1] https://lore.kernel.org/linux-mm/aSip2mWX13sqPW_l@casper.infradead.org/ [2] https://github.com/lianux-mm/ioretry_test/ -v2: * collect tags from Pedro, Kunwu and Lian, thanks! * handle case (2), for uptodate folios, don't retry PF -RFC: https://lore.kernel.org/linux-mm/20251127011438.6918-1-21cnbao@gmail.com/ Barry Song (Xiaomi) (4): mm/swapin: Retry swapin by VMA lock if the lock was released for I/O mm: Move folio_lock_or_retry() and drop __folio_lock_or_retry() mm: Don't retry page fault if folio is uptodate during swap-in mm/filemap: Avoid retrying page faults on uptodate folios in filemap faults Oven Liyang (1): mm/filemap: Retry fault by VMA lock if the lock was released for I/O arch/arm/mm/fault.c | 5 +++ arch/arm64/mm/fault.c | 5 +++ arch/loongarch/mm/fault.c | 4 +++ arch/powerpc/mm/fault.c | 5 ++- arch/riscv/mm/fault.c | 4 +++ arch/s390/mm/fault.c | 4 +++ arch/x86/mm/fault.c | 4 +++ include/linux/mm_types.h | 9 ++--- include/linux/pagemap.h | 17 ---------- mm/filemap.c | 57 ++++++------------------------- mm/memory.c | 70 +++++++++++++++++++++++++++++++++++++-- 11 files changed, 114 insertions(+), 70 deletions(-) -- * The work began during my collaboration with OPPO and has continued through my current collaboration with Xiaomi. Although the OPPO collaboration has ended, OPPO still deserves more than half of the credit for this series, if any credit is to be assigned. 2.39.3 (Apple Git-146) 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 C51B8CD1297 for ; Thu, 30 Apr 2026 04:05:03 +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:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=ErRBV1hekdzDOVLWbnE/KPT9J4bBCdjwMYh6Rw4icO4=; b=oNLKz/Ck1haqXD u9Ut7h8nMvGOTbg+gyiz0llNazBgvlFpguAcoZVrSMVIHP0r+/104MoW+IyTJ41GyDAbb4aOGMMkb sJRuMvYc5TpVn/kr2vJvhEa8NmJxdP6KHjIZlALIHm2Iy7VOx4OHclVh8L60Q/4ZU6m369/Iau6FZ d6D6NvQeLBH25bcUPB7GEqc5R+p6Vkr2XDmcZ/KzaoXWt6eY6NR+YDA/E2e36k1/qDDYVns5/+bQJ HHkd/VSoyKmmCmjRLC27vvdohjej/ygv8OwVwDEZ17q/yCP+meugO3nFn//OXPQEWnVxdWKB28jkZ EhU2OQVDHHRratH9BS8w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wIIe0-00000004ck6-1iXt; Thu, 30 Apr 2026 04:04:56 +0000 Received: from tor.source.kernel.org ([2600:3c04:e001:324:0:1991:8:25]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wIIdy-00000004cjo-3dVa; Thu, 30 Apr 2026 04:04:55 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id 9FF0960582; Thu, 30 Apr 2026 04:04:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E6B0C2BCB8; Thu, 30 Apr 2026 04:04:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777521893; bh=SQbc6yap3IwxIjf5vkMZhpQlq9soeHHQjAS0yGku44k=; h=From:To:Cc:Subject:Date:From; b=XmywiKhuyr1+iRfR3PHU6v9GONpwVAKCcc0eTlQU9yjUnF6uRHR/EBTZ/UN8UVVVB kG/ZtEEtVbHvFaU+7KcGKU5U2/IzqdlsTRcV5sdP0HYPRqvAozZqjFb0EOASauV2xC xUaKzad/uIF07HjedFILdewu7IjvV/gAtfxZbzVm8Kt/pEV3hdCFjBHz3/a9JeCr35 5oYSoSs/WSqmNPs15idDrhOJSsG7WKscp9W5QVhlflYcPmOPSGHTGSFBqz1kz4GAV0 apuUfkjNj3pyaP8/fgBFyApKG9AU7GKaHlnxXjL4Jva5JTKwRj7lbU5sCFB18KTvNd ycxSlp7jRcFKg== From: "Barry Song (Xiaomi)" To: akpm@linux-foundation.org, linux-mm@kvack.org, willy@infradead.org Cc: david@kernel.org, ljs@kernel.org, liam@infradead.org, vbabka@kernel.org, rppt@kernel.org, surenb@google.com, mhocko@suse.com, jack@suse.cz, pfalcato@suse.de, wanglian@kylinos.cn, chentao@kylinos.cn, lianux.mm@gmail.com, kunwu.chan@gmail.com, liyangouwen1@oppo.com, chrisl@kernel.org, kasong@tencent.com, shikemeng@huaweicloud.com, nphamcs@gmail.com, bhe@redhat.com, youngjun.park@lge.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, "Barry Song (Xiaomi)" Subject: [PATCH v2 0/5] mm: reduce mmap_lock contention and improve page fault performance Date: Thu, 30 Apr 2026 12:04:22 +0800 Message-Id: <20260430040427.4672-1-baohua@kernel.org> X-Mailer: git-send-email 2.39.3 (Apple Git-146) MIME-Version: 1.0 X-BeenThere: linux-riscv@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-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org T3ZlbiBvYnNlcnZlZCBtb3N0IG1tYXBfbG9jayBjb250ZW50aW9uIGFuZCBwcmlvcml0eSBpbnZl cnNpb24KY29tZSBmcm9tIHBhZ2UgZmF1bHQgcmV0cmllcyBhZnRlciB3YWl0aW5nIGZvciBJL08g Y29tcGxldGlvbi4KT3ZlbiBzdWJzZXF1ZW50bHkgcmFpc2VkIHRoZSBmb2xsb3dpbmcgaWRlYToK ClRoZXJlIGlzIG5vIG5lZWQgdG8gYWx3YXlzIGZhbGwgYmFjayB0byBtbWFwX2xvY2sgd2hlbiB0 aGUgcGVyLVZNQSBsb2NrCmlzIHJlbGVhc2VkIG9ubHkgdG8gd2FpdCBmb3IgdGhlIHBhZ2UgY2Fj aGUgdG8gYmVjb21lIHJlYWR5LiBPbiBhIHBhZ2UKZmF1bHQgcmV0cnksIHRoZSBwZXItVk1BIGxv Y2sgY2FuIHN0aWxsIGJlIHJldXNlZC4KCldlIGJlbGlldmUgdGhlIHNhbWUgc2hvdWxkIGFsc28g YXBwbHkgdG8gYW5vbnltb3VzIGZvbGlvcy4gSG93ZXZlciwgdGhlcmUKaXMgYSBjYXNlIHdoZXJl IEkvTyBoYXMgY29tcGxldGVkIGJ1dCB3ZSBmYWlsIHRvIGFjcXVpcmUgdGhlIGZvbGlvIGxvY2sK YmVjYXVzZSBhIGNvbmN1cnJlbnQgdGhyZWFkIG1heSBiZSBpbnN0YWxsaW5nIFBURXMgZm9yIHRo ZSBmb2xpby4gVGhpcwppcyBleHBlY3RlZCB0byBiZSBzaG9ydC1saXZlZCwgc28gcmV0cnlpbmcg dGhlIHBhZ2UgZmF1bHQgaXMgdW5uZWNlc3NhcnkuCgpUaGlzIHBhdGNoc2V0IGhhbmRsZXMgdHdv IGNhc2VzOgoKKDEpIElmIHdlIG5lZWQgdG8gd2FpdCBmb3IgSS9PIGNvbXBsZXRpb24sIHdlIHN0 aWxsIGRyb3AgdGhlIHBlci1WTUEgbG9jaywgYXMKY3VycmVudCBwYWdlIGZhdWx0IGhhbmRsaW5n IGFscmVhZHkgZG9lcy4gSG9sZGluZyBpdCBmb3IgdG9vIGxvbmcgbWF5IGludHJvZHVjZQp2YXJp b3VzIHByaW9yaXR5IGludmVyc2lvbiBpc3N1ZXMgb24gbW9iaWxlIGRldmljZXMuIEFmdGVyIEkv TyBjb21wbGV0ZXMsIHdlCnJldHJ5IHRoZSBwYWdlIGZhdWx0IHdpdGggdGhlIHBlci1WTUEgbG9j aywgcmF0aGVyIHRoYW4gZmFsbGluZyBiYWNrIHRvCm1tYXBfbG9jay4KCigyKSBJZiBJL08gaGFz IGFscmVhZHkgY29tcGxldGVkIGFuZCB0aGUgZm9saW8gaXMgdXAgdG8gZGF0ZSwgdGhlIHdhaXQg aXMKbGlrZWx5IGR1ZSB0byBhIGNvbmN1cnJlbnQgUFRFIGluc3RhbGxhdGlvbi4gSW4gdGhpcyBj YXNlLCB3ZSBrZWVwIHRoZQpwZXItVk1BIGxvY2sgYW5kIGF2b2lkIHJldHJ5aW5nIHRoZSBwYWdl IGZhdWx0LgoKV2l0aCAoMSksIHRoZSBkcmFtYXRpY2FsbHkgcmVkdWNlZCBtbWFwX2xvY2sgY29u dGVudGlvbiBsZWFkcyB0byBhCnNpZ25pZmljYW50IGltcHJvdmVtZW50IGluIERvdXlpbiBwZXJm b3JtYW5jZS4gT3ZlbuKAmXMgZGF0YSBpcyBzaG93bgpiZWxvdy4KCkRvdXlpbiAodGhlIENoaW5l c2UgdmVyc2lvbiBvZiBUaWtUb2spIHdhcm0gc3RhcnQgb24gYSBzbWFydHBob25lIHdpdGgKOEdC IFJBTS4KCj09IG1tYXBfbG9jayBBY3F1aXNpdGlvbnMgQW5kIFdhaXQgVGltZSA9PQoKTWV0cmlj ICAgICAgICAgICAgICAgICAgICBCZWZvcmUgKEF2ZykgICAgQWZ0ZXIgKEF2ZykgICAgQ2hhbmdl Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQpSZWFkIExvY2sgQ291bnQgICAgICAgICAgIDIwLDAxMCAgICAgICAg ICA1LDcxOSAgICAgICAgICAtNzEuNDIlClJlYWQgVG90YWwgV2FpdCAodXMpICAgICAgMTAsNjk1 LDg3NyAgICAgNDA4LDQzNiAgICAgICAgLTk2LjE4JQpSZWFkIEF2ZyBXYWl0ICh1cykgICAgICAg IDUzNC4wMCAgICAgICAgIDcxLjAwICAgICAgICAgICAtODYuNzAlCldyaXRlIExvY2sgQ291bnQg ICAgICAgICAgODM4ICAgICAgICAgICAgIDkwOSAgICAgICAgICAgICs4LjQ3JQpXcml0ZSBUb3Rh bCBXYWl0ICh1cykgICAgIDUwMSwyOTMgICAgICAgIDk3LDYzMyAgICAgICAgICAtODAuNTIlCldy aXRlIEF2ZyBXYWl0ICh1cykgICAgICAgNTk4LjAwICAgICAgICAgMTA3LjAwICAgICAgICAgIC04 Mi4xMSUKCgo9PSBSZWFkIExvY2sgV2FpdGluZyBUaW1lIERpc3RyaWJ1dGlvbiBvZiBtbWFwX2xv Y2sgPT0KClJhbmdlICh1cykgICAgICAgICAgICAgICAgIEJlZm9yZSAoQXZnKSAgICBBZnRlciAo QXZnKSAgICBDaGFuZ2UKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClswLCAxKSAgICAgICAgICAgICAgICAgICAg IDksOTI3ICAgICAgICAgICA0LDI4NiAgICAgICAgICAtNTYuODIlClsxLCAxMCkgICAgICAgICAg ICAgICAgICAgIDksMTc5ICAgICAgICAgICAxLDMyNyAgICAgICAgICAtODUuNTQlClsxMCwgMTAw KSAgICAgICAgICAgICAgICAgIDE5MSAgICAgICAgICAgICA4OCAgICAgICAgICAgICAtNTMuOTMl ClsxMDAsIDEwMDApICAgICAgICAgICAgICAgIDU3ICAgICAgICAgICAgICA2ICAgICAgICAgICAg ICAtODkuNDclClsxMDAwLCAxMDAwMCkgICAgICAgICAgICAgIDMyOCAgICAgICAgICAgICA5ICAg ICAgICAgICAgICAtOTcuMjYlClsxMDAwMCwgMTAwMDAwKSAgICAgICAgICAgIDMyOCAgICAgICAg ICAgICA2ICAgICAgICAgICAgICAtOTguMTclClsxMDAwMDAsIDEwMDAwMDApICAgICAgICAgIDAg ICAgICAgICAgICAgICAwICAgICAgICAgICAgICBOL0EKWzEwMDAwMDAsICspICAgICAgICAgICAg ICAgMCAgICAgICAgICAgICAgIDAgICAgICAgICAgICAgIE4vQQoKPT0gV3JpdGUgTG9jayBXYWl0 aW5nIFRpbWUgRGlzdHJpYnV0aW9uIG9mIG1tYXBfbG9jayA9PQoKUmFuZ2UgKHVzKSAgICAgICAg ICAgICAgICAgQmVmb3JlIChBdmcpICAgIEFmdGVyIChBdmcpICAgIENoYW5nZQotLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0KWzAsIDEpICAgICAgICAgICAgICAgICAgICAgMjUwICAgICAgICAgICAgIDMwMCAgICAg ICAgICAgICsyMC4wMCUKWzEsIDEwKSAgICAgICAgICAgICAgICAgICAgNDgzICAgICAgICAgICAg IDU1NiAgICAgICAgICAgICsxNS4xMSUKWzEwLCAxMDApICAgICAgICAgICAgICAgICAgNTIgICAg ICAgICAgICAgIDQxICAgICAgICAgICAgIC0yMS4xNSUKWzEwMCwgMTAwMCkgICAgICAgICAgICAg ICAgMTIgICAgICAgICAgICAgIDUgICAgICAgICAgICAgIC01OC4zMyUKWzEwMDAsIDEwMDAwKSAg ICAgICAgICAgICAgMjIgICAgICAgICAgICAgIDQgICAgICAgICAgICAgIC04MS44MiUKWzEwMDAw LCAxMDAwMDApICAgICAgICAgICAgMTYgICAgICAgICAgICAgIDEgICAgICAgICAgICAgIC05My43 NSUKWzEwMDAwMCwgMTAwMDAwMCkgICAgICAgICAgMCAgICAgICAgICAgICAgIDAgICAgICAgICAg ICAgIE4vQQpbMTAwMDAwMCwgKykgICAgICAgICAgICAgICAwICAgICAgICAgICAgICAgMCAgICAg ICAgICAgICAgTi9BCgpBZnRlciB0aGUgb3B0aW1pemF0aW9uLCB0aGUgbnVtYmVyIG9mIHJlYWQg bG9jayBhY3F1aXNpdGlvbnMgaXMgCnNpZ25pZmljYW50bHkgcmVkdWNlZCwgYW5kIGJvdGggbG9j ayB3YWl0aW5nIHRpbWUgYW5kIHRhaWwgbGF0ZW5jeSBhcmUgCmRyYW1hdGljYWxseSBpbXByb3Zl ZC4KCkt1bnd1IGFuZCBMaWFuIGFsc28gZGV2ZWxvcGVkIGEgbW9kZWwgdG8gY2FwdHVyZSB0aGUg c2l0dWF0aW9uIGRlc2NyaWJlZApieSBNYXR0aGV3IFsxXSwgd2hlcmUgYSBtZW1jZyB3aXRoIGxp bWl0ZWQgbWVtb3J5IG1heSBmYWlsIHRvIG1ha2UKcHJvZ3Jlc3MuIFRoaXMgaGFwcGVucyBiZWNh dXNlIGFmdGVyIEkvTyBpcyBpbml0aWF0ZWQgb24gdGhlIGZpcnN0IHBhZ2UKZmF1bHQsIHRoZSBm b2xpb3MgbWF5IGJlIHJlY2xhaW1lZCBieSB0aGUgdGltZSBvZiB0aGUgcmV0cnksIGxlYXZpbmcg dGhlCndvcmtsb2FkIHdpdGggbGl0dGxlIG9yIG5vIGZvcndhcmQgcHJvZ3Jlc3MuCgpBIHN0cmVz cyBzZXR1cCBtYWRlIGJ5IEt1bnd1IGFuZCBMaWFuIGFzIGZvbGxvd3M6CiogMjU2LWNvcmUgeDg2 IHN5c3RlbQoqIDUwMCB0aHJlYWRzIGNvbnRpbnVvdXNseSBmYXVsdGluZyBvbiAxNk1CIGZpbGVz CgpUaGUgbW9kZWwgd2FzIHJ1bm5pbmcgd2l0aGluIGEgbWVtY2cgd2l0aCBsaW1pdGVkIG1lbW9y eSwKYXMgc2hvd24gYmVsb3c6CgpzeXN0ZW1kLXJ1biAtLXNjb3BlIC1wIE1lbW9yeUhpZ2g9MUcg LXAgTWVtb3J5TWF4PTEuMkcgLXAgTWVtb3J5U3dhcE1heD0wIFwKLS11bml0PW1tYXAtdGhyYXNo LSQkIC4vbW1hcF9sb2NrICYgXApURVNUX1BJRD0kIQoKVGhlIHJlcHJvZHVjZXIgY29kZSBpcyBz aG93biBiZWxvdzoKCiAjZGVmaW5lIFRIUkVBRFMgNTAwIAogI2RlZmluZSBGSUxFX1NJWkUgKDE2 ICogMTAyNCAqIDEwMjQpIC8qIDE2TUIgKi8gCiBzdGF0aWMgX0F0b21pYyBpbnQgZ19zdG9wID0g MDsgCiAjZGVmaW5lIFJVTl9TRUNPTkRTIDYwMCAKIAogc3RydWN0IHdvcmtlcl9hcmcgeyAKICAg ICAgICAgbG9uZyBpZDsgCiAgICAgICAgIHVpbnQ2NF90ICpjb3VudHM7IAogfTsgCiAKIHZvaWQg Kndvcmtlcih2b2lkICphcmcpIAogeyAKICAgICAgICAgc3RydWN0IHdvcmtlcl9hcmcgKndhID0g KHN0cnVjdCB3b3JrZXJfYXJnICopYXJnOyAKICAgICAgICAgbG9uZyBpZCA9IHdhLT5pZDsgCiAg ICAgICAgIGNoYXIgcGF0aFs2NF07IAogICAgICAgICB1aW50NjRfdCBsb2NhbF9yb3VuZHMgPSAw OyAKIAogICAgICAgICBzbnByaW50ZihwYXRoLCBzaXplb2YocGF0aCksICIuL3Rlc3RfZmlsZV8l ZF8lbGQuZGF0IiwgCiAgICAgICAgICAgICAgICAgIGdldHBpZCgpLCBpZCk7IAogICAgICAgICBp bnQgZmQgPSBvcGVuKHBhdGgsIE9fUkRXUiB8IE9fQ1JFQVQgfCBPX1RSVU5DLCAwNjY2KTsgCiAg ICAgICAgIGlmIChmZCA8IDApIHJldHVybiBOVUxMOyAKICAgICAgICAgaWYgKGZ0cnVuY2F0ZShm ZCwgRklMRV9TSVpFKSA8IDApIHsgCiAgICAgICAgICAgICAgICAgY2xvc2UoZmQpOyByZXR1cm4g TlVMTDsgCiAgICAgICAgIH0gCiAKICAgICAgICAgd2hpbGUgKCFhdG9taWNfbG9hZF9leHBsaWNp dCgmZ19zdG9wLCBtZW1vcnlfb3JkZXJfcmVsYXhlZCkpIHsgCiAgICAgICAgICAgICAgICAgY2hh ciAqZl9tYXAgPSBtbWFwKE5VTEwsIEZJTEVfU0laRSwgUFJPVF9SRUFELCAKICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgTUFQX1NIQVJFRCwgZmQsIDApOyAKICAgICAgICAgICAg ICAgICBpZiAoZl9tYXAgIT0gTUFQX0ZBSUxFRCkgeyAKICAgICAgICAgICAgICAgICAgICAgICAg IC8qIFB1cmUgcGFnZSBjYWNoZSB0aHJhc2hpbmcgKi8gCiAgICAgICAgICAgICAgICAgICAgICAg ICBmb3IgKGludCBpID0gMDsgaSA8IEZJTEVfU0laRTsgaSArPSA0MDk2KSB7IAogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB2b2xhdGlsZSB1bnNpZ25lZCBjaGFyIGMgPSAKICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhcilmX21hcFtp XTsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKWM7IAogICAgICAgICAg ICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgICAgICAgICAgIG11bm1hcChmX21hcCwg RklMRV9TSVpFKTsgCiAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbF9yb3VuZHMrKzsgCiAg ICAgICAgICAgICAgICAgfSAKICAgICAgICAgfSAKICAgICAgICAgd2EtPmNvdW50c1tpZF0gPSBs b2NhbF9yb3VuZHM7IAogICAgICAgICBjbG9zZShmZCk7IAogICAgICAgICB1bmxpbmsocGF0aCk7 IAogICAgICAgICByZXR1cm4gTlVMTDsgCiB9IAogCiBpbnQgbWFpbih2b2lkKSAKIHsgCiAgICAg ICAgIHByaW50ZigiUHVyZSBGaWxlIFRocmFzaGluZyBTdGFydGVkLiBQSUQ6ICVkXG4iLCBnZXRw aWQoKSk7IAogICAgICAgICBwdGhyZWFkX3QgdFtUSFJFQURTXTsgCiAgICAgICAgIHVpbnQ2NF90 IGxvY2FsX2NvdW50c1tUSFJFQURTXTsgCiAgICAgICAgIG1lbXNldChsb2NhbF9jb3VudHMsIDAs IHNpemVvZihsb2NhbF9jb3VudHMpKTsgCiAgICAgICAgIHN0cnVjdCB3b3JrZXJfYXJnIGFyZ3Nb VEhSRUFEU107IAogCiAgICAgICAgIGZvciAobG9uZyBpID0gMDsgaSA8IFRIUkVBRFM7IGkrKykg eyAKICAgICAgICAgICAgICAgICBhcmdzW2ldLmlkID0gaTsgCiAgICAgICAgICAgICAgICAgYXJn c1tpXS5jb3VudHMgPSBsb2NhbF9jb3VudHM7IAogICAgICAgICAgICAgICAgIHB0aHJlYWRfY3Jl YXRlKCZ0W2ldLCBOVUxMLCB3b3JrZXIsICZhcmdzW2ldKTsgCiAgICAgICAgIH0gCiAKICAgICAg ICAgc2xlZXAoUlVOX1NFQ09ORFMpOyAKICAgICAgICAgYXRvbWljX3N0b3JlX2V4cGxpY2l0KCZn X3N0b3AsIDEsIG1lbW9yeV9vcmRlcl9yZWxheGVkKTsgCiAKICAgICAgICAgZm9yIChpbnQgaSA9 IDA7IGkgPCBUSFJFQURTOyBpKyspIHB0aHJlYWRfam9pbih0W2ldLCBOVUxMKTsgCiAKICAgICAg ICAgdWludDY0X3QgdG90YWwgPSAwOyAKICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBUSFJF QURTOyBpKyspIHRvdGFsICs9IGxvY2FsX2NvdW50c1tpXTsgCiAKICAgICAgICAgcHJpbnRmKCJU b3RhbCByb3VuZHMgICAgIDogJWxsdVxuIiwgKHVuc2lnbmVkIGxvbmcgbG9uZyl0b3RhbCk7IAog ICAgICAgICBwcmludGYoIlRocm91Z2hwdXQgICAgICAgOiAlLjJmIHJvdW5kcy9zZWNcbiIsIAog ICAgICAgICAgICAgICAgKGRvdWJsZSl0b3RhbCAvIFJVTl9TRUNPTkRTKTsgCiAgICAgICAgIHJl dHVybiAwOyAKIH0KClRoZXkgYWxzbyBhZGRlZCB0ZW1wb3JhcnkgY291bnRlcnMgaW4gcGFnZSBm YXVsdCByZXRyaWVzIFsyXToKLSBSRVRSWV9JT19NSVNTICAgOiBmb2xpbyBub3QgcHJlc2VudCBh ZnRlciBJL08gY29tcGxldGlvbgotIFJFVFJZX01NQVBfRFJPUCA6IHJldHJ5IGZhbGxiYWNrIGR1 ZSB0byB3YWl0aW5nIGZvciBJL08KClRoZWlyIHJlc3VsdHMgYXJlIGFzIGZvbGxvd3M6Cgp8IENh c2UgICAgICAgICAgICAgICAgfCBUb3RhbCBSb3VuZHMgfCBUaHJvdWdocHV0IHwgTWlzcy9Ecm9w KCUpIHwgUkVUUllfTU1BUF9EUk9QIHwgUkVUUllfSU9fTUlTUyB8CnwgLS0tLS0tLS0tLS0tLS0t LS0tLSB8IC0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0gfCAtLS0tLS0t LS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tIHwKfCBCYXNlbGluZSAoUnVuIDEpICAgIHwgMjIsNzEx ICAgICAgIHwgMzcuODUgL3MgICB8IDQ1LjA0ICAgICAgICB8IDk3MCwwNzggICAgICAgICB8IDQz Niw5NTYgICAgICAgfAp8IEJhc2VsaW5lIChSdW4gMikgICAgfCAyMyw1MzAgICAgICAgfCAzOS4y MiAvcyAgIHwgNDQuOTYgICAgICAgIHwgOTcyLDA0MyAgICAgICAgIHwgNDM3LDA3NyAgICAgICB8 CnwgV2l0aCBTZXJpZXMgKFJ1biBBKSB8IDU0LDQyOCAgICAgICB8IDkwLjcxIC9zICAgfCAxLjY5 ICAgICAgICAgfCAxLDIwNCwxMjQgICAgICAgfCAyMCwzOTggICAgICAgIHwKfCBXaXRoIFNlcmll cyAoUnVuIEIpIHwgMzUsOTQ5ICAgICAgIHwgNTkuOTEgL3MgICB8IDAuMDMgICAgICAgICB8IDMy NywwMjMgICAgICAgICB8IDk5ICAgICAgICAgICAgfAoKV2l0aG91dCB0aGlzIHNlcmllcywgbmVh cmx5IGhhbGYgb2YgdGhlIHJldHJpZXMgZmFpbCB0byBvYnNlcnZlIGNvbXBsZXRlZApJL08gcmVz dWx0cywgbGVhZGluZyB0byBzaWduaWZpY2FudCBDUFUgYW5kIEkvTyB3YXN0ZS4gV2l0aCB0aGUg ZmluZXItCmdyYWluZWQgVk1BIGxvY2ssIGZhdWx0aW5nIHRocmVhZHMgYXZvaWQgdGhlIGhlYXZp bHkgY29udGVuZGVkIG1tYXBfbG9jawpkdXJpbmcgcmV0cmllcyBhbmQgYXJlIHRoZXJlZm9yZSBh YmxlIHRvIGNvbXBsZXRlIHRoZSBwYWdlIGZhdWx0LgoKV2l0aCAoMiksIHRoZXJlIGlzIGEgY2xl YXIgaW1wcm92ZW1lbnQgaW4gc3dhcC1pbiBiYW5kd2lkdGggaW4gYSBtb2RlbAp3aXRoIGZpdmUg dGhyZWFkcyBpc3N1aW5nIE1BRFZfUEFHRU9VVC1iYXNlZCBzd2FwLW91dHMgYW5kIGZpdmUgdGhy ZWFkcwpwZXJmb3JtaW5nIHN3YXAtaW5zIG9uIGEgMTAwTUIgYW5vbnltb3VzIG1tYXAgVk1BLgoK ICNkZWZpbmUgU0laRSAoMTAwICogMTAyNCAqIDEwMjQpCiAjZGVmaW5lIFBBR0VfU0laRSA0MDk2 CiAjZGVmaW5lIFdSSVRFUl9USFJFQURTIDUKICNkZWZpbmUgUkVBREVSX1RIUkVBRFMgNQogI2Rl ZmluZSBSVU5fU0VDT05EUyAzMAogCiBzdGF0aWMgdWludDhfdCAqYnVmOwogc3RhdGljIGF0b21p Y191bG9uZyBwYWdlb3V0X3JvdW5kcyA9IDA7CiBzdGF0aWMgYXRvbWljX3Vsb25nIHN3YXBpbl9y b3VuZHMgPSAwOwogc3RhdGljIGF0b21pY19pbnQgc3RvcF9mbGFnID0gMDsKIAogc3RhdGljIHZv aWQgKnBhZ2VvdXRfdGhyZWFkKHZvaWQgKmFyZykKIHsKICAgICAodm9pZClhcmc7CiAgICAgd2hp bGUgKCFhdG9taWNfbG9hZCgmc3RvcF9mbGFnKSkgewogICAgICAgICBpZiAobWFkdmlzZShidWYs IFNJWkUsIE1BRFZfUEFHRU9VVCkgPT0gMCkgewogICAgICAgICAgICAgYXRvbWljX2ZldGNoX2Fk ZCgmcGFnZW91dF9yb3VuZHMsIDEpOwogICAgICAgICB9CiAgICAgfQogICAgIHJldHVybiBOVUxM OwogfQogCiBzdGF0aWMgdm9pZCAqcmVhZGVyX3RocmVhZCh2b2lkICphcmcpCiB7CiAgICAgKHZv aWQpYXJnOwogICAgIHZvbGF0aWxlIHVpbnQ2NF90IHN1bSA9IDA7CiAKICAgICB3aGlsZSAoIWF0 b21pY19sb2FkKCZzdG9wX2ZsYWcpKSB7CiAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwg U0laRTsgaSArPSBQQUdFX1NJWkUpIHsKICAgICAgICAgICAgIHN1bSArPSBidWZbaV07CiAgICAg ICAgIH0KICAgICAgICAgLyogT25lIGZ1bGwgcGFzcyBvdmVyIDEwME1CLCBjb3VudGVkIGFzIG9u ZSBzd2FwLWluIHJvdW5kIChhcHByb3hpbWF0ZSkgKi8KICAgICAgICAgYXRvbWljX2ZldGNoX2Fk ZCgmc3dhcGluX3JvdW5kcywgMSk7CiAgICAgfQogICAgIHJldHVybiBOVUxMOwogfQogCiBpbnQg bWFpbih2b2lkKQogewogICAgIHB0aHJlYWRfdCB3cml0ZXJzW1dSSVRFUl9USFJFQURTXTsKICAg ICBwdGhyZWFkX3QgcmVhZGVyc1tSRUFERVJfVEhSRUFEU107CiAKICAgICBidWYgPSBtbWFwKE5V TEwsIFNJWkUsIFBST1RfUkVBRCB8IFBST1RfV1JJVEUsCiAgICAgICAgICAgICAgICBNQVBfUFJJ VkFURSB8IE1BUF9BTk9OWU1PVVMsIC0xLCAwKTsKICAgICBpZiAoYnVmID09IE1BUF9GQUlMRUQp IHsKICAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgIH0KICAgICBtZW1zZXQoYnVmLCAw LCBTSVpFKTsKIAogICAgIGZvciAoaW50IGkgPSAwOyBpIDwgV1JJVEVSX1RIUkVBRFM7IGkrKykg ewogICAgICAgICBpZiAocHRocmVhZF9jcmVhdGUoJndyaXRlcnNbaV0sIE5VTEwsIHBhZ2VvdXRf dGhyZWFkLCBOVUxMKSAhPSAwKSB7CiAgICAgICAgICAgICBwZXJyb3IoInB0aHJlYWRfY3JlYXRl Iik7CiAgICAgICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICAgICAgIH0KICAgICB9CiAg ICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUFERVJfVEhSRUFEUzsgaSsrKSB7CiAgICAgICAgIGlm IChwdGhyZWFkX2NyZWF0ZSgmcmVhZGVyc1tpXSwgTlVMTCwgcmVhZGVyX3RocmVhZCwgTlVMTCkg IT0gMCkgewogICAgICAgICAgICAgcGVycm9yKCJwdGhyZWFkX2NyZWF0ZSIpOwogICAgICAgICAg ICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgICAgICB9CiAgICAgfQogCiAgICAgc2xlZXAoUlVO X1NFQ09ORFMpOwogICAgIGF0b21pY19zdG9yZSgmc3RvcF9mbGFnLCAxKTsKICAgICBmb3IgKGlu dCBpID0gMDsgaSA8IFdSSVRFUl9USFJFQURTOyBpKyspCiAgICAgICAgIHB0aHJlYWRfam9pbih3 cml0ZXJzW2ldLCBOVUxMKTsKICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQURFUl9USFJFQURT OyBpKyspCiAgICAgICAgIHB0aHJlYWRfam9pbihyZWFkZXJzW2ldLCBOVUxMKTsKIAogICAgIHBy aW50ZigiPT09IFJlc3VsdCAoMzBzKSA9PT1cbiIpOwogICAgIHByaW50ZigiUGFnZW91dCByb3Vu ZHM6ICVsdVxuIiwgcGFnZW91dF9yb3VuZHMpOwogICAgIHByaW50ZigiU3dhcC1pbiByb3VuZHMg KGFwcHJveCk6ICVsdVxuIiwgc3dhcGluX3JvdW5kcyk7CiAgICAgbXVubWFwKGJ1ZiwgU0laRSk7 CiAgICAgcmV0dXJuIDA7CiB9CgpXL28gcGF0Y2hlczoKPT09IFJlc3VsdCAoMzBzKSA9PT0KUGFn ZW91dCByb3VuZHM6IDEzMjQ4NDcKU3dhcC1pbiByb3VuZHMgKGFwcHJveCk6IDg3NAoKVy9wYXRj aGVzOgo9PT0gUmVzdWx0ICgzMHMpID09PQpQYWdlb3V0IHJvdW5kczogMTMzMDU1MApTd2FwLWlu IHJvdW5kcyAoYXBwcm94KTogMTAxNwoKWzFdIGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2xpbnV4 LW1tL2FTaXAybVdYMTNzcVBXX2xAY2FzcGVyLmluZnJhZGVhZC5vcmcvClsyXSBodHRwczovL2dp dGh1Yi5jb20vbGlhbnV4LW1tL2lvcmV0cnlfdGVzdC8KCi12MjoKICAqIGNvbGxlY3QgdGFncyBm cm9tIFBlZHJvLCBLdW53dSBhbmQgTGlhbiwgdGhhbmtzIQogICogaGFuZGxlIGNhc2UgKDIpLCBm b3IgdXB0b2RhdGUgZm9saW9zLCBkb24ndCByZXRyeSBQRgotUkZDOgogIGh0dHBzOi8vbG9yZS5r ZXJuZWwub3JnL2xpbnV4LW1tLzIwMjUxMTI3MDExNDM4LjY5MTgtMS0yMWNuYmFvQGdtYWlsLmNv bS8KCkJhcnJ5IFNvbmcgKFhpYW9taSkgKDQpOgogIG1tL3N3YXBpbjogUmV0cnkgc3dhcGluIGJ5 IFZNQSBsb2NrIGlmIHRoZSBsb2NrIHdhcyByZWxlYXNlZCBmb3IgSS9PCiAgbW06IE1vdmUgZm9s aW9fbG9ja19vcl9yZXRyeSgpIGFuZCBkcm9wIF9fZm9saW9fbG9ja19vcl9yZXRyeSgpCiAgbW06 IERvbid0IHJldHJ5IHBhZ2UgZmF1bHQgaWYgZm9saW8gaXMgdXB0b2RhdGUgZHVyaW5nIHN3YXAt aW4KICBtbS9maWxlbWFwOiBBdm9pZCByZXRyeWluZyBwYWdlIGZhdWx0cyBvbiB1cHRvZGF0ZSBm b2xpb3MgaW4gZmlsZW1hcAogICAgZmF1bHRzCgpPdmVuIExpeWFuZyAoMSk6CiAgbW0vZmlsZW1h cDogUmV0cnkgZmF1bHQgYnkgVk1BIGxvY2sgaWYgdGhlIGxvY2sgd2FzIHJlbGVhc2VkIGZvciBJ L08KCiBhcmNoL2FybS9tbS9mYXVsdC5jICAgICAgIHwgIDUgKysrCiBhcmNoL2FybTY0L21tL2Zh dWx0LmMgICAgIHwgIDUgKysrCiBhcmNoL2xvb25nYXJjaC9tbS9mYXVsdC5jIHwgIDQgKysrCiBh cmNoL3Bvd2VycGMvbW0vZmF1bHQuYyAgIHwgIDUgKystCiBhcmNoL3Jpc2N2L21tL2ZhdWx0LmMg ICAgIHwgIDQgKysrCiBhcmNoL3MzOTAvbW0vZmF1bHQuYyAgICAgIHwgIDQgKysrCiBhcmNoL3g4 Ni9tbS9mYXVsdC5jICAgICAgIHwgIDQgKysrCiBpbmNsdWRlL2xpbnV4L21tX3R5cGVzLmggIHwg IDkgKystLS0KIGluY2x1ZGUvbGludXgvcGFnZW1hcC5oICAgfCAxNyAtLS0tLS0tLS0tCiBtbS9m aWxlbWFwLmMgICAgICAgICAgICAgIHwgNTcgKysrKysrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQogbW0vbWVtb3J5LmMgICAgICAgICAgICAgICB8IDcwICsrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKystLQogMTEgZmlsZXMgY2hhbmdlZCwgMTE0IGluc2VydGlvbnMoKyksIDcw IGRlbGV0aW9ucygtKQoKLS0gCiogVGhlIHdvcmsgYmVnYW4gZHVyaW5nIG15IGNvbGxhYm9yYXRp b24gd2l0aCBPUFBPIGFuZCBoYXMgY29udGludWVkIHRocm91Z2gKbXkgY3VycmVudCBjb2xsYWJv cmF0aW9uIHdpdGggWGlhb21pLiBBbHRob3VnaCB0aGUgT1BQTyBjb2xsYWJvcmF0aW9uIGhhcwpl bmRlZCwgT1BQTyBzdGlsbCBkZXNlcnZlcyBtb3JlIHRoYW4gaGFsZiBvZiB0aGUgY3JlZGl0IGZv ciB0aGlzIHNlcmllcywKaWYgYW55IGNyZWRpdCBpcyB0byBiZSBhc3NpZ25lZC4KCjIuMzkuMyAo QXBwbGUgR2l0LTE0NikKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51eC1yaXNjdkBsaXN0cy5pbmZyYWRl YWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgt cmlzY3YK