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 AF218C433EF for ; Thu, 14 Apr 2022 06:03:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239917AbiDNGFy (ORCPT ); Thu, 14 Apr 2022 02:05:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38236 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237010AbiDNGFw (ORCPT ); Thu, 14 Apr 2022 02:05:52 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DF2D1B7AB; Wed, 13 Apr 2022 23:03:26 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id c6so4994624edn.8; Wed, 13 Apr 2022 23:03:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=fhA5BymqZ4e+SI6zc/bl76P99FRTbpdXYhS7zgXjwvI=; b=TPRKpEemhQ9lNQexIZNeTC5yOgXcrmtzEt9CkbAuth/bvWz2mQZekUJ/ik/D5DutSS FxPO30nPNk6PgbYmA+F1a7BP8AKMHfBRAeKg7iBnCZMCahlNOCDBBPBeyT/9eA2ugH5Y /2m5Ut3DUVoms+C7PCDyGL3zVBqjD0EkDnGEa8KdQseP2Tt80Tyen4MtFFj9ov43RkBB dVrT0n9iZFvQxeYr1DORVazOdUcjGhq88WqxXWEjYQEz8KmEgZSz6Ks7wjDvJpZzP5eo r/03Mz6ZhL2TWmH15L6Nl+5PtwXLG8Ck3eo+z/TAWfZokvukDrXkeCNkS10Y8SUxyQ5n uaBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=fhA5BymqZ4e+SI6zc/bl76P99FRTbpdXYhS7zgXjwvI=; b=zNYcX/czLyX7Ob6RR+nhwaMGHclJ8/vh8QCBanqLjSh8YK5iOOciwLH0RXnVQbUdXF +Fa66kbER5zl9gFYahQUFGjChmN7xHTEQINUddBknwaomKxclL/mzOheKVbe/lPj/squ J0QQXnrgv1m4+prxtZhcoSPhRfQe1xjQ3gtgMKOeyea69HOMFvO+A9pS6n+UhtKS4Idj o43MvMc3Jdx5pMbN8iNC8GMh/8NoR32UqIrzMQTENAbHX6uFRRAIHUUD4hLHbZp0wSWq lEkDfYotAq9ezSoWD+Hr/V1cyiEwIVwkb9Pviv8erJAB7jwiX5C5ejim76lxk4/4Tzul hrtA== X-Gm-Message-State: AOAM5313gknmRm57WhHMnXk0q1DCBh+1wslsLW8oggxtuJ2F0FMHT7bi uReQWXtoBO8w0eXnVw1mEtrh/fZVuWHuB/BJu+8= X-Google-Smtp-Source: ABdhPJyuBD9RI5lRXTwZjYRu356H0kJGf5Q9CjOQQbFjlPhMaspIlBONTiwWMn9mTFlg6XgRrrUnNhLvQN9FuymIz6s= X-Received: by 2002:a05:6402:1695:b0:41d:6b06:f81 with SMTP id a21-20020a056402169500b0041d6b060f81mr1252015edv.98.1649916204113; Wed, 13 Apr 2022 23:03:24 -0700 (PDT) MIME-Version: 1.0 References: <20220407031525.2368067-1-yuzhao@google.com> <20220407031525.2368067-7-yuzhao@google.com> In-Reply-To: <20220407031525.2368067-7-yuzhao@google.com> From: Barry Song <21cnbao@gmail.com> Date: Thu, 14 Apr 2022 18:03:10 +1200 Message-ID: Subject: Re: [PATCH v10 06/14] mm: multi-gen LRU: minimal implementation To: Yu Zhao Cc: Stephen Rothwell , Linux-MM , Andi Kleen , Andrew Morton , Aneesh Kumar , Catalin Marinas , Dave Hansen , Hillf Danton , Jens Axboe , Jesse Barnes , Johannes Weiner , Jonathan Corbet , Linus Torvalds , Matthew Wilcox , Mel Gorman , Michael Larabel , Michal Hocko , Mike Rapoport , Rik van Riel , Vlastimil Babka , Will Deacon , Ying Huang , LAK , Linux Doc Mailing List , LKML , Kernel Page Reclaim v2 , x86 , Brian Geffon , Jan Alexander Steffens , Oleksandr Natalenko , Steven Barrett , Suleiman Souhlal , Daniel Byrne , Donald Carr , =?UTF-8?Q?Holger_Hoffst=C3=A4tte?= , Konstantin Kharlamov , Shuang Zhai , Sofia Trinh , Vaibhav Jain Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org () On Thu, Apr 7, 2022 at 3:16 PM Yu Zhao wrote: > > To avoid confusion, the terms "promotion" and "demotion" will be > applied to the multi-gen LRU, as a new convention; the terms > "activation" and "deactivation" will be applied to the active/inactive > LRU, as usual. > > The aging produces young generations. Given an lruvec, it increments > max_seq when max_seq-min_seq+1 approaches MIN_NR_GENS. The aging > promotes hot pages to the youngest generation when it finds them > accessed through page tables; the demotion of cold pages happens > consequently when it increments max_seq. The aging has the complexity > O(nr_hot_pages), since it is only interested in hot pages. Promotion > in the aging path does not require any LRU list operations, only the > updates of the gen counter and lrugen->nr_pages[]; demotion, unless as > the result of the increment of max_seq, requires LRU list operations, > e.g., lru_deactivate_fn(). > > The eviction consumes old generations. Given an lruvec, it increments > min_seq when the lists indexed by min_seq%MAX_NR_GENS become empty. A > feedback loop modeled after the PID controller monitors refaults over > anon and file types and decides which type to evict when both types > are available from the same generation. > > Each generation is divided into multiple tiers. Tiers represent > different ranges of numbers of accesses through file descriptors. A > page accessed N times through file descriptors is in tier > order_base_2(N). Tiers do not have dedicated lrugen->lists[], only > bits in folio->flags. In contrast to moving across generations, which > requires the LRU lock, moving across tiers only involves operations on > folio->flags. The feedback loop also monitors refaults over all tiers > and decides when to protect pages in which tiers (N>1), using the > first tier (N=3D0,1) as a baseline. The first tier contains single-use > unmapped clean pages, which are most likely the best choices. The > eviction moves a page to the next generation, i.e., min_seq+1, if the > feedback loop decides so. This approach has the following advantages: > 1. It removes the cost of activation in the buffered access path by > inferring whether pages accessed multiple times through file > descriptors are statistically hot and thus worth protecting in the > eviction path. > 2. It takes pages accessed through page tables into account and avoids > overprotecting pages accessed multiple times through file > descriptors. (Pages accessed through page tables are in the first > tier, since N=3D0.) > 3. More tiers provide better protection for pages accessed more than > twice through file descriptors, when under heavy buffered I/O > workloads. > > Server benchmark results: > Single workload: > fio (buffered I/O): +[40, 42]% > IOPS BW > 5.18-rc1: 2463k 9621MiB/s > patch1-6: 3484k 13.3GiB/s > > Single workload: > memcached (anon): +[44, 46]% > Ops/sec KB/sec > 5.18-rc1: 771403.27 30004.17 > patch1-6: 1120643.70 43588.06 > > Configurations: > CPU: two Xeon 6154 > Mem: total 256G > > Node 1 was only used as a ram disk to reduce the variance in the > results. > > patch drivers/block/brd.c < 99,100c99,100 > < gfp_flags =3D GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM; > < page =3D alloc_page(gfp_flags); > --- > > gfp_flags =3D GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM | __GFP_THISN= ODE; > > page =3D alloc_pages_node(1, gfp_flags, 0); > EOF > > cat >>/etc/systemd/system.conf < CPUAffinity=3Dnuma > NUMAPolicy=3Dbind > NUMAMask=3D0 > EOF > > cat >>/etc/memcached.conf < -m 184320 > -s /var/run/memcached/memcached.sock > -a 0766 > -t 36 > -B binary > EOF > > cat fio.sh > modprobe brd rd_nr=3D1 rd_size=3D113246208 > swapoff -a > mkfs.ext4 /dev/ram0 > mount -t ext4 /dev/ram0 /mnt > > mkdir /sys/fs/cgroup/user.slice/test > echo 38654705664 >/sys/fs/cgroup/user.slice/test/memory.max > echo $$ >/sys/fs/cgroup/user.slice/test/cgroup.procs > fio -name=3Dmglru --numjobs=3D72 --directory=3D/mnt --size=3D1408m \ > --buffered=3D1 --ioengine=3Dio_uring --iodepth=3D128 \ > --iodepth_batch_submit=3D32 --iodepth_batch_complete=3D32 \ > --rw=3Drandread --random_distribution=3Drandom --norandommap \ > --time_based --ramp_time=3D10m --runtime=3D5m --group_reporting > > cat memcached.sh > modprobe brd rd_nr=3D1 rd_size=3D113246208 > swapoff -a > mkswap /dev/ram0 > swapon /dev/ram0 > > memtier_benchmark -S /var/run/memcached/memcached.sock \ > -P memcache_binary -n allkeys --key-minimum=3D1 \ > --key-maximum=3D65000000 --key-pattern=3DP:P -c 1 -t 36 \ > --ratio 1:0 --pipeline 8 -d 2000 > > memtier_benchmark -S /var/run/memcached/memcached.sock \ > -P memcache_binary -n allkeys --key-minimum=3D1 \ > --key-maximum=3D65000000 --key-pattern=3DR:R -c 1 -t 36 \ > --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed > > Client benchmark results: > kswapd profiles: > 5.18-rc1 > 40.53% page_vma_mapped_walk > 20.37% lzo1x_1_do_compress (real work) > 6.99% do_raw_spin_lock > 3.93% _raw_spin_unlock_irq > 2.08% vma_interval_tree_subtree_search > 2.06% vma_interval_tree_iter_next > 1.95% folio_referenced_one > 1.93% anon_vma_interval_tree_iter_first > 1.51% ptep_clear_flush > 1.35% __anon_vma_interval_tree_subtree_search > > patch1-6 > 35.99% lzo1x_1_do_compress (real work) > 19.40% page_vma_mapped_walk > 6.31% _raw_spin_unlock_irq > 3.95% do_raw_spin_lock > 2.39% anon_vma_interval_tree_iter_first > 2.25% ptep_clear_flush > 1.92% __anon_vma_interval_tree_subtree_search > 1.70% folio_referenced_one > 1.68% __zram_bvec_write > 1.43% anon_vma_interval_tree_iter_next > > Configurations: > CPU: single Snapdragon 7c > Mem: total 4G > > Chrome OS MemoryPressure [1] > > [1] https://chromium.googlesource.com/chromiumos/platform/tast-tests/ > > Signed-off-by: Yu Zhao > Acked-by: Brian Geffon > Acked-by: Jan Alexander Steffens (heftig) > Acked-by: Oleksandr Natalenko > Acked-by: Steven Barrett > Acked-by: Suleiman Souhlal > Tested-by: Daniel Byrne > Tested-by: Donald Carr > Tested-by: Holger Hoffst=C3=A4tte > Tested-by: Konstantin Kharlamov > Tested-by: Shuang Zhai > Tested-by: Sofia Trinh > Tested-by: Vaibhav Jain > --- > include/linux/mm_inline.h | 24 ++ > include/linux/mmzone.h | 41 ++ > kernel/bounds.c | 2 +- > mm/Kconfig | 11 + > mm/swap.c | 42 ++ > mm/vmscan.c | 805 +++++++++++++++++++++++++++++++++++++- > mm/workingset.c | 119 +++++- > 7 files changed, 1040 insertions(+), 4 deletions(-) > > diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h > index 9abd72a95462..8a8f87b72540 100644 > --- a/include/linux/mm_inline.h > +++ b/include/linux/mm_inline.h > @@ -119,6 +119,19 @@ static inline int lru_gen_from_seq(unsigned long seq= ) > return seq % MAX_NR_GENS; > } > > +static inline int lru_hist_from_seq(unsigned long seq) > +{ > + return seq % NR_HIST_GENS; > +} > + > +static inline int lru_tier_from_refs(int refs) > +{ > + VM_BUG_ON(refs > BIT(LRU_REFS_WIDTH)); > + > + /* see the comment on MAX_NR_TIERS */ > + return order_base_2(refs + 1); > +} > + > static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen) > { > unsigned long max_seq =3D lruvec->lrugen.max_seq; > @@ -164,6 +177,15 @@ static inline void lru_gen_update_size(struct lruvec= *lruvec, struct folio *foli > __update_lru_size(lruvec, lru, zone, -delta); > return; > } > + > + /* promotion */ > + if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruv= ec, new_gen)) { > + __update_lru_size(lruvec, lru, zone, -delta); > + __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta); > + } > + > + /* demotion requires isolation, e.g., lru_deactivate_fn() */ > + VM_BUG_ON(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_activ= e(lruvec, new_gen)); > } > > static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio= *folio, bool reclaiming) > @@ -229,6 +251,8 @@ static inline bool lru_gen_del_folio(struct lruvec *l= ruvec, struct folio *folio, > gen =3D ((new_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1= ; > > new_flags &=3D ~LRU_GEN_MASK; > + if (!(new_flags & BIT(PG_referenced))) > + new_flags &=3D ~(LRU_REFS_MASK | LRU_REFS_FLAGS); > /* for shrink_page_list() */ > if (reclaiming) > new_flags &=3D ~(BIT(PG_referenced) | BIT(PG_recl= aim)); > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > index bde05427e2bb..c8a7ceee7a0a 100644 > --- a/include/linux/mmzone.h > +++ b/include/linux/mmzone.h > @@ -347,12 +347,34 @@ enum lruvec_flags { > #define MIN_NR_GENS 2U > #define MAX_NR_GENS 4U > > +/* > + * Each generation is divided into multiple tiers. Tiers represent diffe= rent > + * ranges of numbers of accesses through file descriptors. A page access= ed N > + * times through file descriptors is in tier order_base_2(N). A page in = the > + * first tier (N=3D0,1) is marked by PG_referenced unless it was faulted= in > + * though page tables or read ahead. A page in any other tier (N>1) is m= arked > + * by PG_referenced and PG_workingset. > + * > + * In contrast to moving across generations which requires the LRU lock,= moving > + * across tiers only requires operations on folio->flags and therefore h= as a > + * negligible cost in the buffered access path. In the eviction path, > + * comparisons of refaulted/(evicted+protected) from the first tier and = the > + * rest infer whether pages accessed multiple times through file descrip= tors > + * are statistically hot and thus worth protecting. > + * > + * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice = of the > + * categories of the active/inactive LRU when keeping track of accesses = through > + * file descriptors. It requires MAX_NR_TIERS-2 additional bits in folio= ->flags. > + */ > +#define MAX_NR_TIERS 4U > + > #ifndef __GENERATING_BOUNDS_H > > struct lruvec; > > #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOF= F) > #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PG= OFF) > +#define LRU_REFS_FLAGS (BIT(PG_referenced) | BIT(PG_workingset)) > > #ifdef CONFIG_LRU_GEN > > @@ -361,6 +383,16 @@ enum { > LRU_GEN_FILE, > }; > > +#define MIN_LRU_BATCH BITS_PER_LONG > +#define MAX_LRU_BATCH (MIN_LRU_BATCH * 128) > + > +/* whether to keep historical stats from evicted generations */ > +#ifdef CONFIG_LRU_GEN_STATS > +#define NR_HIST_GENS MAX_NR_GENS > +#else > +#define NR_HIST_GENS 1U > +#endif > + > /* > * The youngest generation number is stored in max_seq for both anon and= file > * types as they are aged on an equal footing. The oldest generation num= bers are > @@ -380,6 +412,15 @@ struct lru_gen_struct { > struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; > /* the sizes of the above lists */ > unsigned long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; > + /* the exponential moving average of refaulted */ > + unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS]; > + /* the exponential moving average of evicted+protected */ > + unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS]; > + /* the first tier doesn't need protection, hence the minus one */ > + unsigned long protected[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS= - 1]; > + /* can be modified without holding the LRU lock */ > + atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; > + atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS= ]; > }; > > void lru_gen_init_lruvec(struct lruvec *lruvec); > diff --git a/kernel/bounds.c b/kernel/bounds.c > index e08fb89f87f4..10dd9e6b03e5 100644 > --- a/kernel/bounds.c > +++ b/kernel/bounds.c > @@ -24,7 +24,7 @@ int main(void) > DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); > #ifdef CONFIG_LRU_GEN > DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1)); > - DEFINE(LRU_REFS_WIDTH, 0); > + DEFINE(LRU_REFS_WIDTH, MAX_NR_TIERS - 2); > #else > DEFINE(LRU_GEN_WIDTH, 0); > DEFINE(LRU_REFS_WIDTH, 0); > diff --git a/mm/Kconfig b/mm/Kconfig > index 4595fc654181..c40777d098a8 100644 > --- a/mm/Kconfig > +++ b/mm/Kconfig > @@ -909,6 +909,7 @@ config ANON_VMA_NAME > area from being merged with adjacent virtual memory areas due t= o the > difference in their name. > > +# multi-gen LRU { > config LRU_GEN > bool "Multi-Gen LRU" > depends on MMU > @@ -917,6 +918,16 @@ config LRU_GEN > help > A high performance LRU implementation to overcommit memory. > > +config LRU_GEN_STATS > + bool "Full stats for debugging" > + depends on LRU_GEN > + help > + Do not enable this option unless you plan to look at historical= stats > + from evicted generations for debugging purpose. > + > + This option has a per-memcg and per-node memory overhead. > +# } > + > source "mm/damon/Kconfig" > > endmenu > diff --git a/mm/swap.c b/mm/swap.c > index a6870ba0bd83..6a5203f18b0a 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -405,6 +405,43 @@ static void __lru_cache_activate_folio(struct folio = *folio) > local_unlock(&lru_pvecs.lock); > } > > +#ifdef CONFIG_LRU_GEN > +static void folio_inc_refs(struct folio *folio) > +{ > + unsigned long refs; > + unsigned long old_flags, new_flags; > + > + if (folio_test_unevictable(folio)) > + return; > + > + /* see the comment on MAX_NR_TIERS */ > + do { > + new_flags =3D old_flags =3D READ_ONCE(folio->flags); > + > + if (!(new_flags & BIT(PG_referenced))) { > + new_flags |=3D BIT(PG_referenced); > + continue; > + } > + > + if (!(new_flags & BIT(PG_workingset))) { > + new_flags |=3D BIT(PG_workingset); > + continue; > + } > + > + refs =3D new_flags & LRU_REFS_MASK; > + refs =3D min(refs + BIT(LRU_REFS_PGOFF), LRU_REFS_MASK); > + > + new_flags &=3D ~LRU_REFS_MASK; > + new_flags |=3D refs; > + } while (new_flags !=3D old_flags && > + cmpxchg(&folio->flags, old_flags, new_flags) !=3D old_fl= ags); > +} > +#else > +static void folio_inc_refs(struct folio *folio) > +{ > +} > +#endif /* CONFIG_LRU_GEN */ > + > /* > * Mark a page as having seen activity. > * > @@ -417,6 +454,11 @@ static void __lru_cache_activate_folio(struct folio = *folio) > */ > void folio_mark_accessed(struct folio *folio) > { > + if (lru_gen_enabled()) { > + folio_inc_refs(folio); > + return; > + } > + > if (!folio_test_referenced(folio)) { > folio_set_referenced(folio); > } else if (folio_test_unevictable(folio)) { > diff --git a/mm/vmscan.c b/mm/vmscan.c > index 37dd5d1c3d07..bb3d705c5282 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -1275,9 +1275,11 @@ static int __remove_mapping(struct address_space *= mapping, struct folio *folio, > > if (folio_test_swapcache(folio)) { > swp_entry_t swap =3D folio_swap_entry(folio); > - mem_cgroup_swapout(folio, swap); > + > + /* get a shadow entry before mem_cgroup_swapout() clears = folio_memcg() */ > if (reclaimed && !mapping_exiting(mapping)) > shadow =3D workingset_eviction(folio, target_memc= g); > + mem_cgroup_swapout(folio, swap); > __delete_from_swap_cache(&folio->page, swap, shadow); > xa_unlock_irq(&mapping->i_pages); > put_swap_page(&folio->page, swap); > @@ -2649,6 +2651,9 @@ static void prepare_scan_count(pg_data_t *pgdat, st= ruct scan_control *sc) > unsigned long file; > struct lruvec *target_lruvec; > > + if (lru_gen_enabled()) > + return; > + > target_lruvec =3D mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat)= ; > > /* > @@ -2974,11 +2979,38 @@ static bool can_age_anon_pages(struct pglist_data= *pgdat, > * shorthand helpers > ***********************************************************************= *******/ > > +#define DEFINE_MAX_SEQ(lruvec) \ > + unsigned long max_seq =3D READ_ONCE((lruvec)->lrugen.max_seq) > + > +#define DEFINE_MIN_SEQ(lruvec) \ > + unsigned long min_seq[ANON_AND_FILE] =3D { = \ > + READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_ANON]), \ > + READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_FILE]), \ > + } > + > #define for_each_gen_type_zone(gen, type, zone) = \ > for ((gen) =3D 0; (gen) < MAX_NR_GENS; (gen)++) = \ > for ((type) =3D 0; (type) < ANON_AND_FILE; (type)++) = \ > for ((zone) =3D 0; (zone) < MAX_NR_ZONES; (zone)+= +) > > +static int folio_lru_gen(struct folio *folio) > +{ > + unsigned long flags =3D READ_ONCE(folio->flags); > + > + return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; > +} > + > +static int folio_lru_tier(struct folio *folio) > +{ > + int refs; > + unsigned long flags =3D READ_ONCE(folio->flags); > + > + refs =3D (flags & LRU_REFS_FLAGS) =3D=3D LRU_REFS_FLAGS ? > + ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + 1 : 0; > + > + return lru_tier_from_refs(refs); > +} > + > static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg= , int nid) > { > struct pglist_data *pgdat =3D NODE_DATA(nid); > @@ -2999,6 +3031,754 @@ static struct lruvec __maybe_unused *get_lruvec(s= truct mem_cgroup *memcg, int ni > return pgdat ? &pgdat->__lruvec : NULL; > } > > +static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc= ) > +{ > + struct mem_cgroup *memcg =3D lruvec_memcg(lruvec); > + struct pglist_data *pgdat =3D lruvec_pgdat(lruvec); > + > + if (!can_demote(pgdat->node_id, sc) && > + mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH) > + return 0; > + > + return mem_cgroup_swappiness(memcg); > +} > + > +static int get_nr_gens(struct lruvec *lruvec, int type) > +{ > + return lruvec->lrugen.max_seq - lruvec->lrugen.min_seq[type] + 1; > +} > + > +static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) > +{ > + /* see the comment on lru_gen_struct */ > + return get_nr_gens(lruvec, LRU_GEN_FILE) >=3D MIN_NR_GENS && > + get_nr_gens(lruvec, LRU_GEN_FILE) <=3D get_nr_gens(lruvec,= LRU_GEN_ANON) && > + get_nr_gens(lruvec, LRU_GEN_ANON) <=3D MAX_NR_GENS; > +} > + > +/***********************************************************************= ******* > + * refault feedback loop > + ***********************************************************************= *******/ > + > +/* > + * A feedback loop based on Proportional-Integral-Derivative (PID) contr= oller. > + * > + * The P term is refaulted/(evicted+protected) from a tier in the genera= tion > + * currently being evicted; the I term is the exponential moving average= of the > + * P term over the generations previously evicted, using the smoothing f= actor > + * 1/2; the D term isn't supported. > + * > + * The setpoint (SP) is always the first tier of one type; the process v= ariable > + * (PV) is either any tier of the other type or any other tier of the sa= me > + * type. > + * > + * The error is the difference between the SP and the PV; the correction= is > + * turn off protection when SP>PV or turn on protection when SP + * > + * For future optimizations: > + * 1. The D term may discount the other two terms over time so that long= -lived > + * generations can resist stale information. > + */ > +struct ctrl_pos { > + unsigned long refaulted; > + unsigned long total; > + int gain; > +}; > + > +static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int= gain, > + struct ctrl_pos *pos) > +{ > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + int hist =3D lru_hist_from_seq(lrugen->min_seq[type]); > + > + pos->refaulted =3D lrugen->avg_refaulted[type][tier] + > + atomic_long_read(&lrugen->refaulted[hist][type][= tier]); > + pos->total =3D lrugen->avg_total[type][tier] + > + atomic_long_read(&lrugen->evicted[hist][type][tier])= ; > + if (tier) > + pos->total +=3D lrugen->protected[hist][type][tier - 1]; > + pos->gain =3D gain; > +} > + > +static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryov= er) > +{ > + int hist, tier; > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + bool clear =3D carryover ? NR_HIST_GENS =3D=3D 1 : NR_HIST_GENS >= 1; > + unsigned long seq =3D carryover ? lrugen->min_seq[type] : lrugen-= >max_seq + 1; > + > + lockdep_assert_held(&lruvec->lru_lock); > + > + if (!carryover && !clear) > + return; > + > + hist =3D lru_hist_from_seq(seq); > + > + for (tier =3D 0; tier < MAX_NR_TIERS; tier++) { > + if (carryover) { > + unsigned long sum; > + > + sum =3D lrugen->avg_refaulted[type][tier] + > + atomic_long_read(&lrugen->refaulted[hist][t= ype][tier]); > + WRITE_ONCE(lrugen->avg_refaulted[type][tier], sum= / 2); > + > + sum =3D lrugen->avg_total[type][tier] + > + atomic_long_read(&lrugen->evicted[hist][typ= e][tier]); > + if (tier) > + sum +=3D lrugen->protected[hist][type][ti= er - 1]; > + WRITE_ONCE(lrugen->avg_total[type][tier], sum / 2= ); > + } > + > + if (clear) { > + atomic_long_set(&lrugen->refaulted[hist][type][ti= er], 0); > + atomic_long_set(&lrugen->evicted[hist][type][tier= ], 0); > + if (tier) > + WRITE_ONCE(lrugen->protected[hist][type][= tier - 1], 0); > + } > + } > +} > + > +static bool positive_ctrl_err(struct ctrl_pos *sp, struct ctrl_pos *pv) > +{ > + /* > + * Return true if the PV has a limited number of refaults or a lo= wer > + * refaulted/total than the SP. > + */ > + return pv->refaulted < MIN_LRU_BATCH || > + pv->refaulted * (sp->total + MIN_LRU_BATCH) * sp->gain <= =3D > + (sp->refaulted + 1) * pv->total * pv->gain; > +} > + > +/***********************************************************************= ******* > + * the aging > + ***********************************************************************= *******/ > + > +static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, boo= l reclaiming) > +{ > + unsigned long old_flags, new_flags; > + int type =3D folio_is_file_lru(folio); > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + int new_gen, old_gen =3D lru_gen_from_seq(lrugen->min_seq[type]); > + > + do { > + new_flags =3D old_flags =3D READ_ONCE(folio->flags); > + VM_BUG_ON_FOLIO(!(new_flags & LRU_GEN_MASK), folio); > + > + new_gen =3D (old_gen + 1) % MAX_NR_GENS; > + > + new_flags &=3D ~LRU_GEN_MASK; > + new_flags |=3D (new_gen + 1UL) << LRU_GEN_PGOFF; > + new_flags &=3D ~(LRU_REFS_MASK | LRU_REFS_FLAGS); > + /* for folio_end_writeback() */ > + if (reclaiming) > + new_flags |=3D BIT(PG_reclaim); > + } while (cmpxchg(&folio->flags, old_flags, new_flags) !=3D old_fl= ags); > + > + lru_gen_update_size(lruvec, folio, old_gen, new_gen); > + > + return new_gen; > +} > + > +static void inc_min_seq(struct lruvec *lruvec) > +{ > + int type; > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + > + VM_BUG_ON(!seq_is_valid(lruvec)); > + > + for (type =3D 0; type < ANON_AND_FILE; type++) { > + if (get_nr_gens(lruvec, type) !=3D MAX_NR_GENS) > + continue; > + > + reset_ctrl_pos(lruvec, type, true); > + WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] += 1); > + } > +} > + > +static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap) > +{ > + int gen, type, zone; > + bool success =3D false; > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + DEFINE_MIN_SEQ(lruvec); > + > + VM_BUG_ON(!seq_is_valid(lruvec)); > + > + for (type =3D !can_swap; type < ANON_AND_FILE; type++) { > + while (min_seq[type] + MIN_NR_GENS <=3D lrugen->max_seq) = { > + gen =3D lru_gen_from_seq(min_seq[type]); > + > + for (zone =3D 0; zone < MAX_NR_ZONES; zone++) { > + if (!list_empty(&lrugen->lists[gen][type]= [zone])) > + goto next; > + } > + > + min_seq[type]++; > + } > +next: > + ; > + } > + > + /* see the comment on lru_gen_struct */ > + if (can_swap) { > + min_seq[LRU_GEN_ANON] =3D min(min_seq[LRU_GEN_ANON], min_= seq[LRU_GEN_FILE]); > + min_seq[LRU_GEN_FILE] =3D max(min_seq[LRU_GEN_ANON], lrug= en->min_seq[LRU_GEN_FILE]); > + } > + > + for (type =3D !can_swap; type < ANON_AND_FILE; type++) { > + if (min_seq[type] =3D=3D lrugen->min_seq[type]) > + continue; > + > + reset_ctrl_pos(lruvec, type, true); > + WRITE_ONCE(lrugen->min_seq[type], min_seq[type]); > + success =3D true; > + } > + > + return success; > +} > + > +static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq) > +{ > + int prev, next; > + int type, zone; > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + > + spin_lock_irq(&lruvec->lru_lock); > + > + VM_BUG_ON(!seq_is_valid(lruvec)); > + > + if (max_seq !=3D lrugen->max_seq) > + goto unlock; > + > + inc_min_seq(lruvec); > + > + /* > + * Update the active/inactive LRU sizes for compatibility. Both s= ides of > + * the current max_seq need to be covered, since max_seq+1 can ov= erlap > + * with min_seq[LRU_GEN_ANON] if swapping is constrained. And if = they do > + * overlap, cold/hot inversion happens. This can be solved by mov= ing > + * pages from min_seq to min_seq+1 but is omitted for simplicity. > + */ > + prev =3D lru_gen_from_seq(lrugen->max_seq - 1); > + next =3D lru_gen_from_seq(lrugen->max_seq + 1); > + > + for (type =3D 0; type < ANON_AND_FILE; type++) { > + for (zone =3D 0; zone < MAX_NR_ZONES; zone++) { > + enum lru_list lru =3D type * LRU_INACTIVE_FILE; > + long delta =3D lrugen->nr_pages[prev][type][zone]= - > + lrugen->nr_pages[next][type][zone]; > + > + if (!delta) > + continue; > + > + __update_lru_size(lruvec, lru, zone, delta); > + __update_lru_size(lruvec, lru + LRU_ACTIVE, zone,= -delta); > + } > + } > + > + for (type =3D 0; type < ANON_AND_FILE; type++) > + reset_ctrl_pos(lruvec, type, false); > + > + /* make sure preceding modifications appear */ > + smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); > +unlock: > + spin_unlock_irq(&lruvec->lru_lock); > +} > + > +static long get_nr_evictable(struct lruvec *lruvec, unsigned long max_se= q, > + unsigned long *min_seq, bool can_swap, bool = *need_aging) > +{ > + int gen, type, zone; > + long old =3D 0; > + long young =3D 0; > + long total =3D 0; > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + > + for (type =3D !can_swap; type < ANON_AND_FILE; type++) { > + unsigned long seq; > + > + for (seq =3D min_seq[type]; seq <=3D max_seq; seq++) { > + long size =3D 0; > + > + gen =3D lru_gen_from_seq(seq); > + > + for (zone =3D 0; zone < MAX_NR_ZONES; zone++) > + size +=3D READ_ONCE(lrugen->nr_pages[gen]= [type][zone]); > + > + total +=3D size; > + if (seq =3D=3D max_seq) > + young +=3D size; > + if (seq + MIN_NR_GENS =3D=3D max_seq) > + old +=3D size; > + } > + } > + > + /* > + * The aging and the eviction is a typical producer-consumer mode= l. The > + * aging tries to be lazy to reduce the unnecessary overhead. On = the > + * other hand, the eviction stalls when the number of generations > + * reaches MIN_NR_GENS. So ideally, there should be MIN_NR_GENS+1 > + * generations, hence the first two if's. > + * > + * In addition, it's ideal to spread pages out evenly, meaning > + * 1/(MIN_NR_GENS+1) of the total number of pages for each genera= tion. A > + * reasonable range for this average portion would [1/MIN_NR_GENS= , > + * 1/(MIN_NR_GENS+2)]. From the consumer's POV, the eviction only= cares > + * about the lower bound of cold pages, i.e., 1/(MIN_NR_GENS+2), = whereas > + * from the producer's POV, the aging only cares about the upper = bound > + * of hot pages, i.e., 1/MIN_NR_GENS. > + */ > + if (min_seq[LRU_GEN_FILE] + MIN_NR_GENS > max_seq) > + *need_aging =3D true; > + else if (min_seq[LRU_GEN_FILE] + MIN_NR_GENS < max_seq) > + *need_aging =3D false; > + else if (young * MIN_NR_GENS > total) > + *need_aging =3D true; > + else if (old * (MIN_NR_GENS + 2) < total) > + *need_aging =3D true; > + else > + *need_aging =3D false; > + > + return total > 0 ? total : 0; > +} > + > +static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc) > +{ > + bool need_aging; > + long nr_to_scan; > + int swappiness =3D get_swappiness(lruvec, sc); > + struct mem_cgroup *memcg =3D lruvec_memcg(lruvec); > + DEFINE_MAX_SEQ(lruvec); > + DEFINE_MIN_SEQ(lruvec); > + > + mem_cgroup_calculate_protection(NULL, memcg); > + > + if (mem_cgroup_below_min(memcg)) > + return; > + > + nr_to_scan =3D get_nr_evictable(lruvec, max_seq, min_seq, swappin= ess, &need_aging); > + if (!nr_to_scan) > + return; > + > + nr_to_scan >>=3D sc->priority; > + > + if (!mem_cgroup_online(memcg)) > + nr_to_scan++; > + > + if (nr_to_scan && need_aging && (!mem_cgroup_below_low(memcg) || = sc->memcg_low_reclaim)) > + inc_max_seq(lruvec, max_seq); > +} > + > +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_cont= rol *sc) > +{ > + struct mem_cgroup *memcg; > + > + VM_BUG_ON(!current_is_kswapd()); > + > + memcg =3D mem_cgroup_iter(NULL, NULL, NULL); > + do { > + struct lruvec *lruvec =3D mem_cgroup_lruvec(memcg, pgdat)= ; > + > + age_lruvec(lruvec, sc); > + > + cond_resched(); > + } while ((memcg =3D mem_cgroup_iter(NULL, memcg, NULL))); > +} > + > +/***********************************************************************= ******* > + * the eviction > + ***********************************************************************= *******/ > + > +static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int t= ier_idx) > +{ > + bool success; > + int gen =3D folio_lru_gen(folio); > + int type =3D folio_is_file_lru(folio); > + int zone =3D folio_zonenum(folio); > + int tier =3D folio_lru_tier(folio); > + int delta =3D folio_nr_pages(folio); > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + > + VM_BUG_ON_FOLIO(gen >=3D MAX_NR_GENS, folio); > + > + if (!folio_evictable(folio)) { > + success =3D lru_gen_del_folio(lruvec, folio, true); > + VM_BUG_ON_FOLIO(!success, folio); > + folio_set_unevictable(folio); > + lruvec_add_folio(lruvec, folio); > + __count_vm_events(UNEVICTABLE_PGCULLED, delta); > + return true; > + } > + > + if (type =3D=3D LRU_GEN_FILE && folio_test_anon(folio) && folio_t= est_dirty(folio)) { > + success =3D lru_gen_del_folio(lruvec, folio, true); > + VM_BUG_ON_FOLIO(!success, folio); > + folio_set_swapbacked(folio); > + lruvec_add_folio_tail(lruvec, folio); > + return true; > + } > + > + if (tier > tier_idx) { > + int hist =3D lru_hist_from_seq(lrugen->min_seq[type]); > + > + gen =3D folio_inc_gen(lruvec, folio, false); > + list_move_tail(&folio->lru, &lrugen->lists[gen][type][zon= e]); > + > + WRITE_ONCE(lrugen->protected[hist][type][tier - 1], > + lrugen->protected[hist][type][tier - 1] + delt= a); > + __mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + typ= e, delta); > + return true; > + } > + > + if (folio_test_locked(folio) || folio_test_writeback(folio) || > + (type =3D=3D LRU_GEN_FILE && folio_test_dirty(folio))) { > + gen =3D folio_inc_gen(lruvec, folio, true); > + list_move(&folio->lru, &lrugen->lists[gen][type][zone]); > + return true; > + } > + > + return false; > +} > + > +static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, st= ruct scan_control *sc) > +{ > + bool success; > + > + if (!sc->may_unmap && folio_mapped(folio)) > + return false; > + > + if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && > + (folio_test_dirty(folio) || > + (folio_test_anon(folio) && !folio_test_swapcache(folio)))) > + return false; > + > + if (!folio_try_get(folio)) > + return false; > + > + if (!folio_test_clear_lru(folio)) { > + folio_put(folio); > + return false; > + } > + > + success =3D lru_gen_del_folio(lruvec, folio, true); > + VM_BUG_ON_FOLIO(!success, folio); > + > + return true; > +} > + > +static int scan_folios(struct lruvec *lruvec, struct scan_control *sc, > + int type, int tier, struct list_head *list) > +{ > + int gen, zone; > + enum vm_event_item item; > + int sorted =3D 0; > + int scanned =3D 0; > + int isolated =3D 0; > + int remaining =3D MAX_LRU_BATCH; > + struct lru_gen_struct *lrugen =3D &lruvec->lrugen; > + struct mem_cgroup *memcg =3D lruvec_memcg(lruvec); > + > + VM_BUG_ON(!list_empty(list)); > + > + if (get_nr_gens(lruvec, type) =3D=3D MIN_NR_GENS) > + return 0; > + > + gen =3D lru_gen_from_seq(lrugen->min_seq[type]); > + > + for (zone =3D sc->reclaim_idx; zone >=3D 0; zone--) { > + LIST_HEAD(moved); > + int skipped =3D 0; > + struct list_head *head =3D &lrugen->lists[gen][type][zone= ]; > + > + while (!list_empty(head)) { > + struct folio *folio =3D lru_to_folio(head); > + int delta =3D folio_nr_pages(folio); > + > + VM_BUG_ON_FOLIO(folio_test_unevictable(folio), fo= lio); > + VM_BUG_ON_FOLIO(folio_test_active(folio), folio); > + VM_BUG_ON_FOLIO(folio_is_file_lru(folio) !=3D typ= e, folio); > + VM_BUG_ON_FOLIO(folio_zonenum(folio) !=3D zone, f= olio); > + > + scanned +=3D delta; > + > + if (sort_folio(lruvec, folio, tier)) > + sorted +=3D delta; > + else if (isolate_folio(lruvec, folio, sc)) { > + list_add(&folio->lru, list); > + isolated +=3D delta; > + } else { > + list_move(&folio->lru, &moved); > + skipped +=3D delta; > + } > + > + if (!--remaining || max(isolated, skipped) >=3D M= IN_LRU_BATCH) > + break; > + } > + > + if (skipped) { > + list_splice(&moved, head); > + __count_zid_vm_events(PGSCAN_SKIP, zone, skipped)= ; > + } > + > + if (!remaining || isolated >=3D MIN_LRU_BATCH) > + break; > + } > + > + item =3D current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT; > + if (!cgroup_reclaim(sc)) { > + __count_vm_events(item, isolated); > + __count_vm_events(PGREFILL, sorted); > + } > + __count_memcg_events(memcg, item, isolated); > + __count_memcg_events(memcg, PGREFILL, sorted); > + __count_vm_events(PGSCAN_ANON + type, isolated); > + > + /* > + * There might not be eligible pages due to reclaim_idx, may_unma= p and > + * may_writepage. Check the remaining to prevent livelock if ther= e is no > + * progress. > + */ > + return isolated || !remaining ? scanned : 0; > +} > + > +static int get_tier_idx(struct lruvec *lruvec, int type) > +{ > + int tier; > + struct ctrl_pos sp, pv; > + > + /* > + * To leave a margin for fluctuations, use a larger gain factor (= 1:2). > + * This value is chosen because any other tier would have at leas= t twice > + * as many refaults as the first tier. > + */ > + read_ctrl_pos(lruvec, type, 0, 1, &sp); > + for (tier =3D 1; tier < MAX_NR_TIERS; tier++) { > + read_ctrl_pos(lruvec, type, tier, 2, &pv); > + if (!positive_ctrl_err(&sp, &pv)) > + break; > + } > + > + return tier - 1; > +} > + > +static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *= tier_idx) > +{ > + int type, tier; > + struct ctrl_pos sp, pv; > + int gain[ANON_AND_FILE] =3D { swappiness, 200 - swappiness }; > + > + /* > + * Compare the first tier of anon with that of file to determine = which > + * type to scan. Also need to compare other tiers of the selected= type > + * with the first tier of the other type to determine the last ti= er (of > + * the selected type) to evict. > + */ > + read_ctrl_pos(lruvec, LRU_GEN_ANON, 0, gain[LRU_GEN_ANON], &sp); > + read_ctrl_pos(lruvec, LRU_GEN_FILE, 0, gain[LRU_GEN_FILE], &pv); > + type =3D positive_ctrl_err(&sp, &pv); > + > + read_ctrl_pos(lruvec, !type, 0, gain[!type], &sp); > + for (tier =3D 1; tier < MAX_NR_TIERS; tier++) { > + read_ctrl_pos(lruvec, type, tier, gain[type], &pv); > + if (!positive_ctrl_err(&sp, &pv)) > + break; > + } > + > + *tier_idx =3D tier - 1; > + > + return type; > +} > + > +static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc= , int swappiness, > + int *type_scanned, struct list_head *list) > +{ > + int i; > + int type; > + int scanned; > + int tier =3D -1; > + DEFINE_MIN_SEQ(lruvec); > + > + VM_BUG_ON(!seq_is_valid(lruvec)); > + > + /* > + * Try to make the obvious choice first. When anon and file are b= oth > + * available from the same generation, interpret swappiness 1 as = file > + * first and 200 as anon first. > + */ Has this changed the ABI of swapiness? or it is only something meaningful for the internal code? if so, can we rename it to something else? otherwise, it is quite confusing. it seems 1 is set internally as a magic number here: +static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) +{ + ... + else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc)) + swappiness =3D 1; + else + swappiness =3D 0; + } obviously this swappiness is neither /proc/sys/vm/swappiness nor /sys/fs/cgroup/memory//>memory.swappiness, right? > + if (!swappiness) > + type =3D LRU_GEN_FILE; > + else if (min_seq[LRU_GEN_ANON] < min_seq[LRU_GEN_FILE]) > + type =3D LRU_GEN_ANON; > + else if (swappiness =3D=3D 1) > + type =3D LRU_GEN_FILE; > + else if (swappiness =3D=3D 200) > + type =3D LRU_GEN_ANON; > + else > + type =3D get_type_to_scan(lruvec, swappiness, &tier); > + > + for (i =3D !swappiness; i < ANON_AND_FILE; i++) { > + if (tier < 0) > + tier =3D get_tier_idx(lruvec, type); > + > + scanned =3D scan_folios(lruvec, sc, type, tier, list); > + if (scanned) > + break; > + > + type =3D !type; > + tier =3D -1; > + } > + > + *type_scanned =3D type; > + > + return scanned; > +} > + > +static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, = int swappiness) > +{ > + int type; > + int scanned; > + int reclaimed; > + LIST_HEAD(list); > + struct folio *folio; > + enum vm_event_item item; > + struct reclaim_stat stat; > + struct mem_cgroup *memcg =3D lruvec_memcg(lruvec); > + struct pglist_data *pgdat =3D lruvec_pgdat(lruvec); > + > + spin_lock_irq(&lruvec->lru_lock); > + > + scanned =3D isolate_folios(lruvec, sc, swappiness, &type, &list); > + > + if (try_to_inc_min_seq(lruvec, swappiness)) > + scanned++; > + > + if (get_nr_gens(lruvec, LRU_GEN_FILE) =3D=3D MIN_NR_GENS) > + scanned =3D 0; > + > + spin_unlock_irq(&lruvec->lru_lock); > + > + if (list_empty(&list)) > + return scanned; > + > + reclaimed =3D shrink_page_list(&list, pgdat, sc, &stat, false); > + > + /* > + * To avoid livelock, don't add rejected pages back to the same l= ists > + * they were isolated from. See lru_gen_add_folio(). > + */ > + list_for_each_entry(folio, &list, lru) { > + folio_clear_referenced(folio); > + folio_clear_workingset(folio); > + > + if (folio_test_reclaim(folio) && > + (folio_test_dirty(folio) || folio_test_writeback(foli= o))) > + folio_clear_active(folio); > + else > + folio_set_active(folio); > + } > + > + spin_lock_irq(&lruvec->lru_lock); > + > + move_pages_to_lru(lruvec, &list); > + > + item =3D current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT; > + if (!cgroup_reclaim(sc)) > + __count_vm_events(item, reclaimed); > + __count_memcg_events(memcg, item, reclaimed); > + __count_vm_events(PGSTEAL_ANON + type, reclaimed); > + > + spin_unlock_irq(&lruvec->lru_lock); > + > + mem_cgroup_uncharge_list(&list); > + free_unref_page_list(&list); > + > + sc->nr_reclaimed +=3D reclaimed; > + > + return scanned; > +} > + > +static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *s= c, bool can_swap) > +{ > + bool need_aging; > + long nr_to_scan; > + struct mem_cgroup *memcg =3D lruvec_memcg(lruvec); > + DEFINE_MAX_SEQ(lruvec); > + DEFINE_MIN_SEQ(lruvec); > + > + if (mem_cgroup_below_min(memcg) || > + (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) > + return 0; > + > + nr_to_scan =3D get_nr_evictable(lruvec, max_seq, min_seq, can_swa= p, &need_aging); > + if (!nr_to_scan) > + return 0; > + > + /* reset the priority if the target has been met */ > + nr_to_scan >>=3D sc->nr_reclaimed < sc->nr_to_reclaim ? sc->prior= ity : DEF_PRIORITY; > + > + if (!mem_cgroup_online(memcg)) > + nr_to_scan++; > + > + if (!nr_to_scan) > + return 0; > + > + if (!need_aging) > + return nr_to_scan; > + > + /* leave the work to lru_gen_age_node() */ > + if (current_is_kswapd()) > + return 0; > + > + /* try other memcgs before going to the aging path */ > + if (!cgroup_reclaim(sc) && !sc->force_deactivate) { > + sc->skipped_deactivate =3D true; > + return 0; > + } > + > + inc_max_seq(lruvec, max_seq); > + > + return nr_to_scan; > +} > + > +static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_con= trol *sc) > +{ > + struct blk_plug plug; > + long scanned =3D 0; > + > + lru_add_drain(); > + > + blk_start_plug(&plug); > + > + while (true) { () > + int delta; > + int swappiness; > + long nr_to_scan; > + > + if (sc->may_swap) > + swappiness =3D get_swappiness(lruvec, sc); > + else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc= )) > + swappiness =3D 1; > + else > + swappiness =3D 0; > + > + nr_to_scan =3D get_nr_to_scan(lruvec, sc, swappiness); > + if (!nr_to_scan) > + break; > + > + delta =3D evict_folios(lruvec, sc, swappiness); > + if (!delta) > + break; > + > + scanned +=3D delta; > + if (scanned >=3D nr_to_scan) > + break; > + > + cond_resched(); > + } > + > + blk_finish_plug(&plug); > +} > + > /***********************************************************************= ******* > * initialization > ***********************************************************************= *******/ > @@ -3041,6 +3821,16 @@ static int __init init_lru_gen(void) > }; > late_initcall(init_lru_gen); > > +#else > + > +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_cont= rol *sc) > +{ > +} > + > +static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_con= trol *sc) > +{ > +} > + > #endif /* CONFIG_LRU_GEN */ > > static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc= ) > @@ -3054,6 +3844,11 @@ static void shrink_lruvec(struct lruvec *lruvec, s= truct scan_control *sc) > struct blk_plug plug; > bool scan_adjusted; > > + if (lru_gen_enabled()) { > + lru_gen_shrink_lruvec(lruvec, sc); > + return; > + } > + > get_scan_count(lruvec, sc, nr); > > /* Record the original scan target for proportional adjustments l= ater */ > @@ -3558,6 +4353,9 @@ static void snapshot_refaults(struct mem_cgroup *ta= rget_memcg, pg_data_t *pgdat) > struct lruvec *target_lruvec; > unsigned long refaults; > > + if (lru_gen_enabled()) > + return; > + > target_lruvec =3D mem_cgroup_lruvec(target_memcg, pgdat); > refaults =3D lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE= _ANON); > target_lruvec->refaults[0] =3D refaults; > @@ -3928,6 +4726,11 @@ static void age_active_anon(struct pglist_data *pg= dat, > struct mem_cgroup *memcg; > struct lruvec *lruvec; > > + if (lru_gen_enabled()) { > + lru_gen_age_node(pgdat, sc); > + return; > + } is it really a good place for lru_gen_age_node() since the function is named age_active_anon() but here you are doing aging for both anon and file pages? obviously lru_gen_age_node() is not doing "age active anon". > + > if (!can_age_anon_pages(pgdat, sc)) > return; > > diff --git a/mm/workingset.c b/mm/workingset.c > index 8a3828acc0bf..89b46af74eef 100644 > --- a/mm/workingset.c > +++ b/mm/workingset.c > @@ -187,7 +187,6 @@ static unsigned int bucket_order __read_mostly; > static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long ev= iction, > bool workingset) > { > - eviction >>=3D bucket_order; > eviction &=3D EVICTION_MASK; > eviction =3D (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; > eviction =3D (eviction << NODES_SHIFT) | pgdat->node_id; > @@ -212,10 +211,116 @@ static void unpack_shadow(void *shadow, int *memcg= idp, pg_data_t **pgdat, > > *memcgidp =3D memcgid; > *pgdat =3D NODE_DATA(nid); > - *evictionp =3D entry << bucket_order; > + *evictionp =3D entry; > *workingsetp =3D workingset; > } > > +#ifdef CONFIG_LRU_GEN > + > +static int folio_lru_refs(struct folio *folio) > +{ > + unsigned long flags =3D READ_ONCE(folio->flags); > + > + BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVI= CTION_SHIFT); > + > + /* see the comment on MAX_NR_TIERS */ > + return flags & BIT(PG_workingset) ? (flags & LRU_REFS_MASK) >> LR= U_REFS_PGOFF : 0; > +} > + > +static void *lru_gen_eviction(struct folio *folio) > +{ > + int hist, tier; > + unsigned long token; > + unsigned long min_seq; > + struct lruvec *lruvec; > + struct lru_gen_struct *lrugen; > + int type =3D folio_is_file_lru(folio); > + int refs =3D folio_lru_refs(folio); > + int delta =3D folio_nr_pages(folio); > + bool workingset =3D folio_test_workingset(folio); > + struct mem_cgroup *memcg =3D folio_memcg(folio); > + struct pglist_data *pgdat =3D folio_pgdat(folio); > + > + lruvec =3D mem_cgroup_lruvec(memcg, pgdat); > + lrugen =3D &lruvec->lrugen; > + min_seq =3D READ_ONCE(lrugen->min_seq[type]); > + token =3D (min_seq << LRU_REFS_WIDTH) | refs; > + > + hist =3D lru_hist_from_seq(min_seq); > + tier =3D lru_tier_from_refs(refs + workingset); > + atomic_long_add(delta, &lrugen->evicted[hist][type][tier]); > + > + return pack_shadow(mem_cgroup_id(memcg), pgdat, token, workingset= ); > +} > + > +static void lru_gen_refault(struct folio *folio, void *shadow) > +{ > + int hist, tier, refs; > + int memcg_id; > + bool workingset; > + unsigned long token; > + unsigned long min_seq; > + struct lruvec *lruvec; > + struct lru_gen_struct *lrugen; > + struct mem_cgroup *memcg; > + struct pglist_data *pgdat; > + int type =3D folio_is_file_lru(folio); > + int delta =3D folio_nr_pages(folio); > + > + unpack_shadow(shadow, &memcg_id, &pgdat, &token, &workingset); > + > + refs =3D token & (BIT(LRU_REFS_WIDTH) - 1); > + if (refs && !workingset) > + return; > + > + if (folio_pgdat(folio) !=3D pgdat) > + return; > + > + rcu_read_lock(); > + memcg =3D folio_memcg_rcu(folio); > + if (mem_cgroup_id(memcg) !=3D memcg_id) > + goto unlock; > + > + token >>=3D LRU_REFS_WIDTH; > + lruvec =3D mem_cgroup_lruvec(memcg, pgdat); > + lrugen =3D &lruvec->lrugen; > + min_seq =3D READ_ONCE(lrugen->min_seq[type]); > + if (token !=3D (min_seq & (EVICTION_MASK >> LRU_REFS_WIDTH))) > + goto unlock; > + > + hist =3D lru_hist_from_seq(min_seq); > + tier =3D lru_tier_from_refs(refs + workingset); > + atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]); > + mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type, delta); > + > + /* > + * Count the following two cases as stalls: > + * 1. For pages accessed through page tables, hotter pages pushed= out > + * hot pages which refaulted immediately. > + * 2. For pages accessed through file descriptors, numbers of acc= esses > + * might have been beyond the limit. > + */ > + if (lru_gen_in_fault() || refs + workingset =3D=3D BIT(LRU_REFS_W= IDTH)) { > + folio_set_workingset(folio); > + mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, = delta); > + } > +unlock: > + rcu_read_unlock(); > +} > + > +#else > + > +static void *lru_gen_eviction(struct folio *folio) > +{ > + return NULL; > +} > + > +static void lru_gen_refault(struct folio *folio, void *shadow) > +{ > +} > + > +#endif /* CONFIG_LRU_GEN */ > + > /** > * workingset_age_nonresident - age non-resident entries as LRU ages > * @lruvec: the lruvec that was aged > @@ -264,10 +369,14 @@ void *workingset_eviction(struct folio *folio, stru= ct mem_cgroup *target_memcg) > VM_BUG_ON_FOLIO(folio_ref_count(folio), folio); > VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio); > > + if (lru_gen_enabled()) > + return lru_gen_eviction(folio); > + > lruvec =3D mem_cgroup_lruvec(target_memcg, pgdat); > /* XXX: target_memcg can be NULL, go through lruvec */ > memcgid =3D mem_cgroup_id(lruvec_memcg(lruvec)); > eviction =3D atomic_long_read(&lruvec->nonresident_age); > + eviction >>=3D bucket_order; > workingset_age_nonresident(lruvec, folio_nr_pages(folio)); > return pack_shadow(memcgid, pgdat, eviction, > folio_test_workingset(folio)); > @@ -298,7 +407,13 @@ void workingset_refault(struct folio *folio, void *s= hadow) > int memcgid; > long nr; > > + if (lru_gen_enabled()) { > + lru_gen_refault(folio, shadow); > + return; > + } > + > unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset); > + eviction <<=3D bucket_order; > > rcu_read_lock(); > /* > -- > 2.35.1.1094.g7c7d902a7c-goog > Thanks Barry 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 31432C433EF for ; Thu, 14 Apr 2022 06:05:16 +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:Cc:To:Subject:Message-ID:Date:From: In-Reply-To:References:MIME-Version:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=dDchU5ssbvIruhenAzaUE/30hEUMVWEyc+Z5npOiafM=; b=TaxE4eUjmIBLch 1fazwpMtB3MpwIVu0Nl/huc9U+Tm6OFsNzH449avqwv8XLs5sdIFySAag0l7AFbuQIS9VMPlVA39r 9nAgNd7vy32nGhy2ZS/F2ANLpFlTsXm0KqwBX6qhz3iaoLGO1mQwUeHz667HODjUQXkeRfhDjgUry 2uuXa08xW+QK90OEAYJeOGg/PjOlZyLyWtGYjovffShaTQAL7o8hthafLy/0ApUxvzf48YO8sPiNc vQdAdVuQ61fWkeqyQvFB/lKRuoQ8T/xPlDKCfU4DFxskRErSIEGhwQgQa5ayeJ3sNfhoeEmadzCgf gio6XG8vtfR94mif6/ew==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nesZw-0040aj-4l; Thu, 14 Apr 2022 06:03:40 +0000 Received: from mail-ed1-x535.google.com ([2a00:1450:4864:20::535]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nesZn-0040Y0-Lm for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 06:03:37 +0000 Received: by mail-ed1-x535.google.com with SMTP id u18so5026456eda.3 for ; Wed, 13 Apr 2022 23:03:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=fhA5BymqZ4e+SI6zc/bl76P99FRTbpdXYhS7zgXjwvI=; b=TPRKpEemhQ9lNQexIZNeTC5yOgXcrmtzEt9CkbAuth/bvWz2mQZekUJ/ik/D5DutSS FxPO30nPNk6PgbYmA+F1a7BP8AKMHfBRAeKg7iBnCZMCahlNOCDBBPBeyT/9eA2ugH5Y /2m5Ut3DUVoms+C7PCDyGL3zVBqjD0EkDnGEa8KdQseP2Tt80Tyen4MtFFj9ov43RkBB dVrT0n9iZFvQxeYr1DORVazOdUcjGhq88WqxXWEjYQEz8KmEgZSz6Ks7wjDvJpZzP5eo r/03Mz6ZhL2TWmH15L6Nl+5PtwXLG8Ck3eo+z/TAWfZokvukDrXkeCNkS10Y8SUxyQ5n uaBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=fhA5BymqZ4e+SI6zc/bl76P99FRTbpdXYhS7zgXjwvI=; b=xbj7l6ASpkGWuabwK/pwWZdrDeHYVPg7gAV+9M4CvgOgZcnYRU1r5mOg3t/sdeUPAz y5Jecoo9HiXGrq/nlqT1qrVWIXdEgqnbMaSi6CVOd7+BXOeGZHODmnD3l7RTovThC7hN zVLVV71nVDzavUKL+dyfhvI31dBvYPWl6dbutsQwTMiWZcmwoJ0ZHpAU7KnGwiK8k7OX 2vt380M93E7lXfhYE5HNhFqkRqBZcLQpuMWIiwQ8N6Y+5ZKvKUjowrd64VaRIA4RFIM5 RDyeOEjv5bEDxqkHvXa5aAIsPUs7fsOFA4gYySkqIAE+GBOVNJRcgeIBVfiAAGDsnEtr +76g== X-Gm-Message-State: AOAM53389k1oPS8KLTFTsgVacLsaNlUX0QyPfiyYjHB7HrTVAHvMgHVU q5y9doeyYBfApNdR3gUJ8wpXSxxEupAtc3/tty8= X-Google-Smtp-Source: ABdhPJyuBD9RI5lRXTwZjYRu356H0kJGf5Q9CjOQQbFjlPhMaspIlBONTiwWMn9mTFlg6XgRrrUnNhLvQN9FuymIz6s= X-Received: by 2002:a05:6402:1695:b0:41d:6b06:f81 with SMTP id a21-20020a056402169500b0041d6b060f81mr1252015edv.98.1649916204113; Wed, 13 Apr 2022 23:03:24 -0700 (PDT) MIME-Version: 1.0 References: <20220407031525.2368067-1-yuzhao@google.com> <20220407031525.2368067-7-yuzhao@google.com> In-Reply-To: <20220407031525.2368067-7-yuzhao@google.com> From: Barry Song <21cnbao@gmail.com> Date: Thu, 14 Apr 2022 18:03:10 +1200 Message-ID: Subject: Re: [PATCH v10 06/14] mm: multi-gen LRU: minimal implementation To: Yu Zhao Cc: Stephen Rothwell , Linux-MM , Andi Kleen , Andrew Morton , Aneesh Kumar , Catalin Marinas , Dave Hansen , Hillf Danton , Jens Axboe , Jesse Barnes , Johannes Weiner , Jonathan Corbet , Linus Torvalds , Matthew Wilcox , Mel Gorman , Michael Larabel , Michal Hocko , Mike Rapoport , Rik van Riel , Vlastimil Babka , Will Deacon , Ying Huang , LAK , Linux Doc Mailing List , LKML , Kernel Page Reclaim v2 , x86 , Brian Geffon , Jan Alexander Steffens , Oleksandr Natalenko , Steven Barrett , Suleiman Souhlal , Daniel Byrne , Donald Carr , =?UTF-8?Q?Holger_Hoffst=C3=A4tte?= , Konstantin Kharlamov , Shuang Zhai , Sofia Trinh , Vaibhav Jain X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220413_230331_805652_DB82C6FD X-CRM114-Status: GOOD ( 38.59 ) 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 KCkKCgoKT24gVGh1LCBBcHIgNywgMjAyMiBhdCAzOjE2IFBNIFl1IFpoYW8gPHl1emhhb0Bnb29n bGUuY29tPiB3cm90ZToKPgo+IFRvIGF2b2lkIGNvbmZ1c2lvbiwgdGhlIHRlcm1zICJwcm9tb3Rp b24iIGFuZCAiZGVtb3Rpb24iIHdpbGwgYmUKPiBhcHBsaWVkIHRvIHRoZSBtdWx0aS1nZW4gTFJV LCBhcyBhIG5ldyBjb252ZW50aW9uOyB0aGUgdGVybXMKPiAiYWN0aXZhdGlvbiIgYW5kICJkZWFj dGl2YXRpb24iIHdpbGwgYmUgYXBwbGllZCB0byB0aGUgYWN0aXZlL2luYWN0aXZlCj4gTFJVLCBh cyB1c3VhbC4KPgo+IFRoZSBhZ2luZyBwcm9kdWNlcyB5b3VuZyBnZW5lcmF0aW9ucy4gR2l2ZW4g YW4gbHJ1dmVjLCBpdCBpbmNyZW1lbnRzCj4gbWF4X3NlcSB3aGVuIG1heF9zZXEtbWluX3NlcSsx IGFwcHJvYWNoZXMgTUlOX05SX0dFTlMuIFRoZSBhZ2luZwo+IHByb21vdGVzIGhvdCBwYWdlcyB0 byB0aGUgeW91bmdlc3QgZ2VuZXJhdGlvbiB3aGVuIGl0IGZpbmRzIHRoZW0KPiBhY2Nlc3NlZCB0 aHJvdWdoIHBhZ2UgdGFibGVzOyB0aGUgZGVtb3Rpb24gb2YgY29sZCBwYWdlcyBoYXBwZW5zCj4g Y29uc2VxdWVudGx5IHdoZW4gaXQgaW5jcmVtZW50cyBtYXhfc2VxLiBUaGUgYWdpbmcgaGFzIHRo ZSBjb21wbGV4aXR5Cj4gTyhucl9ob3RfcGFnZXMpLCBzaW5jZSBpdCBpcyBvbmx5IGludGVyZXN0 ZWQgaW4gaG90IHBhZ2VzLiBQcm9tb3Rpb24KPiBpbiB0aGUgYWdpbmcgcGF0aCBkb2VzIG5vdCBy ZXF1aXJlIGFueSBMUlUgbGlzdCBvcGVyYXRpb25zLCBvbmx5IHRoZQo+IHVwZGF0ZXMgb2YgdGhl IGdlbiBjb3VudGVyIGFuZCBscnVnZW4tPm5yX3BhZ2VzW107IGRlbW90aW9uLCB1bmxlc3MgYXMK PiB0aGUgcmVzdWx0IG9mIHRoZSBpbmNyZW1lbnQgb2YgbWF4X3NlcSwgcmVxdWlyZXMgTFJVIGxp c3Qgb3BlcmF0aW9ucywKPiBlLmcuLCBscnVfZGVhY3RpdmF0ZV9mbigpLgo+Cj4gVGhlIGV2aWN0 aW9uIGNvbnN1bWVzIG9sZCBnZW5lcmF0aW9ucy4gR2l2ZW4gYW4gbHJ1dmVjLCBpdCBpbmNyZW1l bnRzCj4gbWluX3NlcSB3aGVuIHRoZSBsaXN0cyBpbmRleGVkIGJ5IG1pbl9zZXElTUFYX05SX0dF TlMgYmVjb21lIGVtcHR5LiBBCj4gZmVlZGJhY2sgbG9vcCBtb2RlbGVkIGFmdGVyIHRoZSBQSUQg Y29udHJvbGxlciBtb25pdG9ycyByZWZhdWx0cyBvdmVyCj4gYW5vbiBhbmQgZmlsZSB0eXBlcyBh bmQgZGVjaWRlcyB3aGljaCB0eXBlIHRvIGV2aWN0IHdoZW4gYm90aCB0eXBlcwo+IGFyZSBhdmFp bGFibGUgZnJvbSB0aGUgc2FtZSBnZW5lcmF0aW9uLgo+Cj4gRWFjaCBnZW5lcmF0aW9uIGlzIGRp dmlkZWQgaW50byBtdWx0aXBsZSB0aWVycy4gVGllcnMgcmVwcmVzZW50Cj4gZGlmZmVyZW50IHJh bmdlcyBvZiBudW1iZXJzIG9mIGFjY2Vzc2VzIHRocm91Z2ggZmlsZSBkZXNjcmlwdG9ycy4gQQo+ IHBhZ2UgYWNjZXNzZWQgTiB0aW1lcyB0aHJvdWdoIGZpbGUgZGVzY3JpcHRvcnMgaXMgaW4gdGll cgo+IG9yZGVyX2Jhc2VfMihOKS4gVGllcnMgZG8gbm90IGhhdmUgZGVkaWNhdGVkIGxydWdlbi0+ bGlzdHNbXSwgb25seQo+IGJpdHMgaW4gZm9saW8tPmZsYWdzLiBJbiBjb250cmFzdCB0byBtb3Zp bmcgYWNyb3NzIGdlbmVyYXRpb25zLCB3aGljaAo+IHJlcXVpcmVzIHRoZSBMUlUgbG9jaywgbW92 aW5nIGFjcm9zcyB0aWVycyBvbmx5IGludm9sdmVzIG9wZXJhdGlvbnMgb24KPiBmb2xpby0+Zmxh Z3MuIFRoZSBmZWVkYmFjayBsb29wIGFsc28gbW9uaXRvcnMgcmVmYXVsdHMgb3ZlciBhbGwgdGll cnMKPiBhbmQgZGVjaWRlcyB3aGVuIHRvIHByb3RlY3QgcGFnZXMgaW4gd2hpY2ggdGllcnMgKE4+ MSksIHVzaW5nIHRoZQo+IGZpcnN0IHRpZXIgKE49MCwxKSBhcyBhIGJhc2VsaW5lLiBUaGUgZmly c3QgdGllciBjb250YWlucyBzaW5nbGUtdXNlCj4gdW5tYXBwZWQgY2xlYW4gcGFnZXMsIHdoaWNo IGFyZSBtb3N0IGxpa2VseSB0aGUgYmVzdCBjaG9pY2VzLiBUaGUKPiBldmljdGlvbiBtb3ZlcyBh IHBhZ2UgdG8gdGhlIG5leHQgZ2VuZXJhdGlvbiwgaS5lLiwgbWluX3NlcSsxLCBpZiB0aGUKPiBm ZWVkYmFjayBsb29wIGRlY2lkZXMgc28uIFRoaXMgYXBwcm9hY2ggaGFzIHRoZSBmb2xsb3dpbmcg YWR2YW50YWdlczoKPiAxLiBJdCByZW1vdmVzIHRoZSBjb3N0IG9mIGFjdGl2YXRpb24gaW4gdGhl IGJ1ZmZlcmVkIGFjY2VzcyBwYXRoIGJ5Cj4gICAgaW5mZXJyaW5nIHdoZXRoZXIgcGFnZXMgYWNj ZXNzZWQgbXVsdGlwbGUgdGltZXMgdGhyb3VnaCBmaWxlCj4gICAgZGVzY3JpcHRvcnMgYXJlIHN0 YXRpc3RpY2FsbHkgaG90IGFuZCB0aHVzIHdvcnRoIHByb3RlY3RpbmcgaW4gdGhlCj4gICAgZXZp Y3Rpb24gcGF0aC4KPiAyLiBJdCB0YWtlcyBwYWdlcyBhY2Nlc3NlZCB0aHJvdWdoIHBhZ2UgdGFi bGVzIGludG8gYWNjb3VudCBhbmQgYXZvaWRzCj4gICAgb3ZlcnByb3RlY3RpbmcgcGFnZXMgYWNj ZXNzZWQgbXVsdGlwbGUgdGltZXMgdGhyb3VnaCBmaWxlCj4gICAgZGVzY3JpcHRvcnMuIChQYWdl cyBhY2Nlc3NlZCB0aHJvdWdoIHBhZ2UgdGFibGVzIGFyZSBpbiB0aGUgZmlyc3QKPiAgICB0aWVy LCBzaW5jZSBOPTAuKQo+IDMuIE1vcmUgdGllcnMgcHJvdmlkZSBiZXR0ZXIgcHJvdGVjdGlvbiBm b3IgcGFnZXMgYWNjZXNzZWQgbW9yZSB0aGFuCj4gICAgdHdpY2UgdGhyb3VnaCBmaWxlIGRlc2Ny aXB0b3JzLCB3aGVuIHVuZGVyIGhlYXZ5IGJ1ZmZlcmVkIEkvTwo+ICAgIHdvcmtsb2Fkcy4KPgo+ IFNlcnZlciBiZW5jaG1hcmsgcmVzdWx0czoKPiAgIFNpbmdsZSB3b3JrbG9hZDoKPiAgICAgZmlv IChidWZmZXJlZCBJL08pOiArWzQwLCA0Ml0lCj4gICAgICAgICAgICAgICAgIElPUFMgICAgICAg ICBCVwo+ICAgICAgIDUuMTgtcmMxOiAyNDYzayAgICAgICAgOTYyMU1pQi9zCj4gICAgICAgcGF0 Y2gxLTY6IDM0ODRrICAgICAgICAxMy4zR2lCL3MKPgo+ICAgU2luZ2xlIHdvcmtsb2FkOgo+ICAg ICBtZW1jYWNoZWQgKGFub24pOiArWzQ0LCA0Nl0lCj4gICAgICAgICAgICAgICAgIE9wcy9zZWMg ICAgICBLQi9zZWMKPiAgICAgICA1LjE4LXJjMTogNzcxNDAzLjI3ICAgIDMwMDA0LjE3Cj4gICAg ICAgcGF0Y2gxLTY6IDExMjA2NDMuNzAgICA0MzU4OC4wNgo+Cj4gICBDb25maWd1cmF0aW9uczoK PiAgICAgQ1BVOiB0d28gWGVvbiA2MTU0Cj4gICAgIE1lbTogdG90YWwgMjU2Rwo+Cj4gICAgIE5v ZGUgMSB3YXMgb25seSB1c2VkIGFzIGEgcmFtIGRpc2sgdG8gcmVkdWNlIHRoZSB2YXJpYW5jZSBp biB0aGUKPiAgICAgcmVzdWx0cy4KPgo+ICAgICBwYXRjaCBkcml2ZXJzL2Jsb2NrL2JyZC5jIDw8 RU9GCj4gICAgIDk5LDEwMGM5OSwxMDAKPiAgICAgPCAgIGdmcF9mbGFncyA9IEdGUF9OT0lPIHwg X19HRlBfWkVSTyB8IF9fR0ZQX0hJR0hNRU07Cj4gICAgIDwgICBwYWdlID0gYWxsb2NfcGFnZShn ZnBfZmxhZ3MpOwo+ICAgICAtLS0KPiAgICAgPiAgIGdmcF9mbGFncyA9IEdGUF9OT0lPIHwgX19H RlBfWkVSTyB8IF9fR0ZQX0hJR0hNRU0gfCBfX0dGUF9USElTTk9ERTsKPiAgICAgPiAgIHBhZ2Ug PSBhbGxvY19wYWdlc19ub2RlKDEsIGdmcF9mbGFncywgMCk7Cj4gICAgIEVPRgo+Cj4gICAgIGNh dCA+Pi9ldGMvc3lzdGVtZC9zeXN0ZW0uY29uZiA8PEVPRgo+ICAgICBDUFVBZmZpbml0eT1udW1h Cj4gICAgIE5VTUFQb2xpY3k9YmluZAo+ICAgICBOVU1BTWFzaz0wCj4gICAgIEVPRgo+Cj4gICAg IGNhdCA+Pi9ldGMvbWVtY2FjaGVkLmNvbmYgPDxFT0YKPiAgICAgLW0gMTg0MzIwCj4gICAgIC1z IC92YXIvcnVuL21lbWNhY2hlZC9tZW1jYWNoZWQuc29jawo+ICAgICAtYSAwNzY2Cj4gICAgIC10 IDM2Cj4gICAgIC1CIGJpbmFyeQo+ICAgICBFT0YKPgo+ICAgICBjYXQgZmlvLnNoCj4gICAgIG1v ZHByb2JlIGJyZCByZF9ucj0xIHJkX3NpemU9MTEzMjQ2MjA4Cj4gICAgIHN3YXBvZmYgLWEKPiAg ICAgbWtmcy5leHQ0IC9kZXYvcmFtMAo+ICAgICBtb3VudCAtdCBleHQ0IC9kZXYvcmFtMCAvbW50 Cj4KPiAgICAgbWtkaXIgL3N5cy9mcy9jZ3JvdXAvdXNlci5zbGljZS90ZXN0Cj4gICAgIGVjaG8g Mzg2NTQ3MDU2NjQgPi9zeXMvZnMvY2dyb3VwL3VzZXIuc2xpY2UvdGVzdC9tZW1vcnkubWF4Cj4g ICAgIGVjaG8gJCQgPi9zeXMvZnMvY2dyb3VwL3VzZXIuc2xpY2UvdGVzdC9jZ3JvdXAucHJvY3MK PiAgICAgZmlvIC1uYW1lPW1nbHJ1IC0tbnVtam9icz03MiAtLWRpcmVjdG9yeT0vbW50IC0tc2l6 ZT0xNDA4bSBcCj4gICAgICAgLS1idWZmZXJlZD0xIC0taW9lbmdpbmU9aW9fdXJpbmcgLS1pb2Rl cHRoPTEyOCBcCj4gICAgICAgLS1pb2RlcHRoX2JhdGNoX3N1Ym1pdD0zMiAtLWlvZGVwdGhfYmF0 Y2hfY29tcGxldGU9MzIgXAo+ICAgICAgIC0tcnc9cmFuZHJlYWQgLS1yYW5kb21fZGlzdHJpYnV0 aW9uPXJhbmRvbSAtLW5vcmFuZG9tbWFwIFwKPiAgICAgICAtLXRpbWVfYmFzZWQgLS1yYW1wX3Rp bWU9MTBtIC0tcnVudGltZT01bSAtLWdyb3VwX3JlcG9ydGluZwo+Cj4gICAgIGNhdCBtZW1jYWNo ZWQuc2gKPiAgICAgbW9kcHJvYmUgYnJkIHJkX25yPTEgcmRfc2l6ZT0xMTMyNDYyMDgKPiAgICAg c3dhcG9mZiAtYQo+ICAgICBta3N3YXAgL2Rldi9yYW0wCj4gICAgIHN3YXBvbiAvZGV2L3JhbTAK Pgo+ICAgICBtZW10aWVyX2JlbmNobWFyayAtUyAvdmFyL3J1bi9tZW1jYWNoZWQvbWVtY2FjaGVk LnNvY2sgXAo+ICAgICAgIC1QIG1lbWNhY2hlX2JpbmFyeSAtbiBhbGxrZXlzIC0ta2V5LW1pbmlt dW09MSBcCj4gICAgICAgLS1rZXktbWF4aW11bT02NTAwMDAwMCAtLWtleS1wYXR0ZXJuPVA6UCAt YyAxIC10IDM2IFwKPiAgICAgICAtLXJhdGlvIDE6MCAtLXBpcGVsaW5lIDggLWQgMjAwMAo+Cj4g ICAgIG1lbXRpZXJfYmVuY2htYXJrIC1TIC92YXIvcnVuL21lbWNhY2hlZC9tZW1jYWNoZWQuc29j ayBcCj4gICAgICAgLVAgbWVtY2FjaGVfYmluYXJ5IC1uIGFsbGtleXMgLS1rZXktbWluaW11bT0x IFwKPiAgICAgICAtLWtleS1tYXhpbXVtPTY1MDAwMDAwIC0ta2V5LXBhdHRlcm49UjpSIC1jIDEg LXQgMzYgXAo+ICAgICAgIC0tcmF0aW8gMDoxIC0tcGlwZWxpbmUgOCAtLXJhbmRvbWl6ZSAtLWRp c3RpbmN0LWNsaWVudC1zZWVkCj4KPiBDbGllbnQgYmVuY2htYXJrIHJlc3VsdHM6Cj4gICBrc3dh cGQgcHJvZmlsZXM6Cj4gICAgIDUuMTgtcmMxCj4gICAgICAgNDAuNTMlICBwYWdlX3ZtYV9tYXBw ZWRfd2Fsawo+ICAgICAgIDIwLjM3JSAgbHpvMXhfMV9kb19jb21wcmVzcyAocmVhbCB3b3JrKQo+ ICAgICAgICA2Ljk5JSAgZG9fcmF3X3NwaW5fbG9jawo+ICAgICAgICAzLjkzJSAgX3Jhd19zcGlu X3VubG9ja19pcnEKPiAgICAgICAgMi4wOCUgIHZtYV9pbnRlcnZhbF90cmVlX3N1YnRyZWVfc2Vh cmNoCj4gICAgICAgIDIuMDYlICB2bWFfaW50ZXJ2YWxfdHJlZV9pdGVyX25leHQKPiAgICAgICAg MS45NSUgIGZvbGlvX3JlZmVyZW5jZWRfb25lCj4gICAgICAgIDEuOTMlICBhbm9uX3ZtYV9pbnRl cnZhbF90cmVlX2l0ZXJfZmlyc3QKPiAgICAgICAgMS41MSUgIHB0ZXBfY2xlYXJfZmx1c2gKPiAg ICAgICAgMS4zNSUgIF9fYW5vbl92bWFfaW50ZXJ2YWxfdHJlZV9zdWJ0cmVlX3NlYXJjaAo+Cj4g ICAgIHBhdGNoMS02Cj4gICAgICAgMzUuOTklICBsem8xeF8xX2RvX2NvbXByZXNzIChyZWFsIHdv cmspCj4gICAgICAgMTkuNDAlICBwYWdlX3ZtYV9tYXBwZWRfd2Fsawo+ICAgICAgICA2LjMxJSAg X3Jhd19zcGluX3VubG9ja19pcnEKPiAgICAgICAgMy45NSUgIGRvX3Jhd19zcGluX2xvY2sKPiAg ICAgICAgMi4zOSUgIGFub25fdm1hX2ludGVydmFsX3RyZWVfaXRlcl9maXJzdAo+ICAgICAgICAy LjI1JSAgcHRlcF9jbGVhcl9mbHVzaAo+ICAgICAgICAxLjkyJSAgX19hbm9uX3ZtYV9pbnRlcnZh bF90cmVlX3N1YnRyZWVfc2VhcmNoCj4gICAgICAgIDEuNzAlICBmb2xpb19yZWZlcmVuY2VkX29u ZQo+ICAgICAgICAxLjY4JSAgX196cmFtX2J2ZWNfd3JpdGUKPiAgICAgICAgMS40MyUgIGFub25f dm1hX2ludGVydmFsX3RyZWVfaXRlcl9uZXh0Cj4KPiAgIENvbmZpZ3VyYXRpb25zOgo+ICAgICBD UFU6IHNpbmdsZSBTbmFwZHJhZ29uIDdjCj4gICAgIE1lbTogdG90YWwgNEcKPgo+ICAgICBDaHJv bWUgT1MgTWVtb3J5UHJlc3N1cmUgWzFdCj4KPiBbMV0gaHR0cHM6Ly9jaHJvbWl1bS5nb29nbGVz b3VyY2UuY29tL2Nocm9taXVtb3MvcGxhdGZvcm0vdGFzdC10ZXN0cy8KPgo+IFNpZ25lZC1vZmYt Ynk6IFl1IFpoYW8gPHl1emhhb0Bnb29nbGUuY29tPgo+IEFja2VkLWJ5OiBCcmlhbiBHZWZmb24g PGJnZWZmb25AZ29vZ2xlLmNvbT4KPiBBY2tlZC1ieTogSmFuIEFsZXhhbmRlciBTdGVmZmVucyAo aGVmdGlnKSA8aGVmdGlnQGFyY2hsaW51eC5vcmc+Cj4gQWNrZWQtYnk6IE9sZWtzYW5kciBOYXRh bGVua28gPG9sZWtzYW5kckBuYXRhbGVua28ubmFtZT4KPiBBY2tlZC1ieTogU3RldmVuIEJhcnJl dHQgPHN0ZXZlbkBsaXF1b3JpeC5uZXQ+Cj4gQWNrZWQtYnk6IFN1bGVpbWFuIFNvdWhsYWwgPHN1 bGVpbWFuQGdvb2dsZS5jb20+Cj4gVGVzdGVkLWJ5OiBEYW5pZWwgQnlybmUgPGRqYnlybmVAbXR1 LmVkdT4KPiBUZXN0ZWQtYnk6IERvbmFsZCBDYXJyIDxkQGNoYW9zLXJlaW5zLmNvbT4KPiBUZXN0 ZWQtYnk6IEhvbGdlciBIb2Zmc3TDpHR0ZSA8aG9sZ2VyQGFwcGxpZWQtYXN5bmNocm9ueS5jb20+ Cj4gVGVzdGVkLWJ5OiBLb25zdGFudGluIEtoYXJsYW1vdiA8SGktQW5nZWxAeWFuZGV4LnJ1Pgo+ IFRlc3RlZC1ieTogU2h1YW5nIFpoYWkgPHN6aGFpMkBjcy5yb2NoZXN0ZXIuZWR1Pgo+IFRlc3Rl ZC1ieTogU29maWEgVHJpbmggPHNvZmlhLnRyaW5oQGVkaS53b3Jrcz4KPiBUZXN0ZWQtYnk6IFZh aWJoYXYgSmFpbiA8dmFpYmhhdkBsaW51eC5pYm0uY29tPgo+IC0tLQo+ICBpbmNsdWRlL2xpbnV4 L21tX2lubGluZS5oIHwgIDI0ICsrCj4gIGluY2x1ZGUvbGludXgvbW16b25lLmggICAgfCAgNDEg KysKPiAga2VybmVsL2JvdW5kcy5jICAgICAgICAgICB8ICAgMiArLQo+ICBtbS9LY29uZmlnICAg ICAgICAgICAgICAgIHwgIDExICsKPiAgbW0vc3dhcC5jICAgICAgICAgICAgICAgICB8ICA0MiAr Kwo+ICBtbS92bXNjYW4uYyAgICAgICAgICAgICAgIHwgODA1ICsrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKystCj4gIG1tL3dvcmtpbmdzZXQuYyAgICAgICAgICAgfCAxMTkgKysr KystCj4gIDcgZmlsZXMgY2hhbmdlZCwgMTA0MCBpbnNlcnRpb25zKCspLCA0IGRlbGV0aW9ucygt KQo+Cj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvbW1faW5saW5lLmggYi9pbmNsdWRlL2xp bnV4L21tX2lubGluZS5oCj4gaW5kZXggOWFiZDcyYTk1NDYyLi44YThmODdiNzI1NDAgMTAwNjQ0 Cj4gLS0tIGEvaW5jbHVkZS9saW51eC9tbV9pbmxpbmUuaAo+ICsrKyBiL2luY2x1ZGUvbGludXgv bW1faW5saW5lLmgKPiBAQCAtMTE5LDYgKzExOSwxOSBAQCBzdGF0aWMgaW5saW5lIGludCBscnVf Z2VuX2Zyb21fc2VxKHVuc2lnbmVkIGxvbmcgc2VxKQo+ICAgICAgICAgcmV0dXJuIHNlcSAlIE1B WF9OUl9HRU5TOwo+ICB9Cj4KPiArc3RhdGljIGlubGluZSBpbnQgbHJ1X2hpc3RfZnJvbV9zZXEo dW5zaWduZWQgbG9uZyBzZXEpCj4gK3sKPiArICAgICAgIHJldHVybiBzZXEgJSBOUl9ISVNUX0dF TlM7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgaW50IGxydV90aWVyX2Zyb21fcmVmcyhpbnQg cmVmcykKPiArewo+ICsgICAgICAgVk1fQlVHX09OKHJlZnMgPiBCSVQoTFJVX1JFRlNfV0lEVEgp KTsKPiArCj4gKyAgICAgICAvKiBzZWUgdGhlIGNvbW1lbnQgb24gTUFYX05SX1RJRVJTICovCj4g KyAgICAgICByZXR1cm4gb3JkZXJfYmFzZV8yKHJlZnMgKyAxKTsKPiArfQo+ICsKPiAgc3RhdGlj IGlubGluZSBib29sIGxydV9nZW5faXNfYWN0aXZlKHN0cnVjdCBscnV2ZWMgKmxydXZlYywgaW50 IGdlbikKPiAgewo+ICAgICAgICAgdW5zaWduZWQgbG9uZyBtYXhfc2VxID0gbHJ1dmVjLT5scnVn ZW4ubWF4X3NlcTsKPiBAQCAtMTY0LDYgKzE3NywxNSBAQCBzdGF0aWMgaW5saW5lIHZvaWQgbHJ1 X2dlbl91cGRhdGVfc2l6ZShzdHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIHN0cnVjdCBmb2xpbyAqZm9s aQo+ICAgICAgICAgICAgICAgICBfX3VwZGF0ZV9scnVfc2l6ZShscnV2ZWMsIGxydSwgem9uZSwg LWRlbHRhKTsKPiAgICAgICAgICAgICAgICAgcmV0dXJuOwo+ICAgICAgICAgfQo+ICsKPiArICAg ICAgIC8qIHByb21vdGlvbiAqLwo+ICsgICAgICAgaWYgKCFscnVfZ2VuX2lzX2FjdGl2ZShscnV2 ZWMsIG9sZF9nZW4pICYmIGxydV9nZW5faXNfYWN0aXZlKGxydXZlYywgbmV3X2dlbikpIHsKPiAr ICAgICAgICAgICAgICAgX191cGRhdGVfbHJ1X3NpemUobHJ1dmVjLCBscnUsIHpvbmUsIC1kZWx0 YSk7Cj4gKyAgICAgICAgICAgICAgIF9fdXBkYXRlX2xydV9zaXplKGxydXZlYywgbHJ1ICsgTFJV X0FDVElWRSwgem9uZSwgZGVsdGEpOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIC8qIGRlbW90 aW9uIHJlcXVpcmVzIGlzb2xhdGlvbiwgZS5nLiwgbHJ1X2RlYWN0aXZhdGVfZm4oKSAqLwo+ICsg ICAgICAgVk1fQlVHX09OKGxydV9nZW5faXNfYWN0aXZlKGxydXZlYywgb2xkX2dlbikgJiYgIWxy dV9nZW5faXNfYWN0aXZlKGxydXZlYywgbmV3X2dlbikpOwo+ICB9Cj4KPiAgc3RhdGljIGlubGlu ZSBib29sIGxydV9nZW5fYWRkX2ZvbGlvKHN0cnVjdCBscnV2ZWMgKmxydXZlYywgc3RydWN0IGZv bGlvICpmb2xpbywgYm9vbCByZWNsYWltaW5nKQo+IEBAIC0yMjksNiArMjUxLDggQEAgc3RhdGlj IGlubGluZSBib29sIGxydV9nZW5fZGVsX2ZvbGlvKHN0cnVjdCBscnV2ZWMgKmxydXZlYywgc3Ry dWN0IGZvbGlvICpmb2xpbywKPiAgICAgICAgICAgICAgICAgZ2VuID0gKChuZXdfZmxhZ3MgJiBM UlVfR0VOX01BU0spID4+IExSVV9HRU5fUEdPRkYpIC0gMTsKPgo+ICAgICAgICAgICAgICAgICBu ZXdfZmxhZ3MgJj0gfkxSVV9HRU5fTUFTSzsKPiArICAgICAgICAgICAgICAgaWYgKCEobmV3X2Zs YWdzICYgQklUKFBHX3JlZmVyZW5jZWQpKSkKPiArICAgICAgICAgICAgICAgICAgICAgICBuZXdf ZmxhZ3MgJj0gfihMUlVfUkVGU19NQVNLIHwgTFJVX1JFRlNfRkxBR1MpOwo+ICAgICAgICAgICAg ICAgICAvKiBmb3Igc2hyaW5rX3BhZ2VfbGlzdCgpICovCj4gICAgICAgICAgICAgICAgIGlmIChy ZWNsYWltaW5nKQo+ICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19mbGFncyAmPSB+KEJJVChQ R19yZWZlcmVuY2VkKSB8IEJJVChQR19yZWNsYWltKSk7Cj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUv bGludXgvbW16b25lLmggYi9pbmNsdWRlL2xpbnV4L21tem9uZS5oCj4gaW5kZXggYmRlMDU0Mjdl MmJiLi5jOGE3Y2VlZTdhMGEgMTAwNjQ0Cj4gLS0tIGEvaW5jbHVkZS9saW51eC9tbXpvbmUuaAo+ ICsrKyBiL2luY2x1ZGUvbGludXgvbW16b25lLmgKPiBAQCAtMzQ3LDEyICszNDcsMzQgQEAgZW51 bSBscnV2ZWNfZmxhZ3Mgewo+ICAjZGVmaW5lIE1JTl9OUl9HRU5TICAgICAgICAgICAgMlUKPiAg I2RlZmluZSBNQVhfTlJfR0VOUyAgICAgICAgICAgIDRVCj4KPiArLyoKPiArICogRWFjaCBnZW5l cmF0aW9uIGlzIGRpdmlkZWQgaW50byBtdWx0aXBsZSB0aWVycy4gVGllcnMgcmVwcmVzZW50IGRp ZmZlcmVudAo+ICsgKiByYW5nZXMgb2YgbnVtYmVycyBvZiBhY2Nlc3NlcyB0aHJvdWdoIGZpbGUg ZGVzY3JpcHRvcnMuIEEgcGFnZSBhY2Nlc3NlZCBOCj4gKyAqIHRpbWVzIHRocm91Z2ggZmlsZSBk ZXNjcmlwdG9ycyBpcyBpbiB0aWVyIG9yZGVyX2Jhc2VfMihOKS4gQSBwYWdlIGluIHRoZQo+ICsg KiBmaXJzdCB0aWVyIChOPTAsMSkgaXMgbWFya2VkIGJ5IFBHX3JlZmVyZW5jZWQgdW5sZXNzIGl0 IHdhcyBmYXVsdGVkIGluCj4gKyAqIHRob3VnaCBwYWdlIHRhYmxlcyBvciByZWFkIGFoZWFkLiBB IHBhZ2UgaW4gYW55IG90aGVyIHRpZXIgKE4+MSkgaXMgbWFya2VkCj4gKyAqIGJ5IFBHX3JlZmVy ZW5jZWQgYW5kIFBHX3dvcmtpbmdzZXQuCj4gKyAqCj4gKyAqIEluIGNvbnRyYXN0IHRvIG1vdmlu ZyBhY3Jvc3MgZ2VuZXJhdGlvbnMgd2hpY2ggcmVxdWlyZXMgdGhlIExSVSBsb2NrLCBtb3ZpbmcK PiArICogYWNyb3NzIHRpZXJzIG9ubHkgcmVxdWlyZXMgb3BlcmF0aW9ucyBvbiBmb2xpby0+Zmxh Z3MgYW5kIHRoZXJlZm9yZSBoYXMgYQo+ICsgKiBuZWdsaWdpYmxlIGNvc3QgaW4gdGhlIGJ1ZmZl cmVkIGFjY2VzcyBwYXRoLiBJbiB0aGUgZXZpY3Rpb24gcGF0aCwKPiArICogY29tcGFyaXNvbnMg b2YgcmVmYXVsdGVkLyhldmljdGVkK3Byb3RlY3RlZCkgZnJvbSB0aGUgZmlyc3QgdGllciBhbmQg dGhlCj4gKyAqIHJlc3QgaW5mZXIgd2hldGhlciBwYWdlcyBhY2Nlc3NlZCBtdWx0aXBsZSB0aW1l cyB0aHJvdWdoIGZpbGUgZGVzY3JpcHRvcnMKPiArICogYXJlIHN0YXRpc3RpY2FsbHkgaG90IGFu ZCB0aHVzIHdvcnRoIHByb3RlY3RpbmcuCj4gKyAqCj4gKyAqIE1BWF9OUl9USUVSUyBpcyBzZXQg dG8gNCBzbyB0aGF0IHRoZSBtdWx0aS1nZW4gTFJVIGNhbiBzdXBwb3J0IHR3aWNlIG9mIHRoZQo+ ICsgKiBjYXRlZ29yaWVzIG9mIHRoZSBhY3RpdmUvaW5hY3RpdmUgTFJVIHdoZW4ga2VlcGluZyB0 cmFjayBvZiBhY2Nlc3NlcyB0aHJvdWdoCj4gKyAqIGZpbGUgZGVzY3JpcHRvcnMuIEl0IHJlcXVp cmVzIE1BWF9OUl9USUVSUy0yIGFkZGl0aW9uYWwgYml0cyBpbiBmb2xpby0+ZmxhZ3MuCj4gKyAq Lwo+ICsjZGVmaW5lIE1BWF9OUl9USUVSUyAgICAgICAgICAgNFUKPiArCj4gICNpZm5kZWYgX19H RU5FUkFUSU5HX0JPVU5EU19ICj4KPiAgc3RydWN0IGxydXZlYzsKPgo+ICAjZGVmaW5lIExSVV9H RU5fTUFTSyAgICAgICAgICAgKChCSVQoTFJVX0dFTl9XSURUSCkgLSAxKSA8PCBMUlVfR0VOX1BH T0ZGKQo+ICAjZGVmaW5lIExSVV9SRUZTX01BU0sgICAgICAgICAgKChCSVQoTFJVX1JFRlNfV0lE VEgpIC0gMSkgPDwgTFJVX1JFRlNfUEdPRkYpCj4gKyNkZWZpbmUgTFJVX1JFRlNfRkxBR1MgICAg ICAgICAoQklUKFBHX3JlZmVyZW5jZWQpIHwgQklUKFBHX3dvcmtpbmdzZXQpKQo+Cj4gICNpZmRl ZiBDT05GSUdfTFJVX0dFTgo+Cj4gQEAgLTM2MSw2ICszODMsMTYgQEAgZW51bSB7Cj4gICAgICAg ICBMUlVfR0VOX0ZJTEUsCj4gIH07Cj4KPiArI2RlZmluZSBNSU5fTFJVX0JBVENIICAgICAgICAg IEJJVFNfUEVSX0xPTkcKPiArI2RlZmluZSBNQVhfTFJVX0JBVENIICAgICAgICAgIChNSU5fTFJV X0JBVENIICogMTI4KQo+ICsKPiArLyogd2hldGhlciB0byBrZWVwIGhpc3RvcmljYWwgc3RhdHMg ZnJvbSBldmljdGVkIGdlbmVyYXRpb25zICovCj4gKyNpZmRlZiBDT05GSUdfTFJVX0dFTl9TVEFU Uwo+ICsjZGVmaW5lIE5SX0hJU1RfR0VOUyAgICAgICAgICAgTUFYX05SX0dFTlMKPiArI2Vsc2UK PiArI2RlZmluZSBOUl9ISVNUX0dFTlMgICAgICAgICAgIDFVCj4gKyNlbmRpZgo+ICsKPiAgLyoK PiAgICogVGhlIHlvdW5nZXN0IGdlbmVyYXRpb24gbnVtYmVyIGlzIHN0b3JlZCBpbiBtYXhfc2Vx IGZvciBib3RoIGFub24gYW5kIGZpbGUKPiAgICogdHlwZXMgYXMgdGhleSBhcmUgYWdlZCBvbiBh biBlcXVhbCBmb290aW5nLiBUaGUgb2xkZXN0IGdlbmVyYXRpb24gbnVtYmVycyBhcmUKPiBAQCAt MzgwLDYgKzQxMiwxNSBAQCBzdHJ1Y3QgbHJ1X2dlbl9zdHJ1Y3Qgewo+ICAgICAgICAgc3RydWN0 IGxpc3RfaGVhZCBsaXN0c1tNQVhfTlJfR0VOU11bQU5PTl9BTkRfRklMRV1bTUFYX05SX1pPTkVT XTsKPiAgICAgICAgIC8qIHRoZSBzaXplcyBvZiB0aGUgYWJvdmUgbGlzdHMgKi8KPiAgICAgICAg IHVuc2lnbmVkIGxvbmcgbnJfcGFnZXNbTUFYX05SX0dFTlNdW0FOT05fQU5EX0ZJTEVdW01BWF9O Ul9aT05FU107Cj4gKyAgICAgICAvKiB0aGUgZXhwb25lbnRpYWwgbW92aW5nIGF2ZXJhZ2Ugb2Yg cmVmYXVsdGVkICovCj4gKyAgICAgICB1bnNpZ25lZCBsb25nIGF2Z19yZWZhdWx0ZWRbQU5PTl9B TkRfRklMRV1bTUFYX05SX1RJRVJTXTsKPiArICAgICAgIC8qIHRoZSBleHBvbmVudGlhbCBtb3Zp bmcgYXZlcmFnZSBvZiBldmljdGVkK3Byb3RlY3RlZCAqLwo+ICsgICAgICAgdW5zaWduZWQgbG9u ZyBhdmdfdG90YWxbQU5PTl9BTkRfRklMRV1bTUFYX05SX1RJRVJTXTsKPiArICAgICAgIC8qIHRo ZSBmaXJzdCB0aWVyIGRvZXNuJ3QgbmVlZCBwcm90ZWN0aW9uLCBoZW5jZSB0aGUgbWludXMgb25l ICovCj4gKyAgICAgICB1bnNpZ25lZCBsb25nIHByb3RlY3RlZFtOUl9ISVNUX0dFTlNdW0FOT05f QU5EX0ZJTEVdW01BWF9OUl9USUVSUyAtIDFdOwo+ICsgICAgICAgLyogY2FuIGJlIG1vZGlmaWVk IHdpdGhvdXQgaG9sZGluZyB0aGUgTFJVIGxvY2sgKi8KPiArICAgICAgIGF0b21pY19sb25nX3Qg ZXZpY3RlZFtOUl9ISVNUX0dFTlNdW0FOT05fQU5EX0ZJTEVdW01BWF9OUl9USUVSU107Cj4gKyAg ICAgICBhdG9taWNfbG9uZ190IHJlZmF1bHRlZFtOUl9ISVNUX0dFTlNdW0FOT05fQU5EX0ZJTEVd W01BWF9OUl9USUVSU107Cj4gIH07Cj4KPiAgdm9pZCBscnVfZ2VuX2luaXRfbHJ1dmVjKHN0cnVj dCBscnV2ZWMgKmxydXZlYyk7Cj4gZGlmZiAtLWdpdCBhL2tlcm5lbC9ib3VuZHMuYyBiL2tlcm5l bC9ib3VuZHMuYwo+IGluZGV4IGUwOGZiODlmODdmNC4uMTBkZDllNmIwM2U1IDEwMDY0NAo+IC0t LSBhL2tlcm5lbC9ib3VuZHMuYwo+ICsrKyBiL2tlcm5lbC9ib3VuZHMuYwo+IEBAIC0yNCw3ICsy NCw3IEBAIGludCBtYWluKHZvaWQpCj4gICAgICAgICBERUZJTkUoU1BJTkxPQ0tfU0laRSwgc2l6 ZW9mKHNwaW5sb2NrX3QpKTsKPiAgI2lmZGVmIENPTkZJR19MUlVfR0VOCj4gICAgICAgICBERUZJ TkUoTFJVX0dFTl9XSURUSCwgb3JkZXJfYmFzZV8yKE1BWF9OUl9HRU5TICsgMSkpOwo+IC0gICAg ICAgREVGSU5FKExSVV9SRUZTX1dJRFRILCAwKTsKPiArICAgICAgIERFRklORShMUlVfUkVGU19X SURUSCwgTUFYX05SX1RJRVJTIC0gMik7Cj4gICNlbHNlCj4gICAgICAgICBERUZJTkUoTFJVX0dF Tl9XSURUSCwgMCk7Cj4gICAgICAgICBERUZJTkUoTFJVX1JFRlNfV0lEVEgsIDApOwo+IGRpZmYg LS1naXQgYS9tbS9LY29uZmlnIGIvbW0vS2NvbmZpZwo+IGluZGV4IDQ1OTVmYzY1NDE4MS4uYzQw Nzc3ZDA5OGE4IDEwMDY0NAo+IC0tLSBhL21tL0tjb25maWcKPiArKysgYi9tbS9LY29uZmlnCj4g QEAgLTkwOSw2ICs5MDksNyBAQCBjb25maWcgQU5PTl9WTUFfTkFNRQo+ICAgICAgICAgICBhcmVh IGZyb20gYmVpbmcgbWVyZ2VkIHdpdGggYWRqYWNlbnQgdmlydHVhbCBtZW1vcnkgYXJlYXMgZHVl IHRvIHRoZQo+ICAgICAgICAgICBkaWZmZXJlbmNlIGluIHRoZWlyIG5hbWUuCj4KPiArIyBtdWx0 aS1nZW4gTFJVIHsKPiAgY29uZmlnIExSVV9HRU4KPiAgICAgICAgIGJvb2wgIk11bHRpLUdlbiBM UlUiCj4gICAgICAgICBkZXBlbmRzIG9uIE1NVQo+IEBAIC05MTcsNiArOTE4LDE2IEBAIGNvbmZp ZyBMUlVfR0VOCj4gICAgICAgICBoZWxwCj4gICAgICAgICAgIEEgaGlnaCBwZXJmb3JtYW5jZSBM UlUgaW1wbGVtZW50YXRpb24gdG8gb3ZlcmNvbW1pdCBtZW1vcnkuCj4KPiArY29uZmlnIExSVV9H RU5fU1RBVFMKPiArICAgICAgIGJvb2wgIkZ1bGwgc3RhdHMgZm9yIGRlYnVnZ2luZyIKPiArICAg ICAgIGRlcGVuZHMgb24gTFJVX0dFTgo+ICsgICAgICAgaGVscAo+ICsgICAgICAgICBEbyBub3Qg ZW5hYmxlIHRoaXMgb3B0aW9uIHVubGVzcyB5b3UgcGxhbiB0byBsb29rIGF0IGhpc3RvcmljYWwg c3RhdHMKPiArICAgICAgICAgZnJvbSBldmljdGVkIGdlbmVyYXRpb25zIGZvciBkZWJ1Z2dpbmcg cHVycG9zZS4KPiArCj4gKyAgICAgICAgIFRoaXMgb3B0aW9uIGhhcyBhIHBlci1tZW1jZyBhbmQg cGVyLW5vZGUgbWVtb3J5IG92ZXJoZWFkLgo+ICsjIH0KPiArCj4gIHNvdXJjZSAibW0vZGFtb24v S2NvbmZpZyIKPgo+ICBlbmRtZW51Cj4gZGlmZiAtLWdpdCBhL21tL3N3YXAuYyBiL21tL3N3YXAu Ywo+IGluZGV4IGE2ODcwYmEwYmQ4My4uNmE1MjAzZjE4YjBhIDEwMDY0NAo+IC0tLSBhL21tL3N3 YXAuYwo+ICsrKyBiL21tL3N3YXAuYwo+IEBAIC00MDUsNiArNDA1LDQzIEBAIHN0YXRpYyB2b2lk IF9fbHJ1X2NhY2hlX2FjdGl2YXRlX2ZvbGlvKHN0cnVjdCBmb2xpbyAqZm9saW8pCj4gICAgICAg ICBsb2NhbF91bmxvY2soJmxydV9wdmVjcy5sb2NrKTsKPiAgfQo+Cj4gKyNpZmRlZiBDT05GSUdf TFJVX0dFTgo+ICtzdGF0aWMgdm9pZCBmb2xpb19pbmNfcmVmcyhzdHJ1Y3QgZm9saW8gKmZvbGlv KQo+ICt7Cj4gKyAgICAgICB1bnNpZ25lZCBsb25nIHJlZnM7Cj4gKyAgICAgICB1bnNpZ25lZCBs b25nIG9sZF9mbGFncywgbmV3X2ZsYWdzOwo+ICsKPiArICAgICAgIGlmIChmb2xpb190ZXN0X3Vu ZXZpY3RhYmxlKGZvbGlvKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ICsKPiArICAgICAg IC8qIHNlZSB0aGUgY29tbWVudCBvbiBNQVhfTlJfVElFUlMgKi8KPiArICAgICAgIGRvIHsKPiAr ICAgICAgICAgICAgICAgbmV3X2ZsYWdzID0gb2xkX2ZsYWdzID0gUkVBRF9PTkNFKGZvbGlvLT5m bGFncyk7Cj4gKwo+ICsgICAgICAgICAgICAgICBpZiAoIShuZXdfZmxhZ3MgJiBCSVQoUEdfcmVm ZXJlbmNlZCkpKSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgbmV3X2ZsYWdzIHw9IEJJVChQ R19yZWZlcmVuY2VkKTsKPiArICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKPiArICAg ICAgICAgICAgICAgfQo+ICsKPiArICAgICAgICAgICAgICAgaWYgKCEobmV3X2ZsYWdzICYgQklU KFBHX3dvcmtpbmdzZXQpKSkgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIG5ld19mbGFncyB8 PSBCSVQoUEdfd29ya2luZ3NldCk7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7 Cj4gKyAgICAgICAgICAgICAgIH0KPiArCj4gKyAgICAgICAgICAgICAgIHJlZnMgPSBuZXdfZmxh Z3MgJiBMUlVfUkVGU19NQVNLOwo+ICsgICAgICAgICAgICAgICByZWZzID0gbWluKHJlZnMgKyBC SVQoTFJVX1JFRlNfUEdPRkYpLCBMUlVfUkVGU19NQVNLKTsKPiArCj4gKyAgICAgICAgICAgICAg IG5ld19mbGFncyAmPSB+TFJVX1JFRlNfTUFTSzsKPiArICAgICAgICAgICAgICAgbmV3X2ZsYWdz IHw9IHJlZnM7Cj4gKyAgICAgICB9IHdoaWxlIChuZXdfZmxhZ3MgIT0gb2xkX2ZsYWdzICYmCj4g KyAgICAgICAgICAgICAgICBjbXB4Y2hnKCZmb2xpby0+ZmxhZ3MsIG9sZF9mbGFncywgbmV3X2Zs YWdzKSAhPSBvbGRfZmxhZ3MpOwo+ICt9Cj4gKyNlbHNlCj4gK3N0YXRpYyB2b2lkIGZvbGlvX2lu Y19yZWZzKHN0cnVjdCBmb2xpbyAqZm9saW8pCj4gK3sKPiArfQo+ICsjZW5kaWYgLyogQ09ORklH X0xSVV9HRU4gKi8KPiArCj4gIC8qCj4gICAqIE1hcmsgYSBwYWdlIGFzIGhhdmluZyBzZWVuIGFj dGl2aXR5Lgo+ICAgKgo+IEBAIC00MTcsNiArNDU0LDExIEBAIHN0YXRpYyB2b2lkIF9fbHJ1X2Nh Y2hlX2FjdGl2YXRlX2ZvbGlvKHN0cnVjdCBmb2xpbyAqZm9saW8pCj4gICAqLwo+ICB2b2lkIGZv bGlvX21hcmtfYWNjZXNzZWQoc3RydWN0IGZvbGlvICpmb2xpbykKPiAgewo+ICsgICAgICAgaWYg KGxydV9nZW5fZW5hYmxlZCgpKSB7Cj4gKyAgICAgICAgICAgICAgIGZvbGlvX2luY19yZWZzKGZv bGlvKTsKPiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ICsgICAgICAgfQo+ICsKPiAgICAgICAg IGlmICghZm9saW9fdGVzdF9yZWZlcmVuY2VkKGZvbGlvKSkgewo+ICAgICAgICAgICAgICAgICBm b2xpb19zZXRfcmVmZXJlbmNlZChmb2xpbyk7Cj4gICAgICAgICB9IGVsc2UgaWYgKGZvbGlvX3Rl c3RfdW5ldmljdGFibGUoZm9saW8pKSB7Cj4gZGlmZiAtLWdpdCBhL21tL3Ztc2Nhbi5jIGIvbW0v dm1zY2FuLmMKPiBpbmRleCAzN2RkNWQxYzNkMDcuLmJiM2Q3MDVjNTI4MiAxMDA2NDQKPiAtLS0g YS9tbS92bXNjYW4uYwo+ICsrKyBiL21tL3Ztc2Nhbi5jCj4gQEAgLTEyNzUsOSArMTI3NSwxMSBA QCBzdGF0aWMgaW50IF9fcmVtb3ZlX21hcHBpbmcoc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBp bmcsIHN0cnVjdCBmb2xpbyAqZm9saW8sCj4KPiAgICAgICAgIGlmIChmb2xpb190ZXN0X3N3YXBj YWNoZShmb2xpbykpIHsKPiAgICAgICAgICAgICAgICAgc3dwX2VudHJ5X3Qgc3dhcCA9IGZvbGlv X3N3YXBfZW50cnkoZm9saW8pOwo+IC0gICAgICAgICAgICAgICBtZW1fY2dyb3VwX3N3YXBvdXQo Zm9saW8sIHN3YXApOwo+ICsKPiArICAgICAgICAgICAgICAgLyogZ2V0IGEgc2hhZG93IGVudHJ5 IGJlZm9yZSBtZW1fY2dyb3VwX3N3YXBvdXQoKSBjbGVhcnMgZm9saW9fbWVtY2coKSAqLwo+ICAg ICAgICAgICAgICAgICBpZiAocmVjbGFpbWVkICYmICFtYXBwaW5nX2V4aXRpbmcobWFwcGluZykp Cj4gICAgICAgICAgICAgICAgICAgICAgICAgc2hhZG93ID0gd29ya2luZ3NldF9ldmljdGlvbihm b2xpbywgdGFyZ2V0X21lbWNnKTsKPiArICAgICAgICAgICAgICAgbWVtX2Nncm91cF9zd2Fwb3V0 KGZvbGlvLCBzd2FwKTsKPiAgICAgICAgICAgICAgICAgX19kZWxldGVfZnJvbV9zd2FwX2NhY2hl KCZmb2xpby0+cGFnZSwgc3dhcCwgc2hhZG93KTsKPiAgICAgICAgICAgICAgICAgeGFfdW5sb2Nr X2lycSgmbWFwcGluZy0+aV9wYWdlcyk7Cj4gICAgICAgICAgICAgICAgIHB1dF9zd2FwX3BhZ2Uo JmZvbGlvLT5wYWdlLCBzd2FwKTsKPiBAQCAtMjY0OSw2ICsyNjUxLDkgQEAgc3RhdGljIHZvaWQg cHJlcGFyZV9zY2FuX2NvdW50KHBnX2RhdGFfdCAqcGdkYXQsIHN0cnVjdCBzY2FuX2NvbnRyb2wg KnNjKQo+ICAgICAgICAgdW5zaWduZWQgbG9uZyBmaWxlOwo+ICAgICAgICAgc3RydWN0IGxydXZl YyAqdGFyZ2V0X2xydXZlYzsKPgo+ICsgICAgICAgaWYgKGxydV9nZW5fZW5hYmxlZCgpKQo+ICsg ICAgICAgICAgICAgICByZXR1cm47Cj4gKwo+ICAgICAgICAgdGFyZ2V0X2xydXZlYyA9IG1lbV9j Z3JvdXBfbHJ1dmVjKHNjLT50YXJnZXRfbWVtX2Nncm91cCwgcGdkYXQpOwo+Cj4gICAgICAgICAv Kgo+IEBAIC0yOTc0LDExICsyOTc5LDM4IEBAIHN0YXRpYyBib29sIGNhbl9hZ2VfYW5vbl9wYWdl cyhzdHJ1Y3QgcGdsaXN0X2RhdGEgKnBnZGF0LAo+ICAgKiAgICAgICAgICAgICAgICAgICAgICAg ICAgc2hvcnRoYW5kIGhlbHBlcnMKPiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KPgo+ICsjZGVm aW5lIERFRklORV9NQVhfU0VRKGxydXZlYykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIFwKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgbWF4X3NlcSA9IFJFQURfT05DRSgo bHJ1dmVjKS0+bHJ1Z2VuLm1heF9zZXEpCj4gKwo+ICsjZGVmaW5lIERFRklORV9NSU5fU0VRKGxy dXZlYykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKPiArICAgICAg IHVuc2lnbmVkIGxvbmcgbWluX3NlcVtBTk9OX0FORF9GSUxFXSA9IHsgICAgICAgICAgICAgICAg ICAgICAgICBcCj4gKyAgICAgICAgICAgICAgIFJFQURfT05DRSgobHJ1dmVjKS0+bHJ1Z2VuLm1p bl9zZXFbTFJVX0dFTl9BTk9OXSksICAgICAgXAo+ICsgICAgICAgICAgICAgICBSRUFEX09OQ0Uo KGxydXZlYyktPmxydWdlbi5taW5fc2VxW0xSVV9HRU5fRklMRV0pLCAgICAgIFwKPiArICAgICAg IH0KPiArCj4gICNkZWZpbmUgZm9yX2VhY2hfZ2VuX3R5cGVfem9uZShnZW4sIHR5cGUsIHpvbmUp ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCj4gICAgICAgICBmb3IgKChnZW4pID0g MDsgKGdlbikgPCBNQVhfTlJfR0VOUzsgKGdlbikrKykgICAgICAgICAgICAgICAgICAgXAo+ICAg ICAgICAgICAgICAgICBmb3IgKCh0eXBlKSA9IDA7ICh0eXBlKSA8IEFOT05fQU5EX0ZJTEU7ICh0 eXBlKSsrKSAgICAgIFwKPiAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKCh6b25lKSA9IDA7 ICh6b25lKSA8IE1BWF9OUl9aT05FUzsgKHpvbmUpKyspCj4KPiArc3RhdGljIGludCBmb2xpb19s cnVfZ2VuKHN0cnVjdCBmb2xpbyAqZm9saW8pCj4gK3sKPiArICAgICAgIHVuc2lnbmVkIGxvbmcg ZmxhZ3MgPSBSRUFEX09OQ0UoZm9saW8tPmZsYWdzKTsKPiArCj4gKyAgICAgICByZXR1cm4gKChm bGFncyAmIExSVV9HRU5fTUFTSykgPj4gTFJVX0dFTl9QR09GRikgLSAxOwo+ICt9Cj4gKwo+ICtz dGF0aWMgaW50IGZvbGlvX2xydV90aWVyKHN0cnVjdCBmb2xpbyAqZm9saW8pCj4gK3sKPiArICAg ICAgIGludCByZWZzOwo+ICsgICAgICAgdW5zaWduZWQgbG9uZyBmbGFncyA9IFJFQURfT05DRShm b2xpby0+ZmxhZ3MpOwo+ICsKPiArICAgICAgIHJlZnMgPSAoZmxhZ3MgJiBMUlVfUkVGU19GTEFH UykgPT0gTFJVX1JFRlNfRkxBR1MgPwo+ICsgICAgICAgICAgICAgICgoZmxhZ3MgJiBMUlVfUkVG U19NQVNLKSA+PiBMUlVfUkVGU19QR09GRikgKyAxIDogMDsKPiArCj4gKyAgICAgICByZXR1cm4g bHJ1X3RpZXJfZnJvbV9yZWZzKHJlZnMpOwo+ICt9Cj4gKwo+ICBzdGF0aWMgc3RydWN0IGxydXZl YyBfX21heWJlX3VudXNlZCAqZ2V0X2xydXZlYyhzdHJ1Y3QgbWVtX2Nncm91cCAqbWVtY2csIGlu dCBuaWQpCj4gIHsKPiAgICAgICAgIHN0cnVjdCBwZ2xpc3RfZGF0YSAqcGdkYXQgPSBOT0RFX0RB VEEobmlkKTsKPiBAQCAtMjk5OSw2ICszMDMxLDc1NCBAQCBzdGF0aWMgc3RydWN0IGxydXZlYyBf X21heWJlX3VudXNlZCAqZ2V0X2xydXZlYyhzdHJ1Y3QgbWVtX2Nncm91cCAqbWVtY2csIGludCBu aQo+ICAgICAgICAgcmV0dXJuIHBnZGF0ID8gJnBnZGF0LT5fX2xydXZlYyA6IE5VTEw7Cj4gIH0K Pgo+ICtzdGF0aWMgaW50IGdldF9zd2FwcGluZXNzKHN0cnVjdCBscnV2ZWMgKmxydXZlYywgc3Ry dWN0IHNjYW5fY29udHJvbCAqc2MpCj4gK3sKPiArICAgICAgIHN0cnVjdCBtZW1fY2dyb3VwICpt ZW1jZyA9IGxydXZlY19tZW1jZyhscnV2ZWMpOwo+ICsgICAgICAgc3RydWN0IHBnbGlzdF9kYXRh ICpwZ2RhdCA9IGxydXZlY19wZ2RhdChscnV2ZWMpOwo+ICsKPiArICAgICAgIGlmICghY2FuX2Rl bW90ZShwZ2RhdC0+bm9kZV9pZCwgc2MpICYmCj4gKyAgICAgICAgICAgbWVtX2Nncm91cF9nZXRf bnJfc3dhcF9wYWdlcyhtZW1jZykgPCBNSU5fTFJVX0JBVENIKQo+ICsgICAgICAgICAgICAgICBy ZXR1cm4gMDsKPiArCj4gKyAgICAgICByZXR1cm4gbWVtX2Nncm91cF9zd2FwcGluZXNzKG1lbWNn KTsKPiArfQo+ICsKPiArc3RhdGljIGludCBnZXRfbnJfZ2VucyhzdHJ1Y3QgbHJ1dmVjICpscnV2 ZWMsIGludCB0eXBlKQo+ICt7Cj4gKyAgICAgICByZXR1cm4gbHJ1dmVjLT5scnVnZW4ubWF4X3Nl cSAtIGxydXZlYy0+bHJ1Z2VuLm1pbl9zZXFbdHlwZV0gKyAxOwo+ICt9Cj4gKwo+ICtzdGF0aWMg Ym9vbCBfX21heWJlX3VudXNlZCBzZXFfaXNfdmFsaWQoc3RydWN0IGxydXZlYyAqbHJ1dmVjKQo+ ICt7Cj4gKyAgICAgICAvKiBzZWUgdGhlIGNvbW1lbnQgb24gbHJ1X2dlbl9zdHJ1Y3QgKi8KPiAr ICAgICAgIHJldHVybiBnZXRfbnJfZ2VucyhscnV2ZWMsIExSVV9HRU5fRklMRSkgPj0gTUlOX05S X0dFTlMgJiYKPiArICAgICAgICAgICAgICBnZXRfbnJfZ2VucyhscnV2ZWMsIExSVV9HRU5fRklM RSkgPD0gZ2V0X25yX2dlbnMobHJ1dmVjLCBMUlVfR0VOX0FOT04pICYmCj4gKyAgICAgICAgICAg ICAgZ2V0X25yX2dlbnMobHJ1dmVjLCBMUlVfR0VOX0FOT04pIDw9IE1BWF9OUl9HRU5TOwo+ICt9 Cj4gKwo+ICsvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCj4gKyAqICAgICAgICAgICAgICAgICAgICAg ICAgICByZWZhdWx0IGZlZWRiYWNrIGxvb3AKPiArICoqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KPiAr Cj4gKy8qCj4gKyAqIEEgZmVlZGJhY2sgbG9vcCBiYXNlZCBvbiBQcm9wb3J0aW9uYWwtSW50ZWdy YWwtRGVyaXZhdGl2ZSAoUElEKSBjb250cm9sbGVyLgo+ICsgKgo+ICsgKiBUaGUgUCB0ZXJtIGlz IHJlZmF1bHRlZC8oZXZpY3RlZCtwcm90ZWN0ZWQpIGZyb20gYSB0aWVyIGluIHRoZSBnZW5lcmF0 aW9uCj4gKyAqIGN1cnJlbnRseSBiZWluZyBldmljdGVkOyB0aGUgSSB0ZXJtIGlzIHRoZSBleHBv bmVudGlhbCBtb3ZpbmcgYXZlcmFnZSBvZiB0aGUKPiArICogUCB0ZXJtIG92ZXIgdGhlIGdlbmVy YXRpb25zIHByZXZpb3VzbHkgZXZpY3RlZCwgdXNpbmcgdGhlIHNtb290aGluZyBmYWN0b3IKPiAr ICogMS8yOyB0aGUgRCB0ZXJtIGlzbid0IHN1cHBvcnRlZC4KPiArICoKPiArICogVGhlIHNldHBv aW50IChTUCkgaXMgYWx3YXlzIHRoZSBmaXJzdCB0aWVyIG9mIG9uZSB0eXBlOyB0aGUgcHJvY2Vz cyB2YXJpYWJsZQo+ICsgKiAoUFYpIGlzIGVpdGhlciBhbnkgdGllciBvZiB0aGUgb3RoZXIgdHlw ZSBvciBhbnkgb3RoZXIgdGllciBvZiB0aGUgc2FtZQo+ICsgKiB0eXBlLgo+ICsgKgo+ICsgKiBU aGUgZXJyb3IgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgU1AgYW5kIHRoZSBQVjsgdGhl IGNvcnJlY3Rpb24gaXMKPiArICogdHVybiBvZmYgcHJvdGVjdGlvbiB3aGVuIFNQPlBWIG9yIHR1 cm4gb24gcHJvdGVjdGlvbiB3aGVuIFNQPFBWLgo+ICsgKgo+ICsgKiBGb3IgZnV0dXJlIG9wdGlt aXphdGlvbnM6Cj4gKyAqIDEuIFRoZSBEIHRlcm0gbWF5IGRpc2NvdW50IHRoZSBvdGhlciB0d28g dGVybXMgb3ZlciB0aW1lIHNvIHRoYXQgbG9uZy1saXZlZAo+ICsgKiAgICBnZW5lcmF0aW9ucyBj YW4gcmVzaXN0IHN0YWxlIGluZm9ybWF0aW9uLgo+ICsgKi8KPiArc3RydWN0IGN0cmxfcG9zIHsK PiArICAgICAgIHVuc2lnbmVkIGxvbmcgcmVmYXVsdGVkOwo+ICsgICAgICAgdW5zaWduZWQgbG9u ZyB0b3RhbDsKPiArICAgICAgIGludCBnYWluOwo+ICt9Owo+ICsKPiArc3RhdGljIHZvaWQgcmVh ZF9jdHJsX3BvcyhzdHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIGludCB0eXBlLCBpbnQgdGllciwgaW50 IGdhaW4sCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY3RybF9wb3MgKnBvcykK PiArewo+ICsgICAgICAgc3RydWN0IGxydV9nZW5fc3RydWN0ICpscnVnZW4gPSAmbHJ1dmVjLT5s cnVnZW47Cj4gKyAgICAgICBpbnQgaGlzdCA9IGxydV9oaXN0X2Zyb21fc2VxKGxydWdlbi0+bWlu X3NlcVt0eXBlXSk7Cj4gKwo+ICsgICAgICAgcG9zLT5yZWZhdWx0ZWQgPSBscnVnZW4tPmF2Z19y ZWZhdWx0ZWRbdHlwZV1bdGllcl0gKwo+ICsgICAgICAgICAgICAgICAgICAgICAgICBhdG9taWNf bG9uZ19yZWFkKCZscnVnZW4tPnJlZmF1bHRlZFtoaXN0XVt0eXBlXVt0aWVyXSk7Cj4gKyAgICAg ICBwb3MtPnRvdGFsID0gbHJ1Z2VuLT5hdmdfdG90YWxbdHlwZV1bdGllcl0gKwo+ICsgICAgICAg ICAgICAgICAgICAgIGF0b21pY19sb25nX3JlYWQoJmxydWdlbi0+ZXZpY3RlZFtoaXN0XVt0eXBl XVt0aWVyXSk7Cj4gKyAgICAgICBpZiAodGllcikKPiArICAgICAgICAgICAgICAgcG9zLT50b3Rh bCArPSBscnVnZW4tPnByb3RlY3RlZFtoaXN0XVt0eXBlXVt0aWVyIC0gMV07Cj4gKyAgICAgICBw b3MtPmdhaW4gPSBnYWluOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCByZXNldF9jdHJsX3Bvcyhz dHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIGludCB0eXBlLCBib29sIGNhcnJ5b3ZlcikKPiArewo+ICsg ICAgICAgaW50IGhpc3QsIHRpZXI7Cj4gKyAgICAgICBzdHJ1Y3QgbHJ1X2dlbl9zdHJ1Y3QgKmxy dWdlbiA9ICZscnV2ZWMtPmxydWdlbjsKPiArICAgICAgIGJvb2wgY2xlYXIgPSBjYXJyeW92ZXIg PyBOUl9ISVNUX0dFTlMgPT0gMSA6IE5SX0hJU1RfR0VOUyA+IDE7Cj4gKyAgICAgICB1bnNpZ25l ZCBsb25nIHNlcSA9IGNhcnJ5b3ZlciA/IGxydWdlbi0+bWluX3NlcVt0eXBlXSA6IGxydWdlbi0+ bWF4X3NlcSArIDE7Cj4gKwo+ICsgICAgICAgbG9ja2RlcF9hc3NlcnRfaGVsZCgmbHJ1dmVjLT5s cnVfbG9jayk7Cj4gKwo+ICsgICAgICAgaWYgKCFjYXJyeW92ZXIgJiYgIWNsZWFyKQo+ICsgICAg ICAgICAgICAgICByZXR1cm47Cj4gKwo+ICsgICAgICAgaGlzdCA9IGxydV9oaXN0X2Zyb21fc2Vx KHNlcSk7Cj4gKwo+ICsgICAgICAgZm9yICh0aWVyID0gMDsgdGllciA8IE1BWF9OUl9USUVSUzsg dGllcisrKSB7Cj4gKyAgICAgICAgICAgICAgIGlmIChjYXJyeW92ZXIpIHsKPiArICAgICAgICAg ICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIHN1bTsKPiArCj4gKyAgICAgICAgICAgICAgICAg ICAgICAgc3VtID0gbHJ1Z2VuLT5hdmdfcmVmYXVsdGVkW3R5cGVdW3RpZXJdICsKPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBhdG9taWNfbG9uZ19yZWFkKCZscnVnZW4tPnJlZmF1bHRl ZFtoaXN0XVt0eXBlXVt0aWVyXSk7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgV1JJVEVfT05D RShscnVnZW4tPmF2Z19yZWZhdWx0ZWRbdHlwZV1bdGllcl0sIHN1bSAvIDIpOwo+ICsKPiArICAg ICAgICAgICAgICAgICAgICAgICBzdW0gPSBscnVnZW4tPmF2Z190b3RhbFt0eXBlXVt0aWVyXSAr Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXRvbWljX2xvbmdfcmVhZCgmbHJ1Z2Vu LT5ldmljdGVkW2hpc3RdW3R5cGVdW3RpZXJdKTsKPiArICAgICAgICAgICAgICAgICAgICAgICBp ZiAodGllcikKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bSArPSBscnVnZW4t PnByb3RlY3RlZFtoaXN0XVt0eXBlXVt0aWVyIC0gMV07Cj4gKyAgICAgICAgICAgICAgICAgICAg ICAgV1JJVEVfT05DRShscnVnZW4tPmF2Z190b3RhbFt0eXBlXVt0aWVyXSwgc3VtIC8gMik7Cj4g KyAgICAgICAgICAgICAgIH0KPiArCj4gKyAgICAgICAgICAgICAgIGlmIChjbGVhcikgewo+ICsg ICAgICAgICAgICAgICAgICAgICAgIGF0b21pY19sb25nX3NldCgmbHJ1Z2VuLT5yZWZhdWx0ZWRb aGlzdF1bdHlwZV1bdGllcl0sIDApOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGF0b21pY19s b25nX3NldCgmbHJ1Z2VuLT5ldmljdGVkW2hpc3RdW3R5cGVdW3RpZXJdLCAwKTsKPiArICAgICAg ICAgICAgICAgICAgICAgICBpZiAodGllcikKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIFdSSVRFX09OQ0UobHJ1Z2VuLT5wcm90ZWN0ZWRbaGlzdF1bdHlwZV1bdGllciAtIDFdLCAw KTsKPiArICAgICAgICAgICAgICAgfQo+ICsgICAgICAgfQo+ICt9Cj4gKwo+ICtzdGF0aWMgYm9v bCBwb3NpdGl2ZV9jdHJsX2VycihzdHJ1Y3QgY3RybF9wb3MgKnNwLCBzdHJ1Y3QgY3RybF9wb3Mg KnB2KQo+ICt7Cj4gKyAgICAgICAvKgo+ICsgICAgICAgICogUmV0dXJuIHRydWUgaWYgdGhlIFBW IGhhcyBhIGxpbWl0ZWQgbnVtYmVyIG9mIHJlZmF1bHRzIG9yIGEgbG93ZXIKPiArICAgICAgICAq IHJlZmF1bHRlZC90b3RhbCB0aGFuIHRoZSBTUC4KPiArICAgICAgICAqLwo+ICsgICAgICAgcmV0 dXJuIHB2LT5yZWZhdWx0ZWQgPCBNSU5fTFJVX0JBVENIIHx8Cj4gKyAgICAgICAgICAgICAgcHYt PnJlZmF1bHRlZCAqIChzcC0+dG90YWwgKyBNSU5fTFJVX0JBVENIKSAqIHNwLT5nYWluIDw9Cj4g KyAgICAgICAgICAgICAgKHNwLT5yZWZhdWx0ZWQgKyAxKSAqIHB2LT50b3RhbCAqIHB2LT5nYWlu Owo+ICt9Cj4gKwo+ICsvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCj4gKyAqICAgICAgICAgICAgICAg ICAgICAgICAgICB0aGUgYWdpbmcKPiArICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KPiArCj4gK3N0 YXRpYyBpbnQgZm9saW9faW5jX2dlbihzdHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIHN0cnVjdCBmb2xp byAqZm9saW8sIGJvb2wgcmVjbGFpbWluZykKPiArewo+ICsgICAgICAgdW5zaWduZWQgbG9uZyBv bGRfZmxhZ3MsIG5ld19mbGFnczsKPiArICAgICAgIGludCB0eXBlID0gZm9saW9faXNfZmlsZV9s cnUoZm9saW8pOwo+ICsgICAgICAgc3RydWN0IGxydV9nZW5fc3RydWN0ICpscnVnZW4gPSAmbHJ1 dmVjLT5scnVnZW47Cj4gKyAgICAgICBpbnQgbmV3X2dlbiwgb2xkX2dlbiA9IGxydV9nZW5fZnJv bV9zZXEobHJ1Z2VuLT5taW5fc2VxW3R5cGVdKTsKPiArCj4gKyAgICAgICBkbyB7Cj4gKyAgICAg ICAgICAgICAgIG5ld19mbGFncyA9IG9sZF9mbGFncyA9IFJFQURfT05DRShmb2xpby0+ZmxhZ3Mp Owo+ICsgICAgICAgICAgICAgICBWTV9CVUdfT05fRk9MSU8oIShuZXdfZmxhZ3MgJiBMUlVfR0VO X01BU0spLCBmb2xpbyk7Cj4gKwo+ICsgICAgICAgICAgICAgICBuZXdfZ2VuID0gKG9sZF9nZW4g KyAxKSAlIE1BWF9OUl9HRU5TOwo+ICsKPiArICAgICAgICAgICAgICAgbmV3X2ZsYWdzICY9IH5M UlVfR0VOX01BU0s7Cj4gKyAgICAgICAgICAgICAgIG5ld19mbGFncyB8PSAobmV3X2dlbiArIDFV TCkgPDwgTFJVX0dFTl9QR09GRjsKPiArICAgICAgICAgICAgICAgbmV3X2ZsYWdzICY9IH4oTFJV X1JFRlNfTUFTSyB8IExSVV9SRUZTX0ZMQUdTKTsKPiArICAgICAgICAgICAgICAgLyogZm9yIGZv bGlvX2VuZF93cml0ZWJhY2soKSAqLwo+ICsgICAgICAgICAgICAgICBpZiAocmVjbGFpbWluZykK PiArICAgICAgICAgICAgICAgICAgICAgICBuZXdfZmxhZ3MgfD0gQklUKFBHX3JlY2xhaW0pOwo+ ICsgICAgICAgfSB3aGlsZSAoY21weGNoZygmZm9saW8tPmZsYWdzLCBvbGRfZmxhZ3MsIG5ld19m bGFncykgIT0gb2xkX2ZsYWdzKTsKPiArCj4gKyAgICAgICBscnVfZ2VuX3VwZGF0ZV9zaXplKGxy dXZlYywgZm9saW8sIG9sZF9nZW4sIG5ld19nZW4pOwo+ICsKPiArICAgICAgIHJldHVybiBuZXdf Z2VuOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBpbmNfbWluX3NlcShzdHJ1Y3QgbHJ1dmVjICps cnV2ZWMpCj4gK3sKPiArICAgICAgIGludCB0eXBlOwo+ICsgICAgICAgc3RydWN0IGxydV9nZW5f c3RydWN0ICpscnVnZW4gPSAmbHJ1dmVjLT5scnVnZW47Cj4gKwo+ICsgICAgICAgVk1fQlVHX09O KCFzZXFfaXNfdmFsaWQobHJ1dmVjKSk7Cj4gKwo+ICsgICAgICAgZm9yICh0eXBlID0gMDsgdHlw ZSA8IEFOT05fQU5EX0ZJTEU7IHR5cGUrKykgewo+ICsgICAgICAgICAgICAgICBpZiAoZ2V0X25y X2dlbnMobHJ1dmVjLCB0eXBlKSAhPSBNQVhfTlJfR0VOUykKPiArICAgICAgICAgICAgICAgICAg ICAgICBjb250aW51ZTsKPiArCj4gKyAgICAgICAgICAgICAgIHJlc2V0X2N0cmxfcG9zKGxydXZl YywgdHlwZSwgdHJ1ZSk7Cj4gKyAgICAgICAgICAgICAgIFdSSVRFX09OQ0UobHJ1Z2VuLT5taW5f c2VxW3R5cGVdLCBscnVnZW4tPm1pbl9zZXFbdHlwZV0gKyAxKTsKPiArICAgICAgIH0KPiArfQo+ ICsKPiArc3RhdGljIGJvb2wgdHJ5X3RvX2luY19taW5fc2VxKHN0cnVjdCBscnV2ZWMgKmxydXZl YywgYm9vbCBjYW5fc3dhcCkKPiArewo+ICsgICAgICAgaW50IGdlbiwgdHlwZSwgem9uZTsKPiAr ICAgICAgIGJvb2wgc3VjY2VzcyA9IGZhbHNlOwo+ICsgICAgICAgc3RydWN0IGxydV9nZW5fc3Ry dWN0ICpscnVnZW4gPSAmbHJ1dmVjLT5scnVnZW47Cj4gKyAgICAgICBERUZJTkVfTUlOX1NFUShs cnV2ZWMpOwo+ICsKPiArICAgICAgIFZNX0JVR19PTighc2VxX2lzX3ZhbGlkKGxydXZlYykpOwo+ ICsKPiArICAgICAgIGZvciAodHlwZSA9ICFjYW5fc3dhcDsgdHlwZSA8IEFOT05fQU5EX0ZJTEU7 IHR5cGUrKykgewo+ICsgICAgICAgICAgICAgICB3aGlsZSAobWluX3NlcVt0eXBlXSArIE1JTl9O Ul9HRU5TIDw9IGxydWdlbi0+bWF4X3NlcSkgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIGdl biA9IGxydV9nZW5fZnJvbV9zZXEobWluX3NlcVt0eXBlXSk7Cj4gKwo+ICsgICAgICAgICAgICAg ICAgICAgICAgIGZvciAoem9uZSA9IDA7IHpvbmUgPCBNQVhfTlJfWk9ORVM7IHpvbmUrKykgewo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFsaXN0X2VtcHR5KCZscnVnZW4t Pmxpc3RzW2dlbl1bdHlwZV1bem9uZV0pKQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBnb3RvIG5leHQ7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgfQo+ICsKPiAr ICAgICAgICAgICAgICAgICAgICAgICBtaW5fc2VxW3R5cGVdKys7Cj4gKyAgICAgICAgICAgICAg IH0KPiArbmV4dDoKPiArICAgICAgICAgICAgICAgOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAg IC8qIHNlZSB0aGUgY29tbWVudCBvbiBscnVfZ2VuX3N0cnVjdCAqLwo+ICsgICAgICAgaWYgKGNh bl9zd2FwKSB7Cj4gKyAgICAgICAgICAgICAgIG1pbl9zZXFbTFJVX0dFTl9BTk9OXSA9IG1pbiht aW5fc2VxW0xSVV9HRU5fQU5PTl0sIG1pbl9zZXFbTFJVX0dFTl9GSUxFXSk7Cj4gKyAgICAgICAg ICAgICAgIG1pbl9zZXFbTFJVX0dFTl9GSUxFXSA9IG1heChtaW5fc2VxW0xSVV9HRU5fQU5PTl0s IGxydWdlbi0+bWluX3NlcVtMUlVfR0VOX0ZJTEVdKTsKPiArICAgICAgIH0KPiArCj4gKyAgICAg ICBmb3IgKHR5cGUgPSAhY2FuX3N3YXA7IHR5cGUgPCBBTk9OX0FORF9GSUxFOyB0eXBlKyspIHsK PiArICAgICAgICAgICAgICAgaWYgKG1pbl9zZXFbdHlwZV0gPT0gbHJ1Z2VuLT5taW5fc2VxW3R5 cGVdKQo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwo+ICsKPiArICAgICAgICAg ICAgICAgcmVzZXRfY3RybF9wb3MobHJ1dmVjLCB0eXBlLCB0cnVlKTsKPiArICAgICAgICAgICAg ICAgV1JJVEVfT05DRShscnVnZW4tPm1pbl9zZXFbdHlwZV0sIG1pbl9zZXFbdHlwZV0pOwo+ICsg ICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBy ZXR1cm4gc3VjY2VzczsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgaW5jX21heF9zZXEoc3RydWN0 IGxydXZlYyAqbHJ1dmVjLCB1bnNpZ25lZCBsb25nIG1heF9zZXEpCj4gK3sKPiArICAgICAgIGlu dCBwcmV2LCBuZXh0Owo+ICsgICAgICAgaW50IHR5cGUsIHpvbmU7Cj4gKyAgICAgICBzdHJ1Y3Qg bHJ1X2dlbl9zdHJ1Y3QgKmxydWdlbiA9ICZscnV2ZWMtPmxydWdlbjsKPiArCj4gKyAgICAgICBz cGluX2xvY2tfaXJxKCZscnV2ZWMtPmxydV9sb2NrKTsKPiArCj4gKyAgICAgICBWTV9CVUdfT04o IXNlcV9pc192YWxpZChscnV2ZWMpKTsKPiArCj4gKyAgICAgICBpZiAobWF4X3NlcSAhPSBscnVn ZW4tPm1heF9zZXEpCj4gKyAgICAgICAgICAgICAgIGdvdG8gdW5sb2NrOwo+ICsKPiArICAgICAg IGluY19taW5fc2VxKGxydXZlYyk7Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIFVwZGF0 ZSB0aGUgYWN0aXZlL2luYWN0aXZlIExSVSBzaXplcyBmb3IgY29tcGF0aWJpbGl0eS4gQm90aCBz aWRlcyBvZgo+ICsgICAgICAgICogdGhlIGN1cnJlbnQgbWF4X3NlcSBuZWVkIHRvIGJlIGNvdmVy ZWQsIHNpbmNlIG1heF9zZXErMSBjYW4gb3ZlcmxhcAo+ICsgICAgICAgICogd2l0aCBtaW5fc2Vx W0xSVV9HRU5fQU5PTl0gaWYgc3dhcHBpbmcgaXMgY29uc3RyYWluZWQuIEFuZCBpZiB0aGV5IGRv Cj4gKyAgICAgICAgKiBvdmVybGFwLCBjb2xkL2hvdCBpbnZlcnNpb24gaGFwcGVucy4gVGhpcyBj YW4gYmUgc29sdmVkIGJ5IG1vdmluZwo+ICsgICAgICAgICogcGFnZXMgZnJvbSBtaW5fc2VxIHRv IG1pbl9zZXErMSBidXQgaXMgb21pdHRlZCBmb3Igc2ltcGxpY2l0eS4KPiArICAgICAgICAqLwo+ ICsgICAgICAgcHJldiA9IGxydV9nZW5fZnJvbV9zZXEobHJ1Z2VuLT5tYXhfc2VxIC0gMSk7Cj4g KyAgICAgICBuZXh0ID0gbHJ1X2dlbl9mcm9tX3NlcShscnVnZW4tPm1heF9zZXEgKyAxKTsKPiAr Cj4gKyAgICAgICBmb3IgKHR5cGUgPSAwOyB0eXBlIDwgQU5PTl9BTkRfRklMRTsgdHlwZSsrKSB7 Cj4gKyAgICAgICAgICAgICAgIGZvciAoem9uZSA9IDA7IHpvbmUgPCBNQVhfTlJfWk9ORVM7IHpv bmUrKykgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIGVudW0gbHJ1X2xpc3QgbHJ1ID0gdHlw ZSAqIExSVV9JTkFDVElWRV9GSUxFOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVs dGEgPSBscnVnZW4tPm5yX3BhZ2VzW3ByZXZdW3R5cGVdW3pvbmVdIC0KPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgbHJ1Z2VuLT5ucl9wYWdlc1tuZXh0XVt0eXBlXVt6b25l XTsKPiArCj4gKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkZWx0YSkKPiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwo+ICsKPiArICAgICAgICAgICAgICAgICAg ICAgICBfX3VwZGF0ZV9scnVfc2l6ZShscnV2ZWMsIGxydSwgem9uZSwgZGVsdGEpOwo+ICsgICAg ICAgICAgICAgICAgICAgICAgIF9fdXBkYXRlX2xydV9zaXplKGxydXZlYywgbHJ1ICsgTFJVX0FD VElWRSwgem9uZSwgLWRlbHRhKTsKPiArICAgICAgICAgICAgICAgfQo+ICsgICAgICAgfQo+ICsK PiArICAgICAgIGZvciAodHlwZSA9IDA7IHR5cGUgPCBBTk9OX0FORF9GSUxFOyB0eXBlKyspCj4g KyAgICAgICAgICAgICAgIHJlc2V0X2N0cmxfcG9zKGxydXZlYywgdHlwZSwgZmFsc2UpOwo+ICsK PiArICAgICAgIC8qIG1ha2Ugc3VyZSBwcmVjZWRpbmcgbW9kaWZpY2F0aW9ucyBhcHBlYXIgKi8K PiArICAgICAgIHNtcF9zdG9yZV9yZWxlYXNlKCZscnVnZW4tPm1heF9zZXEsIGxydWdlbi0+bWF4 X3NlcSArIDEpOwo+ICt1bmxvY2s6Cj4gKyAgICAgICBzcGluX3VubG9ja19pcnEoJmxydXZlYy0+ bHJ1X2xvY2spOwo+ICt9Cj4gKwo+ICtzdGF0aWMgbG9uZyBnZXRfbnJfZXZpY3RhYmxlKHN0cnVj dCBscnV2ZWMgKmxydXZlYywgdW5zaWduZWQgbG9uZyBtYXhfc2VxLAo+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAqbWluX3NlcSwgYm9vbCBjYW5fc3dhcCwgYm9v bCAqbmVlZF9hZ2luZykKPiArewo+ICsgICAgICAgaW50IGdlbiwgdHlwZSwgem9uZTsKPiArICAg ICAgIGxvbmcgb2xkID0gMDsKPiArICAgICAgIGxvbmcgeW91bmcgPSAwOwo+ICsgICAgICAgbG9u ZyB0b3RhbCA9IDA7Cj4gKyAgICAgICBzdHJ1Y3QgbHJ1X2dlbl9zdHJ1Y3QgKmxydWdlbiA9ICZs cnV2ZWMtPmxydWdlbjsKPiArCj4gKyAgICAgICBmb3IgKHR5cGUgPSAhY2FuX3N3YXA7IHR5cGUg PCBBTk9OX0FORF9GSUxFOyB0eXBlKyspIHsKPiArICAgICAgICAgICAgICAgdW5zaWduZWQgbG9u ZyBzZXE7Cj4gKwo+ICsgICAgICAgICAgICAgICBmb3IgKHNlcSA9IG1pbl9zZXFbdHlwZV07IHNl cSA8PSBtYXhfc2VxOyBzZXErKykgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgc2l6 ZSA9IDA7Cj4gKwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGdlbiA9IGxydV9nZW5fZnJvbV9z ZXEoc2VxKTsKPiArCj4gKyAgICAgICAgICAgICAgICAgICAgICAgZm9yICh6b25lID0gMDsgem9u ZSA8IE1BWF9OUl9aT05FUzsgem9uZSsrKQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgc2l6ZSArPSBSRUFEX09OQ0UobHJ1Z2VuLT5ucl9wYWdlc1tnZW5dW3R5cGVdW3pvbmVdKTsK PiArCj4gKyAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gc2l6ZTsKPiArICAgICAgICAg ICAgICAgICAgICAgICBpZiAoc2VxID09IG1heF9zZXEpCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB5b3VuZyArPSBzaXplOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGlmIChz ZXEgKyBNSU5fTlJfR0VOUyA9PSBtYXhfc2VxKQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgb2xkICs9IHNpemU7Cj4gKyAgICAgICAgICAgICAgIH0KPiArICAgICAgIH0KPiArCj4g KyAgICAgICAvKgo+ICsgICAgICAgICogVGhlIGFnaW5nIGFuZCB0aGUgZXZpY3Rpb24gaXMgYSB0 eXBpY2FsIHByb2R1Y2VyLWNvbnN1bWVyIG1vZGVsLiBUaGUKPiArICAgICAgICAqIGFnaW5nIHRy aWVzIHRvIGJlIGxhenkgdG8gcmVkdWNlIHRoZSB1bm5lY2Vzc2FyeSBvdmVyaGVhZC4gT24gdGhl Cj4gKyAgICAgICAgKiBvdGhlciBoYW5kLCB0aGUgZXZpY3Rpb24gc3RhbGxzIHdoZW4gdGhlIG51 bWJlciBvZiBnZW5lcmF0aW9ucwo+ICsgICAgICAgICogcmVhY2hlcyBNSU5fTlJfR0VOUy4gU28g aWRlYWxseSwgdGhlcmUgc2hvdWxkIGJlIE1JTl9OUl9HRU5TKzEKPiArICAgICAgICAqIGdlbmVy YXRpb25zLCBoZW5jZSB0aGUgZmlyc3QgdHdvIGlmJ3MuCj4gKyAgICAgICAgKgo+ICsgICAgICAg ICogSW4gYWRkaXRpb24sIGl0J3MgaWRlYWwgdG8gc3ByZWFkIHBhZ2VzIG91dCBldmVubHksIG1l YW5pbmcKPiArICAgICAgICAqIDEvKE1JTl9OUl9HRU5TKzEpIG9mIHRoZSB0b3RhbCBudW1iZXIg b2YgcGFnZXMgZm9yIGVhY2ggZ2VuZXJhdGlvbi4gQQo+ICsgICAgICAgICogcmVhc29uYWJsZSBy YW5nZSBmb3IgdGhpcyBhdmVyYWdlIHBvcnRpb24gd291bGQgWzEvTUlOX05SX0dFTlMsCj4gKyAg ICAgICAgKiAxLyhNSU5fTlJfR0VOUysyKV0uIEZyb20gdGhlIGNvbnN1bWVyJ3MgUE9WLCB0aGUg ZXZpY3Rpb24gb25seSBjYXJlcwo+ICsgICAgICAgICogYWJvdXQgdGhlIGxvd2VyIGJvdW5kIG9m IGNvbGQgcGFnZXMsIGkuZS4sIDEvKE1JTl9OUl9HRU5TKzIpLCB3aGVyZWFzCj4gKyAgICAgICAg KiBmcm9tIHRoZSBwcm9kdWNlcidzIFBPViwgdGhlIGFnaW5nIG9ubHkgY2FyZXMgYWJvdXQgdGhl IHVwcGVyIGJvdW5kCj4gKyAgICAgICAgKiBvZiBob3QgcGFnZXMsIGkuZS4sIDEvTUlOX05SX0dF TlMuCj4gKyAgICAgICAgKi8KPiArICAgICAgIGlmIChtaW5fc2VxW0xSVV9HRU5fRklMRV0gKyBN SU5fTlJfR0VOUyA+IG1heF9zZXEpCj4gKyAgICAgICAgICAgICAgICpuZWVkX2FnaW5nID0gdHJ1 ZTsKPiArICAgICAgIGVsc2UgaWYgKG1pbl9zZXFbTFJVX0dFTl9GSUxFXSArIE1JTl9OUl9HRU5T IDwgbWF4X3NlcSkKPiArICAgICAgICAgICAgICAgKm5lZWRfYWdpbmcgPSBmYWxzZTsKPiArICAg ICAgIGVsc2UgaWYgKHlvdW5nICogTUlOX05SX0dFTlMgPiB0b3RhbCkKPiArICAgICAgICAgICAg ICAgKm5lZWRfYWdpbmcgPSB0cnVlOwo+ICsgICAgICAgZWxzZSBpZiAob2xkICogKE1JTl9OUl9H RU5TICsgMikgPCB0b3RhbCkKPiArICAgICAgICAgICAgICAgKm5lZWRfYWdpbmcgPSB0cnVlOwo+ ICsgICAgICAgZWxzZQo+ICsgICAgICAgICAgICAgICAqbmVlZF9hZ2luZyA9IGZhbHNlOwo+ICsK PiArICAgICAgIHJldHVybiB0b3RhbCA+IDAgPyB0b3RhbCA6IDA7Cj4gK30KPiArCj4gK3N0YXRp YyB2b2lkIGFnZV9scnV2ZWMoc3RydWN0IGxydXZlYyAqbHJ1dmVjLCBzdHJ1Y3Qgc2Nhbl9jb250 cm9sICpzYykKPiArewo+ICsgICAgICAgYm9vbCBuZWVkX2FnaW5nOwo+ICsgICAgICAgbG9uZyBu cl90b19zY2FuOwo+ICsgICAgICAgaW50IHN3YXBwaW5lc3MgPSBnZXRfc3dhcHBpbmVzcyhscnV2 ZWMsIHNjKTsKPiArICAgICAgIHN0cnVjdCBtZW1fY2dyb3VwICptZW1jZyA9IGxydXZlY19tZW1j ZyhscnV2ZWMpOwo+ICsgICAgICAgREVGSU5FX01BWF9TRVEobHJ1dmVjKTsKPiArICAgICAgIERF RklORV9NSU5fU0VRKGxydXZlYyk7Cj4gKwo+ICsgICAgICAgbWVtX2Nncm91cF9jYWxjdWxhdGVf cHJvdGVjdGlvbihOVUxMLCBtZW1jZyk7Cj4gKwo+ICsgICAgICAgaWYgKG1lbV9jZ3JvdXBfYmVs b3dfbWluKG1lbWNnKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ICsKPiArICAgICAgIG5y X3RvX3NjYW4gPSBnZXRfbnJfZXZpY3RhYmxlKGxydXZlYywgbWF4X3NlcSwgbWluX3NlcSwgc3dh cHBpbmVzcywgJm5lZWRfYWdpbmcpOwo+ICsgICAgICAgaWYgKCFucl90b19zY2FuKQo+ICsgICAg ICAgICAgICAgICByZXR1cm47Cj4gKwo+ICsgICAgICAgbnJfdG9fc2NhbiA+Pj0gc2MtPnByaW9y aXR5Owo+ICsKPiArICAgICAgIGlmICghbWVtX2Nncm91cF9vbmxpbmUobWVtY2cpKQo+ICsgICAg ICAgICAgICAgICBucl90b19zY2FuKys7Cj4gKwo+ICsgICAgICAgaWYgKG5yX3RvX3NjYW4gJiYg bmVlZF9hZ2luZyAmJiAoIW1lbV9jZ3JvdXBfYmVsb3dfbG93KG1lbWNnKSB8fCBzYy0+bWVtY2df bG93X3JlY2xhaW0pKQo+ICsgICAgICAgICAgICAgICBpbmNfbWF4X3NlcShscnV2ZWMsIG1heF9z ZXEpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBscnVfZ2VuX2FnZV9ub2RlKHN0cnVjdCBwZ2xp c3RfZGF0YSAqcGdkYXQsIHN0cnVjdCBzY2FuX2NvbnRyb2wgKnNjKQo+ICt7Cj4gKyAgICAgICBz dHJ1Y3QgbWVtX2Nncm91cCAqbWVtY2c7Cj4gKwo+ICsgICAgICAgVk1fQlVHX09OKCFjdXJyZW50 X2lzX2tzd2FwZCgpKTsKPiArCj4gKyAgICAgICBtZW1jZyA9IG1lbV9jZ3JvdXBfaXRlcihOVUxM LCBOVUxMLCBOVUxMKTsKPiArICAgICAgIGRvIHsKPiArICAgICAgICAgICAgICAgc3RydWN0IGxy dXZlYyAqbHJ1dmVjID0gbWVtX2Nncm91cF9scnV2ZWMobWVtY2csIHBnZGF0KTsKPiArCj4gKyAg ICAgICAgICAgICAgIGFnZV9scnV2ZWMobHJ1dmVjLCBzYyk7Cj4gKwo+ICsgICAgICAgICAgICAg ICBjb25kX3Jlc2NoZWQoKTsKPiArICAgICAgIH0gd2hpbGUgKChtZW1jZyA9IG1lbV9jZ3JvdXBf aXRlcihOVUxMLCBtZW1jZywgTlVMTCkpKTsKPiArfQo+ICsKPiArLyoqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKgo+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGV2aWN0aW9uCj4gKyAqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKiovCj4gKwo+ICtzdGF0aWMgYm9vbCBzb3J0X2ZvbGlvKHN0cnVjdCBs cnV2ZWMgKmxydXZlYywgc3RydWN0IGZvbGlvICpmb2xpbywgaW50IHRpZXJfaWR4KQo+ICt7Cj4g KyAgICAgICBib29sIHN1Y2Nlc3M7Cj4gKyAgICAgICBpbnQgZ2VuID0gZm9saW9fbHJ1X2dlbihm b2xpbyk7Cj4gKyAgICAgICBpbnQgdHlwZSA9IGZvbGlvX2lzX2ZpbGVfbHJ1KGZvbGlvKTsKPiAr ICAgICAgIGludCB6b25lID0gZm9saW9fem9uZW51bShmb2xpbyk7Cj4gKyAgICAgICBpbnQgdGll ciA9IGZvbGlvX2xydV90aWVyKGZvbGlvKTsKPiArICAgICAgIGludCBkZWx0YSA9IGZvbGlvX25y X3BhZ2VzKGZvbGlvKTsKPiArICAgICAgIHN0cnVjdCBscnVfZ2VuX3N0cnVjdCAqbHJ1Z2VuID0g JmxydXZlYy0+bHJ1Z2VuOwo+ICsKPiArICAgICAgIFZNX0JVR19PTl9GT0xJTyhnZW4gPj0gTUFY X05SX0dFTlMsIGZvbGlvKTsKPiArCj4gKyAgICAgICBpZiAoIWZvbGlvX2V2aWN0YWJsZShmb2xp bykpIHsKPiArICAgICAgICAgICAgICAgc3VjY2VzcyA9IGxydV9nZW5fZGVsX2ZvbGlvKGxydXZl YywgZm9saW8sIHRydWUpOwo+ICsgICAgICAgICAgICAgICBWTV9CVUdfT05fRk9MSU8oIXN1Y2Nl c3MsIGZvbGlvKTsKPiArICAgICAgICAgICAgICAgZm9saW9fc2V0X3VuZXZpY3RhYmxlKGZvbGlv KTsKPiArICAgICAgICAgICAgICAgbHJ1dmVjX2FkZF9mb2xpbyhscnV2ZWMsIGZvbGlvKTsKPiAr ICAgICAgICAgICAgICAgX19jb3VudF92bV9ldmVudHMoVU5FVklDVEFCTEVfUEdDVUxMRUQsIGRl bHRhKTsKPiArICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Cj4gKyAgICAgICB9Cj4gKwo+ICsg ICAgICAgaWYgKHR5cGUgPT0gTFJVX0dFTl9GSUxFICYmIGZvbGlvX3Rlc3RfYW5vbihmb2xpbykg JiYgZm9saW9fdGVzdF9kaXJ0eShmb2xpbykpIHsKPiArICAgICAgICAgICAgICAgc3VjY2VzcyA9 IGxydV9nZW5fZGVsX2ZvbGlvKGxydXZlYywgZm9saW8sIHRydWUpOwo+ICsgICAgICAgICAgICAg ICBWTV9CVUdfT05fRk9MSU8oIXN1Y2Nlc3MsIGZvbGlvKTsKPiArICAgICAgICAgICAgICAgZm9s aW9fc2V0X3N3YXBiYWNrZWQoZm9saW8pOwo+ICsgICAgICAgICAgICAgICBscnV2ZWNfYWRkX2Zv bGlvX3RhaWwobHJ1dmVjLCBmb2xpbyk7Cj4gKyAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwo+ ICsgICAgICAgfQo+ICsKPiArICAgICAgIGlmICh0aWVyID4gdGllcl9pZHgpIHsKPiArICAgICAg ICAgICAgICAgaW50IGhpc3QgPSBscnVfaGlzdF9mcm9tX3NlcShscnVnZW4tPm1pbl9zZXFbdHlw ZV0pOwo+ICsKPiArICAgICAgICAgICAgICAgZ2VuID0gZm9saW9faW5jX2dlbihscnV2ZWMsIGZv bGlvLCBmYWxzZSk7Cj4gKyAgICAgICAgICAgICAgIGxpc3RfbW92ZV90YWlsKCZmb2xpby0+bHJ1 LCAmbHJ1Z2VuLT5saXN0c1tnZW5dW3R5cGVdW3pvbmVdKTsKPiArCj4gKyAgICAgICAgICAgICAg IFdSSVRFX09OQ0UobHJ1Z2VuLT5wcm90ZWN0ZWRbaGlzdF1bdHlwZV1bdGllciAtIDFdLAo+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgIGxydWdlbi0+cHJvdGVjdGVkW2hpc3RdW3R5cGVdW3Rp ZXIgLSAxXSArIGRlbHRhKTsKPiArICAgICAgICAgICAgICAgX19tb2RfbHJ1dmVjX3N0YXRlKGxy dXZlYywgV09SS0lOR1NFVF9BQ1RJVkFURV9CQVNFICsgdHlwZSwgZGVsdGEpOwo+ICsgICAgICAg ICAgICAgICByZXR1cm4gdHJ1ZTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBpZiAoZm9saW9f dGVzdF9sb2NrZWQoZm9saW8pIHx8IGZvbGlvX3Rlc3Rfd3JpdGViYWNrKGZvbGlvKSB8fAo+ICsg ICAgICAgICAgICh0eXBlID09IExSVV9HRU5fRklMRSAmJiBmb2xpb190ZXN0X2RpcnR5KGZvbGlv KSkpIHsKPiArICAgICAgICAgICAgICAgZ2VuID0gZm9saW9faW5jX2dlbihscnV2ZWMsIGZvbGlv LCB0cnVlKTsKPiArICAgICAgICAgICAgICAgbGlzdF9tb3ZlKCZmb2xpby0+bHJ1LCAmbHJ1Z2Vu LT5saXN0c1tnZW5dW3R5cGVdW3pvbmVdKTsKPiArICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7 Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgcmV0dXJuIGZhbHNlOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgYm9vbCBpc29sYXRlX2ZvbGlvKHN0cnVjdCBscnV2ZWMgKmxydXZlYywgc3RydWN0IGZvbGlv ICpmb2xpbywgc3RydWN0IHNjYW5fY29udHJvbCAqc2MpCj4gK3sKPiArICAgICAgIGJvb2wgc3Vj Y2VzczsKPiArCj4gKyAgICAgICBpZiAoIXNjLT5tYXlfdW5tYXAgJiYgZm9saW9fbWFwcGVkKGZv bGlvKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwo+ICsKPiArICAgICAgIGlmICgh KHNjLT5tYXlfd3JpdGVwYWdlICYmIChzYy0+Z2ZwX21hc2sgJiBfX0dGUF9JTykpICYmCj4gKyAg ICAgICAgICAgKGZvbGlvX3Rlc3RfZGlydHkoZm9saW8pIHx8Cj4gKyAgICAgICAgICAgIChmb2xp b190ZXN0X2Fub24oZm9saW8pICYmICFmb2xpb190ZXN0X3N3YXBjYWNoZShmb2xpbykpKSkKPiAr ICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwo+ICsKPiArICAgICAgIGlmICghZm9saW9fdHJ5 X2dldChmb2xpbykpCj4gKyAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKPiArCj4gKyAgICAg ICBpZiAoIWZvbGlvX3Rlc3RfY2xlYXJfbHJ1KGZvbGlvKSkgewo+ICsgICAgICAgICAgICAgICBm b2xpb19wdXQoZm9saW8pOwo+ICsgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Cj4gKyAgICAg ICB9Cj4gKwo+ICsgICAgICAgc3VjY2VzcyA9IGxydV9nZW5fZGVsX2ZvbGlvKGxydXZlYywgZm9s aW8sIHRydWUpOwo+ICsgICAgICAgVk1fQlVHX09OX0ZPTElPKCFzdWNjZXNzLCBmb2xpbyk7Cj4g Kwo+ICsgICAgICAgcmV0dXJuIHRydWU7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgc2Nhbl9mb2xp b3Moc3RydWN0IGxydXZlYyAqbHJ1dmVjLCBzdHJ1Y3Qgc2Nhbl9jb250cm9sICpzYywKPiArICAg ICAgICAgICAgICAgICAgICAgIGludCB0eXBlLCBpbnQgdGllciwgc3RydWN0IGxpc3RfaGVhZCAq bGlzdCkKPiArewo+ICsgICAgICAgaW50IGdlbiwgem9uZTsKPiArICAgICAgIGVudW0gdm1fZXZl bnRfaXRlbSBpdGVtOwo+ICsgICAgICAgaW50IHNvcnRlZCA9IDA7Cj4gKyAgICAgICBpbnQgc2Nh bm5lZCA9IDA7Cj4gKyAgICAgICBpbnQgaXNvbGF0ZWQgPSAwOwo+ICsgICAgICAgaW50IHJlbWFp bmluZyA9IE1BWF9MUlVfQkFUQ0g7Cj4gKyAgICAgICBzdHJ1Y3QgbHJ1X2dlbl9zdHJ1Y3QgKmxy dWdlbiA9ICZscnV2ZWMtPmxydWdlbjsKPiArICAgICAgIHN0cnVjdCBtZW1fY2dyb3VwICptZW1j ZyA9IGxydXZlY19tZW1jZyhscnV2ZWMpOwo+ICsKPiArICAgICAgIFZNX0JVR19PTighbGlzdF9l bXB0eShsaXN0KSk7Cj4gKwo+ICsgICAgICAgaWYgKGdldF9ucl9nZW5zKGxydXZlYywgdHlwZSkg PT0gTUlOX05SX0dFTlMpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAwOwo+ICsKPiArICAgICAg IGdlbiA9IGxydV9nZW5fZnJvbV9zZXEobHJ1Z2VuLT5taW5fc2VxW3R5cGVdKTsKPiArCj4gKyAg ICAgICBmb3IgKHpvbmUgPSBzYy0+cmVjbGFpbV9pZHg7IHpvbmUgPj0gMDsgem9uZS0tKSB7Cj4g KyAgICAgICAgICAgICAgIExJU1RfSEVBRChtb3ZlZCk7Cj4gKyAgICAgICAgICAgICAgIGludCBz a2lwcGVkID0gMDsKPiArICAgICAgICAgICAgICAgc3RydWN0IGxpc3RfaGVhZCAqaGVhZCA9ICZs cnVnZW4tPmxpc3RzW2dlbl1bdHlwZV1bem9uZV07Cj4gKwo+ICsgICAgICAgICAgICAgICB3aGls ZSAoIWxpc3RfZW1wdHkoaGVhZCkpIHsKPiArICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qg Zm9saW8gKmZvbGlvID0gbHJ1X3RvX2ZvbGlvKGhlYWQpOwo+ICsgICAgICAgICAgICAgICAgICAg ICAgIGludCBkZWx0YSA9IGZvbGlvX25yX3BhZ2VzKGZvbGlvKTsKPiArCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgVk1fQlVHX09OX0ZPTElPKGZvbGlvX3Rlc3RfdW5ldmljdGFibGUoZm9saW8p LCBmb2xpbyk7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgVk1fQlVHX09OX0ZPTElPKGZvbGlv X3Rlc3RfYWN0aXZlKGZvbGlvKSwgZm9saW8pOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIFZN X0JVR19PTl9GT0xJTyhmb2xpb19pc19maWxlX2xydShmb2xpbykgIT0gdHlwZSwgZm9saW8pOwo+ ICsgICAgICAgICAgICAgICAgICAgICAgIFZNX0JVR19PTl9GT0xJTyhmb2xpb196b25lbnVtKGZv bGlvKSAhPSB6b25lLCBmb2xpbyk7Cj4gKwo+ICsgICAgICAgICAgICAgICAgICAgICAgIHNjYW5u ZWQgKz0gZGVsdGE7Cj4gKwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3J0X2ZvbGlv KGxydXZlYywgZm9saW8sIHRpZXIpKQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg c29ydGVkICs9IGRlbHRhOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzb2xh dGVfZm9saW8obHJ1dmVjLCBmb2xpbywgc2MpKSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBsaXN0X2FkZCgmZm9saW8tPmxydSwgbGlzdCk7Cj4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBpc29sYXRlZCArPSBkZWx0YTsKPiArICAgICAgICAgICAgICAgICAgICAg ICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9tb3ZlKCZm b2xpby0+bHJ1LCAmbW92ZWQpOwo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tp cHBlZCArPSBkZWx0YTsKPiArICAgICAgICAgICAgICAgICAgICAgICB9Cj4gKwo+ICsgICAgICAg ICAgICAgICAgICAgICAgIGlmICghLS1yZW1haW5pbmcgfHwgbWF4KGlzb2xhdGVkLCBza2lwcGVk KSA+PSBNSU5fTFJVX0JBVENIKQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJl YWs7Cj4gKyAgICAgICAgICAgICAgIH0KPiArCj4gKyAgICAgICAgICAgICAgIGlmIChza2lwcGVk KSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9zcGxpY2UoJm1vdmVkLCBoZWFkKTsK PiArICAgICAgICAgICAgICAgICAgICAgICBfX2NvdW50X3ppZF92bV9ldmVudHMoUEdTQ0FOX1NL SVAsIHpvbmUsIHNraXBwZWQpOwo+ICsgICAgICAgICAgICAgICB9Cj4gKwo+ICsgICAgICAgICAg ICAgICBpZiAoIXJlbWFpbmluZyB8fCBpc29sYXRlZCA+PSBNSU5fTFJVX0JBVENIKQo+ICsgICAg ICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIGl0ZW0g PSBjdXJyZW50X2lzX2tzd2FwZCgpID8gUEdTQ0FOX0tTV0FQRCA6IFBHU0NBTl9ESVJFQ1Q7Cj4g KyAgICAgICBpZiAoIWNncm91cF9yZWNsYWltKHNjKSkgewo+ICsgICAgICAgICAgICAgICBfX2Nv dW50X3ZtX2V2ZW50cyhpdGVtLCBpc29sYXRlZCk7Cj4gKyAgICAgICAgICAgICAgIF9fY291bnRf dm1fZXZlbnRzKFBHUkVGSUxMLCBzb3J0ZWQpOwo+ICsgICAgICAgfQo+ICsgICAgICAgX19jb3Vu dF9tZW1jZ19ldmVudHMobWVtY2csIGl0ZW0sIGlzb2xhdGVkKTsKPiArICAgICAgIF9fY291bnRf bWVtY2dfZXZlbnRzKG1lbWNnLCBQR1JFRklMTCwgc29ydGVkKTsKPiArICAgICAgIF9fY291bnRf dm1fZXZlbnRzKFBHU0NBTl9BTk9OICsgdHlwZSwgaXNvbGF0ZWQpOwo+ICsKPiArICAgICAgIC8q Cj4gKyAgICAgICAgKiBUaGVyZSBtaWdodCBub3QgYmUgZWxpZ2libGUgcGFnZXMgZHVlIHRvIHJl Y2xhaW1faWR4LCBtYXlfdW5tYXAgYW5kCj4gKyAgICAgICAgKiBtYXlfd3JpdGVwYWdlLiBDaGVj ayB0aGUgcmVtYWluaW5nIHRvIHByZXZlbnQgbGl2ZWxvY2sgaWYgdGhlcmUgaXMgbm8KPiArICAg ICAgICAqIHByb2dyZXNzLgo+ICsgICAgICAgICovCj4gKyAgICAgICByZXR1cm4gaXNvbGF0ZWQg fHwgIXJlbWFpbmluZyA/IHNjYW5uZWQgOiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGdldF90 aWVyX2lkeChzdHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIGludCB0eXBlKQo+ICt7Cj4gKyAgICAgICBp bnQgdGllcjsKPiArICAgICAgIHN0cnVjdCBjdHJsX3BvcyBzcCwgcHY7Cj4gKwo+ICsgICAgICAg LyoKPiArICAgICAgICAqIFRvIGxlYXZlIGEgbWFyZ2luIGZvciBmbHVjdHVhdGlvbnMsIHVzZSBh IGxhcmdlciBnYWluIGZhY3RvciAoMToyKS4KPiArICAgICAgICAqIFRoaXMgdmFsdWUgaXMgY2hv c2VuIGJlY2F1c2UgYW55IG90aGVyIHRpZXIgd291bGQgaGF2ZSBhdCBsZWFzdCB0d2ljZQo+ICsg ICAgICAgICogYXMgbWFueSByZWZhdWx0cyBhcyB0aGUgZmlyc3QgdGllci4KPiArICAgICAgICAq Lwo+ICsgICAgICAgcmVhZF9jdHJsX3BvcyhscnV2ZWMsIHR5cGUsIDAsIDEsICZzcCk7Cj4gKyAg ICAgICBmb3IgKHRpZXIgPSAxOyB0aWVyIDwgTUFYX05SX1RJRVJTOyB0aWVyKyspIHsKPiArICAg ICAgICAgICAgICAgcmVhZF9jdHJsX3BvcyhscnV2ZWMsIHR5cGUsIHRpZXIsIDIsICZwdik7Cj4g KyAgICAgICAgICAgICAgIGlmICghcG9zaXRpdmVfY3RybF9lcnIoJnNwLCAmcHYpKQo+ICsgICAg ICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHJldHVy biB0aWVyIC0gMTsKPiArfQo+ICsKPiArc3RhdGljIGludCBnZXRfdHlwZV90b19zY2FuKHN0cnVj dCBscnV2ZWMgKmxydXZlYywgaW50IHN3YXBwaW5lc3MsIGludCAqdGllcl9pZHgpCj4gK3sKPiAr ICAgICAgIGludCB0eXBlLCB0aWVyOwo+ICsgICAgICAgc3RydWN0IGN0cmxfcG9zIHNwLCBwdjsK PiArICAgICAgIGludCBnYWluW0FOT05fQU5EX0ZJTEVdID0geyBzd2FwcGluZXNzLCAyMDAgLSBz d2FwcGluZXNzIH07Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIENvbXBhcmUgdGhlIGZp cnN0IHRpZXIgb2YgYW5vbiB3aXRoIHRoYXQgb2YgZmlsZSB0byBkZXRlcm1pbmUgd2hpY2gKPiAr ICAgICAgICAqIHR5cGUgdG8gc2Nhbi4gQWxzbyBuZWVkIHRvIGNvbXBhcmUgb3RoZXIgdGllcnMg b2YgdGhlIHNlbGVjdGVkIHR5cGUKPiArICAgICAgICAqIHdpdGggdGhlIGZpcnN0IHRpZXIgb2Yg dGhlIG90aGVyIHR5cGUgdG8gZGV0ZXJtaW5lIHRoZSBsYXN0IHRpZXIgKG9mCj4gKyAgICAgICAg KiB0aGUgc2VsZWN0ZWQgdHlwZSkgdG8gZXZpY3QuCj4gKyAgICAgICAgKi8KPiArICAgICAgIHJl YWRfY3RybF9wb3MobHJ1dmVjLCBMUlVfR0VOX0FOT04sIDAsIGdhaW5bTFJVX0dFTl9BTk9OXSwg JnNwKTsKPiArICAgICAgIHJlYWRfY3RybF9wb3MobHJ1dmVjLCBMUlVfR0VOX0ZJTEUsIDAsIGdh aW5bTFJVX0dFTl9GSUxFXSwgJnB2KTsKPiArICAgICAgIHR5cGUgPSBwb3NpdGl2ZV9jdHJsX2Vy cigmc3AsICZwdik7Cj4gKwo+ICsgICAgICAgcmVhZF9jdHJsX3BvcyhscnV2ZWMsICF0eXBlLCAw LCBnYWluWyF0eXBlXSwgJnNwKTsKPiArICAgICAgIGZvciAodGllciA9IDE7IHRpZXIgPCBNQVhf TlJfVElFUlM7IHRpZXIrKykgewo+ICsgICAgICAgICAgICAgICByZWFkX2N0cmxfcG9zKGxydXZl YywgdHlwZSwgdGllciwgZ2Fpblt0eXBlXSwgJnB2KTsKPiArICAgICAgICAgICAgICAgaWYgKCFw b3NpdGl2ZV9jdHJsX2Vycigmc3AsICZwdikpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgYnJl YWs7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgKnRpZXJfaWR4ID0gdGllciAtIDE7Cj4gKwo+ ICsgICAgICAgcmV0dXJuIHR5cGU7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgaXNvbGF0ZV9mb2xp b3Moc3RydWN0IGxydXZlYyAqbHJ1dmVjLCBzdHJ1Y3Qgc2Nhbl9jb250cm9sICpzYywgaW50IHN3 YXBwaW5lc3MsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKnR5cGVfc2Nhbm5lZCwg c3RydWN0IGxpc3RfaGVhZCAqbGlzdCkKPiArewo+ICsgICAgICAgaW50IGk7Cj4gKyAgICAgICBp bnQgdHlwZTsKPiArICAgICAgIGludCBzY2FubmVkOwo+ICsgICAgICAgaW50IHRpZXIgPSAtMTsK PiArICAgICAgIERFRklORV9NSU5fU0VRKGxydXZlYyk7Cj4gKwo+ICsgICAgICAgVk1fQlVHX09O KCFzZXFfaXNfdmFsaWQobHJ1dmVjKSk7Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIFRy eSB0byBtYWtlIHRoZSBvYnZpb3VzIGNob2ljZSBmaXJzdC4gV2hlbiBhbm9uIGFuZCBmaWxlIGFy ZSBib3RoCj4gKyAgICAgICAgKiBhdmFpbGFibGUgZnJvbSB0aGUgc2FtZSBnZW5lcmF0aW9uLCBp bnRlcnByZXQgc3dhcHBpbmVzcyAxIGFzIGZpbGUKPiArICAgICAgICAqIGZpcnN0IGFuZCAyMDAg YXMgYW5vbiBmaXJzdC4KPiArICAgICAgICAqLwoKSGFzIHRoaXMgY2hhbmdlZCB0aGUgQUJJIG9m IHN3YXBpbmVzcz8gIG9yIGl0IGlzIG9ubHkgc29tZXRoaW5nCm1lYW5pbmdmdWwgZm9yIHRoZSBp bnRlcm5hbCBjb2RlPyBpZiBzbywgY2FuIHdlIHJlbmFtZSBpdCB0bwpzb21ldGhpbmcgZWxzZT8g b3RoZXJ3aXNlLCBpdCBpcyBxdWl0ZSBjb25mdXNpbmcuCgppdCBzZWVtcyAxIGlzIHNldCBpbnRl cm5hbGx5IGFzIGEgbWFnaWMgbnVtYmVyIGhlcmU6CitzdGF0aWMgdm9pZCBscnVfZ2VuX3Nocmlu a19scnV2ZWMoc3RydWN0IGxydXZlYyAqbHJ1dmVjLCBzdHJ1Y3QKc2Nhbl9jb250cm9sICpzYykK K3sKKyAuLi4KKyBlbHNlIGlmICghY2dyb3VwX3JlY2xhaW0oc2MpICYmIGdldF9zd2FwcGluZXNz KGxydXZlYywgc2MpKQorIHN3YXBwaW5lc3MgPSAxOworIGVsc2UKKyBzd2FwcGluZXNzID0gMDsK KyB9Cm9idmlvdXNseSB0aGlzIHN3YXBwaW5lc3MgaXMgbmVpdGhlciAvcHJvYy9zeXMvdm0vc3dh cHBpbmVzcyAgbm9yCi9zeXMvZnMvY2dyb3VwL21lbW9yeS88Z3JvdXA+Lz5tZW1vcnkuc3dhcHBp bmVzcywgcmlnaHQ/CgoKPiArICAgICAgIGlmICghc3dhcHBpbmVzcykKPiArICAgICAgICAgICAg ICAgdHlwZSA9IExSVV9HRU5fRklMRTsKPiArICAgICAgIGVsc2UgaWYgKG1pbl9zZXFbTFJVX0dF Tl9BTk9OXSA8IG1pbl9zZXFbTFJVX0dFTl9GSUxFXSkKPiArICAgICAgICAgICAgICAgdHlwZSA9 IExSVV9HRU5fQU5PTjsKPiArICAgICAgIGVsc2UgaWYgKHN3YXBwaW5lc3MgPT0gMSkKPiArICAg ICAgICAgICAgICAgdHlwZSA9IExSVV9HRU5fRklMRTsKPiArICAgICAgIGVsc2UgaWYgKHN3YXBw aW5lc3MgPT0gMjAwKQo+ICsgICAgICAgICAgICAgICB0eXBlID0gTFJVX0dFTl9BTk9OOwo+ICsg ICAgICAgZWxzZQo+ICsgICAgICAgICAgICAgICB0eXBlID0gZ2V0X3R5cGVfdG9fc2NhbihscnV2 ZWMsIHN3YXBwaW5lc3MsICZ0aWVyKTsKPiArCj4gKyAgICAgICBmb3IgKGkgPSAhc3dhcHBpbmVz czsgaSA8IEFOT05fQU5EX0ZJTEU7IGkrKykgewo+ICsgICAgICAgICAgICAgICBpZiAodGllciA8 IDApCj4gKyAgICAgICAgICAgICAgICAgICAgICAgdGllciA9IGdldF90aWVyX2lkeChscnV2ZWMs IHR5cGUpOwo+ICsKPiArICAgICAgICAgICAgICAgc2Nhbm5lZCA9IHNjYW5fZm9saW9zKGxydXZl Yywgc2MsIHR5cGUsIHRpZXIsIGxpc3QpOwo+ICsgICAgICAgICAgICAgICBpZiAoc2Nhbm5lZCkK PiArICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKPiArCj4gKyAgICAgICAgICAgICAgIHR5 cGUgPSAhdHlwZTsKPiArICAgICAgICAgICAgICAgdGllciA9IC0xOwo+ICsgICAgICAgfQo+ICsK PiArICAgICAgICp0eXBlX3NjYW5uZWQgPSB0eXBlOwo+ICsKPiArICAgICAgIHJldHVybiBzY2Fu bmVkOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGV2aWN0X2ZvbGlvcyhzdHJ1Y3QgbHJ1dmVjICps cnV2ZWMsIHN0cnVjdCBzY2FuX2NvbnRyb2wgKnNjLCBpbnQgc3dhcHBpbmVzcykKPiArewo+ICsg ICAgICAgaW50IHR5cGU7Cj4gKyAgICAgICBpbnQgc2Nhbm5lZDsKPiArICAgICAgIGludCByZWNs YWltZWQ7Cj4gKyAgICAgICBMSVNUX0hFQUQobGlzdCk7Cj4gKyAgICAgICBzdHJ1Y3QgZm9saW8g KmZvbGlvOwo+ICsgICAgICAgZW51bSB2bV9ldmVudF9pdGVtIGl0ZW07Cj4gKyAgICAgICBzdHJ1 Y3QgcmVjbGFpbV9zdGF0IHN0YXQ7Cj4gKyAgICAgICBzdHJ1Y3QgbWVtX2Nncm91cCAqbWVtY2cg PSBscnV2ZWNfbWVtY2cobHJ1dmVjKTsKPiArICAgICAgIHN0cnVjdCBwZ2xpc3RfZGF0YSAqcGdk YXQgPSBscnV2ZWNfcGdkYXQobHJ1dmVjKTsKPiArCj4gKyAgICAgICBzcGluX2xvY2tfaXJxKCZs cnV2ZWMtPmxydV9sb2NrKTsKPiArCj4gKyAgICAgICBzY2FubmVkID0gaXNvbGF0ZV9mb2xpb3Mo bHJ1dmVjLCBzYywgc3dhcHBpbmVzcywgJnR5cGUsICZsaXN0KTsKPiArCj4gKyAgICAgICBpZiAo dHJ5X3RvX2luY19taW5fc2VxKGxydXZlYywgc3dhcHBpbmVzcykpCj4gKyAgICAgICAgICAgICAg IHNjYW5uZWQrKzsKPiArCj4gKyAgICAgICBpZiAoZ2V0X25yX2dlbnMobHJ1dmVjLCBMUlVfR0VO X0ZJTEUpID09IE1JTl9OUl9HRU5TKQo+ICsgICAgICAgICAgICAgICBzY2FubmVkID0gMDsKPiAr Cj4gKyAgICAgICBzcGluX3VubG9ja19pcnEoJmxydXZlYy0+bHJ1X2xvY2spOwo+ICsKPiArICAg ICAgIGlmIChsaXN0X2VtcHR5KCZsaXN0KSkKPiArICAgICAgICAgICAgICAgcmV0dXJuIHNjYW5u ZWQ7Cj4gKwo+ICsgICAgICAgcmVjbGFpbWVkID0gc2hyaW5rX3BhZ2VfbGlzdCgmbGlzdCwgcGdk YXQsIHNjLCAmc3RhdCwgZmFsc2UpOwo+ICsKPiArICAgICAgIC8qCj4gKyAgICAgICAgKiBUbyBh dm9pZCBsaXZlbG9jaywgZG9uJ3QgYWRkIHJlamVjdGVkIHBhZ2VzIGJhY2sgdG8gdGhlIHNhbWUg bGlzdHMKPiArICAgICAgICAqIHRoZXkgd2VyZSBpc29sYXRlZCBmcm9tLiBTZWUgbHJ1X2dlbl9h ZGRfZm9saW8oKS4KPiArICAgICAgICAqLwo+ICsgICAgICAgbGlzdF9mb3JfZWFjaF9lbnRyeShm b2xpbywgJmxpc3QsIGxydSkgewo+ICsgICAgICAgICAgICAgICBmb2xpb19jbGVhcl9yZWZlcmVu Y2VkKGZvbGlvKTsKPiArICAgICAgICAgICAgICAgZm9saW9fY2xlYXJfd29ya2luZ3NldChmb2xp byk7Cj4gKwo+ICsgICAgICAgICAgICAgICBpZiAoZm9saW9fdGVzdF9yZWNsYWltKGZvbGlvKSAm Jgo+ICsgICAgICAgICAgICAgICAgICAgKGZvbGlvX3Rlc3RfZGlydHkoZm9saW8pIHx8IGZvbGlv X3Rlc3Rfd3JpdGViYWNrKGZvbGlvKSkpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgZm9saW9f Y2xlYXJfYWN0aXZlKGZvbGlvKTsKPiArICAgICAgICAgICAgICAgZWxzZQo+ICsgICAgICAgICAg ICAgICAgICAgICAgIGZvbGlvX3NldF9hY3RpdmUoZm9saW8pOwo+ICsgICAgICAgfQo+ICsKPiAr ICAgICAgIHNwaW5fbG9ja19pcnEoJmxydXZlYy0+bHJ1X2xvY2spOwo+ICsKPiArICAgICAgIG1v dmVfcGFnZXNfdG9fbHJ1KGxydXZlYywgJmxpc3QpOwo+ICsKPiArICAgICAgIGl0ZW0gPSBjdXJy ZW50X2lzX2tzd2FwZCgpID8gUEdTVEVBTF9LU1dBUEQgOiBQR1NURUFMX0RJUkVDVDsKPiArICAg ICAgIGlmICghY2dyb3VwX3JlY2xhaW0oc2MpKQo+ICsgICAgICAgICAgICAgICBfX2NvdW50X3Zt X2V2ZW50cyhpdGVtLCByZWNsYWltZWQpOwo+ICsgICAgICAgX19jb3VudF9tZW1jZ19ldmVudHMo bWVtY2csIGl0ZW0sIHJlY2xhaW1lZCk7Cj4gKyAgICAgICBfX2NvdW50X3ZtX2V2ZW50cyhQR1NU RUFMX0FOT04gKyB0eXBlLCByZWNsYWltZWQpOwo+ICsKPiArICAgICAgIHNwaW5fdW5sb2NrX2ly cSgmbHJ1dmVjLT5scnVfbG9jayk7Cj4gKwo+ICsgICAgICAgbWVtX2Nncm91cF91bmNoYXJnZV9s aXN0KCZsaXN0KTsKPiArICAgICAgIGZyZWVfdW5yZWZfcGFnZV9saXN0KCZsaXN0KTsKPiArCj4g KyAgICAgICBzYy0+bnJfcmVjbGFpbWVkICs9IHJlY2xhaW1lZDsKPiArCj4gKyAgICAgICByZXR1 cm4gc2Nhbm5lZDsKPiArfQo+ICsKPiArc3RhdGljIGxvbmcgZ2V0X25yX3RvX3NjYW4oc3RydWN0 IGxydXZlYyAqbHJ1dmVjLCBzdHJ1Y3Qgc2Nhbl9jb250cm9sICpzYywgYm9vbCBjYW5fc3dhcCkK PiArewo+ICsgICAgICAgYm9vbCBuZWVkX2FnaW5nOwo+ICsgICAgICAgbG9uZyBucl90b19zY2Fu Owo+ICsgICAgICAgc3RydWN0IG1lbV9jZ3JvdXAgKm1lbWNnID0gbHJ1dmVjX21lbWNnKGxydXZl Yyk7Cj4gKyAgICAgICBERUZJTkVfTUFYX1NFUShscnV2ZWMpOwo+ICsgICAgICAgREVGSU5FX01J Tl9TRVEobHJ1dmVjKTsKPiArCj4gKyAgICAgICBpZiAobWVtX2Nncm91cF9iZWxvd19taW4obWVt Y2cpIHx8Cj4gKyAgICAgICAgICAgKG1lbV9jZ3JvdXBfYmVsb3dfbG93KG1lbWNnKSAmJiAhc2Mt Pm1lbWNnX2xvd19yZWNsYWltKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuIDA7Cj4gKwo+ICsg ICAgICAgbnJfdG9fc2NhbiA9IGdldF9ucl9ldmljdGFibGUobHJ1dmVjLCBtYXhfc2VxLCBtaW5f c2VxLCBjYW5fc3dhcCwgJm5lZWRfYWdpbmcpOwo+ICsgICAgICAgaWYgKCFucl90b19zY2FuKQo+ ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPiArCj4gKyAgICAgICAvKiByZXNldCB0aGUgcHJp b3JpdHkgaWYgdGhlIHRhcmdldCBoYXMgYmVlbiBtZXQgKi8KPiArICAgICAgIG5yX3RvX3NjYW4g Pj49IHNjLT5ucl9yZWNsYWltZWQgPCBzYy0+bnJfdG9fcmVjbGFpbSA/IHNjLT5wcmlvcml0eSA6 IERFRl9QUklPUklUWTsKPiArCj4gKyAgICAgICBpZiAoIW1lbV9jZ3JvdXBfb25saW5lKG1lbWNn KSkKPiArICAgICAgICAgICAgICAgbnJfdG9fc2NhbisrOwo+ICsKPiArICAgICAgIGlmICghbnJf dG9fc2NhbikKPiArICAgICAgICAgICAgICAgcmV0dXJuIDA7Cj4gKwo+ICsgICAgICAgaWYgKCFu ZWVkX2FnaW5nKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gbnJfdG9fc2NhbjsKPiArCj4gKyAg ICAgICAvKiBsZWF2ZSB0aGUgd29yayB0byBscnVfZ2VuX2FnZV9ub2RlKCkgKi8KPiArICAgICAg IGlmIChjdXJyZW50X2lzX2tzd2FwZCgpKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPiAr Cj4gKyAgICAgICAvKiB0cnkgb3RoZXIgbWVtY2dzIGJlZm9yZSBnb2luZyB0byB0aGUgYWdpbmcg cGF0aCAqLwo+ICsgICAgICAgaWYgKCFjZ3JvdXBfcmVjbGFpbShzYykgJiYgIXNjLT5mb3JjZV9k ZWFjdGl2YXRlKSB7Cj4gKyAgICAgICAgICAgICAgIHNjLT5za2lwcGVkX2RlYWN0aXZhdGUgPSB0 cnVlOwo+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPiArICAgICAgIH0KPiArCj4gKyAgICAg ICBpbmNfbWF4X3NlcShscnV2ZWMsIG1heF9zZXEpOwo+ICsKPiArICAgICAgIHJldHVybiBucl90 b19zY2FuOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBscnVfZ2VuX3Nocmlua19scnV2ZWMoc3Ry dWN0IGxydXZlYyAqbHJ1dmVjLCBzdHJ1Y3Qgc2Nhbl9jb250cm9sICpzYykKPiArewo+ICsgICAg ICAgc3RydWN0IGJsa19wbHVnIHBsdWc7Cj4gKyAgICAgICBsb25nIHNjYW5uZWQgPSAwOwo+ICsK PiArICAgICAgIGxydV9hZGRfZHJhaW4oKTsKPiArCj4gKyAgICAgICBibGtfc3RhcnRfcGx1Zygm cGx1Zyk7Cj4gKwo+ICsgICAgICAgd2hpbGUgKHRydWUpIHsKKCkgPiArICAgICAgICAgICAgICAg aW50IGRlbHRhOwo+ICsgICAgICAgICAgICAgICBpbnQgc3dhcHBpbmVzczsKPiArICAgICAgICAg ICAgICAgbG9uZyBucl90b19zY2FuOwo+ICsKPiArICAgICAgICAgICAgICAgaWYgKHNjLT5tYXlf c3dhcCkKPiArICAgICAgICAgICAgICAgICAgICAgICBzd2FwcGluZXNzID0gZ2V0X3N3YXBwaW5l c3MobHJ1dmVjLCBzYyk7Cj4gKyAgICAgICAgICAgICAgIGVsc2UgaWYgKCFjZ3JvdXBfcmVjbGFp bShzYykgJiYgZ2V0X3N3YXBwaW5lc3MobHJ1dmVjLCBzYykpCj4gKyAgICAgICAgICAgICAgICAg ICAgICAgc3dhcHBpbmVzcyA9IDE7Cj4gKyAgICAgICAgICAgICAgIGVsc2UKPiArICAgICAgICAg ICAgICAgICAgICAgICBzd2FwcGluZXNzID0gMDsKPiArCj4gKyAgICAgICAgICAgICAgIG5yX3Rv X3NjYW4gPSBnZXRfbnJfdG9fc2NhbihscnV2ZWMsIHNjLCBzd2FwcGluZXNzKTsKPiArICAgICAg ICAgICAgICAgaWYgKCFucl90b19zY2FuKQo+ICsgICAgICAgICAgICAgICAgICAgICAgIGJyZWFr Owo+ICsKPiArICAgICAgICAgICAgICAgZGVsdGEgPSBldmljdF9mb2xpb3MobHJ1dmVjLCBzYywg c3dhcHBpbmVzcyk7Cj4gKyAgICAgICAgICAgICAgIGlmICghZGVsdGEpCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgYnJlYWs7Cj4gKwo+ICsgICAgICAgICAgICAgICBzY2FubmVkICs9IGRlbHRh Owo+ICsgICAgICAgICAgICAgICBpZiAoc2Nhbm5lZCA+PSBucl90b19zY2FuKQo+ICsgICAgICAg ICAgICAgICAgICAgICAgIGJyZWFrOwo+ICsKPiArICAgICAgICAgICAgICAgY29uZF9yZXNjaGVk KCk7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgYmxrX2ZpbmlzaF9wbHVnKCZwbHVnKTsKPiAr fQo+ICsKPiAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgo+ICAgKiAgICAgICAgICAgICAgICAgICAg ICAgICAgaW5pdGlhbGl6YXRpb24KPiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KPiBAQCAtMzA0 MSw2ICszODIxLDE2IEBAIHN0YXRpYyBpbnQgX19pbml0IGluaXRfbHJ1X2dlbih2b2lkKQo+ICB9 Owo+ICBsYXRlX2luaXRjYWxsKGluaXRfbHJ1X2dlbik7Cj4KPiArI2Vsc2UKPiArCj4gK3N0YXRp YyB2b2lkIGxydV9nZW5fYWdlX25vZGUoc3RydWN0IHBnbGlzdF9kYXRhICpwZ2RhdCwgc3RydWN0 IHNjYW5fY29udHJvbCAqc2MpCj4gK3sKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbHJ1X2dlbl9z aHJpbmtfbHJ1dmVjKHN0cnVjdCBscnV2ZWMgKmxydXZlYywgc3RydWN0IHNjYW5fY29udHJvbCAq c2MpCj4gK3sKPiArfQo+ICsKPiAgI2VuZGlmIC8qIENPTkZJR19MUlVfR0VOICovCj4KPiAgc3Rh dGljIHZvaWQgc2hyaW5rX2xydXZlYyhzdHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIHN0cnVjdCBzY2Fu X2NvbnRyb2wgKnNjKQo+IEBAIC0zMDU0LDYgKzM4NDQsMTEgQEAgc3RhdGljIHZvaWQgc2hyaW5r X2xydXZlYyhzdHJ1Y3QgbHJ1dmVjICpscnV2ZWMsIHN0cnVjdCBzY2FuX2NvbnRyb2wgKnNjKQo+ ICAgICAgICAgc3RydWN0IGJsa19wbHVnIHBsdWc7Cj4gICAgICAgICBib29sIHNjYW5fYWRqdXN0 ZWQ7Cj4KPiArICAgICAgIGlmIChscnVfZ2VuX2VuYWJsZWQoKSkgewo+ICsgICAgICAgICAgICAg ICBscnVfZ2VuX3Nocmlua19scnV2ZWMobHJ1dmVjLCBzYyk7Cj4gKyAgICAgICAgICAgICAgIHJl dHVybjsKPiArICAgICAgIH0KPiArCj4gICAgICAgICBnZXRfc2Nhbl9jb3VudChscnV2ZWMsIHNj LCBucik7Cj4KPiAgICAgICAgIC8qIFJlY29yZCB0aGUgb3JpZ2luYWwgc2NhbiB0YXJnZXQgZm9y IHByb3BvcnRpb25hbCBhZGp1c3RtZW50cyBsYXRlciAqLwo+IEBAIC0zNTU4LDYgKzQzNTMsOSBA QCBzdGF0aWMgdm9pZCBzbmFwc2hvdF9yZWZhdWx0cyhzdHJ1Y3QgbWVtX2Nncm91cCAqdGFyZ2V0 X21lbWNnLCBwZ19kYXRhX3QgKnBnZGF0KQo+ICAgICAgICAgc3RydWN0IGxydXZlYyAqdGFyZ2V0 X2xydXZlYzsKPiAgICAgICAgIHVuc2lnbmVkIGxvbmcgcmVmYXVsdHM7Cj4KPiArICAgICAgIGlm IChscnVfZ2VuX2VuYWJsZWQoKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ICsKPiAgICAg ICAgIHRhcmdldF9scnV2ZWMgPSBtZW1fY2dyb3VwX2xydXZlYyh0YXJnZXRfbWVtY2csIHBnZGF0 KTsKPiAgICAgICAgIHJlZmF1bHRzID0gbHJ1dmVjX3BhZ2Vfc3RhdGUodGFyZ2V0X2xydXZlYywg V09SS0lOR1NFVF9BQ1RJVkFURV9BTk9OKTsKPiAgICAgICAgIHRhcmdldF9scnV2ZWMtPnJlZmF1 bHRzWzBdID0gcmVmYXVsdHM7Cj4gQEAgLTM5MjgsNiArNDcyNiwxMSBAQCBzdGF0aWMgdm9pZCBh Z2VfYWN0aXZlX2Fub24oc3RydWN0IHBnbGlzdF9kYXRhICpwZ2RhdCwKPiAgICAgICAgIHN0cnVj dCBtZW1fY2dyb3VwICptZW1jZzsKPiAgICAgICAgIHN0cnVjdCBscnV2ZWMgKmxydXZlYzsKPgo+ ICsgICAgICAgaWYgKGxydV9nZW5fZW5hYmxlZCgpKSB7Cj4gKyAgICAgICAgICAgICAgIGxydV9n ZW5fYWdlX25vZGUocGdkYXQsIHNjKTsKPiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ICsgICAg ICAgfQoKaXMgaXQgcmVhbGx5IGEgZ29vZCBwbGFjZSBmb3IgIGxydV9nZW5fYWdlX25vZGUoKSBz aW5jZSB0aGUgZnVuY3Rpb24KaXMgbmFtZWQgYWdlX2FjdGl2ZV9hbm9uKCkKYnV0IGhlcmUgeW91 IGFyZSBkb2luZyBhZ2luZyBmb3IgYm90aCBhbm9uIGFuZCBmaWxlIHBhZ2VzPyBvYnZpb3VzbHkK bHJ1X2dlbl9hZ2Vfbm9kZSgpIGlzIG5vdApkb2luZyAiYWdlIGFjdGl2ZSBhbm9uIi4KCgo+ICsK PiAgICAgICAgIGlmICghY2FuX2FnZV9hbm9uX3BhZ2VzKHBnZGF0LCBzYykpCj4gICAgICAgICAg ICAgICAgIHJldHVybjsKPgo+IGRpZmYgLS1naXQgYS9tbS93b3JraW5nc2V0LmMgYi9tbS93b3Jr aW5nc2V0LmMKPiBpbmRleCA4YTM4MjhhY2MwYmYuLjg5YjQ2YWY3NGVlZiAxMDA2NDQKPiAtLS0g YS9tbS93b3JraW5nc2V0LmMKPiArKysgYi9tbS93b3JraW5nc2V0LmMKPiBAQCAtMTg3LDcgKzE4 Nyw2IEBAIHN0YXRpYyB1bnNpZ25lZCBpbnQgYnVja2V0X29yZGVyIF9fcmVhZF9tb3N0bHk7Cj4g IHN0YXRpYyB2b2lkICpwYWNrX3NoYWRvdyhpbnQgbWVtY2dpZCwgcGdfZGF0YV90ICpwZ2RhdCwg dW5zaWduZWQgbG9uZyBldmljdGlvbiwKPiAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCB3 b3JraW5nc2V0KQo+ICB7Cj4gLSAgICAgICBldmljdGlvbiA+Pj0gYnVja2V0X29yZGVyOwo+ICAg ICAgICAgZXZpY3Rpb24gJj0gRVZJQ1RJT05fTUFTSzsKPiAgICAgICAgIGV2aWN0aW9uID0gKGV2 aWN0aW9uIDw8IE1FTV9DR1JPVVBfSURfU0hJRlQpIHwgbWVtY2dpZDsKPiAgICAgICAgIGV2aWN0 aW9uID0gKGV2aWN0aW9uIDw8IE5PREVTX1NISUZUKSB8IHBnZGF0LT5ub2RlX2lkOwo+IEBAIC0y MTIsMTAgKzIxMSwxMTYgQEAgc3RhdGljIHZvaWQgdW5wYWNrX3NoYWRvdyh2b2lkICpzaGFkb3cs IGludCAqbWVtY2dpZHAsIHBnX2RhdGFfdCAqKnBnZGF0LAo+Cj4gICAgICAgICAqbWVtY2dpZHAg PSBtZW1jZ2lkOwo+ICAgICAgICAgKnBnZGF0ID0gTk9ERV9EQVRBKG5pZCk7Cj4gLSAgICAgICAq ZXZpY3Rpb25wID0gZW50cnkgPDwgYnVja2V0X29yZGVyOwo+ICsgICAgICAgKmV2aWN0aW9ucCA9 IGVudHJ5Owo+ICAgICAgICAgKndvcmtpbmdzZXRwID0gd29ya2luZ3NldDsKPiAgfQo+Cj4gKyNp ZmRlZiBDT05GSUdfTFJVX0dFTgo+ICsKPiArc3RhdGljIGludCBmb2xpb19scnVfcmVmcyhzdHJ1 Y3QgZm9saW8gKmZvbGlvKQo+ICt7Cj4gKyAgICAgICB1bnNpZ25lZCBsb25nIGZsYWdzID0gUkVB RF9PTkNFKGZvbGlvLT5mbGFncyk7Cj4gKwo+ICsgICAgICAgQlVJTERfQlVHX09OKExSVV9HRU5f V0lEVEggKyBMUlVfUkVGU19XSURUSCA+IEJJVFNfUEVSX0xPTkcgLSBFVklDVElPTl9TSElGVCk7 Cj4gKwo+ICsgICAgICAgLyogc2VlIHRoZSBjb21tZW50IG9uIE1BWF9OUl9USUVSUyAqLwo+ICsg ICAgICAgcmV0dXJuIGZsYWdzICYgQklUKFBHX3dvcmtpbmdzZXQpID8gKGZsYWdzICYgTFJVX1JF RlNfTUFTSykgPj4gTFJVX1JFRlNfUEdPRkYgOiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCAq bHJ1X2dlbl9ldmljdGlvbihzdHJ1Y3QgZm9saW8gKmZvbGlvKQo+ICt7Cj4gKyAgICAgICBpbnQg aGlzdCwgdGllcjsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgdG9rZW47Cj4gKyAgICAgICB1bnNp Z25lZCBsb25nIG1pbl9zZXE7Cj4gKyAgICAgICBzdHJ1Y3QgbHJ1dmVjICpscnV2ZWM7Cj4gKyAg ICAgICBzdHJ1Y3QgbHJ1X2dlbl9zdHJ1Y3QgKmxydWdlbjsKPiArICAgICAgIGludCB0eXBlID0g Zm9saW9faXNfZmlsZV9scnUoZm9saW8pOwo+ICsgICAgICAgaW50IHJlZnMgPSBmb2xpb19scnVf cmVmcyhmb2xpbyk7Cj4gKyAgICAgICBpbnQgZGVsdGEgPSBmb2xpb19ucl9wYWdlcyhmb2xpbyk7 Cj4gKyAgICAgICBib29sIHdvcmtpbmdzZXQgPSBmb2xpb190ZXN0X3dvcmtpbmdzZXQoZm9saW8p Owo+ICsgICAgICAgc3RydWN0IG1lbV9jZ3JvdXAgKm1lbWNnID0gZm9saW9fbWVtY2coZm9saW8p Owo+ICsgICAgICAgc3RydWN0IHBnbGlzdF9kYXRhICpwZ2RhdCA9IGZvbGlvX3BnZGF0KGZvbGlv KTsKPiArCj4gKyAgICAgICBscnV2ZWMgPSBtZW1fY2dyb3VwX2xydXZlYyhtZW1jZywgcGdkYXQp Owo+ICsgICAgICAgbHJ1Z2VuID0gJmxydXZlYy0+bHJ1Z2VuOwo+ICsgICAgICAgbWluX3NlcSA9 IFJFQURfT05DRShscnVnZW4tPm1pbl9zZXFbdHlwZV0pOwo+ICsgICAgICAgdG9rZW4gPSAobWlu X3NlcSA8PCBMUlVfUkVGU19XSURUSCkgfCByZWZzOwo+ICsKPiArICAgICAgIGhpc3QgPSBscnVf aGlzdF9mcm9tX3NlcShtaW5fc2VxKTsKPiArICAgICAgIHRpZXIgPSBscnVfdGllcl9mcm9tX3Jl ZnMocmVmcyArIHdvcmtpbmdzZXQpOwo+ICsgICAgICAgYXRvbWljX2xvbmdfYWRkKGRlbHRhLCAm bHJ1Z2VuLT5ldmljdGVkW2hpc3RdW3R5cGVdW3RpZXJdKTsKPiArCj4gKyAgICAgICByZXR1cm4g cGFja19zaGFkb3cobWVtX2Nncm91cF9pZChtZW1jZyksIHBnZGF0LCB0b2tlbiwgd29ya2luZ3Nl dCk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGxydV9nZW5fcmVmYXVsdChzdHJ1Y3QgZm9saW8g KmZvbGlvLCB2b2lkICpzaGFkb3cpCj4gK3sKPiArICAgICAgIGludCBoaXN0LCB0aWVyLCByZWZz Owo+ICsgICAgICAgaW50IG1lbWNnX2lkOwo+ICsgICAgICAgYm9vbCB3b3JraW5nc2V0Owo+ICsg ICAgICAgdW5zaWduZWQgbG9uZyB0b2tlbjsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgbWluX3Nl cTsKPiArICAgICAgIHN0cnVjdCBscnV2ZWMgKmxydXZlYzsKPiArICAgICAgIHN0cnVjdCBscnVf Z2VuX3N0cnVjdCAqbHJ1Z2VuOwo+ICsgICAgICAgc3RydWN0IG1lbV9jZ3JvdXAgKm1lbWNnOwo+ ICsgICAgICAgc3RydWN0IHBnbGlzdF9kYXRhICpwZ2RhdDsKPiArICAgICAgIGludCB0eXBlID0g Zm9saW9faXNfZmlsZV9scnUoZm9saW8pOwo+ICsgICAgICAgaW50IGRlbHRhID0gZm9saW9fbnJf cGFnZXMoZm9saW8pOwo+ICsKPiArICAgICAgIHVucGFja19zaGFkb3coc2hhZG93LCAmbWVtY2df aWQsICZwZ2RhdCwgJnRva2VuLCAmd29ya2luZ3NldCk7Cj4gKwo+ICsgICAgICAgcmVmcyA9IHRv a2VuICYgKEJJVChMUlVfUkVGU19XSURUSCkgLSAxKTsKPiArICAgICAgIGlmIChyZWZzICYmICF3 b3JraW5nc2V0KQo+ICsgICAgICAgICAgICAgICByZXR1cm47Cj4gKwo+ICsgICAgICAgaWYgKGZv bGlvX3BnZGF0KGZvbGlvKSAhPSBwZ2RhdCkKPiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ICsK PiArICAgICAgIHJjdV9yZWFkX2xvY2soKTsKPiArICAgICAgIG1lbWNnID0gZm9saW9fbWVtY2df cmN1KGZvbGlvKTsKPiArICAgICAgIGlmIChtZW1fY2dyb3VwX2lkKG1lbWNnKSAhPSBtZW1jZ19p ZCkKPiArICAgICAgICAgICAgICAgZ290byB1bmxvY2s7Cj4gKwo+ICsgICAgICAgdG9rZW4gPj49 IExSVV9SRUZTX1dJRFRIOwo+ICsgICAgICAgbHJ1dmVjID0gbWVtX2Nncm91cF9scnV2ZWMobWVt Y2csIHBnZGF0KTsKPiArICAgICAgIGxydWdlbiA9ICZscnV2ZWMtPmxydWdlbjsKPiArICAgICAg IG1pbl9zZXEgPSBSRUFEX09OQ0UobHJ1Z2VuLT5taW5fc2VxW3R5cGVdKTsKPiArICAgICAgIGlm ICh0b2tlbiAhPSAobWluX3NlcSAmIChFVklDVElPTl9NQVNLID4+IExSVV9SRUZTX1dJRFRIKSkp Cj4gKyAgICAgICAgICAgICAgIGdvdG8gdW5sb2NrOwo+ICsKPiArICAgICAgIGhpc3QgPSBscnVf aGlzdF9mcm9tX3NlcShtaW5fc2VxKTsKPiArICAgICAgIHRpZXIgPSBscnVfdGllcl9mcm9tX3Jl ZnMocmVmcyArIHdvcmtpbmdzZXQpOwo+ICsgICAgICAgYXRvbWljX2xvbmdfYWRkKGRlbHRhLCAm bHJ1Z2VuLT5yZWZhdWx0ZWRbaGlzdF1bdHlwZV1bdGllcl0pOwo+ICsgICAgICAgbW9kX2xydXZl Y19zdGF0ZShscnV2ZWMsIFdPUktJTkdTRVRfUkVGQVVMVF9CQVNFICsgdHlwZSwgZGVsdGEpOwo+ ICsKPiArICAgICAgIC8qCj4gKyAgICAgICAgKiBDb3VudCB0aGUgZm9sbG93aW5nIHR3byBjYXNl cyBhcyBzdGFsbHM6Cj4gKyAgICAgICAgKiAxLiBGb3IgcGFnZXMgYWNjZXNzZWQgdGhyb3VnaCBw YWdlIHRhYmxlcywgaG90dGVyIHBhZ2VzIHB1c2hlZCBvdXQKPiArICAgICAgICAqICAgIGhvdCBw YWdlcyB3aGljaCByZWZhdWx0ZWQgaW1tZWRpYXRlbHkuCj4gKyAgICAgICAgKiAyLiBGb3IgcGFn ZXMgYWNjZXNzZWQgdGhyb3VnaCBmaWxlIGRlc2NyaXB0b3JzLCBudW1iZXJzIG9mIGFjY2Vzc2Vz Cj4gKyAgICAgICAgKiAgICBtaWdodCBoYXZlIGJlZW4gYmV5b25kIHRoZSBsaW1pdC4KPiArICAg ICAgICAqLwo+ICsgICAgICAgaWYgKGxydV9nZW5faW5fZmF1bHQoKSB8fCByZWZzICsgd29ya2lu Z3NldCA9PSBCSVQoTFJVX1JFRlNfV0lEVEgpKSB7Cj4gKyAgICAgICAgICAgICAgIGZvbGlvX3Nl dF93b3JraW5nc2V0KGZvbGlvKTsKPiArICAgICAgICAgICAgICAgbW9kX2xydXZlY19zdGF0ZShs cnV2ZWMsIFdPUktJTkdTRVRfUkVTVE9SRV9CQVNFICsgdHlwZSwgZGVsdGEpOwo+ICsgICAgICAg fQo+ICt1bmxvY2s6Cj4gKyAgICAgICByY3VfcmVhZF91bmxvY2soKTsKPiArfQo+ICsKPiArI2Vs c2UKPiArCj4gK3N0YXRpYyB2b2lkICpscnVfZ2VuX2V2aWN0aW9uKHN0cnVjdCBmb2xpbyAqZm9s aW8pCj4gK3sKPiArICAgICAgIHJldHVybiBOVUxMOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBs cnVfZ2VuX3JlZmF1bHQoc3RydWN0IGZvbGlvICpmb2xpbywgdm9pZCAqc2hhZG93KQo+ICt7Cj4g K30KPiArCj4gKyNlbmRpZiAvKiBDT05GSUdfTFJVX0dFTiAqLwo+ICsKPiAgLyoqCj4gICAqIHdv cmtpbmdzZXRfYWdlX25vbnJlc2lkZW50IC0gYWdlIG5vbi1yZXNpZGVudCBlbnRyaWVzIGFzIExS VSBhZ2VzCj4gICAqIEBscnV2ZWM6IHRoZSBscnV2ZWMgdGhhdCB3YXMgYWdlZAo+IEBAIC0yNjQs MTAgKzM2OSwxNCBAQCB2b2lkICp3b3JraW5nc2V0X2V2aWN0aW9uKHN0cnVjdCBmb2xpbyAqZm9s aW8sIHN0cnVjdCBtZW1fY2dyb3VwICp0YXJnZXRfbWVtY2cpCj4gICAgICAgICBWTV9CVUdfT05f Rk9MSU8oZm9saW9fcmVmX2NvdW50KGZvbGlvKSwgZm9saW8pOwo+ICAgICAgICAgVk1fQlVHX09O X0ZPTElPKCFmb2xpb190ZXN0X2xvY2tlZChmb2xpbyksIGZvbGlvKTsKPgo+ICsgICAgICAgaWYg KGxydV9nZW5fZW5hYmxlZCgpKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gbHJ1X2dlbl9ldmlj dGlvbihmb2xpbyk7Cj4gKwo+ICAgICAgICAgbHJ1dmVjID0gbWVtX2Nncm91cF9scnV2ZWModGFy Z2V0X21lbWNnLCBwZ2RhdCk7Cj4gICAgICAgICAvKiBYWFg6IHRhcmdldF9tZW1jZyBjYW4gYmUg TlVMTCwgZ28gdGhyb3VnaCBscnV2ZWMgKi8KPiAgICAgICAgIG1lbWNnaWQgPSBtZW1fY2dyb3Vw X2lkKGxydXZlY19tZW1jZyhscnV2ZWMpKTsKPiAgICAgICAgIGV2aWN0aW9uID0gYXRvbWljX2xv bmdfcmVhZCgmbHJ1dmVjLT5ub25yZXNpZGVudF9hZ2UpOwo+ICsgICAgICAgZXZpY3Rpb24gPj49 IGJ1Y2tldF9vcmRlcjsKPiAgICAgICAgIHdvcmtpbmdzZXRfYWdlX25vbnJlc2lkZW50KGxydXZl YywgZm9saW9fbnJfcGFnZXMoZm9saW8pKTsKPiAgICAgICAgIHJldHVybiBwYWNrX3NoYWRvdyht ZW1jZ2lkLCBwZ2RhdCwgZXZpY3Rpb24sCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBmb2xpb190ZXN0X3dvcmtpbmdzZXQoZm9saW8pKTsKPiBAQCAtMjk4LDcgKzQwNywxMyBAQCB2 b2lkIHdvcmtpbmdzZXRfcmVmYXVsdChzdHJ1Y3QgZm9saW8gKmZvbGlvLCB2b2lkICpzaGFkb3cp Cj4gICAgICAgICBpbnQgbWVtY2dpZDsKPiAgICAgICAgIGxvbmcgbnI7Cj4KPiArICAgICAgIGlm IChscnVfZ2VuX2VuYWJsZWQoKSkgewo+ICsgICAgICAgICAgICAgICBscnVfZ2VuX3JlZmF1bHQo Zm9saW8sIHNoYWRvdyk7Cj4gKyAgICAgICAgICAgICAgIHJldHVybjsKPiArICAgICAgIH0KPiAr Cj4gICAgICAgICB1bnBhY2tfc2hhZG93KHNoYWRvdywgJm1lbWNnaWQsICZwZ2RhdCwgJmV2aWN0 aW9uLCAmd29ya2luZ3NldCk7Cj4gKyAgICAgICBldmljdGlvbiA8PD0gYnVja2V0X29yZGVyOwo+ Cj4gICAgICAgICByY3VfcmVhZF9sb2NrKCk7Cj4gICAgICAgICAvKgo+IC0tCj4gMi4zNS4xLjEw OTQuZzdjN2Q5MDJhN2MtZ29vZwo+CgpUaGFua3MKQmFycnkKCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0 CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFk ZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK