From mboxrd@z Thu Jan 1 00:00:00 1970 From: miquel.raynal@bootlin.com (Miquel Raynal) Date: Fri, 29 Jun 2018 20:20:46 +0200 Subject: [PATCH v3 06/17] irqchip/irq-mvebu-icu: switch to regmap In-Reply-To: <868t6xzf4u.wl-marc.zyngier@arm.com> References: <20180622151432.1566-1-miquel.raynal@bootlin.com> <20180622151432.1566-7-miquel.raynal@bootlin.com> <20180629172751.7404a531@xps13> <868t6xzf4u.wl-marc.zyngier@arm.com> Message-ID: <20180629202046.53c7b874@xps13> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Marc, Marc Zyngier wrote on Fri, 29 Jun 2018 18:17:21 +0100: > On Fri, 29 Jun 2018 16:27:51 +0100, > Miquel Raynal wrote: > > > > Hi Marc, > > > > Marc Zyngier wrote on Thu, 28 Jun 2018 13:05:05 > > +0100: > > > > > On 22/06/18 16:14, Miquel Raynal wrote: > > > > Before splitting the code to support multiple platform devices to > > > > be probed (one for the ICU, one per interrupt group), let's switch to > > > > regmap first by creating one in the ->probe(). > > > > > > What's the benefit of doing so? I assume that has to do with supporting > > > multiple devices that share an MMIO range? > > > > Yes, the ICU subnodes will share the same MMIO range. > > So, one MMIO range, shared by multiple devices managed by the same > driver. Why the complexity? Mmmmh... one point :) > > > > > > > > > > > > > > Signed-off-by: Miquel Raynal > > > > --- > > > > drivers/irqchip/irq-mvebu-icu.c | 45 +++++++++++++++++++++++++++-------------- > > > > 1 file changed, 30 insertions(+), 15 deletions(-) > > > > > > > > diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c > > > > index 0f2655d7f19e..3694c0d73c0d 100644 > > > > --- a/drivers/irqchip/irq-mvebu-icu.c > > > > +++ b/drivers/irqchip/irq-mvebu-icu.c > > > > @@ -18,6 +18,8 @@ > > > > #include > > > > #include > > > > #include > > > > +#include > > > > +#include > > > > > > > > #include > > > > > > > > @@ -38,7 +40,7 @@ > > > > > > > > struct mvebu_icu { > > > > struct irq_chip irq_chip; > > > > - void __iomem *base; > > > > + struct regmap *regmap; > > > > struct irq_domain *domain; > > > > struct device *dev; > > > > atomic_t initialized; > > > > @@ -56,10 +58,10 @@ static void mvebu_icu_init(struct mvebu_icu *icu, struct msi_msg *msg) > > > > return; > > > > > > > > /* Set Clear/Set ICU SPI message address in AP */ > > > > - writel_relaxed(msg[0].address_hi, icu->base + ICU_SETSPI_NSR_AH); > > > > - writel_relaxed(msg[0].address_lo, icu->base + ICU_SETSPI_NSR_AL); > > > > - writel_relaxed(msg[1].address_hi, icu->base + ICU_CLRSPI_NSR_AH); > > > > - writel_relaxed(msg[1].address_lo, icu->base + ICU_CLRSPI_NSR_AL); > > > > + regmap_write(icu->regmap, ICU_SETSPI_NSR_AH, msg[0].address_hi); > > > > + regmap_write(icu->regmap, ICU_SETSPI_NSR_AL, msg[0].address_lo); > > > > + regmap_write(icu->regmap, ICU_CLRSPI_NSR_AH, msg[1].address_hi); > > > > + regmap_write(icu->regmap, ICU_CLRSPI_NSR_AL, msg[1].address_lo); > > > > > > Isn't this a change in the way we write things to the MMIO registers? > > > You're now trading a writel_relaxed for a writel, plus some locking... > > > > Is the "writel_relaxed" -> "writel" thing really an issue? > > If you're happy with system-wide barriers (dsb sy) being issued, > synchronising unrelated accesses, and generally slowing down the whole > system in a completely unnecessary way, then there is absolutely no > issue whatsoever. Performance is completely overrated anyway, let's > embrace slow computing. 8-D > > > > > > > > > Talking about which: Are you always in a context where you can take that > > > lock? The bit of documentation I've just read seems to imply that the > > > default lock is a mutex. Is that always safe? My guess is that it isn't, > > > and any callback that can end-up here after having taken something like > > > the desc lock is going to blow in your face. > > > > > > Have you tried lockdep? > > > > Just did -- thanks for pointing it, it failed once the overheat > > interrupt fired. I'm not sure if it is because of the regmap-locking > > mechanism. There is definitely something to fix there, but I don't know > > what for now; I'll come back on it. > > Well, that's interesting: > > > [ 91.376666] mutex_lock_nested+0x1c/0x28 > > [ 91.380606] thermal_zone_get_temp+0x60/0x158 > > [ 91.384982] thermal_zone_device_update.part.4+0x34/0xe0 > > [ 91.390318] thermal_zone_device_update+0x28/0x38 > > [ 91.395043] armada_overheat_isr+0xb0/0xb8 > > [ 91.399159] __handle_irq_event_percpu+0x9c/0x128 > > [ 91.403883] handle_irq_event_percpu+0x34/0x88 > > [ 91.408346] handle_irq_event+0x48/0x78 > > [ 91.412201] handle_fasteoi_irq+0xa0/0x180 > > [ 91.416316] generic_handle_irq+0x24/0x38 > > [ 91.420346] mvebu_sei_handle_cascade_irq+0xc8/0x180 > > [ 91.425332] generic_handle_irq+0x24/0x38 > > [ 91.429360] __handle_domain_irq+0x5c/0xb8 > > [ 91.433473] gic_handle_irq+0x58/0xb0 > > [ 91.437151] el1_irq+0xb4/0x130 > > Taking a mutex in an interrupt handler is... great! On the other hand, > that armada_overheat_isr function doesn't seem to exist in 4.18-rc2, > so that's absolutely fine. I had no troubles with NSRs so I wanted to check with SEIs too. The only device using SEIs for now is this thermal driver which I just contributed, it is still under review. The ISR is making a thermal-core call to update on an overheat situation. This call is synchronous and the core checks for the current temperature, but first locks its tz->lock mutex, which is kind of bad in interrupt context. I just realized it. Sad. > > Nonetheless, regmap usage in this context is still suspect, and my gut > feeling is that you really don't need it at all. You are right on this and I probably over-looked at the initial problem. I'm pretty sure I can get rid of it as long as only one driver touches this MMIO region. Thanks for all your thoughts, I'll resend a version next week. Thank you very much, Miqu?l From mboxrd@z Thu Jan 1 00:00:00 1970 From: Miquel Raynal Subject: Re: [PATCH v3 06/17] irqchip/irq-mvebu-icu: switch to regmap Date: Fri, 29 Jun 2018 20:20:46 +0200 Message-ID: <20180629202046.53c7b874@xps13> References: <20180622151432.1566-1-miquel.raynal@bootlin.com> <20180622151432.1566-7-miquel.raynal@bootlin.com> <20180629172751.7404a531@xps13> <868t6xzf4u.wl-marc.zyngier@arm.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <868t6xzf4u.wl-marc.zyngier@arm.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Marc Zyngier Cc: Mark Rutland , Andrew Lunn , Jason Cooper , devicetree@vger.kernel.org, Antoine Tenart , Catalin Marinas , Gregory Clement , Haim Boot , Will Deacon , Maxime Chevallier , Nadav Haklai , Rob Herring , Thomas Petazzoni , Thomas Gleixner , Hanna Hawa , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth List-Id: devicetree@vger.kernel.org SGkgTWFyYywKCk1hcmMgWnluZ2llciA8bWFyYy56eW5naWVyQGFybS5jb20+IHdyb3RlIG9uIEZy aSwgMjkgSnVuIDIwMTggMTg6MTc6MjEKKzAxMDA6Cgo+IE9uIEZyaSwgMjkgSnVuIDIwMTggMTY6 Mjc6NTEgKzAxMDAsCj4gTWlxdWVsIFJheW5hbCA8bWlxdWVsLnJheW5hbEBib290bGluLmNvbT4g d3JvdGU6Cj4gPiAKPiA+IEhpIE1hcmMsCj4gPiAKPiA+IE1hcmMgWnluZ2llciA8bWFyYy56eW5n aWVyQGFybS5jb20+IHdyb3RlIG9uIFRodSwgMjggSnVuIDIwMTggMTM6MDU6MDUKPiA+ICswMTAw Ogo+ID4gICAKPiA+ID4gT24gMjIvMDYvMTggMTY6MTQsIE1pcXVlbCBSYXluYWwgd3JvdGU6ICAK PiA+ID4gPiBCZWZvcmUgc3BsaXR0aW5nIHRoZSBjb2RlIHRvIHN1cHBvcnQgbXVsdGlwbGUgcGxh dGZvcm0gZGV2aWNlcyB0bwo+ID4gPiA+IGJlIHByb2JlZCAob25lIGZvciB0aGUgSUNVLCBvbmUg cGVyIGludGVycnVwdCBncm91cCksIGxldCdzIHN3aXRjaCB0bwo+ID4gPiA+IHJlZ21hcCBmaXJz dCBieSBjcmVhdGluZyBvbmUgaW4gdGhlIC0+cHJvYmUoKS4gICAgCj4gPiA+IAo+ID4gPiBXaGF0 J3MgdGhlIGJlbmVmaXQgb2YgZG9pbmcgc28/IEkgYXNzdW1lIHRoYXQgaGFzIHRvIGRvIHdpdGgg c3VwcG9ydGluZwo+ID4gPiBtdWx0aXBsZSBkZXZpY2VzIHRoYXQgc2hhcmUgYW4gTU1JTyByYW5n ZT8gIAo+ID4gCj4gPiBZZXMsIHRoZSBJQ1Ugc3Vibm9kZXMgd2lsbCBzaGFyZSB0aGUgc2FtZSBN TUlPIHJhbmdlLiAgCj4gCj4gU28sIG9uZSBNTUlPIHJhbmdlLCBzaGFyZWQgYnkgbXVsdGlwbGUg ZGV2aWNlcyBtYW5hZ2VkIGJ5IHRoZSBzYW1lCj4gZHJpdmVyLiBXaHkgdGhlIGNvbXBsZXhpdHk/ CgpNbW1taC4uLiBvbmUgcG9pbnQgOikKCj4gCj4gPiAgIAo+ID4gPiAgIAo+ID4gPiA+IAo+ID4g PiA+IFNpZ25lZC1vZmYtYnk6IE1pcXVlbCBSYXluYWwgPG1pcXVlbC5yYXluYWxAYm9vdGxpbi5j b20+Cj4gPiA+ID4gLS0tCj4gPiA+ID4gIGRyaXZlcnMvaXJxY2hpcC9pcnEtbXZlYnUtaWN1LmMg fCA0NSArKysrKysrKysrKysrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLQo+ID4gPiA+ICAx IGZpbGUgY2hhbmdlZCwgMzAgaW5zZXJ0aW9ucygrKSwgMTUgZGVsZXRpb25zKC0pCj4gPiA+ID4g Cj4gPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaXJxY2hpcC9pcnEtbXZlYnUtaWN1LmMgYi9k cml2ZXJzL2lycWNoaXAvaXJxLW12ZWJ1LWljdS5jCj4gPiA+ID4gaW5kZXggMGYyNjU1ZDdmMTll Li4zNjk0YzBkNzNjMGQgMTAwNjQ0Cj4gPiA+ID4gLS0tIGEvZHJpdmVycy9pcnFjaGlwL2lycS1t dmVidS1pY3UuYwo+ID4gPiA+ICsrKyBiL2RyaXZlcnMvaXJxY2hpcC9pcnEtbXZlYnUtaWN1LmMK PiA+ID4gPiBAQCAtMTgsNiArMTgsOCBAQAo+ID4gPiA+ICAjaW5jbHVkZSA8bGludXgvb2ZfaXJx Lmg+Cj4gPiA+ID4gICNpbmNsdWRlIDxsaW51eC9vZl9wbGF0Zm9ybS5oPgo+ID4gPiA+ICAjaW5j bHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9y ZWdtYXAuaD4KPiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L21mZC9zeXNjb24uaD4KPiA+ID4gPiAg Cj4gPiA+ID4gICNpbmNsdWRlIDxkdC1iaW5kaW5ncy9pbnRlcnJ1cHQtY29udHJvbGxlci9tdmVi dS1pY3UuaD4KPiA+ID4gPiAgCj4gPiA+ID4gQEAgLTM4LDcgKzQwLDcgQEAKPiA+ID4gPiAgCj4g PiA+ID4gIHN0cnVjdCBtdmVidV9pY3Ugewo+ID4gPiA+ICAJc3RydWN0IGlycV9jaGlwIGlycV9j aGlwOwo+ID4gPiA+IC0Jdm9pZCBfX2lvbWVtICpiYXNlOwo+ID4gPiA+ICsJc3RydWN0IHJlZ21h cCAqcmVnbWFwOwo+ID4gPiA+ICAJc3RydWN0IGlycV9kb21haW4gKmRvbWFpbjsKPiA+ID4gPiAg CXN0cnVjdCBkZXZpY2UgKmRldjsKPiA+ID4gPiAgCWF0b21pY190IGluaXRpYWxpemVkOwo+ID4g PiA+IEBAIC01NiwxMCArNTgsMTAgQEAgc3RhdGljIHZvaWQgbXZlYnVfaWN1X2luaXQoc3RydWN0 IG12ZWJ1X2ljdSAqaWN1LCBzdHJ1Y3QgbXNpX21zZyAqbXNnKQo+ID4gPiA+ICAJCXJldHVybjsK PiA+ID4gPiAgCj4gPiA+ID4gIAkvKiBTZXQgQ2xlYXIvU2V0IElDVSBTUEkgbWVzc2FnZSBhZGRy ZXNzIGluIEFQICovCj4gPiA+ID4gLQl3cml0ZWxfcmVsYXhlZChtc2dbMF0uYWRkcmVzc19oaSwg aWN1LT5iYXNlICsgSUNVX1NFVFNQSV9OU1JfQUgpOwo+ID4gPiA+IC0Jd3JpdGVsX3JlbGF4ZWQo bXNnWzBdLmFkZHJlc3NfbG8sIGljdS0+YmFzZSArIElDVV9TRVRTUElfTlNSX0FMKTsKPiA+ID4g PiAtCXdyaXRlbF9yZWxheGVkKG1zZ1sxXS5hZGRyZXNzX2hpLCBpY3UtPmJhc2UgKyBJQ1VfQ0xS U1BJX05TUl9BSCk7Cj4gPiA+ID4gLQl3cml0ZWxfcmVsYXhlZChtc2dbMV0uYWRkcmVzc19sbywg aWN1LT5iYXNlICsgSUNVX0NMUlNQSV9OU1JfQUwpOwo+ID4gPiA+ICsJcmVnbWFwX3dyaXRlKGlj dS0+cmVnbWFwLCBJQ1VfU0VUU1BJX05TUl9BSCwgbXNnWzBdLmFkZHJlc3NfaGkpOwo+ID4gPiA+ ICsJcmVnbWFwX3dyaXRlKGljdS0+cmVnbWFwLCBJQ1VfU0VUU1BJX05TUl9BTCwgbXNnWzBdLmFk ZHJlc3NfbG8pOwo+ID4gPiA+ICsJcmVnbWFwX3dyaXRlKGljdS0+cmVnbWFwLCBJQ1VfQ0xSU1BJ X05TUl9BSCwgbXNnWzFdLmFkZHJlc3NfaGkpOwo+ID4gPiA+ICsJcmVnbWFwX3dyaXRlKGljdS0+ cmVnbWFwLCBJQ1VfQ0xSU1BJX05TUl9BTCwgbXNnWzFdLmFkZHJlc3NfbG8pOyAgICAKPiA+ID4g Cj4gPiA+IElzbid0IHRoaXMgYSBjaGFuZ2UgaW4gdGhlIHdheSB3ZSB3cml0ZSB0aGluZ3MgdG8g dGhlIE1NSU8gcmVnaXN0ZXJzPwo+ID4gPiBZb3UncmUgbm93IHRyYWRpbmcgYSB3cml0ZWxfcmVs YXhlZCBmb3IgYSB3cml0ZWwsIHBsdXMgc29tZSBsb2NraW5nLi4uICAKPiA+IAo+ID4gSXMgdGhl ICJ3cml0ZWxfcmVsYXhlZCIgLT4gIndyaXRlbCIgdGhpbmcgcmVhbGx5IGFuIGlzc3VlPyAgCj4g Cj4gSWYgeW91J3JlIGhhcHB5IHdpdGggc3lzdGVtLXdpZGUgYmFycmllcnMgKGRzYiBzeSkgYmVp bmcgaXNzdWVkLAo+IHN5bmNocm9uaXNpbmcgdW5yZWxhdGVkIGFjY2Vzc2VzLCBhbmQgZ2VuZXJh bGx5IHNsb3dpbmcgZG93biB0aGUgd2hvbGUKPiBzeXN0ZW0gaW4gYSBjb21wbGV0ZWx5IHVubmVj ZXNzYXJ5IHdheSwgdGhlbiB0aGVyZSBpcyBhYnNvbHV0ZWx5IG5vCj4gaXNzdWUgd2hhdHNvZXZl ci4gUGVyZm9ybWFuY2UgaXMgY29tcGxldGVseSBvdmVycmF0ZWQgYW55d2F5LCBsZXQncwo+IGVt YnJhY2Ugc2xvdyBjb21wdXRpbmcuCgo4LUQKCj4gCj4gPiAgIAo+ID4gPiAKPiA+ID4gVGFsa2lu ZyBhYm91dCB3aGljaDogQXJlIHlvdSBhbHdheXMgaW4gYSBjb250ZXh0IHdoZXJlIHlvdSBjYW4g dGFrZSB0aGF0Cj4gPiA+IGxvY2s/IFRoZSBiaXQgb2YgZG9jdW1lbnRhdGlvbiBJJ3ZlIGp1c3Qg cmVhZCBzZWVtcyB0byBpbXBseSB0aGF0IHRoZQo+ID4gPiBkZWZhdWx0IGxvY2sgaXMgYSBtdXRl eC4gSXMgdGhhdCBhbHdheXMgc2FmZT8gTXkgZ3Vlc3MgaXMgdGhhdCBpdCBpc24ndCwKPiA+ID4g YW5kIGFueSBjYWxsYmFjayB0aGF0IGNhbiBlbmQtdXAgaGVyZSBhZnRlciBoYXZpbmcgdGFrZW4g c29tZXRoaW5nIGxpa2UKPiA+ID4gdGhlIGRlc2MgbG9jayBpcyBnb2luZyB0byBibG93IGluIHlv dXIgZmFjZS4KPiA+ID4gCj4gPiA+IEhhdmUgeW91IHRyaWVkIGxvY2tkZXA/ICAKPiA+IAo+ID4g SnVzdCBkaWQgLS0gdGhhbmtzIGZvciBwb2ludGluZyBpdCwgaXQgZmFpbGVkIG9uY2UgdGhlIG92 ZXJoZWF0Cj4gPiBpbnRlcnJ1cHQgZmlyZWQuIEknbSBub3Qgc3VyZSBpZiBpdCBpcyBiZWNhdXNl IG9mIHRoZSByZWdtYXAtbG9ja2luZwo+ID4gbWVjaGFuaXNtLiBUaGVyZSBpcyBkZWZpbml0ZWx5 IHNvbWV0aGluZyB0byBmaXggdGhlcmUsIGJ1dCBJIGRvbid0IGtub3cKPiA+IHdoYXQgZm9yIG5v dzsgSSdsbCBjb21lIGJhY2sgb24gaXQuICAKPiAKPiBXZWxsLCB0aGF0J3MgaW50ZXJlc3Rpbmc6 Cj4gCj4gPiBbICAgOTEuMzc2NjY2XSAgbXV0ZXhfbG9ja19uZXN0ZWQrMHgxYy8weDI4Cj4gPiBb ICAgOTEuMzgwNjA2XSAgdGhlcm1hbF96b25lX2dldF90ZW1wKzB4NjAvMHgxNTgKPiA+IFsgICA5 MS4zODQ5ODJdICB0aGVybWFsX3pvbmVfZGV2aWNlX3VwZGF0ZS5wYXJ0LjQrMHgzNC8weGUwCj4g PiBbICAgOTEuMzkwMzE4XSAgdGhlcm1hbF96b25lX2RldmljZV91cGRhdGUrMHgyOC8weDM4Cj4g PiBbICAgOTEuMzk1MDQzXSAgYXJtYWRhX292ZXJoZWF0X2lzcisweGIwLzB4YjgKPiA+IFsgICA5 MS4zOTkxNTldICBfX2hhbmRsZV9pcnFfZXZlbnRfcGVyY3B1KzB4OWMvMHgxMjgKPiA+IFsgICA5 MS40MDM4ODNdICBoYW5kbGVfaXJxX2V2ZW50X3BlcmNwdSsweDM0LzB4ODgKPiA+IFsgICA5MS40 MDgzNDZdICBoYW5kbGVfaXJxX2V2ZW50KzB4NDgvMHg3OAo+ID4gWyAgIDkxLjQxMjIwMV0gIGhh bmRsZV9mYXN0ZW9pX2lycSsweGEwLzB4MTgwCj4gPiBbICAgOTEuNDE2MzE2XSAgZ2VuZXJpY19o YW5kbGVfaXJxKzB4MjQvMHgzOAo+ID4gWyAgIDkxLjQyMDM0Nl0gIG12ZWJ1X3NlaV9oYW5kbGVf Y2FzY2FkZV9pcnErMHhjOC8weDE4MAo+ID4gWyAgIDkxLjQyNTMzMl0gIGdlbmVyaWNfaGFuZGxl X2lycSsweDI0LzB4MzgKPiA+IFsgICA5MS40MjkzNjBdICBfX2hhbmRsZV9kb21haW5faXJxKzB4 NWMvMHhiOAo+ID4gWyAgIDkxLjQzMzQ3M10gIGdpY19oYW5kbGVfaXJxKzB4NTgvMHhiMAo+ID4g WyAgIDkxLjQzNzE1MV0gIGVsMV9pcnErMHhiNC8weDEzMCAgCj4gCj4gVGFraW5nIGEgbXV0ZXgg aW4gYW4gaW50ZXJydXB0IGhhbmRsZXIgaXMuLi4gZ3JlYXQhIE9uIHRoZSBvdGhlciBoYW5kLAo+ IHRoYXQgYXJtYWRhX292ZXJoZWF0X2lzciBmdW5jdGlvbiBkb2Vzbid0IHNlZW0gdG8gZXhpc3Qg aW4gNC4xOC1yYzIsCj4gc28gdGhhdCdzIGFic29sdXRlbHkgZmluZS4KCkkgaGFkIG5vIHRyb3Vi bGVzIHdpdGggTlNScyBzbyBJIHdhbnRlZCB0byBjaGVjayB3aXRoIFNFSXMgdG9vLgoKVGhlIG9u bHkgZGV2aWNlIHVzaW5nIFNFSXMgZm9yIG5vdyBpcyB0aGlzIHRoZXJtYWwgZHJpdmVyIHdoaWNo IEkganVzdApjb250cmlidXRlZCwgaXQgaXMgc3RpbGwgdW5kZXIgcmV2aWV3LiBUaGUgSVNSIGlz IG1ha2luZyBhIHRoZXJtYWwtY29yZQpjYWxsIHRvIHVwZGF0ZSBvbiBhbiBvdmVyaGVhdCBzaXR1 YXRpb24uIFRoaXMgY2FsbCBpcyBzeW5jaHJvbm91cyBhbmQKdGhlIGNvcmUgY2hlY2tzIGZvciB0 aGUgY3VycmVudCB0ZW1wZXJhdHVyZSwgYnV0IGZpcnN0IGxvY2tzIGl0cwp0ei0+bG9jayBtdXRl eCwgd2hpY2ggaXMga2luZCBvZiBiYWQgaW4gaW50ZXJydXB0IGNvbnRleHQuIEkganVzdApyZWFs aXplZCBpdC4gU2FkLgoKPiAKPiBOb25ldGhlbGVzcywgcmVnbWFwIHVzYWdlIGluIHRoaXMgY29u dGV4dCBpcyBzdGlsbCBzdXNwZWN0LCBhbmQgbXkgZ3V0Cj4gZmVlbGluZyBpcyB0aGF0IHlvdSBy ZWFsbHkgZG9uJ3QgbmVlZCBpdCBhdCBhbGwuCgpZb3UgYXJlIHJpZ2h0IG9uIHRoaXMgYW5kIEkg cHJvYmFibHkgb3Zlci1sb29rZWQgYXQgdGhlIGluaXRpYWwKcHJvYmxlbS4gSSdtIHByZXR0eSBz dXJlIEkgY2FuIGdldCByaWQgb2YgaXQgYXMgbG9uZyBhcyBvbmx5IG9uZSBkcml2ZXIKdG91Y2hl cyB0aGlzIE1NSU8gcmVnaW9uLgoKVGhhbmtzIGZvciBhbGwgeW91ciB0aG91Z2h0cywgSSdsbCBy ZXNlbmQgYSB2ZXJzaW9uIG5leHQgd2Vlay4KClRoYW5rIHlvdSB2ZXJ5IG11Y2gsCk1pcXXDqGwK Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFy bS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9y ZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1r ZXJuZWwK