Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w6L8J-004CVe-0U for pgsql-hackers@arkaria.postgresql.org; Sat, 28 Mar 2026 04:18:47 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w6L8H-00DIKj-2C for pgsql-hackers@arkaria.postgresql.org; Sat, 28 Mar 2026 04:18:46 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w6L8H-00DIKO-03 for pgsql-hackers@lists.postgresql.org; Sat, 28 Mar 2026 04:18:45 +0000 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w6L8E-00000001RDo-3KKA for pgsql-hackers@lists.postgresql.org; Sat, 28 Mar 2026 04:18:44 +0000 Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-439b94a19fdso2582988f8f.0 for ; Fri, 27 Mar 2026 21:18:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774671520; cv=none; d=google.com; s=arc-20240605; b=G3T9Z5ir70g9fp8sfIREOIPyVh8ozuCTjlpCgfqBEqqGfGW1aLOrPd9ohh9iGEAjV+ Oo8TlxLoqECzSqDJoMYwVclduntToYEguARedW6aHRRKmo/+/0jQX92NeS0enyleRPBk SW+jqgVhM5xCTxlAWhC9/5OxYpcZPrJ2yDkIW8XzM3RtxBaDTG8ipK3KSdcwophbo3sT hGEkNp3W+eoswzlZmUVxsFcHsfmmEwR/HVmNc+TqxxgJvlYmOBwLVYmtiF3cbYAKfBVi dGGMLZrckWrZmJtrA5J1EAVi2rztwlkf9/XeJkDW4SfMQONzmDpbM1kB3gwFvyjxfXqi /tuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=HNdWaqZ4HUNbW37xfhSmuwPP0Lpb4qB82RcpjJo7WoQ=; fh=y7IBBxKG1GK3EAdrI2j118aR9qI4Uhx7CHirkqbFCvk=; b=eRgL82YziIThAfvyyLpRroVjeSsQth71oFC+0UVk05yWKNdmNY7Bs2yEWQl9vw4LxZ Ahkyj0N3ngB90N5lbE6IQwIDNQplaBixYiLZuWpVA+4vFJqSeiBbEiUMQr6oZTde84GH 1QnTlcy2xZhSoJ+TMnNOFGb2a9w6OPOuZfDKXrTa/GXiIWfHLdnzulJ8/oxmU/BNBZYk Pilh03XCJE3PE5L4fIXWj4Cx/vr2xQlR+mcMHngn7s7kQy8kuLPpahQbUrZmIv2WvKur rXTh3aaFuzyOY7pzLypNRrJ78HXMzbXMDc6szHUPmvUc3/JAxfXTSarGyixb4oIDnLUp SpPg==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774671520; x=1775276320; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=HNdWaqZ4HUNbW37xfhSmuwPP0Lpb4qB82RcpjJo7WoQ=; b=UvT4T+c1WcFIpu296UCxPUg2OacnmRfx4oh+g2vchsMWH2Skk+5TKNVQITY2gLKEIN Z12QFs2FtT7lpMA25Fsm5RyaOLGFmsxtufrYirP4JOFoEHV+DcJfUfFAu/BIRGuhSQcK wJDQcVDkJ1VEyE1Q3QDhDLdSYfyGw/IFpeWQzd4KAi/EA3jEVdtZF/gcTGpqrvOhNHx6 u9fpRf/+DdFFp+L3M8D+PlweTxB6YWdgs/BSr8sKvZ9GH/+sgAajLqTZr64e9DZl2eu1 aoIxyjJQ7+b6F5RW+z6LFb3FMGntjk0DbrD4nOLZXA9ks6iVV+d12E9dG23j5jMh5Cz3 8HEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774671520; x=1775276320; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=HNdWaqZ4HUNbW37xfhSmuwPP0Lpb4qB82RcpjJo7WoQ=; b=d3QKZaJPvLcBfR3vZ09v5/4X5ClGQT/O+rJypbWtIhVifmfSnFH4bP1qlF0a/5Tvpf zJ2ap2aUjMmfEsKpGK3frk3tt3kqYIACrbtCYbtp3fpCm6K2JfXo4W8cxg9OaySjs2/g I78w92liZeyeT+WrhKJuwFoPoVd/Klm3aWEjprQ9Fq4j8lR3C8mB42DoWxMcgmFdWoGd y6iHQRWDVgvTksokjoN0eDzhGhQX0Tb3I/Fwc/JQYL9pjiV9FBcyrRKQN17sB/w0aY9T t+WrGxYZzz6spWpq+6yMfN85apNzTPj40p5Abxh8bGbTKyK49d1yPQRzpiyiCqlZwxuy l8Lg== X-Forwarded-Encrypted: i=1; AJvYcCVmILKqJs74VJiOXU/tFdBYZYy4QGkLGMVMbz8IQM6fl6bhBT3A2XJ8r5mJPzcwu/+tnHkZ6Fss8B0WtoAP@lists.postgresql.org X-Gm-Message-State: AOJu0Yy93Gp5h+U4mtdOeSrtS43jlpvO2ORXlZLpNoRkUlV+KLTRAnZ5 AWJSrCPBwBUNpPQuExjM/QM/Zc1gmNwLiJHUazi0L9/wQvrcP0BRWde3iWZylmMH8udZXEiSzVb 5f/irjGXRMy0NfkUQSgcxyGzMsQ397Lg= X-Gm-Gg: ATEYQzwn9k56ESGeOsP2uMSW3HCQilRDo497hxQw029499U335EJoIb+8ggNDaiwedg 3ylu0vEF49aNFOaUzbWKDikcrjl3/eDpNDaQl+mbWPZZmxBjzsRz+ut1NB/ijQ/a0qmOvluRrN0 6CudLSqi3Jwxyc3d/7qGW+7MoHodxn/bDsjUjjOb9jlwLQGwFzC0ALB/jaAOXJxfrYHHeIFDKN2 vHgkwxLjD+3URuTEIkARVgNV0nMXNmXNMBYiukm+nzJtxxNywk+m4kP3Vd6nZSogSM+mHoeQTO4 Z5c1cbpr0RAJ/VDJZviGHmsulo4Ia8qQ9VWr3U0nRwrLis7AHHI= X-Received: by 2002:a5d:64e6:0:b0:439:cb3d:e42c with SMTP id ffacd0b85a97d-43b9e9d9372mr8064421f8f.8.1774671519968; Fri, 27 Mar 2026 21:18:39 -0700 (PDT) MIME-Version: 1.0 References: <670b867e-6518-48b0-b7c2-bd5f10ab58c6@vondra.me> In-Reply-To: <670b867e-6518-48b0-b7c2-bd5f10ab58c6@vondra.me> From: Ashutosh Bapat Date: Sat, 28 Mar 2026 09:48:26 +0530 X-Gm-Features: AQROBzAeqg0Mz8_56nm6Sw4jwDayVhV_XvXjlHMSecABhSA0RufEmfdaD4tLcek Message-ID: Subject: Re: pg_buffercache: Add per-relation summary stats To: Tomas Vondra , chaturvedipalak1911@gmail.com Cc: Masahiko Sawada , Lukas Fittl , PostgreSQL Hackers , Paul A Jungwirth , Khoa Nguyen Content-Type: multipart/mixed; boundary="0000000000008a8865064e0de95e" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000008a8865064e0de95e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, Mar 28, 2026 at 4:28=E2=80=AFAM Tomas Vondra wrot= e: > > On 3/26/26 05:21, Ashutosh Bapat wrote: > > On Wed, Mar 25, 2026 at 10:19=E2=80=AFPM Masahiko Sawada wrote: > >> > >> On Tue, Mar 24, 2026 at 11:47=E2=80=AFPM Lukas Fittl = wrote: > >>> > >>> Hi Ashutosh, > >>> > >>> On Tue, Mar 24, 2026 at 11:24=E2=80=AFPM Ashutosh Bapat > >>> wrote: > >>>> I know we already have a couple of hand-aggregation functions but I = am > >>>> hesitant to add more of these. Question is where do we stop? For > >>>> example, the current function is useless if someone wants to find th= e > >>>> parts of a relation which are hot since it doesn't include page > >>>> numbers. Do we write another function for the same? Or we add page > >>>> numbers to this function and then there's hardly any aggregation > >>>> happening. What if somebody wanted to perform an aggregation more > >>>> complex than just count() like average number of buffers per relatio= n > >>>> or distribution of relation buffers in the cache, do they write > >>>> separate functions? > >>> > >>> I think the problem this solves for, which is a very common question = I > >>> hear from end users, is "how much of this table/index is in cache" an= d > >>> "was our query slow because the cache contents changed?". > >>> > >>> It can't provide a perfect answer to all questions regarding what's i= n > >>> the cache (i.e. it won't tell you which part of the table is cached), > >>> but its in line with other statistics we do already provide in > >>> pg_stat_user_tables etc., which are all aggregate counts, not further > >>> breakdowns. > >>> > >>> Its also a reasonable compromise on providing something usable that > >>> can be shown on dashboards, as I've seen in collecting this > >>> information using the existing methods from small production systems > >>> in practice over the last ~1.5 years. > >> > >> Regarding the proposed statistics, I find them reasonably useful for > >> many users. I'm not sure we need to draw a strict line on what belongs > >> in the module. If a proposed function does exactly what most > >> pg_buffercache users want or are already writing themselves, that is > >> good enough motivation to include it. > >> > >> I think pg_visibility is a good precedent here. In that module, we > >> have both pg_visibility_map() and pg_visibility_map_summary(), even > >> though we can retrieve the exact same results as the latter by simply > >> using the former: > >> > >> select sum(all_visible::int), sum(all_frozen::int) from > >> pg_visibility_map('test') ; > >> > > > > A summary may still be ok, but this proposal is going a bit farther, > > it's grouping by one subset which should really be done by GROUP BY in > > SQL. And I do > > > > I am afraid that at some point, we will start finding all of these to > > be a maintenance burden. At that point, removing them will become a > > real pain for the backward compatibility reason. For example > > 1. The proposed function is going to add one more test to an already > > huge testing exercise for shared buffers resizing. > > 2. If we change the way to manage buffer cache e.g. use a tree based > > cache instead of hash + array cache, each of the functions which > > traverses the buffer cache array is going to add work - adjusting it > > to the new data structure - and make a hard project even harder. In > > this case we have other ways to get the summary, so the code level > > scan of buffer cache is entirely avoidable. > > > > If I am the only one opposing it, and there are more senior > > contributors in favour of adding this function, we can accept it. > > > > I understand this argument - we have SQL, which allows us to process the > data in a flexible way, without hard-coding all interesting groupings. > The question is whether this particular grouping is special enough to > warrant a custom *faster* function. > > The main argument here seems to be the performance, and the initial > message demonstrates a 10x speedup (2ms vs. 20ms) on a cluster with > 128MB shared buffers. Unless I misunderstood what config it uses. > > I gave it a try on an azure VM with 32GB shared buffers, to make it a > bit more realistic, and my timings are 10ms vs. 700ms. But I also wonder > if the original timings really were from a cluster with 128MB, because > for me that shows 0.3ms vs. 3ms (so an order of magnitude faster than > what was reported). But I suppose that's also hw specific. > > Nevertheless, it is much faster. I haven't profiled this but I assume > it's thanks to not having to write the entries into a tuplestore (and > possibly into a tempfile). Parallely myself and Palak Chaturvedi developed a quick patch to modernise pg_buffercache_pages() and use tuplestore so that it doesn't have to rely on NBuffers being the same between start of the scan, when memory allocated, when the scan ends - a condition possible with resizing buffer cache. It seems to improve the timings by about 10-30% on my laptop for 128MB buffercache size. Without this patch the time taken to execute Lukas's query varies between 10-15ms on my laptop. With this patch it varies between 8-9ms. So the timing is more stable as a side effect. It's not a 10x improvement that we are looking for but it looks like a step in the right direction. That improvement seems to come purely because we avoid creating a heap tuple. I wonder if there are some places up in the execution tree where full heaptuples get formed again instead of continuing to use minimal tuples or places where we perform some extra actions that are not required. I didn't dig into the history to find out why we didn't modernize pg_buffercache_pages(). I don't see any hazard though. Lukas's patch allocates the hash table in memory entirely, whereas tuplestore restricts memory usage to work_mem, so it might cause the function to use more memory than user expects it to use when size of the hash table grows beyond work_mem. --=20 Best Wishes, Ashutosh Bapat --0000000000008a8865064e0de95e Content-Type: text/x-patch; charset="US-ASCII"; name="v20260328-0001-pg_buffercache_pages-modernization-and-opt.patch" Content-Disposition: attachment; filename="v20260328-0001-pg_buffercache_pages-modernization-and-opt.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mn9speeh0 RnJvbSA5MTEyNTM2ZDU5MTI0MDU3ZjgxYjAxYzllNDhmZWVkMzFmMGNjOThkIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBBc2h1dG9zaCBCYXBhdCA8YXNodXRvc2guYmFwYXQub3NzQGdt YWlsLmNvbT4KRGF0ZTogV2VkLCAxMSBNYXIgMjAyNiAxNTo1NzowMiArMDUzMApTdWJqZWN0OiBb UEFUQ0ggdjIwMjYwMzI4XSBwZ19idWZmZXJjYWNoZV9wYWdlcygpIG1vZGVybml6YXRpb24gYW5k CiBvcHRpbWl6YXRpb24KCk1hbnkgb2YgdGhlIHNldCByZXR1cm5pbmcgZnVuY3Rpb25zIChTUkZz KSB1c2UgSW5pdE1hdGVyaWFsaXplZFNSRigpIGFuZAp0dXBsZXN0b3JlIHRvIHN0b3JlIHRoZSBy ZXN1bHQuIEJ1dCBwZ19idWZmZXJjYWNoZV9wYWdlcygpIHVzZXMgaXRzIG93bgpjb2RlIHRvIGlu aXRpYWxpemUgU1JGIHN0YXRlIGFuZCBkb2VzIG5vdCB1c2UgdHVwbGVzdG9yZS4gQmVjYXVzZSBv ZiB0aGUKbGF0ZXIgaXQgaGFzIHRvIGNyZWF0ZSBhIGZ1bGwgaGVhcCB0dXBsZSB3aGVuIG5vdCBu ZWNlc3NhcnkuIEEKdHVwbGVzdG9yZSBvbiB0aGUgb3RoZXIgaGFuZCBoYXMgYWJpbGl0eSB0byBz dG9yZSBtaW5pbWFsIHR1cGxlIHdoaWNoCnNhdmVzIHNvbWUgQ1BVIGN5Y2xlcyBmb3JtaW5nIGFu ZCBkZWZvcm1pbmcgYSBmdWxsIGhlYXAgdHVwbGUuIE1vZGVybml6ZQpwZ19idWZmZXJjYWNoZV9w YWdlcygpIHRvIHVzZSBTUkYgaW5mcmFzdHJ1Y3R1cmUgYW5kIHR1cGxlc3RvcmUuCgpBdXRob3I6 IEFzaHV0b3NoIEJhcGF0IDxhc2h1dG9zaC5iYXBhdC5vc3NAZ21haWwuY29tPgpBdXRob3I6IFBh bGFrIENoYXR1cnZlZGkgPGNoYXR1cnZlZGlwYWxhazE5MTFAZ21haWwuY29tPgotLS0KIGNvbnRy aWIvcGdfYnVmZmVyY2FjaGUvcGdfYnVmZmVyY2FjaGVfcGFnZXMuYyB8IDI1NyArKysrKystLS0t LS0tLS0tLS0KIDEgZmlsZSBjaGFuZ2VkLCA4MSBpbnNlcnRpb25zKCspLCAxNzYgZGVsZXRpb25z KC0pCgpkaWZmIC0tZ2l0IGEvY29udHJpYi9wZ19idWZmZXJjYWNoZS9wZ19idWZmZXJjYWNoZV9w YWdlcy5jIGIvY29udHJpYi9wZ19idWZmZXJjYWNoZS9wZ19idWZmZXJjYWNoZV9wYWdlcy5jCmlu ZGV4IGRiNGQ3MTFjY2U3Li5mYWU1MzE1NzNjYiAxMDA2NDQKLS0tIGEvY29udHJpYi9wZ19idWZm ZXJjYWNoZS9wZ19idWZmZXJjYWNoZV9wYWdlcy5jCisrKyBiL2NvbnRyaWIvcGdfYnVmZmVyY2Fj aGUvcGdfYnVmZmVyY2FjaGVfcGFnZXMuYwpAQCAtMzcsMzkgKzM3LDYgQEAgUEdfTU9EVUxFX01B R0lDX0VYVCgKIAkJCQkJLnZlcnNpb24gPSBQR19WRVJTSU9OCiApOwogCi0vKgotICogUmVjb3Jk IHN0cnVjdHVyZSBob2xkaW5nIHRoZSB0byBiZSBleHBvc2VkIGNhY2hlIGRhdGEuCi0gKi8KLXR5 cGVkZWYgc3RydWN0Ci17Ci0JdWludDMyCQlidWZmZXJpZDsKLQlSZWxGaWxlTnVtYmVyIHJlbGZp bGVudW1iZXI7Ci0JT2lkCQkJcmVsdGFibGVzcGFjZTsKLQlPaWQJCQlyZWxkYXRhYmFzZTsKLQlG b3JrTnVtYmVyCWZvcmtudW07Ci0JQmxvY2tOdW1iZXIgYmxvY2tudW07Ci0JYm9vbAkJaXN2YWxp ZDsKLQlib29sCQlpc2RpcnR5OwotCXVpbnQxNgkJdXNhZ2Vjb3VudDsKLQotCS8qCi0JICogQW4g aW50MzIgaXMgc3VmZmljaWVudGx5IGxhcmdlLCBhcyBNQVhfQkFDS0VORFMgcHJldmVudHMgYSBi dWZmZXIgZnJvbQotCSAqIGJlaW5nIHBpbm5lZCBieSB0b28gbWFueSBiYWNrZW5kcyBhbmQgZWFj aCBiYWNrZW5kIHdpbGwgb25seSBwaW4gb25jZQotCSAqIGJlY2F1c2Ugb2YgYnVmbWdyLmMncyBQ cml2YXRlUmVmQ291bnQgaW5mcmFzdHJ1Y3R1cmUuCi0JICovCi0JaW50MzIJCXBpbm5pbmdfYmFj a2VuZHM7Ci19IEJ1ZmZlckNhY2hlUGFnZXNSZWM7Ci0KLQotLyoKLSAqIEZ1bmN0aW9uIGNvbnRl eHQgZm9yIGRhdGEgcGVyc2lzdGluZyBvdmVyIHJlcGVhdGVkIGNhbGxzLgotICovCi10eXBlZGVm IHN0cnVjdAotewotCVR1cGxlRGVzYwl0dXBkZXNjOwotCUJ1ZmZlckNhY2hlUGFnZXNSZWMgKnJl Y29yZDsKLX0gQnVmZmVyQ2FjaGVQYWdlc0NvbnRleHQ7Ci0KIC8qCiAgKiBSZWNvcmQgc3RydWN0 dXJlIGhvbGRpbmcgdGhlIHRvIGJlIGV4cG9zZWQgY2FjaGUgZGF0YSBmb3IgT1MgcGFnZXMuICBU aGlzCiAgKiBzdHJ1Y3R1cmUgaXMgdXNlZCBieSBwZ19idWZmZXJjYWNoZV9vc19wYWdlcygpLCB3 aGVyZSBOVU1BIGluZm9ybWF0aW9uIG1heQpAQCAtMTE3LDE0MiArODQsOTAgQEAgc3RhdGljIGJv b2wgZmlyc3ROdW1hVG91Y2ggPSB0cnVlOwogRGF0dW0KIHBnX2J1ZmZlcmNhY2hlX3BhZ2VzKFBH X0ZVTkNUSU9OX0FSR1MpCiB7Ci0JRnVuY0NhbGxDb250ZXh0ICpmdW5jY3R4OwotCURhdHVtCQly ZXN1bHQ7Ci0JTWVtb3J5Q29udGV4dCBvbGRjb250ZXh0OwotCUJ1ZmZlckNhY2hlUGFnZXNDb250 ZXh0ICpmY3R4OwkvKiBVc2VyIGZ1bmN0aW9uIGNvbnRleHQuICovCi0JVHVwbGVEZXNjCXR1cGxl ZGVzYzsKKwlSZXR1cm5TZXRJbmZvICpyc2luZm8gPSAoUmV0dXJuU2V0SW5mbyAqKSBmY2luZm8t PnJlc3VsdGluZm87CiAJVHVwbGVEZXNjCWV4cGVjdGVkX3R1cGxlZGVzYzsKLQlIZWFwVHVwbGUJ dHVwbGU7Ci0KLQlpZiAoU1JGX0lTX0ZJUlNUQ0FMTCgpKQotCXsKLQkJaW50CQkJaTsKLQotCQlm dW5jY3R4ID0gU1JGX0ZJUlNUQ0FMTF9JTklUKCk7Ci0KLQkJLyogU3dpdGNoIGNvbnRleHQgd2hl biBhbGxvY2F0aW5nIHN0dWZmIHRvIGJlIHVzZWQgaW4gbGF0ZXIgY2FsbHMgKi8KLQkJb2xkY29u dGV4dCA9IE1lbW9yeUNvbnRleHRTd2l0Y2hUbyhmdW5jY3R4LT5tdWx0aV9jYWxsX21lbW9yeV9j dHgpOwotCi0JCS8qIENyZWF0ZSBhIHVzZXIgZnVuY3Rpb24gY29udGV4dCBmb3IgY3Jvc3MtY2Fs bCBwZXJzaXN0ZW5jZSAqLwotCQlmY3R4ID0gcGFsbG9jX29iamVjdChCdWZmZXJDYWNoZVBhZ2Vz Q29udGV4dCk7Ci0KLQkJLyoKLQkJICogVG8gc21vb3RobHkgc3VwcG9ydCB1cGdyYWRlcyBmcm9t IHZlcnNpb24gMS4wIG9mIHRoaXMgZXh0ZW5zaW9uCi0JCSAqIHRyYW5zcGFyZW50bHkgaGFuZGxl IHRoZSAobm9uLSlleGlzdGVuY2Ugb2YgdGhlIHBpbm5pbmdfYmFja2VuZHMKLQkJICogY29sdW1u LiBXZSB1bmZvcnR1bmF0ZWx5IGhhdmUgdG8gZ2V0IHRoZSByZXN1bHQgdHlwZSBmb3IgdGhhdC4u LiAtCi0JCSAqIHdlIGNhbid0IHVzZSB0aGUgcmVzdWx0IHR5cGUgZGV0ZXJtaW5lZCBieSB0aGUg ZnVuY3Rpb24gZGVmaW5pdGlvbgotCQkgKiB3aXRob3V0IHBvdGVudGlhbGx5IGNyYXNoaW5nIHdo ZW4gc29tZWJvZHkgdXNlcyB0aGUgb2xkIChvciBldmVuCi0JCSAqIHdyb25nKSBmdW5jdGlvbiBk ZWZpbml0aW9uIHRob3VnaC4KLQkJICovCi0JCWlmIChnZXRfY2FsbF9yZXN1bHRfdHlwZShmY2lu Zm8sIE5VTEwsICZleHBlY3RlZF90dXBsZWRlc2MpICE9IFRZUEVGVU5DX0NPTVBPU0lURSkKLQkJ CWVsb2coRVJST1IsICJyZXR1cm4gdHlwZSBtdXN0IGJlIGEgcm93IHR5cGUiKTsKLQotCQlpZiAo ZXhwZWN0ZWRfdHVwbGVkZXNjLT5uYXR0cyA8IE5VTV9CVUZGRVJDQUNIRV9QQUdFU19NSU5fRUxF TSB8fAotCQkJZXhwZWN0ZWRfdHVwbGVkZXNjLT5uYXR0cyA+IE5VTV9CVUZGRVJDQUNIRV9QQUdF U19FTEVNKQotCQkJZWxvZyhFUlJPUiwgImluY29ycmVjdCBudW1iZXIgb2Ygb3V0cHV0IGFyZ3Vt ZW50cyIpOwotCi0JCS8qIENvbnN0cnVjdCBhIHR1cGxlIGRlc2NyaXB0b3IgZm9yIHRoZSByZXN1 bHQgcm93cy4gKi8KLQkJdHVwbGVkZXNjID0gQ3JlYXRlVGVtcGxhdGVUdXBsZURlc2MoZXhwZWN0 ZWRfdHVwbGVkZXNjLT5uYXR0cyk7Ci0JCVR1cGxlRGVzY0luaXRFbnRyeSh0dXBsZWRlc2MsIChB dHRyTnVtYmVyKSAxLCAiYnVmZmVyaWQiLAotCQkJCQkJICAgSU5UNE9JRCwgLTEsIDApOwotCQlU dXBsZURlc2NJbml0RW50cnkodHVwbGVkZXNjLCAoQXR0ck51bWJlcikgMiwgInJlbGZpbGVub2Rl IiwKLQkJCQkJCSAgIE9JRE9JRCwgLTEsIDApOwotCQlUdXBsZURlc2NJbml0RW50cnkodHVwbGVk ZXNjLCAoQXR0ck51bWJlcikgMywgInJlbHRhYmxlc3BhY2UiLAotCQkJCQkJICAgT0lET0lELCAt MSwgMCk7Ci0JCVR1cGxlRGVzY0luaXRFbnRyeSh0dXBsZWRlc2MsIChBdHRyTnVtYmVyKSA0LCAi cmVsZGF0YWJhc2UiLAotCQkJCQkJICAgT0lET0lELCAtMSwgMCk7Ci0JCVR1cGxlRGVzY0luaXRF bnRyeSh0dXBsZWRlc2MsIChBdHRyTnVtYmVyKSA1LCAicmVsZm9ya251bWJlciIsCi0JCQkJCQkg ICBJTlQyT0lELCAtMSwgMCk7Ci0JCVR1cGxlRGVzY0luaXRFbnRyeSh0dXBsZWRlc2MsIChBdHRy TnVtYmVyKSA2LCAicmVsYmxvY2tudW1iZXIiLAotCQkJCQkJICAgSU5UOE9JRCwgLTEsIDApOwot CQlUdXBsZURlc2NJbml0RW50cnkodHVwbGVkZXNjLCAoQXR0ck51bWJlcikgNywgImlzZGlydHki LAotCQkJCQkJICAgQk9PTE9JRCwgLTEsIDApOwotCQlUdXBsZURlc2NJbml0RW50cnkodHVwbGVk ZXNjLCAoQXR0ck51bWJlcikgOCwgInVzYWdlX2NvdW50IiwKLQkJCQkJCSAgIElOVDJPSUQsIC0x LCAwKTsKLQotCQlpZiAoZXhwZWN0ZWRfdHVwbGVkZXNjLT5uYXR0cyA9PSBOVU1fQlVGRkVSQ0FD SEVfUEFHRVNfRUxFTSkKLQkJCVR1cGxlRGVzY0luaXRFbnRyeSh0dXBsZWRlc2MsIChBdHRyTnVt YmVyKSA5LCAicGlubmluZ19iYWNrZW5kcyIsCi0JCQkJCQkJICAgSU5UNE9JRCwgLTEsIDApOwot Ci0JCVR1cGxlRGVzY0ZpbmFsaXplKHR1cGxlZGVzYyk7Ci0JCWZjdHgtPnR1cGRlc2MgPSBCbGVz c1R1cGxlRGVzYyh0dXBsZWRlc2MpOwotCi0JCS8qIEFsbG9jYXRlIE5CdWZmZXJzIHdvcnRoIG9m IEJ1ZmZlckNhY2hlUGFnZXNSZWMgcmVjb3Jkcy4gKi8KLQkJZmN0eC0+cmVjb3JkID0gKEJ1ZmZl ckNhY2hlUGFnZXNSZWMgKikKLQkJCU1lbW9yeUNvbnRleHRBbGxvY0h1Z2UoQ3VycmVudE1lbW9y eUNvbnRleHQsCi0JCQkJCQkJCSAgIHNpemVvZihCdWZmZXJDYWNoZVBhZ2VzUmVjKSAqIE5CdWZm ZXJzKTsKLQotCQkvKiBTZXQgbWF4IGNhbGxzIGFuZCByZW1lbWJlciB0aGUgdXNlciBmdW5jdGlv biBjb250ZXh0LiAqLwotCQlmdW5jY3R4LT5tYXhfY2FsbHMgPSBOQnVmZmVyczsKLQkJZnVuY2N0 eC0+dXNlcl9mY3R4ID0gZmN0eDsKKwlEYXR1bQkJdmFsdWVzW05VTV9CVUZGRVJDQUNIRV9QQUdF U19FTEVNXTsKKwlib29sCQludWxsc1tOVU1fQlVGRkVSQ0FDSEVfUEFHRVNfRUxFTV07CisJaW50 CQkJaTsKIAotCQkvKiBSZXR1cm4gdG8gb3JpZ2luYWwgY29udGV4dCB3aGVuIGFsbG9jYXRpbmcg dHJhbnNpZW50IG1lbW9yeSAqLwotCQlNZW1vcnlDb250ZXh0U3dpdGNoVG8ob2xkY29udGV4dCk7 Ci0KLQkJLyoKLQkJICogU2NhbiB0aHJvdWdoIGFsbCB0aGUgYnVmZmVycywgc2F2aW5nIHRoZSBy ZWxldmFudCBmaWVsZHMgaW4gdGhlCi0JCSAqIGZjdHgtPnJlY29yZCBzdHJ1Y3R1cmUuCi0JCSAq Ci0JCSAqIFdlIGRvbid0IGhvbGQgdGhlIHBhcnRpdGlvbiBsb2Nrcywgc28gd2UgZG9uJ3QgZ2V0 IGEgY29uc2lzdGVudAotCQkgKiBzbmFwc2hvdCBhY3Jvc3MgYWxsIGJ1ZmZlcnMsIGJ1dCB3ZSBk byBncmFiIHRoZSBidWZmZXIgaGVhZGVyCi0JCSAqIGxvY2tzLCBzbyB0aGUgaW5mb3JtYXRpb24g b2YgZWFjaCBidWZmZXIgaXMgc2VsZi1jb25zaXN0ZW50LgotCQkgKi8KLQkJZm9yIChpID0gMDsg aSA8IE5CdWZmZXJzOyBpKyspCi0JCXsKLQkJCUJ1ZmZlckRlc2MgKmJ1ZkhkcjsKLQkJCXVpbnQ2 NAkJYnVmX3N0YXRlOworCS8qCisJICogVG8gc21vb3RobHkgc3VwcG9ydCB1cGdyYWRlcyBmcm9t IHZlcnNpb24gMS4wIG9mIHRoaXMgZXh0ZW5zaW9uCisJICogdHJhbnNwYXJlbnRseSBoYW5kbGUg dGhlIChub24tKWV4aXN0ZW5jZSBvZiB0aGUgcGlubmluZ19iYWNrZW5kcworCSAqIGNvbHVtbi4g V2UgdW5mb3J0dW5hdGVseSBoYXZlIHRvIGdldCB0aGUgcmVzdWx0IHR5cGUgZm9yIHRoYXQuLi4g LSB3ZQorCSAqIGNhbid0IHVzZSB0aGUgcmVzdWx0IHR5cGUgZGV0ZXJtaW5lZCBieSB0aGUgZnVu Y3Rpb24gZGVmaW5pdGlvbiB3aXRob3V0CisJICogcG90ZW50aWFsbHkgY3Jhc2hpbmcgd2hlbiBz b21lYm9keSB1c2VzIHRoZSBvbGQgKG9yIGV2ZW4gd3JvbmcpCisJICogZnVuY3Rpb24gZGVmaW5p dGlvbiB0aG91Z2guCisJICovCisJaWYgKGdldF9jYWxsX3Jlc3VsdF90eXBlKGZjaW5mbywgTlVM TCwgJmV4cGVjdGVkX3R1cGxlZGVzYykgIT0gVFlQRUZVTkNfQ09NUE9TSVRFKQorCQllbG9nKEVS Uk9SLCAicmV0dXJuIHR5cGUgbXVzdCBiZSBhIHJvdyB0eXBlIik7CiAKLQkJCUNIRUNLX0ZPUl9J TlRFUlJVUFRTKCk7CisJaWYgKGV4cGVjdGVkX3R1cGxlZGVzYy0+bmF0dHMgPCBOVU1fQlVGRkVS Q0FDSEVfUEFHRVNfTUlOX0VMRU0gfHwKKwkJZXhwZWN0ZWRfdHVwbGVkZXNjLT5uYXR0cyA+IE5V TV9CVUZGRVJDQUNIRV9QQUdFU19FTEVNKQorCQllbG9nKEVSUk9SLCAiaW5jb3JyZWN0IG51bWJl ciBvZiBvdXRwdXQgYXJndW1lbnRzIik7CiAKLQkJCWJ1ZkhkciA9IEdldEJ1ZmZlckRlc2NyaXB0 b3IoaSk7Ci0JCQkvKiBMb2NrIGVhY2ggYnVmZmVyIGhlYWRlciBiZWZvcmUgaW5zcGVjdGluZy4g Ki8KLQkJCWJ1Zl9zdGF0ZSA9IExvY2tCdWZIZHIoYnVmSGRyKTsKKwlJbml0TWF0ZXJpYWxpemVk U1JGKGZjaW5mbywgMCk7CiAKLQkJCWZjdHgtPnJlY29yZFtpXS5idWZmZXJpZCA9IEJ1ZmZlckRl c2NyaXB0b3JHZXRCdWZmZXIoYnVmSGRyKTsKLQkJCWZjdHgtPnJlY29yZFtpXS5yZWxmaWxlbnVt YmVyID0gQnVmVGFnR2V0UmVsTnVtYmVyKCZidWZIZHItPnRhZyk7Ci0JCQlmY3R4LT5yZWNvcmRb aV0ucmVsdGFibGVzcGFjZSA9IGJ1Zkhkci0+dGFnLnNwY09pZDsKLQkJCWZjdHgtPnJlY29yZFtp XS5yZWxkYXRhYmFzZSA9IGJ1Zkhkci0+dGFnLmRiT2lkOwotCQkJZmN0eC0+cmVjb3JkW2ldLmZv cmtudW0gPSBCdWZUYWdHZXRGb3JrTnVtKCZidWZIZHItPnRhZyk7Ci0JCQlmY3R4LT5yZWNvcmRb aV0uYmxvY2tudW0gPSBidWZIZHItPnRhZy5ibG9ja051bTsKLQkJCWZjdHgtPnJlY29yZFtpXS51 c2FnZWNvdW50ID0gQlVGX1NUQVRFX0dFVF9VU0FHRUNPVU5UKGJ1Zl9zdGF0ZSk7Ci0JCQlmY3R4 LT5yZWNvcmRbaV0ucGlubmluZ19iYWNrZW5kcyA9IEJVRl9TVEFURV9HRVRfUkVGQ09VTlQoYnVm X3N0YXRlKTsKKwkvKgorCSAqIFNjYW4gdGhyb3VnaCBhbGwgdGhlIGJ1ZmZlcnMsIGFkZGluZyBv bmUgcm93IGZvciBlYWNoIG9mIHRoZSBidWZmZXJzIHRvCisJICogdGhlIHR1cGxlc3RvcmUuCisJ ICoKKwkgKiBXZSBkb24ndCBob2xkIHRoZSBwYXJ0aXRpb24gbG9ja3MsIHNvIHdlIGRvbid0IGdl dCBhIGNvbnNpc3RlbnQKKwkgKiBzbmFwc2hvdCBhY3Jvc3MgYWxsIGJ1ZmZlcnMsIGJ1dCB3ZSBk byBncmFiIHRoZSBidWZmZXIgaGVhZGVyIGxvY2tzLCBzbworCSAqIHRoZSBpbmZvcm1hdGlvbiBv ZiBlYWNoIGJ1ZmZlciBpcyBzZWxmLWNvbnNpc3RlbnQuCisJICovCisJZm9yIChpID0gMDsgaSA8 IE5CdWZmZXJzOyBpKyspCisJeworCQlCdWZmZXJEZXNjICpidWZIZHI7CisJCXVpbnQ2NAkJYnVm X3N0YXRlOworCQl1aW50MzIJCWJ1ZmZlcmlkOworCQlSZWxGaWxlTnVtYmVyIHJlbGZpbGVudW1i ZXI7CisJCU9pZAkJCXJlbHRhYmxlc3BhY2U7CisJCU9pZAkJCXJlbGRhdGFiYXNlOworCQlGb3Jr TnVtYmVyCWZvcmtudW07CisJCUJsb2NrTnVtYmVyIGJsb2NrbnVtOworCQlib29sCQlpc3ZhbGlk OworCQlib29sCQlpc2RpcnR5OworCQl1aW50MTYJCXVzYWdlY291bnQ7CisJCWludDMyCQlwaW5u aW5nX2JhY2tlbmRzOwogCi0JCQlpZiAoYnVmX3N0YXRlICYgQk1fRElSVFkpCi0JCQkJZmN0eC0+ cmVjb3JkW2ldLmlzZGlydHkgPSB0cnVlOwotCQkJZWxzZQotCQkJCWZjdHgtPnJlY29yZFtpXS5p c2RpcnR5ID0gZmFsc2U7CisJCUNIRUNLX0ZPUl9JTlRFUlJVUFRTKCk7CiAKLQkJCS8qIE5vdGUg aWYgdGhlIGJ1ZmZlciBpcyB2YWxpZCwgYW5kIGhhcyBzdG9yYWdlIGNyZWF0ZWQgKi8KLQkJCWlm ICgoYnVmX3N0YXRlICYgQk1fVkFMSUQpICYmIChidWZfc3RhdGUgJiBCTV9UQUdfVkFMSUQpKQot CQkJCWZjdHgtPnJlY29yZFtpXS5pc3ZhbGlkID0gdHJ1ZTsKLQkJCWVsc2UKLQkJCQlmY3R4LT5y ZWNvcmRbaV0uaXN2YWxpZCA9IGZhbHNlOworCQlidWZIZHIgPSBHZXRCdWZmZXJEZXNjcmlwdG9y KGkpOworCQkvKiBMb2NrIGVhY2ggYnVmZmVyIGhlYWRlciBiZWZvcmUgaW5zcGVjdGluZy4gKi8K KwkJYnVmX3N0YXRlID0gTG9ja0J1ZkhkcihidWZIZHIpOworCisJCWJ1ZmZlcmlkID0gQnVmZmVy RGVzY3JpcHRvckdldEJ1ZmZlcihidWZIZHIpOworCQlyZWxmaWxlbnVtYmVyID0gQnVmVGFnR2V0 UmVsTnVtYmVyKCZidWZIZHItPnRhZyk7CisJCXJlbHRhYmxlc3BhY2UgPSBidWZIZHItPnRhZy5z cGNPaWQ7CisJCXJlbGRhdGFiYXNlID0gYnVmSGRyLT50YWcuZGJPaWQ7CisJCWZvcmtudW0gPSBC dWZUYWdHZXRGb3JrTnVtKCZidWZIZHItPnRhZyk7CisJCWJsb2NrbnVtID0gYnVmSGRyLT50YWcu YmxvY2tOdW07CisJCXVzYWdlY291bnQgPSBCVUZfU1RBVEVfR0VUX1VTQUdFQ09VTlQoYnVmX3N0 YXRlKTsKKwkJcGlubmluZ19iYWNrZW5kcyA9IEJVRl9TVEFURV9HRVRfUkVGQ09VTlQoYnVmX3N0 YXRlKTsKIAotCQkJVW5sb2NrQnVmSGRyKGJ1Zkhkcik7Ci0JCX0KLQl9CisJCWlmIChidWZfc3Rh dGUgJiBCTV9ESVJUWSkKKwkJCWlzZGlydHkgPSB0cnVlOworCQllbHNlCisJCQlpc2RpcnR5ID0g ZmFsc2U7CiAKLQlmdW5jY3R4ID0gU1JGX1BFUkNBTExfU0VUVVAoKTsKKwkJLyogTm90ZSBpZiB0 aGUgYnVmZmVyIGlzIHZhbGlkLCBhbmQgaGFzIHN0b3JhZ2UgY3JlYXRlZCAqLworCQlpZiAoKGJ1 Zl9zdGF0ZSAmIEJNX1ZBTElEKSAmJiAoYnVmX3N0YXRlICYgQk1fVEFHX1ZBTElEKSkKKwkJCWlz dmFsaWQgPSB0cnVlOworCQllbHNlCisJCQlpc3ZhbGlkID0gZmFsc2U7CiAKLQkvKiBHZXQgdGhl IHNhdmVkIHN0YXRlICovCi0JZmN0eCA9IGZ1bmNjdHgtPnVzZXJfZmN0eDsKKwkJVW5sb2NrQnVm SGRyKGJ1Zkhkcik7CiAKLQlpZiAoZnVuY2N0eC0+Y2FsbF9jbnRyIDwgZnVuY2N0eC0+bWF4X2Nh bGxzKQotCXsKLQkJdWludDMyCQlpID0gZnVuY2N0eC0+Y2FsbF9jbnRyOwotCQlEYXR1bQkJdmFs dWVzW05VTV9CVUZGRVJDQUNIRV9QQUdFU19FTEVNXTsKLQkJYm9vbAkJbnVsbHNbTlVNX0JVRkZF UkNBQ0hFX1BBR0VTX0VMRU1dOworCQkvKiBCdWlsZCB0aGUgdHVwbGUgYW5kIGFkZCBpdCB0byB0 dXBsZXN0b3JlICovCisJCW1lbXNldChudWxscywgMCwgc2l6ZW9mKG51bGxzKSk7CiAKLQkJdmFs dWVzWzBdID0gSW50MzJHZXREYXR1bShmY3R4LT5yZWNvcmRbaV0uYnVmZmVyaWQpOwotCQludWxs c1swXSA9IGZhbHNlOworCQl2YWx1ZXNbMF0gPSBJbnQzMkdldERhdHVtKGJ1ZmZlcmlkKTsKIAog CQkvKgogCQkgKiBTZXQgYWxsIGZpZWxkcyBleGNlcHQgdGhlIGJ1ZmZlcmlkIHRvIG51bGwgaWYg dGhlIGJ1ZmZlciBpcyB1bnVzZWQKIAkJICogb3Igbm90IHZhbGlkLgogCQkgKi8KLQkJaWYgKGZj dHgtPnJlY29yZFtpXS5ibG9ja251bSA9PSBJbnZhbGlkQmxvY2tOdW1iZXIgfHwKLQkJCWZjdHgt PnJlY29yZFtpXS5pc3ZhbGlkID09IGZhbHNlKQorCQlpZiAoYmxvY2tudW0gPT0gSW52YWxpZEJs b2NrTnVtYmVyIHx8IGlzdmFsaWQgPT0gZmFsc2UpCiAJCXsKIAkJCW51bGxzWzFdID0gdHJ1ZTsK IAkJCW51bGxzWzJdID0gdHJ1ZTsKQEAgLTI2MiwzNyArMTc3LDI3IEBAIHBnX2J1ZmZlcmNhY2hl X3BhZ2VzKFBHX0ZVTkNUSU9OX0FSR1MpCiAJCQludWxsc1s2XSA9IHRydWU7CiAJCQludWxsc1s3 XSA9IHRydWU7CiAJCQkvKiB1bnVzZWQgZm9yIHYxLjAgY2FsbGVycywgYnV0IHRoZSBhcnJheSBp cyBhbHdheXMgbG9uZyBlbm91Z2ggKi8KLQkJCW51bGxzWzhdID0gdHJ1ZTsKKwkJCWlmIChleHBl Y3RlZF90dXBsZWRlc2MtPm5hdHRzID09IE5VTV9CVUZGRVJDQUNIRV9QQUdFU19FTEVNKQorCQkJ CW51bGxzWzhdID0gdHJ1ZTsKIAkJfQogCQllbHNlCiAJCXsKLQkJCXZhbHVlc1sxXSA9IE9iamVj dElkR2V0RGF0dW0oZmN0eC0+cmVjb3JkW2ldLnJlbGZpbGVudW1iZXIpOwotCQkJbnVsbHNbMV0g PSBmYWxzZTsKLQkJCXZhbHVlc1syXSA9IE9iamVjdElkR2V0RGF0dW0oZmN0eC0+cmVjb3JkW2ld LnJlbHRhYmxlc3BhY2UpOwotCQkJbnVsbHNbMl0gPSBmYWxzZTsKLQkJCXZhbHVlc1szXSA9IE9i amVjdElkR2V0RGF0dW0oZmN0eC0+cmVjb3JkW2ldLnJlbGRhdGFiYXNlKTsKLQkJCW51bGxzWzNd ID0gZmFsc2U7Ci0JCQl2YWx1ZXNbNF0gPSBJbnQxNkdldERhdHVtKGZjdHgtPnJlY29yZFtpXS5m b3JrbnVtKTsKLQkJCW51bGxzWzRdID0gZmFsc2U7Ci0JCQl2YWx1ZXNbNV0gPSBJbnQ2NEdldERh dHVtKChpbnQ2NCkgZmN0eC0+cmVjb3JkW2ldLmJsb2NrbnVtKTsKLQkJCW51bGxzWzVdID0gZmFs c2U7Ci0JCQl2YWx1ZXNbNl0gPSBCb29sR2V0RGF0dW0oZmN0eC0+cmVjb3JkW2ldLmlzZGlydHkp OwotCQkJbnVsbHNbNl0gPSBmYWxzZTsKLQkJCXZhbHVlc1s3XSA9IFVJbnQxNkdldERhdHVtKGZj dHgtPnJlY29yZFtpXS51c2FnZWNvdW50KTsKLQkJCW51bGxzWzddID0gZmFsc2U7CisJCQl2YWx1 ZXNbMV0gPSBPYmplY3RJZEdldERhdHVtKHJlbGZpbGVudW1iZXIpOworCQkJdmFsdWVzWzJdID0g T2JqZWN0SWRHZXREYXR1bShyZWx0YWJsZXNwYWNlKTsKKwkJCXZhbHVlc1szXSA9IE9iamVjdElk R2V0RGF0dW0ocmVsZGF0YWJhc2UpOworCQkJdmFsdWVzWzRdID0gSW50MTZHZXREYXR1bShmb3Jr bnVtKTsKKwkJCXZhbHVlc1s1XSA9IEludDY0R2V0RGF0dW0oKGludDY0KSBibG9ja251bSk7CisJ CQl2YWx1ZXNbNl0gPSBCb29sR2V0RGF0dW0oaXNkaXJ0eSk7CisJCQl2YWx1ZXNbN10gPSBVSW50 MTZHZXREYXR1bSh1c2FnZWNvdW50KTsKIAkJCS8qIHVudXNlZCBmb3IgdjEuMCBjYWxsZXJzLCBi dXQgdGhlIGFycmF5IGlzIGFsd2F5cyBsb25nIGVub3VnaCAqLwotCQkJdmFsdWVzWzhdID0gSW50 MzJHZXREYXR1bShmY3R4LT5yZWNvcmRbaV0ucGlubmluZ19iYWNrZW5kcyk7Ci0JCQludWxsc1s4 XSA9IGZhbHNlOworCQkJaWYgKGV4cGVjdGVkX3R1cGxlZGVzYy0+bmF0dHMgPT0gTlVNX0JVRkZF UkNBQ0hFX1BBR0VTX0VMRU0pCisJCQkJdmFsdWVzWzhdID0gSW50MzJHZXREYXR1bShwaW5uaW5n X2JhY2tlbmRzKTsKIAkJfQogCi0JCS8qIEJ1aWxkIGFuZCByZXR1cm4gdGhlIHR1cGxlLiAqLwot CQl0dXBsZSA9IGhlYXBfZm9ybV90dXBsZShmY3R4LT50dXBkZXNjLCB2YWx1ZXMsIG51bGxzKTsK LQkJcmVzdWx0ID0gSGVhcFR1cGxlR2V0RGF0dW0odHVwbGUpOwotCi0JCVNSRl9SRVRVUk5fTkVY VChmdW5jY3R4LCByZXN1bHQpOworCQl0dXBsZXN0b3JlX3B1dHZhbHVlcyhyc2luZm8tPnNldFJl c3VsdCwgcnNpbmZvLT5zZXREZXNjLCB2YWx1ZXMsIG51bGxzKTsKIAl9Ci0JZWxzZQotCQlTUkZf UkVUVVJOX0RPTkUoZnVuY2N0eCk7CisKKwlyZXR1cm4gKERhdHVtKSAwOwogfQogCiAvKgoKYmFz ZS1jb21taXQ6IDk5OWRlYzllYzZhODE2NjgwNTc0MjdjMmU5MzEyYjIwNjM1ZmJhMDIKLS0gCjIu MzQuMQoK --0000000000008a8865064e0de95e--