From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933714AbbI2Ir5 (ORCPT ); Tue, 29 Sep 2015 04:47:57 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:36740 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934186AbbI2Irg (ORCPT ); Tue, 29 Sep 2015 04:47:36 -0400 Message-ID: <1443516448.2805.23.camel@gmail.com> Subject: Re: Shared scaffolding to unit-test kernel code in userspace (was Re: [Intel-gfx] [PATCH] drm/i915: Add link training test) From: Ander Conselvan De Oliveira To: Daniel Vetter Cc: intel-gfx , Thomas Wood , Martin Peres , Ben Skeggs , Nouveau Dev , Shuah Khan , Greg KH , Linux Kernel Mailing List Date: Tue, 29 Sep 2015 11:47:28 +0300 In-Reply-To: <20150923093817.GG3383@phenom.ffwll.local> References: <1441980706-9241-1-git-send-email-ander.conselvan.de.oliveira@intel.com> <1442231511-24258-1-git-send-email-ander.conselvan.de.oliveira@intel.com> <20150914131149.GE3383@phenom.ffwll.local> <1442237891.2755.24.camel@gmail.com> <1442322533.2595.11.camel@gmail.com> <20150923082408.GN3383@phenom.ffwll.local> <1442999931.2745.21.camel@gmail.com> <20150923093817.GG3383@phenom.ffwll.local> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.16.3 (3.16.3-2.fc22) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 2015-09-23 at 11:38 +0200, Daniel Vetter wrote: > On Wed, Sep 23, 2015 at 11:18 AM, Ander Conselvan De Oliveira wrote: > > On Wed, 2015-09-23 at 10:24 +0200, Daniel Vetter wrote: > > > On Tue, Sep 15, 2015 at 04:08:53PM +0300, Ander Conselvan De Oliveira wrote: > > > > On Mon, 2015-09-14 at 16:38 +0300, Ander Conselvan De Oliveira wrote: > > > > > On Mon, 2015-09-14 at 15:11 +0200, Daniel Vetter wrote: > > > > > > On Mon, Sep 14, 2015 at 02:51:51PM +0300, Ander Conselvan de Oliveira wrote: > > > > > > > --- > > > > > > > > > > > > > > On Fri, 2015-09-11 at 17:11 +0300, Ander Conselvan de Oliveira wrote: > > > > > > > > On Wed, 2015-09-09 at 11:33 +0100, Thomas Wood wrote: > > > > > > > > > On 8 September 2015 at 13:28, Ander Conselvan de Oliveira > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > diff --git a/link-training-test/Makefile b/link-training-test/Makefile > > > > > > > > > > > > > > > > > > If this is meant to be part of the test suite, then it needs to be in > > > > > > > > > the tests directory and use the igt test infrastructure. Otherwise it > > > > > > > > > should be placed in tools or tools/link-training-test. > > > > > > > > > > > > > > > > I made the test use the igt infrastructure, but I'm not sure if this is > > > > > > > > a good fit for it. The dependency on the kernel is on build time, but > > > > > > > > once compiled this can be run on any machine. This can also introduce > > > > > > > > build failures if the test is not kept in sync with the driver source. > > > > > > > > Ideally that a failure to build this would be reported as the test > > > > > > > > failing, but I have no idea of how to achieve that. > > > > > > > > > > > > > > Alternatively, this could be in the kernel source tree directly. This > > > > > > > patch adds a test subdir to the i915 source dir, containing the link > > > > > > > training test. The test is compiled as part of the normal build using > > > > > > > the extra-y variable so that it doesn't get linked to the final kernel. > > > > > > > > > > > > > > When make is run from the tests directory, a thin wrapper around the > > > > > > > tests is built and linked to the object file compiled as part of the > > > > > > > kernel build. Running make run_tests from the test dir runs the test > > > > > > > and reports success or failure. > > > > > > > > > > > > > > Any thoughts? > > > > > > > > > > > > I think there's some precedence in other subsystems to integrate unit > > > > > > tests directly in the kernel, e.g. locking selftest or similar things. > > > > > > Usual approach is to either have a special module (but that often means > > > > > > piles of EXPORT_SYMBOL only for that selftest module). Or just a y/n > > > > > > Kconfig option which enables that code and runs all the self/unit tests > > > > > > when the module loads. > > > > > > > > > > > > I'd go with that approach since it's simpler. And we'd only need to tell > > > > > > QA to enable that Kconfig option for more testing. > > > > > > > > > > I'll have a look into that Kconfig approach, but there's a couple of things > > > > > I like about having the unit test as user space binaries: > > > > > > > > > > - there's no need to boot the newly compiled kernel, so doing a test run > > > > > is super fast; > > > > > - the binaries can be debugged with gdb just like other user space stuff. > > > > > > > > I implemented the test using the Kconfig approach, and it seems to work well > > > > without impacting the points above. I added the call to run the test as the > > > > first thing in i915_init(), and with the driver compiled built-in, running > > > > the kernel under qemu will run the tests. And qemu can also provide a gdb > > > > remote target. > > > > > > > > One thing might be a problem though. With the previous approach, the > > > > functions overriden by the test where simply reimplemented in the new binary. > > > > But now the test is linked to the entire driver, so that's not possible. To > > > > work around that, I had to add function pointers to all the functions called > > > > by the link training state machine to intel_dp. I don't think that method > > > > scales well. > > > > > > > > I'll send update patches for reference as replies to this mail. > > > > > > I had a few discussions about this at XDC and I know think doing this is > > > userspace is better: > > > - Faster to run tests (since no module reloading required). > > > - Nouveau is developed in userspace and would like to reuse shared link > > > training code too if possible from the dp helpers. > > > > > > So I'm leaning towards scaffolding in userspace now. Might be good to > > > check out how the nouveau userspace runtime works just to steal a few > > > tricks. > > > > I chatted with Martin Peres about this and had a look at the code. There are a few interesting > > tricks in Nouveau indeed. They have user space implementation for some kernel internals such as > > mutexes, ioremap on top of libpciaccess, etc. and an extensive set of stubs. > > > > The one thing that wouldn't be easy to take advantage of is the build integration. Their > > upstream > > repository is not actually a kernel tree. It contains their drm code, the same that ends up in > > the > > kernel plus all the user space stuff. There's a script that converts the commits from that > > repository for inclusion in the kernel tree. > > Could we perhaps move at least some of the scafffolding for kernel > functions to upstream? I guess nouveau has some means to pull changes from > upstream too, so maybe we could push that some place nice. And I'm pretty > sure we're not the only ones thinking about unit-testing specific > kernelcode in a userspace environment. Maybe this would add a burden on nouveau development without any added benefit? Since we need only a small subset of what they already have, perhaps it would make more sense to first replicate that small part for our consumption. I believe what need to be re-implemented and/or stubbed will vary significantly with the code being tested, so it might make more sense to just let it grow organically. I think the more important question is how to include the right code when compiling the user space binaries. The trick nouveau uses is to have only one header that includes code from the kernel. That header is replaced with a version intended for user space if compiling user space binaries. We would have to use the same trick for every subsystem under test, including some include path mangling. At least drm and i915 would be affected for the tests I'm proposing. Ander From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ander Conselvan De Oliveira Subject: Re: Shared scaffolding to unit-test kernel code in userspace (was Re: [PATCH] drm/i915: Add link training test) Date: Tue, 29 Sep 2015 11:47:28 +0300 Message-ID: <1443516448.2805.23.camel@gmail.com> References: <1441980706-9241-1-git-send-email-ander.conselvan.de.oliveira@intel.com> <1442231511-24258-1-git-send-email-ander.conselvan.de.oliveira@intel.com> <20150914131149.GE3383@phenom.ffwll.local> <1442237891.2755.24.camel@gmail.com> <1442322533.2595.11.camel@gmail.com> <20150923082408.GN3383@phenom.ffwll.local> <1442999931.2745.21.camel@gmail.com> <20150923093817.GG3383@phenom.ffwll.local> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20150923093817.GG3383@phenom.ffwll.local> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Daniel Vetter Cc: Nouveau Dev , intel-gfx , Shuah Khan , Linux Kernel Mailing List , Martin Peres , Ben Skeggs , Greg KH , Thomas Wood List-Id: intel-gfx@lists.freedesktop.org T24gV2VkLCAyMDE1LTA5LTIzIGF0IDExOjM4ICswMjAwLCBEYW5pZWwgVmV0dGVyIHdyb3RlOgo+ IE9uIFdlZCwgU2VwIDIzLCAyMDE1IGF0IDExOjE4IEFNLCBBbmRlciBDb25zZWx2YW4gRGUgT2xp dmVpcmEgPGNvbnNlbHZhbjJAZ21haWwuY29tPiB3cm90ZToKPiA+IE9uIFdlZCwgMjAxNS0wOS0y MyBhdCAxMDoyNCArMDIwMCwgRGFuaWVsIFZldHRlciB3cm90ZToKPiA+ID4gT24gVHVlLCBTZXAg MTUsIDIwMTUgYXQgMDQ6MDg6NTNQTSArMDMwMCwgQW5kZXIgQ29uc2VsdmFuIERlIE9saXZlaXJh IHdyb3RlOgo+ID4gPiA+IE9uIE1vbiwgMjAxNS0wOS0xNCBhdCAxNjozOCArMDMwMCwgQW5kZXIg Q29uc2VsdmFuIERlIE9saXZlaXJhIHdyb3RlOgo+ID4gPiA+ID4gT24gTW9uLCAyMDE1LTA5LTE0 IGF0IDE1OjExICswMjAwLCBEYW5pZWwgVmV0dGVyIHdyb3RlOgo+ID4gPiA+ID4gPiBPbiBNb24s IFNlcCAxNCwgMjAxNSBhdCAwMjo1MTo1MVBNICswMzAwLCBBbmRlciBDb25zZWx2YW4gZGUgT2xp dmVpcmEgd3JvdGU6Cj4gPiA+ID4gPiA+ID4gLS0tCj4gPiA+ID4gPiA+ID4gCj4gPiA+ID4gPiA+ ID4gT24gRnJpLCAyMDE1LTA5LTExIGF0IDE3OjExICswMzAwLCBBbmRlciBDb25zZWx2YW4gZGUg T2xpdmVpcmEgd3JvdGU6Cj4gPiA+ID4gPiA+ID4gPiBPbiBXZWQsIDIwMTUtMDktMDkgYXQgMTE6 MzMgKzAxMDAsIFRob21hcyBXb29kIHdyb3RlOgo+ID4gPiA+ID4gPiA+ID4gPiBPbiA4IFNlcHRl bWJlciAyMDE1IGF0IDEzOjI4LCBBbmRlciBDb25zZWx2YW4gZGUgT2xpdmVpcmEKPiA+ID4gPiA+ ID4gPiA+ID4gPGFuZGVyLmNvbnNlbHZhbi5kZS5vbGl2ZWlyYUBpbnRlbC5jb20+IHdyb3RlOgo+ ID4gPiA+ID4gPiA+ID4gPiA+IAo+ID4gPiA+ID4gPiA+ID4gCj4gPiA+ID4gPiA+ID4gPiA+ID4g ZGlmZiAtLWdpdCBhL2xpbmstdHJhaW5pbmctdGVzdC9NYWtlZmlsZSBiL2xpbmstdHJhaW5pbmct dGVzdC9NYWtlZmlsZQo+ID4gPiA+ID4gPiA+ID4gPiAKPiA+ID4gPiA+ID4gPiA+ID4gSWYgdGhp cyBpcyBtZWFudCB0byBiZSBwYXJ0IG9mIHRoZSB0ZXN0IHN1aXRlLCB0aGVuIGl0IG5lZWRzIHRv IGJlIGluCj4gPiA+ID4gPiA+ID4gPiA+IHRoZSB0ZXN0cyBkaXJlY3RvcnkgYW5kIHVzZSB0aGUg aWd0IHRlc3QgaW5mcmFzdHJ1Y3R1cmUuIE90aGVyd2lzZSBpdAo+ID4gPiA+ID4gPiA+ID4gPiBz aG91bGQgYmUgcGxhY2VkIGluIHRvb2xzIG9yIHRvb2xzL2xpbmstdHJhaW5pbmctdGVzdC4KPiA+ ID4gPiA+ID4gPiA+IAo+ID4gPiA+ID4gPiA+ID4gSSBtYWRlIHRoZSB0ZXN0IHVzZSB0aGUgaWd0 IGluZnJhc3RydWN0dXJlLCBidXQgSSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMKPiA+ID4gPiA+ID4g PiA+IGEgZ29vZCBmaXQgZm9yIGl0LiBUaGUgZGVwZW5kZW5jeSBvbiB0aGUga2VybmVsIGlzIG9u IGJ1aWxkIHRpbWUsIGJ1dAo+ID4gPiA+ID4gPiA+ID4gb25jZSBjb21waWxlZCB0aGlzIGNhbiBi ZSBydW4gb24gYW55IG1hY2hpbmUuIFRoaXMgY2FuIGFsc28gaW50cm9kdWNlCj4gPiA+ID4gPiA+ ID4gPiBidWlsZCBmYWlsdXJlcyBpZiB0aGUgdGVzdCBpcyBub3Qga2VwdCBpbiBzeW5jIHdpdGgg dGhlIGRyaXZlciBzb3VyY2UuCj4gPiA+ID4gPiA+ID4gPiBJZGVhbGx5IHRoYXQgYSBmYWlsdXJl IHRvIGJ1aWxkIHRoaXMgd291bGQgYmUgcmVwb3J0ZWQgYXMgdGhlIHRlc3QKPiA+ID4gPiA+ID4g PiA+IGZhaWxpbmcsIGJ1dCBJIGhhdmUgbm8gaWRlYSBvZiBob3cgdG8gYWNoaWV2ZSB0aGF0Lgo+ ID4gPiA+ID4gPiA+IAo+ID4gPiA+ID4gPiA+IEFsdGVybmF0aXZlbHksIHRoaXMgY291bGQgYmUg aW4gdGhlIGtlcm5lbCBzb3VyY2UgdHJlZSBkaXJlY3RseS4gVGhpcwo+ID4gPiA+ID4gPiA+IHBh dGNoIGFkZHMgYSB0ZXN0IHN1YmRpciB0byB0aGUgaTkxNSBzb3VyY2UgZGlyLCBjb250YWluaW5n IHRoZSBsaW5rCj4gPiA+ID4gPiA+ID4gdHJhaW5pbmcgdGVzdC4gVGhlIHRlc3QgaXMgY29tcGls ZWQgYXMgcGFydCBvZiB0aGUgbm9ybWFsIGJ1aWxkIHVzaW5nCj4gPiA+ID4gPiA+ID4gdGhlIGV4 dHJhLXkgdmFyaWFibGUgc28gdGhhdCBpdCBkb2Vzbid0IGdldCBsaW5rZWQgdG8gdGhlIGZpbmFs IGtlcm5lbC4KPiA+ID4gPiA+ID4gPiAKPiA+ID4gPiA+ID4gPiBXaGVuIG1ha2UgaXMgcnVuIGZy b20gdGhlIHRlc3RzIGRpcmVjdG9yeSwgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZQo+ID4gPiA+ ID4gPiA+IHRlc3RzIGlzIGJ1aWx0IGFuZCBsaW5rZWQgdG8gdGhlIG9iamVjdCBmaWxlIGNvbXBp bGVkIGFzIHBhcnQgb2YgdGhlCj4gPiA+ID4gPiA+ID4ga2VybmVsIGJ1aWxkLiBSdW5uaW5nIG1h a2UgcnVuX3Rlc3RzIGZyb20gdGhlIHRlc3QgZGlyIHJ1bnMgdGhlIHRlc3QKPiA+ID4gPiA+ID4g PiBhbmQgcmVwb3J0cyBzdWNjZXNzIG9yIGZhaWx1cmUuCj4gPiA+ID4gPiA+ID4gCj4gPiA+ID4g PiA+ID4gQW55IHRob3VnaHRzPwo+ID4gPiA+ID4gPiAKPiA+ID4gPiA+ID4gSSB0aGluayB0aGVy ZSdzIHNvbWUgcHJlY2VkZW5jZSBpbiBvdGhlciBzdWJzeXN0ZW1zIHRvIGludGVncmF0ZSB1bml0 Cj4gPiA+ID4gPiA+IHRlc3RzIGRpcmVjdGx5IGluIHRoZSBrZXJuZWwsIGUuZy4gbG9ja2luZyBz ZWxmdGVzdCBvciBzaW1pbGFyIHRoaW5ncy4KPiA+ID4gPiA+ID4gVXN1YWwgYXBwcm9hY2ggaXMg dG8gZWl0aGVyIGhhdmUgYSBzcGVjaWFsIG1vZHVsZSAoYnV0IHRoYXQgb2Z0ZW4gbWVhbnMKPiA+ ID4gPiA+ID4gcGlsZXMgb2YgRVhQT1JUX1NZTUJPTCBvbmx5IGZvciB0aGF0IHNlbGZ0ZXN0IG1v ZHVsZSkuIE9yIGp1c3QgYSB5L24KPiA+ID4gPiA+ID4gS2NvbmZpZyBvcHRpb24gd2hpY2ggZW5h YmxlcyB0aGF0IGNvZGUgYW5kIHJ1bnMgYWxsIHRoZSBzZWxmL3VuaXQgdGVzdHMKPiA+ID4gPiA+ ID4gd2hlbiB0aGUgbW9kdWxlIGxvYWRzLgo+ID4gPiA+ID4gPiAKPiA+ID4gPiA+ID4gSSdkIGdv IHdpdGggdGhhdCBhcHByb2FjaCBzaW5jZSBpdCdzIHNpbXBsZXIuIEFuZCB3ZSdkIG9ubHkgbmVl ZCB0byB0ZWxsCj4gPiA+ID4gPiA+IFFBIHRvIGVuYWJsZSB0aGF0IEtjb25maWcgb3B0aW9uIGZv ciBtb3JlIHRlc3RpbmcuCj4gPiA+ID4gPiAKPiA+ID4gPiA+IEknbGwgaGF2ZSBhIGxvb2sgaW50 byB0aGF0IEtjb25maWcgYXBwcm9hY2gsIGJ1dCB0aGVyZSdzIGEgY291cGxlIG9mIHRoaW5ncwo+ ID4gPiA+ID4gSSBsaWtlIGFib3V0IGhhdmluZyB0aGUgdW5pdCB0ZXN0IGFzIHVzZXIgc3BhY2Ug YmluYXJpZXM6Cj4gPiA+ID4gPiAKPiA+ID4gPiA+ICAgLSB0aGVyZSdzIG5vIG5lZWQgdG8gYm9v dCB0aGUgbmV3bHkgY29tcGlsZWQga2VybmVsLCBzbyBkb2luZyBhIHRlc3QgcnVuCj4gPiA+ID4g PiAgICAgaXMgc3VwZXIgZmFzdDsKPiA+ID4gPiA+ICAgLSB0aGUgYmluYXJpZXMgY2FuIGJlIGRl YnVnZ2VkIHdpdGggZ2RiIGp1c3QgbGlrZSBvdGhlciB1c2VyIHNwYWNlIHN0dWZmLgo+ID4gPiA+ IAo+ID4gPiA+IEkgaW1wbGVtZW50ZWQgdGhlIHRlc3QgdXNpbmcgdGhlIEtjb25maWcgYXBwcm9h Y2gsIGFuZCBpdCBzZWVtcyB0byB3b3JrIHdlbGwKPiA+ID4gPiB3aXRob3V0IGltcGFjdGluZyB0 aGUgcG9pbnRzIGFib3ZlLiBJIGFkZGVkIHRoZSBjYWxsIHRvIHJ1biB0aGUgdGVzdCBhcyB0aGUK PiA+ID4gPiBmaXJzdCB0aGluZyBpbiBpOTE1X2luaXQoKSwgYW5kIHdpdGggdGhlIGRyaXZlciBj b21waWxlZCBidWlsdC1pbiwgcnVubmluZwo+ID4gPiA+IHRoZSBrZXJuZWwgdW5kZXIgcWVtdSB3 aWxsIHJ1biB0aGUgdGVzdHMuIEFuZCBxZW11IGNhbiBhbHNvIHByb3ZpZGUgYSBnZGIKPiA+ID4g PiByZW1vdGUgdGFyZ2V0Lgo+ID4gPiA+IAo+ID4gPiA+IE9uZSB0aGluZyBtaWdodCBiZSBhIHBy b2JsZW0gdGhvdWdoLiBXaXRoIHRoZSBwcmV2aW91cyBhcHByb2FjaCwgdGhlCj4gPiA+ID4gZnVu Y3Rpb25zIG92ZXJyaWRlbiBieSB0aGUgdGVzdCB3aGVyZSBzaW1wbHkgcmVpbXBsZW1lbnRlZCBp biB0aGUgbmV3IGJpbmFyeS4KPiA+ID4gPiBCdXQgbm93IHRoZSB0ZXN0IGlzIGxpbmtlZCB0byB0 aGUgZW50aXJlIGRyaXZlciwgc28gdGhhdCdzIG5vdCBwb3NzaWJsZS4gVG8KPiA+ID4gPiB3b3Jr IGFyb3VuZCB0aGF0LCBJIGhhZCB0byBhZGQgZnVuY3Rpb24gcG9pbnRlcnMgdG8gYWxsIHRoZSBm dW5jdGlvbnMgY2FsbGVkCj4gPiA+ID4gYnkgdGhlIGxpbmsgdHJhaW5pbmcgc3RhdGUgbWFjaGlu ZSB0byBpbnRlbF9kcC4gSSBkb24ndCB0aGluayB0aGF0IG1ldGhvZAo+ID4gPiA+IHNjYWxlcyB3 ZWxsLgo+ID4gPiA+IAo+ID4gPiA+IEknbGwgc2VuZCB1cGRhdGUgcGF0Y2hlcyBmb3IgcmVmZXJl bmNlIGFzIHJlcGxpZXMgdG8gdGhpcyBtYWlsLgo+ID4gPiAKPiA+ID4gSSBoYWQgYSBmZXcgZGlz Y3Vzc2lvbnMgYWJvdXQgdGhpcyBhdCBYREMgYW5kIEkga25vdyB0aGluayBkb2luZyB0aGlzIGlz Cj4gPiA+IHVzZXJzcGFjZSBpcyBiZXR0ZXI6Cj4gPiA+IC0gRmFzdGVyIHRvIHJ1biB0ZXN0cyAo c2luY2Ugbm8gbW9kdWxlIHJlbG9hZGluZyByZXF1aXJlZCkuCj4gPiA+IC0gTm91dmVhdSBpcyBk ZXZlbG9wZWQgaW4gdXNlcnNwYWNlIGFuZCB3b3VsZCBsaWtlIHRvIHJldXNlIHNoYXJlZCBsaW5r Cj4gPiA+ICAgdHJhaW5pbmcgY29kZSB0b28gaWYgcG9zc2libGUgZnJvbSB0aGUgZHAgaGVscGVy cy4KPiA+ID4gCj4gPiA+IFNvIEknbSBsZWFuaW5nIHRvd2FyZHMgc2NhZmZvbGRpbmcgaW4gdXNl cnNwYWNlIG5vdy4gTWlnaHQgYmUgZ29vZCB0bwo+ID4gPiBjaGVjayBvdXQgaG93IHRoZSBub3V2 ZWF1IHVzZXJzcGFjZSBydW50aW1lIHdvcmtzIGp1c3QgdG8gc3RlYWwgYSBmZXcKPiA+ID4gdHJp Y2tzLgo+ID4gCj4gPiBJIGNoYXR0ZWQgd2l0aCBNYXJ0aW4gUGVyZXMgYWJvdXQgdGhpcyBhbmQg aGFkIGEgbG9vayBhdCB0aGUgY29kZS4gVGhlcmUgYXJlIGEgZmV3IGludGVyZXN0aW5nCj4gPiB0 cmlja3MgaW4gTm91dmVhdSBpbmRlZWQuIFRoZXkgaGF2ZSB1c2VyIHNwYWNlIGltcGxlbWVudGF0 aW9uIGZvciBzb21lIGtlcm5lbCBpbnRlcm5hbHMgc3VjaCBhcwo+ID4gbXV0ZXhlcywgaW9yZW1h cCBvbiB0b3Agb2YgbGlicGNpYWNjZXNzLCBldGMuIGFuZCBhbiBleHRlbnNpdmUgc2V0IG9mIHN0 dWJzLgo+ID4gCj4gPiBUaGUgb25lIHRoaW5nIHRoYXQgd291bGRuJ3QgYmUgZWFzeSB0byB0YWtl IGFkdmFudGFnZSBvZiBpcyB0aGUgYnVpbGQgaW50ZWdyYXRpb24uIFRoZWlyIAo+ID4gdXBzdHJl YW0KPiA+IHJlcG9zaXRvcnkgaXMgbm90IGFjdHVhbGx5IGEga2VybmVsIHRyZWUuIEl0IGNvbnRh aW5zIHRoZWlyIGRybSBjb2RlLCB0aGUgc2FtZSB0aGF0IGVuZHMgdXAgaW4gCj4gPiB0aGUKPiA+ IGtlcm5lbCBwbHVzIGFsbCB0aGUgdXNlciBzcGFjZSBzdHVmZi4gVGhlcmUncyBhIHNjcmlwdCB0 aGF0IGNvbnZlcnRzIHRoZSBjb21taXRzIGZyb20gdGhhdAo+ID4gcmVwb3NpdG9yeSBmb3IgaW5j bHVzaW9uIGluIHRoZSBrZXJuZWwgdHJlZS4KPiAKPiBDb3VsZCB3ZSBwZXJoYXBzIG1vdmUgYXQg bGVhc3Qgc29tZSBvZiB0aGUgc2NhZmZmb2xkaW5nIGZvciBrZXJuZWwKPiBmdW5jdGlvbnMgdG8g dXBzdHJlYW0/IEkgZ3Vlc3Mgbm91dmVhdSBoYXMgc29tZSBtZWFucyB0byBwdWxsIGNoYW5nZXMg ZnJvbQo+IHVwc3RyZWFtIHRvbywgc28gbWF5YmUgd2UgY291bGQgcHVzaCB0aGF0IHNvbWUgcGxh Y2UgbmljZS4gQW5kIEknbSBwcmV0dHkKPiBzdXJlIHdlJ3JlIG5vdCB0aGUgb25seSBvbmVzIHRo aW5raW5nIGFib3V0IHVuaXQtdGVzdGluZyBzcGVjaWZpYwo+IGtlcm5lbGNvZGUgaW4gYSB1c2Vy c3BhY2UgZW52aXJvbm1lbnQuCgpNYXliZSB0aGlzIHdvdWxkIGFkZCBhIGJ1cmRlbiBvbiBub3V2 ZWF1IGRldmVsb3BtZW50IHdpdGhvdXQgYW55IGFkZGVkIGJlbmVmaXQ/IFNpbmNlIHdlIG5lZWQg b25seSBhCnNtYWxsIHN1YnNldCBvZiB3aGF0IHRoZXkgYWxyZWFkeSBoYXZlLCBwZXJoYXBzIGl0 IHdvdWxkIG1ha2UgbW9yZSBzZW5zZSB0byBmaXJzdCByZXBsaWNhdGUgdGhhdApzbWFsbCBwYXJ0 IGZvciBvdXIgY29uc3VtcHRpb24uIEkgYmVsaWV2ZSB3aGF0IG5lZWQgdG8gYmUgcmUtaW1wbGVt ZW50ZWQgYW5kL29yIHN0dWJiZWQgd2lsbCB2YXJ5CnNpZ25pZmljYW50bHkgd2l0aCB0aGUgY29k ZSBiZWluZyB0ZXN0ZWQsIHNvIGl0IG1pZ2h0IG1ha2UgbW9yZSBzZW5zZSB0byBqdXN0IGxldCBp dCBncm93Cm9yZ2FuaWNhbGx5LgoKSSB0aGluayB0aGUgbW9yZSBpbXBvcnRhbnQgcXVlc3Rpb24g aXMgaG93IHRvIGluY2x1ZGUgdGhlIHJpZ2h0IGNvZGUgd2hlbiBjb21waWxpbmcgdGhlIHVzZXIg c3BhY2UKYmluYXJpZXMuIFRoZSB0cmljayBub3V2ZWF1IHVzZXMgaXMgdG8gaGF2ZSBvbmx5IG9u ZSBoZWFkZXIgdGhhdCBpbmNsdWRlcyBjb2RlIGZyb20gdGhlIGtlcm5lbC4gVGhhdApoZWFkZXIg aXMgcmVwbGFjZWQgd2l0aCBhIHZlcnNpb24gaW50ZW5kZWQgZm9yIHVzZXIgc3BhY2UgaWYgY29t cGlsaW5nIHVzZXIgc3BhY2UgYmluYXJpZXMuIFdlIHdvdWxkCmhhdmUgdG8gdXNlIHRoZSBzYW1l IHRyaWNrIGZvciBldmVyeSBzdWJzeXN0ZW0gdW5kZXIgdGVzdCwgaW5jbHVkaW5nIHNvbWUgaW5j bHVkZSBwYXRoIG1hbmdsaW5nLiBBdApsZWFzdCBkcm0gYW5kIGk5MTUgd291bGQgYmUgYWZmZWN0 ZWQgZm9yIHRoZSB0ZXN0cyBJJ20gcHJvcG9zaW5nLgoKQW5kZXIKCgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpJbnRlbC1nZnggbWFpbGluZyBsaXN0Cklu dGVsLWdmeEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cDovL2xpc3RzLmZyZWVkZXNrdG9wLm9y Zy9tYWlsbWFuL2xpc3RpbmZvL2ludGVsLWdmeAo=