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 D36E9C7EE23 for ; Sun, 28 May 2023 10:10:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229451AbjE1KKW (ORCPT ); Sun, 28 May 2023 06:10:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229447AbjE1KKV (ORCPT ); Sun, 28 May 2023 06:10:21 -0400 Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A35CFBB; Sun, 28 May 2023 03:10:18 -0700 (PDT) Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4QTZCg2x5sz9sbf; Sun, 28 May 2023 12:10:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oltmanns.dev; s=MBO0001; t=1685268607; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7ecNLW5aHDmQUNWlbObUxJA9/xvuYkyqh/+NvM+Nhxg=; b=zMEdO4IjgGb158eTzzQZZnLzSITWQoQMH1N3+CqXcStzA+XStYm3cHRQjbgVFk4CpmNYm5 6BY3UfkEQvcLQgTaH7Zp6gbKKOXvCqER8/oYKlt7eTPj39A9e4JEAUtdKK1aS1wKvebmPB MQx8WLTbb1TczJMmmUSIgb86mSwHqlQTUbJ1zw1DjsFqggfKP1p9X7Cw9QzJGXkx6Vzr1/ /JX0jkYrQ/9IqnwFuVn0L0QnTUSK5VkAmYemxVczCLHOlwKnlHFB/gU7owX+b0Q0PAYqeR qwYsBUpR5WQ9barq+0iPVgd9inUHdjE1HjSOdMoG6iUWNiy7gR30Xa/m0WDGcA== References: <20230527132747.83196-1-frank@oltmanns.dev> <20230527132747.83196-3-frank@oltmanns.dev> From: Frank Oltmanns To: Julian Calaby Cc: linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@lists.linux.dev, Andre Przywara , Chen-Yu Tsai , Icenowy Zheng , Jernej Skrabec , Maxime Ripard , Michael Turquette , Rob Herring , Samuel Holland , Stephen Boyd Subject: Re: [RFC PATCH 2/3] clk: sunxi-ng: Implement precalculated NKM rate selection Date: Sun, 28 May 2023 11:12:19 +0200 In-reply-to: Message-ID: <87sfbgwyvp.fsf@oltmanns.dev> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 4QTZCg2x5sz9sbf Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Hi Julian, On 2023-05-28 at 09:19:36 +1000, Julian Calaby wr= ote: > Hi Frank, > > On Sat, May 27, 2023 at 11:37=E2=80=AFPM Frank Oltmanns wrote: >> >> Add a new precalculation method for NKM clock rate selection in the >> sunxi-ng clock driver. Introduce ccu_nkm_find_best_precalc which uses a >> precalculated table of valid NKM combinations (struct clk_nkm_table and >> struct clk_nkm_combo) to find the best rate. This approach provides >> faster rate selection by searching a table of valid combinations rather >> than calculating for all possible combinations. >> >> The table of NKM combinations needs to be initialized with meaningful >> combinations only, i.e. removing redundant combinations that result in >> the same rate. >> >> Keep the existing ccu_nkm_find_best function in place and use it as a >> fallback if no precalculated table is provided. >> >> Signed-off-by: Frank Oltmanns >> --- >> drivers/clk/sunxi-ng/ccu_nkm.c | 84 +++++++++++++++++++++++++++------- >> drivers/clk/sunxi-ng/ccu_nkm.h | 26 +++++++++++ >> 2 files changed, 94 insertions(+), 16 deletions(-) >> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_n= km.c >> index 94d2a83992b2..9652f6df17bd 100644 >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c >> @@ -54,6 +54,49 @@ static unsigned long ccu_nkm_find_best(unsigned long = parent, unsigned long rate, >> return best_rate; >> } >> >> +static unsigned long ccu_nkm_find_best_precalc(unsigned long parent, >> + unsigned long rate, >> + struct _ccu_nkm *nkm, >> + struct clk_nkm_table *tab= le) >> +{ >> + unsigned long best_rate =3D 0, best_diff =3D ULONG_MAX; >> + unsigned long best_n =3D 0, best_k =3D 0, best_m =3D 0; >> + int start =3D 0, end =3D table->num - 1, mid; >> + >> + while (start <=3D end) { >> + unsigned long tmp_rate; >> + unsigned long tmp_diff; >> + >> + mid =3D (start + end) / 2; >> + >> + tmp_rate =3D parent * table->combos[mid].n * table->comb= os[mid].k / >> + table->combos[mid].m; >> + >> + tmp_diff =3D abs(rate - tmp_rate); >> + >> + if (tmp_diff < best_diff) { >> + best_rate =3D tmp_rate; >> + best_diff =3D tmp_diff; >> + best_n =3D table->combos[mid].n; >> + best_k =3D table->combos[mid].k; >> + best_m =3D table->combos[mid].m; >> + if (best_diff =3D=3D 0) >> + goto out; >> + } > Thank you for your feedback! In my proposal, the code performs a binary search by 1. taking the element in the middle (mid) 2. calculating the rate of the element (tmp_rate) 3. calculating the difference to the requested rate (tmp_diff) 4. if the diff is better than the best_diff making it the new best n-k-m-combo (the if block) > If the table was sorted by n * k / m, this could just be a process of Please note, the table already has to be sorted for the function to work, as is the nature of a binary search. I should definitely add comments. I'm sorry, the code was intended more as a basis to discuss the general idea that I described in the cover letter. I should have made that clearer. > searching through until we either: > - find that the first rate in the table is too high I could see that I could add two steps in the beginning, before the loop: - Take the first element and see if its rate is greater than the requested rate, if so immediatly return it - Take the last element and see if its rate is less than the requested rate, if so immediatly return it Is that what you mean? I'd have to run some simulations to see, if this is a real improvement, because we would need two additional rate calculations. Worst case would therefore be 2+log(n) calculations instead of log(n) and the code would be slightly more complicated in my opinion. But if we run this function with all possible parents rate (as suggested in the end of my cover letter) these two special cases could very well be often applicable. Thanks! > - find an exact rate What do you mean by "exact rate"? Do you mean a rate that matches the requested rate exactly. This is what the code is already trying to do. But, as this is not always possible, in cases where it does not find an exact match, it takes the closest match instead. > - go above the requested rate, then there's only two to compare: our > current rate and the previous one Sorry, you've lost me here. How would I go above the requested rate? You would have to do the binary search to find that rate, but then why not search the closest rate directly (as the code does) instead of searching the closest rate above the requested (as you proposed). I feel like either one of us is missing something. :) > This should massively simplify this function and would still work with > a binary search. Sidenote, we could store best_index instead of best_n, best_k, best_m, but for the first iteration I tried to keep it as close as possible to the original ccu_nkm_find_best() function. > >> + if (rate < tmp_rate) >> + end =3D mid - 1; >> + else >> + start =3D mid + 1; >> + } >> + >> +out: >> + nkm->n =3D best_n; >> + nkm->k =3D best_k; >> + nkm->m =3D best_m; >> + >> + return best_rate; >> +} >> + >> static void ccu_nkm_disable(struct clk_hw *hw) >> { >> struct ccu_nkm *nkm =3D hw_to_ccu_nkm(hw); >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_n= km.h >> index 6601defb3f38..fa5551724921 100644 >> --- a/drivers/clk/sunxi-ng/ccu_nkm.h >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h >> @@ -12,6 +12,30 @@ >> #include "ccu_div.h" >> #include "ccu_mult.h" >> >> +struct clk_nkm_combo { >> + u8 n; >> + u8 k; >> + u8 m; >> +}; >> + >> +/** >> + * struct clk_nkm_table - Table of all meaningful combinations for n, k= , and m >> + * >> + * @num: Number of entries in the table >> + * @combos: Array of combos (of size num) that are supported by this cl= ock. >> + * >> + * This table shall contain all meaningful combinations of n, k, and m.= That >> + * means that combinations that result in the same clock rate shall onl= y be >> + * listed once. For example, if both >> + * { .n =3D 1, .k =3D 2, .m =3D 2} and { .n =3D 2, .k =3D 2, .m =3D 4} >> + * are valid values for n, k, and m, only one of them would be allowed = because >> + * both result in a factor of 1.0. >> + */ >> +struct clk_nkm_table { >> + size_t num; >> + struct clk_nkm_combo *combos; > > Should this be a "flex" array, i.e. > > struct clk_nkm_combo combos[] Thanks, noted. I'll look into that once we have an agreement on the general concept. I think it depends on the fact if we want to use values that have been calculated off-line (i.e. prior to compilation) or if we want to create the table at run-time (i.e. when needed) using kmalloc. See my alternate proposals in the cover letter for details. I'll need to check if the run-time approach works with "flex" arrays. Thanks, Frank > >> +}; >> + >> /* >> * struct ccu_nkm - Definition of an N-K-M clock >> * > > Thanks, 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 3FE4DC77B7C for ; Sun, 28 May 2023 10:10:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:In-reply-to: Date:Subject:Cc:To:From:References:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=k7gkRHnCF1aKSV+j1ipaig6oPyTumNlap5+40hRamqQ=; b=b5wPs2fUybuWoc Ufh9ExFzP1qLaYpewEMIIGNEHAc13Ukde/aMdJYuHgOAhE3/H1hvP4h/VXr4EQn5j41iS361b4Igv UE0Ogzq/uozzJECukge2WynfiAq4p/nrxLembeJ2moV4mByXz2mvzOXUeBavYyEI7m4E+EGtArfUe f8ffe9KEDZq1uJ29yIDAB1hkPh+yjo387Qsz5TIvUSP+9MIxaURhPoOoUiUXt8gA01qPUGsxQ4Xvw efdJzksrVVI7t+tSLaGLhhLOZFrccmoPf1ZyhIcMGvCx9b9vAt87ODcLRlG1cMF1+BFsjXtOyoiD0 wSR4ABC6V05ZHdj3KUrg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q3DLz-007KL1-01; Sun, 28 May 2023 10:10:23 +0000 Received: from mout-p-202.mailbox.org ([80.241.56.172]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q3DLv-007KK8-1Q for linux-arm-kernel@lists.infradead.org; Sun, 28 May 2023 10:10:21 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4QTZCg2x5sz9sbf; Sun, 28 May 2023 12:10:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oltmanns.dev; s=MBO0001; t=1685268607; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7ecNLW5aHDmQUNWlbObUxJA9/xvuYkyqh/+NvM+Nhxg=; b=zMEdO4IjgGb158eTzzQZZnLzSITWQoQMH1N3+CqXcStzA+XStYm3cHRQjbgVFk4CpmNYm5 6BY3UfkEQvcLQgTaH7Zp6gbKKOXvCqER8/oYKlt7eTPj39A9e4JEAUtdKK1aS1wKvebmPB MQx8WLTbb1TczJMmmUSIgb86mSwHqlQTUbJ1zw1DjsFqggfKP1p9X7Cw9QzJGXkx6Vzr1/ /JX0jkYrQ/9IqnwFuVn0L0QnTUSK5VkAmYemxVczCLHOlwKnlHFB/gU7owX+b0Q0PAYqeR qwYsBUpR5WQ9barq+0iPVgd9inUHdjE1HjSOdMoG6iUWNiy7gR30Xa/m0WDGcA== References: <20230527132747.83196-1-frank@oltmanns.dev> <20230527132747.83196-3-frank@oltmanns.dev> From: Frank Oltmanns To: Julian Calaby Cc: linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@lists.linux.dev, Andre Przywara , Chen-Yu Tsai , Icenowy Zheng , Jernej Skrabec , Maxime Ripard , Michael Turquette , Rob Herring , Samuel Holland , Stephen Boyd Subject: Re: [RFC PATCH 2/3] clk: sunxi-ng: Implement precalculated NKM rate selection Date: Sun, 28 May 2023 11:12:19 +0200 In-reply-to: Message-ID: <87sfbgwyvp.fsf@oltmanns.dev> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4QTZCg2x5sz9sbf X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230528_031019_687944_2AB31E60 X-CRM114-Status: GOOD ( 38.99 ) 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 SGkgSnVsaWFuLAoKT24gMjAyMy0wNS0yOCBhdCAwOToxOTozNiArMTAwMCwgSnVsaWFuIENhbGFi eSA8anVsaWFuLmNhbGFieUBnbWFpbC5jb20+IHdyb3RlOgo+IEhpIEZyYW5rLAo+Cj4gT24gU2F0 LCBNYXkgMjcsIDIwMjMgYXQgMTE6MzfigK9QTSBGcmFuayBPbHRtYW5ucyA8ZnJhbmtAb2x0bWFu bnMuZGV2PiB3cm90ZToKPj4KPj4gQWRkIGEgbmV3IHByZWNhbGN1bGF0aW9uIG1ldGhvZCBmb3Ig TktNIGNsb2NrIHJhdGUgc2VsZWN0aW9uIGluIHRoZQo+PiBzdW54aS1uZyBjbG9jayBkcml2ZXIu IEludHJvZHVjZSBjY3VfbmttX2ZpbmRfYmVzdF9wcmVjYWxjIHdoaWNoIHVzZXMgYQo+PiBwcmVj YWxjdWxhdGVkIHRhYmxlIG9mIHZhbGlkIE5LTSBjb21iaW5hdGlvbnMgKHN0cnVjdCBjbGtfbmtt X3RhYmxlIGFuZAo+PiBzdHJ1Y3QgY2xrX25rbV9jb21ibykgdG8gZmluZCB0aGUgYmVzdCByYXRl LiBUaGlzIGFwcHJvYWNoIHByb3ZpZGVzCj4+IGZhc3RlciByYXRlIHNlbGVjdGlvbiBieSBzZWFy Y2hpbmcgYSB0YWJsZSBvZiB2YWxpZCBjb21iaW5hdGlvbnMgcmF0aGVyCj4+IHRoYW4gY2FsY3Vs YXRpbmcgZm9yIGFsbCBwb3NzaWJsZSBjb21iaW5hdGlvbnMuCj4+Cj4+IFRoZSB0YWJsZSBvZiBO S00gY29tYmluYXRpb25zIG5lZWRzIHRvIGJlIGluaXRpYWxpemVkIHdpdGggbWVhbmluZ2Z1bAo+ PiBjb21iaW5hdGlvbnMgb25seSwgaS5lLiByZW1vdmluZyByZWR1bmRhbnQgY29tYmluYXRpb25z IHRoYXQgcmVzdWx0IGluCj4+IHRoZSBzYW1lIHJhdGUuCj4+Cj4+IEtlZXAgdGhlIGV4aXN0aW5n IGNjdV9ua21fZmluZF9iZXN0IGZ1bmN0aW9uIGluIHBsYWNlIGFuZCB1c2UgaXQgYXMgYQo+PiBm YWxsYmFjayBpZiBubyBwcmVjYWxjdWxhdGVkIHRhYmxlIGlzIHByb3ZpZGVkLgo+Pgo+PiBTaWdu ZWQtb2ZmLWJ5OiBGcmFuayBPbHRtYW5ucyA8ZnJhbmtAb2x0bWFubnMuZGV2Pgo+PiAtLS0KPj4g IGRyaXZlcnMvY2xrL3N1bnhpLW5nL2NjdV9ua20uYyB8IDg0ICsrKysrKysrKysrKysrKysrKysr KysrKysrKy0tLS0tLS0KPj4gIGRyaXZlcnMvY2xrL3N1bnhpLW5nL2NjdV9ua20uaCB8IDI2ICsr KysrKysrKysrCj4+ICAyIGZpbGVzIGNoYW5nZWQsIDk0IGluc2VydGlvbnMoKyksIDE2IGRlbGV0 aW9ucygtKQo+Pgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvc3VueGktbmcvY2N1X25rbS5j IGIvZHJpdmVycy9jbGsvc3VueGktbmcvY2N1X25rbS5jCj4+IGluZGV4IDk0ZDJhODM5OTJiMi4u OTY1MmY2ZGYxN2JkIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2Nsay9zdW54aS1uZy9jY3Vfbmtt LmMKPj4gKysrIGIvZHJpdmVycy9jbGsvc3VueGktbmcvY2N1X25rbS5jCj4+IEBAIC01NCw2ICs1 NCw0OSBAQCBzdGF0aWMgdW5zaWduZWQgbG9uZyBjY3VfbmttX2ZpbmRfYmVzdCh1bnNpZ25lZCBs b25nIHBhcmVudCwgdW5zaWduZWQgbG9uZyByYXRlLAo+PiAgICAgICAgIHJldHVybiBiZXN0X3Jh dGU7Cj4+ICB9Cj4+Cj4+ICtzdGF0aWMgdW5zaWduZWQgbG9uZyBjY3VfbmttX2ZpbmRfYmVzdF9w cmVjYWxjKHVuc2lnbmVkIGxvbmcgcGFyZW50LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgcmF0ZSwKPj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX2NjdV9ua20gKm5rbSwK Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qg Y2xrX25rbV90YWJsZSAqdGFibGUpCj4+ICt7Cj4+ICsgICAgICAgdW5zaWduZWQgbG9uZyBiZXN0 X3JhdGUgPSAwLCBiZXN0X2RpZmYgPSBVTE9OR19NQVg7Cj4+ICsgICAgICAgdW5zaWduZWQgbG9u ZyBiZXN0X24gPSAwLCBiZXN0X2sgPSAwLCBiZXN0X20gPSAwOwo+PiArICAgICAgIGludCBzdGFy dCA9IDAsIGVuZCA9IHRhYmxlLT5udW0gLSAxLCBtaWQ7Cj4+ICsKPj4gKyAgICAgICB3aGlsZSAo c3RhcnQgPD0gZW5kKSB7Cj4+ICsgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIHRtcF9yYXRl Owo+PiArICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyB0bXBfZGlmZjsKPj4gKwo+PiArICAg ICAgICAgICAgICAgbWlkID0gKHN0YXJ0ICsgZW5kKSAvIDI7Cj4+ICsKPj4gKyAgICAgICAgICAg ICAgIHRtcF9yYXRlID0gcGFyZW50ICogdGFibGUtPmNvbWJvc1ttaWRdLm4gKiB0YWJsZS0+Y29t Ym9zW21pZF0uayAvCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlLT5jb21ib3Nb bWlkXS5tOwo+PiArCj4+ICsgICAgICAgICAgICAgICB0bXBfZGlmZiA9IGFicyhyYXRlIC0gdG1w X3JhdGUpOwo+PiArCj4+ICsgICAgICAgICAgICAgICBpZiAodG1wX2RpZmYgPCBiZXN0X2RpZmYp IHsKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgYmVzdF9yYXRlID0gdG1wX3JhdGU7Cj4+ICsg ICAgICAgICAgICAgICAgICAgICAgIGJlc3RfZGlmZiA9IHRtcF9kaWZmOwo+PiArICAgICAgICAg ICAgICAgICAgICAgICBiZXN0X24gPSB0YWJsZS0+Y29tYm9zW21pZF0ubjsKPj4gKyAgICAgICAg ICAgICAgICAgICAgICAgYmVzdF9rID0gdGFibGUtPmNvbWJvc1ttaWRdLms7Cj4+ICsgICAgICAg ICAgICAgICAgICAgICAgIGJlc3RfbSA9IHRhYmxlLT5jb21ib3NbbWlkXS5tOwo+PiArICAgICAg ICAgICAgICAgICAgICAgICBpZiAoYmVzdF9kaWZmID09IDApCj4+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgZ290byBvdXQ7Cj4+ICsgICAgICAgICAgICAgICB9Cj4KClRoYW5rIHlv dSBmb3IgeW91ciBmZWVkYmFjayEKCkluIG15IHByb3Bvc2FsLCB0aGUgY29kZSBwZXJmb3JtcyBh IGJpbmFyeSBzZWFyY2ggYnkKIDEuIHRha2luZyB0aGUgZWxlbWVudCBpbiB0aGUgbWlkZGxlICht aWQpCiAyLiBjYWxjdWxhdGluZyB0aGUgcmF0ZSBvZiB0aGUgZWxlbWVudCAodG1wX3JhdGUpCiAz LiBjYWxjdWxhdGluZyB0aGUgZGlmZmVyZW5jZSB0byB0aGUgcmVxdWVzdGVkIHJhdGUgKHRtcF9k aWZmKQogNC4gaWYgdGhlIGRpZmYgaXMgYmV0dGVyIHRoYW4gdGhlIGJlc3RfZGlmZiBtYWtpbmcg aXQgdGhlIG5ldyBiZXN0CiAgICBuLWstbS1jb21ibyAodGhlIGlmIGJsb2NrKQoKPiBJZiB0aGUg dGFibGUgd2FzIHNvcnRlZCBieSBuICogayAvIG0sIHRoaXMgY291bGQganVzdCBiZSBhIHByb2Nl c3Mgb2YKClBsZWFzZSBub3RlLCB0aGUgdGFibGUgYWxyZWFkeSBoYXMgdG8gYmUgc29ydGVkIGZv ciB0aGUgZnVuY3Rpb24gdG8Kd29yaywgYXMgaXMgdGhlIG5hdHVyZSBvZiBhIGJpbmFyeSBzZWFy Y2guIEkgc2hvdWxkIGRlZmluaXRlbHkgYWRkCmNvbW1lbnRzLiBJJ20gc29ycnksIHRoZSBjb2Rl IHdhcyBpbnRlbmRlZCBtb3JlIGFzIGEgYmFzaXMgdG8gZGlzY3Vzcwp0aGUgZ2VuZXJhbCBpZGVh IHRoYXQgSSBkZXNjcmliZWQgaW4gdGhlIGNvdmVyIGxldHRlci4gSSBzaG91bGQgaGF2ZQptYWRl IHRoYXQgY2xlYXJlci4KCj4gc2VhcmNoaW5nIHRocm91Z2ggdW50aWwgd2UgZWl0aGVyOgo+IC0g ZmluZCB0aGF0IHRoZSBmaXJzdCByYXRlIGluIHRoZSB0YWJsZSBpcyB0b28gaGlnaAoKSSBjb3Vs ZCBzZWUgdGhhdCBJIGNvdWxkIGFkZCB0d28gc3RlcHMgaW4gdGhlIGJlZ2lubmluZywgYmVmb3Jl IHRoZSBsb29wOgogLSBUYWtlIHRoZSBmaXJzdCBlbGVtZW50IGFuZCBzZWUgaWYgaXRzIHJhdGUg aXMgZ3JlYXRlciB0aGFuIHRoZQogICByZXF1ZXN0ZWQgcmF0ZSwgaWYgc28gaW1tZWRpYXRseSBy ZXR1cm4gaXQKIC0gVGFrZSB0aGUgbGFzdCBlbGVtZW50IGFuZCBzZWUgaWYgaXRzIHJhdGUgaXMg bGVzcyB0aGFuIHRoZSByZXF1ZXN0ZWQKICAgcmF0ZSwgaWYgc28gaW1tZWRpYXRseSByZXR1cm4g aXQKCklzIHRoYXQgd2hhdCB5b3UgbWVhbj8gSSdkIGhhdmUgdG8gcnVuIHNvbWUgc2ltdWxhdGlv bnMgdG8gc2VlLCBpZiB0aGlzCmlzIGEgcmVhbCBpbXByb3ZlbWVudCwgYmVjYXVzZSB3ZSB3b3Vs ZCBuZWVkIHR3byBhZGRpdGlvbmFsIHJhdGUKY2FsY3VsYXRpb25zLiBXb3JzdCBjYXNlIHdvdWxk IHRoZXJlZm9yZSBiZSAyK2xvZyhuKSBjYWxjdWxhdGlvbnMKaW5zdGVhZCBvZiBsb2cobikgYW5k IHRoZSBjb2RlIHdvdWxkIGJlIHNsaWdodGx5IG1vcmUgY29tcGxpY2F0ZWQgaW4gbXkKb3Bpbmlv bi4gQnV0IGlmIHdlIHJ1biB0aGlzIGZ1bmN0aW9uIHdpdGggYWxsIHBvc3NpYmxlIHBhcmVudHMg cmF0ZSAoYXMKc3VnZ2VzdGVkIGluIHRoZSBlbmQgb2YgbXkgY292ZXIgbGV0dGVyKSB0aGVzZSB0 d28gc3BlY2lhbCBjYXNlcyBjb3VsZAp2ZXJ5IHdlbGwgYmUgb2Z0ZW4gYXBwbGljYWJsZS4gVGhh bmtzIQoKPiAtIGZpbmQgYW4gZXhhY3QgcmF0ZQoKV2hhdCBkbyB5b3UgbWVhbiBieSAiZXhhY3Qg cmF0ZSI/IERvIHlvdSBtZWFuIGEgcmF0ZSB0aGF0IG1hdGNoZXMgdGhlCnJlcXVlc3RlZCByYXRl IGV4YWN0bHkuIFRoaXMgaXMgd2hhdCB0aGUgY29kZSBpcyBhbHJlYWR5IHRyeWluZyB0byBkby4K QnV0LCBhcyB0aGlzIGlzIG5vdCBhbHdheXMgcG9zc2libGUsIGluIGNhc2VzIHdoZXJlIGl0IGRv ZXMgbm90IGZpbmQgYW4KZXhhY3QgbWF0Y2gsIGl0IHRha2VzIHRoZSBjbG9zZXN0IG1hdGNoIGlu c3RlYWQuCgo+IC0gZ28gYWJvdmUgdGhlIHJlcXVlc3RlZCByYXRlLCB0aGVuIHRoZXJlJ3Mgb25s eSB0d28gdG8gY29tcGFyZTogb3VyCj4gY3VycmVudCByYXRlIGFuZCB0aGUgcHJldmlvdXMgb25l CgpTb3JyeSwgeW91J3ZlIGxvc3QgbWUgaGVyZS4gSG93IHdvdWxkIEkgZ28gYWJvdmUgdGhlIHJl cXVlc3RlZCByYXRlPyBZb3UKd291bGQgaGF2ZSB0byBkbyB0aGUgYmluYXJ5IHNlYXJjaCB0byBm aW5kIHRoYXQgcmF0ZSwgYnV0IHRoZW4gd2h5IG5vdApzZWFyY2ggdGhlIGNsb3Nlc3QgcmF0ZSBk aXJlY3RseSAoYXMgdGhlIGNvZGUgZG9lcykgaW5zdGVhZCBvZiBzZWFyY2hpbmcKdGhlIGNsb3Nl c3QgcmF0ZSBhYm92ZSB0aGUgcmVxdWVzdGVkIChhcyB5b3UgcHJvcG9zZWQpLiBJIGZlZWwgbGlr ZQplaXRoZXIgb25lIG9mIHVzIGlzIG1pc3Npbmcgc29tZXRoaW5nLiA6KQoKPiBUaGlzIHNob3Vs ZCBtYXNzaXZlbHkgc2ltcGxpZnkgdGhpcyBmdW5jdGlvbiBhbmQgd291bGQgc3RpbGwgd29yayB3 aXRoCj4gYSBiaW5hcnkgc2VhcmNoLgoKU2lkZW5vdGUsIHdlIGNvdWxkIHN0b3JlIGJlc3RfaW5k ZXggaW5zdGVhZCBvZiBiZXN0X24sIGJlc3RfaywgYmVzdF9tLApidXQgZm9yIHRoZSBmaXJzdCBp dGVyYXRpb24gSSB0cmllZCB0byBrZWVwIGl0IGFzIGNsb3NlIGFzIHBvc3NpYmxlIHRvCnRoZSBv cmlnaW5hbCBjY3VfbmttX2ZpbmRfYmVzdCgpIGZ1bmN0aW9uLgoKPgo+PiArICAgICAgICAgICAg ICAgaWYgKHJhdGUgPCB0bXBfcmF0ZSkKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgZW5kID0g bWlkIC0gMTsKPj4gKyAgICAgICAgICAgICAgIGVsc2UKPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgc3RhcnQgPSBtaWQgKyAxOwo+PiArICAgICAgIH0KPj4gKwo+PiArb3V0Ogo+PiArICAgICAg IG5rbS0+biA9IGJlc3RfbjsKPj4gKyAgICAgICBua20tPmsgPSBiZXN0X2s7Cj4+ICsgICAgICAg bmttLT5tID0gYmVzdF9tOwo+PiArCj4+ICsgICAgICAgcmV0dXJuIGJlc3RfcmF0ZTsKPj4gK30K Pj4gKwo+PiAgc3RhdGljIHZvaWQgY2N1X25rbV9kaXNhYmxlKHN0cnVjdCBjbGtfaHcgKmh3KQo+ PiAgewo+PiAgICAgICAgIHN0cnVjdCBjY3VfbmttICpua20gPSBod190b19jY3VfbmttKGh3KTsK Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2xrL3N1bnhpLW5nL2NjdV9ua20uaCBiL2RyaXZlcnMv Y2xrL3N1bnhpLW5nL2NjdV9ua20uaAo+PiBpbmRleCA2NjAxZGVmYjNmMzguLmZhNTU1MTcyNDky MSAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9jbGsvc3VueGktbmcvY2N1X25rbS5oCj4+ICsrKyBi L2RyaXZlcnMvY2xrL3N1bnhpLW5nL2NjdV9ua20uaAo+PiBAQCAtMTIsNiArMTIsMzAgQEAKPj4g ICNpbmNsdWRlICJjY3VfZGl2LmgiCj4+ICAjaW5jbHVkZSAiY2N1X211bHQuaCIKPj4KPj4gK3N0 cnVjdCBjbGtfbmttX2NvbWJvIHsKPj4gKyAgICAgICB1OCAgICAgIG47Cj4+ICsgICAgICAgdTgg ICAgICBrOwo+PiArICAgICAgIHU4ICAgICAgbTsKPj4gK307Cj4+ICsKPj4gKy8qKgo+PiArICog c3RydWN0IGNsa19ua21fdGFibGUgLSBUYWJsZSBvZiBhbGwgbWVhbmluZ2Z1bCBjb21iaW5hdGlv bnMgZm9yIG4sIGssIGFuZCBtCj4+ICsgKgo+PiArICogQG51bTogTnVtYmVyIG9mIGVudHJpZXMg aW4gdGhlIHRhYmxlCj4+ICsgKiBAY29tYm9zOiBBcnJheSBvZiBjb21ib3MgKG9mIHNpemUgbnVt KSB0aGF0IGFyZSBzdXBwb3J0ZWQgYnkgdGhpcyBjbG9jay4KPj4gKyAqCj4+ICsgKiBUaGlzIHRh YmxlIHNoYWxsIGNvbnRhaW4gYWxsIG1lYW5pbmdmdWwgY29tYmluYXRpb25zIG9mIG4sIGssIGFu ZCBtLiBUaGF0Cj4+ICsgKiBtZWFucyB0aGF0IGNvbWJpbmF0aW9ucyB0aGF0IHJlc3VsdCBpbiB0 aGUgc2FtZSBjbG9jayByYXRlIHNoYWxsIG9ubHkgYmUKPj4gKyAqIGxpc3RlZCBvbmNlLiBGb3Ig ZXhhbXBsZSwgaWYgYm90aAo+PiArICogeyAubiA9IDEsIC5rID0gMiwgLm0gPSAyfSBhbmQgIHsg Lm4gPSAyLCAuayA9IDIsIC5tID0gNH0KPj4gKyAqIGFyZSB2YWxpZCB2YWx1ZXMgZm9yIG4sIGss IGFuZCBtLCBvbmx5IG9uZSBvZiB0aGVtIHdvdWxkIGJlIGFsbG93ZWQgYmVjYXVzZQo+PiArICog Ym90aCByZXN1bHQgaW4gYSBmYWN0b3Igb2YgMS4wLgo+PiArICovCj4+ICtzdHJ1Y3QgY2xrX25r bV90YWJsZSB7Cj4+ICsgICAgICAgc2l6ZV90ICAgICAgICAgICAgICAgICAgbnVtOwo+PiArICAg ICAgIHN0cnVjdCBjbGtfbmttX2NvbWJvICAgICpjb21ib3M7Cj4KPiBTaG91bGQgdGhpcyBiZSBh ICJmbGV4IiBhcnJheSwgaS5lLgo+Cj4gc3RydWN0IGNsa19ua21fY29tYm8gY29tYm9zW10KClRo YW5rcywgbm90ZWQuIEknbGwgbG9vayBpbnRvIHRoYXQgb25jZSB3ZSBoYXZlIGFuIGFncmVlbWVu dCBvbiB0aGUKZ2VuZXJhbCBjb25jZXB0LiBJIHRoaW5rIGl0IGRlcGVuZHMgb24gdGhlIGZhY3Qg aWYgd2Ugd2FudCB0byB1c2UgdmFsdWVzCnRoYXQgaGF2ZSBiZWVuIGNhbGN1bGF0ZWQgb2ZmLWxp bmUgKGkuZS4gcHJpb3IgdG8gY29tcGlsYXRpb24pIG9yIGlmIHdlCndhbnQgdG8gY3JlYXRlIHRo ZSB0YWJsZSBhdCBydW4tdGltZSAoaS5lLiB3aGVuIG5lZWRlZCkgdXNpbmcga21hbGxvYy4KU2Vl IG15IGFsdGVybmF0ZSBwcm9wb3NhbHMgaW4gdGhlIGNvdmVyIGxldHRlciBmb3IgZGV0YWlscy4g SSdsbCBuZWVkIHRvCmNoZWNrIGlmIHRoZSBydW4tdGltZSBhcHByb2FjaCB3b3JrcyB3aXRoICJm bGV4IiBhcnJheXMuCgpUaGFua3MsCiAgRnJhbmsKCj4KPj4gK307Cj4+ICsKPj4gIC8qCj4+ICAg KiBzdHJ1Y3QgY2N1X25rbSAtIERlZmluaXRpb24gb2YgYW4gTi1LLU0gY2xvY2sKPj4gICAqCj4K PiBUaGFua3MsCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmlu ZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1hcm0ta2VybmVsCg==