From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756583AbaGWMf5 (ORCPT ); Wed, 23 Jul 2014 08:35:57 -0400 Received: from mail-ie0-f170.google.com ([209.85.223.170]:46402 "EHLO mail-ie0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755213AbaGWMfz convert rfc822-to-8bit (ORCPT ); Wed, 23 Jul 2014 08:35:55 -0400 MIME-Version: 1.0 In-Reply-To: <53CF5B9F.1050800@amd.com> References: <20140709093124.11354.3774.stgit@patser> <20140709122953.11354.46381.stgit@patser> <53CE2421.5040906@amd.com> <20140722114607.GL15237@phenom.ffwll.local> <20140722115737.GN15237@phenom.ffwll.local> <53CE56ED.4040109@vodafone.de> <20140722132652.GO15237@phenom.ffwll.local> <53CE6AFA.1060807@vodafone.de> <53CE84AA.9030703@amd.com> <53CE8A57.2000803@vodafone.de> <53CF58FB.8070609@canonical.com> <53CF5B9F.1050800@amd.com> Date: Wed, 23 Jul 2014 08:35:54 -0400 Message-ID: Subject: Re: [Nouveau] [PATCH 09/17] drm/radeon: use common fence implementation for fences From: Rob Clark To: =?UTF-8?Q?Christian_K=C3=B6nig?= Cc: Maarten Lankhorst , =?UTF-8?Q?Christian_K=C3=B6nig?= , Daniel Vetter , Thomas Hellstrom , nouveau , LKML , dri-devel , Ben Skeggs , "Deucher, Alexander" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jul 23, 2014 at 2:52 AM, Christian König wrote: > Am 23.07.2014 08:40, schrieb Maarten Lankhorst: > >> op 22-07-14 17:59, Christian König schreef: >>> >>> Am 22.07.2014 17:42, schrieb Daniel Vetter: >>>> >>>> On Tue, Jul 22, 2014 at 5:35 PM, Christian König >>>> wrote: >>>>> >>>>> Drivers exporting fences need to provide a fence->signaled and a >>>>> fence->wait >>>>> function, everything else like fence->enable_signaling or calling >>>>> fence_signaled() from the driver is optional. >>>>> >>>>> Drivers wanting to use exported fences don't call fence->signaled or >>>>> fence->wait in atomic or interrupt context, and not with holding any >>>>> global >>>>> locking primitives (like mmap_sem etc...). Holding locking primitives >>>>> local >>>>> to the driver is ok, as long as they don't conflict with anything >>>>> possible >>>>> used by their own fence implementation. >>>> >>>> Well that's almost what we have right now with the exception that >>>> drivers are allowed (actually must for correctness when updating >>>> fences) the ww_mutexes for dma-bufs (or other buffer objects). >>> >>> In this case sorry for so much noise. I really haven't looked in so much >>> detail into anything but Maarten's Radeon patches. >>> >>> But how does that then work right now? My impression was that it's >>> mandatory for drivers to call fence_signaled()? >> >> It's only mandatory to call fence_signal() if the .enable_signaling >> callback has been called, else you can get away with never calling signaling >> a fence at all before dropping the last refcount to it. >> This allows you to keep interrupts disabled when you don't need them. > > > Can we somehow avoid the need to call fence_signal() at all? The interrupts > at least on radeon are way to unreliable for such a thing. Can > enable_signalling fail? What's the reason for fence_signaled() in the first > place? > the device you are sharing with may not be able to do hw<->hw signalling.. think about buffer sharing w/ camera, for example. You probably want your ->enable_signalling() to enable whatever workaround periodic-polling you need to do to catch missed irq's (and then call fence->signal() once you detect the fence has passed. fwiw, I haven't had a chance to read this whole thread yet, but I expect that a lot of the SoC devices, especially ones with separate kms-only display and gpu drivers, will want callback from gpu's irq to bang a few display controller registers. I agree in general callbacks from atomic ctx is probably something you want to avoid, but in this particular case I think it is worth the extra complexity. Nothing is stopping a driver from using a callback that just chucks something on a workqueue, whereas the inverse is not possible. BR, -R > >>>> Agreed that any shared locks are out of the way (especially stuff like >>>> dev->struct_mutex or other non-strictly driver-private stuff, i915 is >>>> really bad here still). >>> >>> Yeah that's also an point I've wanted to note on Maartens patch. Radeon >>> grabs the read side of it's exclusive semaphore while waiting for fences >>> (because it assumes that the fence it waits for is a Radeon fence). >>> >>> Assuming that we need to wait in both directions with Prime (e.g. Intel >>> driver needs to wait for Radeon to finish rendering and Radeon needs to wait >>> for Intel to finish displaying), this might become a perfect example of >>> locking inversion. >> >> In the preliminary patches where I can sync radeon with other GPU's I've >> been very careful in all the places that call into fences, to make sure that >> radeon wouldn't try to handle lockups for a different (possibly also radeon) >> card. > > > That's actually not such a good idea. > > In case of a lockup we need to handle the lockup cause otherwise it could > happen that radeon waits for the lockup to be resolved and the lockup > handling needs to wait for a fence that's never signaled because of the > lockup. > > Christian. > > >> >> This is also why fence_is_signaled should never block, and why it trylocks >> the exclusive_lock. :-) I think lockdep would complain if I grabbed >> exclusive_lock while blocking in is_signaled. >> >>>> So from the core fence framework I think we already have exactly this, >>>> and we only need to adjust the radeon implementation a bit to make it >>>> less risky and invasive to the radeon driver logic. >>> >>> Agree. Well the biggest problem I see is that exclusive semaphore I need >>> to take when anything calls into the driver. For the fence code I need to >>> move that down into the fence->signaled handler, cause that now can be >>> called from outside the driver. >>> >>> Maarten solved this by telling the driver in the lockup handler (where we >>> grab the write side of the exclusive lock) that all interrupts are already >>> enabled, so that fence->signaled hopefully wouldn't mess with the hardware >>> at all. While this probably works, it just leaves me with a feeling that we >>> are doing something wrong here. >> >> There is unfortunately no global mechanism to say 'this card is locked up, >> please don't call into any of my fences', and I don't associate fences with >> devices, and radeon doesn't keep a global list of fences. >> If all of that existed, it would complicate the interface and its callers >> a lot, while I like to keep things simple. >> So I did the best I could, and simply prevented the fence calls from >> fiddling with the hardware. Fortunately gpu lockup is not a common >> operation. :-) >> >> ~Maarten >> >> > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rob Clark Subject: Re: [Nouveau] [PATCH 09/17] drm/radeon: use common fence implementation for fences Date: Wed, 23 Jul 2014 08:35:54 -0400 Message-ID: References: <20140709093124.11354.3774.stgit@patser> <20140709122953.11354.46381.stgit@patser> <53CE2421.5040906@amd.com> <20140722114607.GL15237@phenom.ffwll.local> <20140722115737.GN15237@phenom.ffwll.local> <53CE56ED.4040109@vodafone.de> <20140722132652.GO15237@phenom.ffwll.local> <53CE6AFA.1060807@vodafone.de> <53CE84AA.9030703@amd.com> <53CE8A57.2000803@vodafone.de> <53CF58FB.8070609@canonical.com> <53CF5B9F.1050800@amd.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <53CF5B9F.1050800@amd.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: =?UTF-8?Q?Christian_K=C3=B6nig?= Cc: Thomas Hellstrom , Daniel Vetter , LKML , dri-devel , "Deucher, Alexander" , Ben Skeggs , nouveau List-Id: nouveau.vger.kernel.org T24gV2VkLCBKdWwgMjMsIDIwMTQgYXQgMjo1MiBBTSwgQ2hyaXN0aWFuIEvDtm5pZwo8Y2hyaXN0 aWFuLmtvZW5pZ0BhbWQuY29tPiB3cm90ZToKPiBBbSAyMy4wNy4yMDE0IDA4OjQwLCBzY2hyaWVi IE1hYXJ0ZW4gTGFua2hvcnN0Ogo+Cj4+IG9wIDIyLTA3LTE0IDE3OjU5LCBDaHJpc3RpYW4gS8O2 bmlnIHNjaHJlZWY6Cj4+Pgo+Pj4gQW0gMjIuMDcuMjAxNCAxNzo0Miwgc2NocmllYiBEYW5pZWwg VmV0dGVyOgo+Pj4+Cj4+Pj4gT24gVHVlLCBKdWwgMjIsIDIwMTQgYXQgNTozNSBQTSwgQ2hyaXN0 aWFuIEvDtm5pZwo+Pj4+IDxjaHJpc3RpYW4ua29lbmlnQGFtZC5jb20+IHdyb3RlOgo+Pj4+Pgo+ Pj4+PiBEcml2ZXJzIGV4cG9ydGluZyBmZW5jZXMgbmVlZCB0byBwcm92aWRlIGEgZmVuY2UtPnNp Z25hbGVkIGFuZCBhCj4+Pj4+IGZlbmNlLT53YWl0Cj4+Pj4+IGZ1bmN0aW9uLCBldmVyeXRoaW5n IGVsc2UgbGlrZSBmZW5jZS0+ZW5hYmxlX3NpZ25hbGluZyBvciBjYWxsaW5nCj4+Pj4+IGZlbmNl X3NpZ25hbGVkKCkgZnJvbSB0aGUgZHJpdmVyIGlzIG9wdGlvbmFsLgo+Pj4+Pgo+Pj4+PiBEcml2 ZXJzIHdhbnRpbmcgdG8gdXNlIGV4cG9ydGVkIGZlbmNlcyBkb24ndCBjYWxsIGZlbmNlLT5zaWdu YWxlZCBvcgo+Pj4+PiBmZW5jZS0+d2FpdCBpbiBhdG9taWMgb3IgaW50ZXJydXB0IGNvbnRleHQs IGFuZCBub3Qgd2l0aCBob2xkaW5nIGFueQo+Pj4+PiBnbG9iYWwKPj4+Pj4gbG9ja2luZyBwcmlt aXRpdmVzIChsaWtlIG1tYXBfc2VtIGV0Yy4uLikuIEhvbGRpbmcgbG9ja2luZyBwcmltaXRpdmVz Cj4+Pj4+IGxvY2FsCj4+Pj4+IHRvIHRoZSBkcml2ZXIgaXMgb2ssIGFzIGxvbmcgYXMgdGhleSBk b24ndCBjb25mbGljdCB3aXRoIGFueXRoaW5nCj4+Pj4+IHBvc3NpYmxlCj4+Pj4+IHVzZWQgYnkg dGhlaXIgb3duIGZlbmNlIGltcGxlbWVudGF0aW9uLgo+Pj4+Cj4+Pj4gV2VsbCB0aGF0J3MgYWxt b3N0IHdoYXQgd2UgaGF2ZSByaWdodCBub3cgd2l0aCB0aGUgZXhjZXB0aW9uIHRoYXQKPj4+PiBk cml2ZXJzIGFyZSBhbGxvd2VkIChhY3R1YWxseSBtdXN0IGZvciBjb3JyZWN0bmVzcyB3aGVuIHVw ZGF0aW5nCj4+Pj4gZmVuY2VzKSB0aGUgd3dfbXV0ZXhlcyBmb3IgZG1hLWJ1ZnMgKG9yIG90aGVy IGJ1ZmZlciBvYmplY3RzKS4KPj4+Cj4+PiBJbiB0aGlzIGNhc2Ugc29ycnkgZm9yIHNvIG11Y2gg bm9pc2UuIEkgcmVhbGx5IGhhdmVuJ3QgbG9va2VkIGluIHNvIG11Y2gKPj4+IGRldGFpbCBpbnRv IGFueXRoaW5nIGJ1dCBNYWFydGVuJ3MgUmFkZW9uIHBhdGNoZXMuCj4+Pgo+Pj4gQnV0IGhvdyBk b2VzIHRoYXQgdGhlbiB3b3JrIHJpZ2h0IG5vdz8gTXkgaW1wcmVzc2lvbiB3YXMgdGhhdCBpdCdz Cj4+PiBtYW5kYXRvcnkgZm9yIGRyaXZlcnMgdG8gY2FsbCBmZW5jZV9zaWduYWxlZCgpPwo+Pgo+ PiBJdCdzIG9ubHkgbWFuZGF0b3J5IHRvIGNhbGwgZmVuY2Vfc2lnbmFsKCkgaWYgdGhlIC5lbmFi bGVfc2lnbmFsaW5nCj4+IGNhbGxiYWNrIGhhcyBiZWVuIGNhbGxlZCwgZWxzZSB5b3UgY2FuIGdl dCBhd2F5IHdpdGggbmV2ZXIgY2FsbGluZyBzaWduYWxpbmcKPj4gYSBmZW5jZSBhdCBhbGwgYmVm b3JlIGRyb3BwaW5nIHRoZSBsYXN0IHJlZmNvdW50IHRvIGl0Lgo+PiBUaGlzIGFsbG93cyB5b3Ug dG8ga2VlcCBpbnRlcnJ1cHRzIGRpc2FibGVkIHdoZW4geW91IGRvbid0IG5lZWQgdGhlbS4KPgo+ Cj4gQ2FuIHdlIHNvbWVob3cgYXZvaWQgdGhlIG5lZWQgdG8gY2FsbCBmZW5jZV9zaWduYWwoKSBh dCBhbGw/IFRoZSBpbnRlcnJ1cHRzCj4gYXQgbGVhc3Qgb24gcmFkZW9uIGFyZSB3YXkgdG8gdW5y ZWxpYWJsZSBmb3Igc3VjaCBhIHRoaW5nLiBDYW4KPiBlbmFibGVfc2lnbmFsbGluZyBmYWlsPyBX aGF0J3MgdGhlIHJlYXNvbiBmb3IgZmVuY2Vfc2lnbmFsZWQoKSBpbiB0aGUgZmlyc3QKPiBwbGFj ZT8KPgoKdGhlIGRldmljZSB5b3UgYXJlIHNoYXJpbmcgd2l0aCBtYXkgbm90IGJlIGFibGUgdG8g ZG8gaHc8LT5odwpzaWduYWxsaW5nLi4gdGhpbmsgYWJvdXQgYnVmZmVyIHNoYXJpbmcgdy8gY2Ft ZXJhLCBmb3IgZXhhbXBsZS4KCllvdSBwcm9iYWJseSB3YW50IHlvdXIgLT5lbmFibGVfc2lnbmFs bGluZygpIHRvIGVuYWJsZSB3aGF0ZXZlcgp3b3JrYXJvdW5kIHBlcmlvZGljLXBvbGxpbmcgeW91 IG5lZWQgdG8gZG8gdG8gY2F0Y2ggbWlzc2VkIGlycSdzIChhbmQKdGhlbiBjYWxsIGZlbmNlLT5z aWduYWwoKSBvbmNlIHlvdSBkZXRlY3QgdGhlIGZlbmNlIGhhcyBwYXNzZWQuCgpmd2l3LCBJIGhh dmVuJ3QgaGFkIGEgY2hhbmNlIHRvIHJlYWQgdGhpcyB3aG9sZSB0aHJlYWQgeWV0LCBidXQgSQpl eHBlY3QgdGhhdCBhIGxvdCBvZiB0aGUgU29DIGRldmljZXMsIGVzcGVjaWFsbHkgb25lcyB3aXRo IHNlcGFyYXRlCmttcy1vbmx5IGRpc3BsYXkgYW5kIGdwdSBkcml2ZXJzLCB3aWxsIHdhbnQgY2Fs bGJhY2sgZnJvbSBncHUncyBpcnEgdG8KYmFuZyBhIGZldyBkaXNwbGF5IGNvbnRyb2xsZXIgcmVn aXN0ZXJzLiAgSSBhZ3JlZSBpbiBnZW5lcmFsIGNhbGxiYWNrcwpmcm9tIGF0b21pYyBjdHggaXMg cHJvYmFibHkgc29tZXRoaW5nIHlvdSB3YW50IHRvIGF2b2lkLCBidXQgaW4gdGhpcwpwYXJ0aWN1 bGFyIGNhc2UgSSB0aGluayBpdCBpcyB3b3J0aCB0aGUgZXh0cmEgY29tcGxleGl0eS4gIE5vdGhp bmcgaXMKc3RvcHBpbmcgYSBkcml2ZXIgZnJvbSB1c2luZyBhIGNhbGxiYWNrIHRoYXQganVzdCBj aHVja3Mgc29tZXRoaW5nIG9uCmEgd29ya3F1ZXVlLCB3aGVyZWFzIHRoZSBpbnZlcnNlIGlzIG5v dCBwb3NzaWJsZS4KCkJSLAotUgoKPgo+Pj4+IEFncmVlZCB0aGF0IGFueSBzaGFyZWQgbG9ja3Mg YXJlIG91dCBvZiB0aGUgd2F5IChlc3BlY2lhbGx5IHN0dWZmIGxpa2UKPj4+PiBkZXYtPnN0cnVj dF9tdXRleCBvciBvdGhlciBub24tc3RyaWN0bHkgZHJpdmVyLXByaXZhdGUgc3R1ZmYsIGk5MTUg aXMKPj4+PiByZWFsbHkgYmFkIGhlcmUgc3RpbGwpLgo+Pj4KPj4+IFllYWggdGhhdCdzIGFsc28g YW4gcG9pbnQgSSd2ZSB3YW50ZWQgdG8gbm90ZSBvbiBNYWFydGVucyBwYXRjaC4gUmFkZW9uCj4+ PiBncmFicyB0aGUgcmVhZCBzaWRlIG9mIGl0J3MgZXhjbHVzaXZlIHNlbWFwaG9yZSB3aGlsZSB3 YWl0aW5nIGZvciBmZW5jZXMKPj4+IChiZWNhdXNlIGl0IGFzc3VtZXMgdGhhdCB0aGUgZmVuY2Ug aXQgd2FpdHMgZm9yIGlzIGEgUmFkZW9uIGZlbmNlKS4KPj4+Cj4+PiBBc3N1bWluZyB0aGF0IHdl IG5lZWQgdG8gd2FpdCBpbiBib3RoIGRpcmVjdGlvbnMgd2l0aCBQcmltZSAoZS5nLiBJbnRlbAo+ Pj4gZHJpdmVyIG5lZWRzIHRvIHdhaXQgZm9yIFJhZGVvbiB0byBmaW5pc2ggcmVuZGVyaW5nIGFu ZCBSYWRlb24gbmVlZHMgdG8gd2FpdAo+Pj4gZm9yIEludGVsIHRvIGZpbmlzaCBkaXNwbGF5aW5n KSwgdGhpcyBtaWdodCBiZWNvbWUgYSBwZXJmZWN0IGV4YW1wbGUgb2YKPj4+IGxvY2tpbmcgaW52 ZXJzaW9uLgo+Pgo+PiBJbiB0aGUgcHJlbGltaW5hcnkgcGF0Y2hlcyB3aGVyZSBJIGNhbiBzeW5j IHJhZGVvbiB3aXRoIG90aGVyIEdQVSdzIEkndmUKPj4gYmVlbiB2ZXJ5IGNhcmVmdWwgaW4gYWxs IHRoZSBwbGFjZXMgdGhhdCBjYWxsIGludG8gZmVuY2VzLCB0byBtYWtlIHN1cmUgdGhhdAo+PiBy YWRlb24gd291bGRuJ3QgdHJ5IHRvIGhhbmRsZSBsb2NrdXBzIGZvciBhIGRpZmZlcmVudCAocG9z c2libHkgYWxzbyByYWRlb24pCj4+IGNhcmQuCj4KPgo+IFRoYXQncyBhY3R1YWxseSBub3Qgc3Vj aCBhIGdvb2QgaWRlYS4KPgo+IEluIGNhc2Ugb2YgYSBsb2NrdXAgd2UgbmVlZCB0byBoYW5kbGUg dGhlIGxvY2t1cCBjYXVzZSBvdGhlcndpc2UgaXQgY291bGQKPiBoYXBwZW4gdGhhdCByYWRlb24g d2FpdHMgZm9yIHRoZSBsb2NrdXAgdG8gYmUgcmVzb2x2ZWQgYW5kIHRoZSBsb2NrdXAKPiBoYW5k bGluZyBuZWVkcyB0byB3YWl0IGZvciBhIGZlbmNlIHRoYXQncyBuZXZlciBzaWduYWxlZCBiZWNh dXNlIG9mIHRoZQo+IGxvY2t1cC4KPgo+IENocmlzdGlhbi4KPgo+Cj4+Cj4+IFRoaXMgaXMgYWxz byB3aHkgZmVuY2VfaXNfc2lnbmFsZWQgc2hvdWxkIG5ldmVyIGJsb2NrLCBhbmQgd2h5IGl0IHRy eWxvY2tzCj4+IHRoZSBleGNsdXNpdmVfbG9jay4gOi0pIEkgdGhpbmsgbG9ja2RlcCB3b3VsZCBj b21wbGFpbiBpZiBJIGdyYWJiZWQKPj4gZXhjbHVzaXZlX2xvY2sgd2hpbGUgYmxvY2tpbmcgaW4g aXNfc2lnbmFsZWQuCj4+Cj4+Pj4gU28gZnJvbSB0aGUgY29yZSBmZW5jZSBmcmFtZXdvcmsgSSB0 aGluayB3ZSBhbHJlYWR5IGhhdmUgZXhhY3RseSB0aGlzLAo+Pj4+IGFuZCB3ZSBvbmx5IG5lZWQg dG8gYWRqdXN0IHRoZSByYWRlb24gaW1wbGVtZW50YXRpb24gYSBiaXQgdG8gbWFrZSBpdAo+Pj4+ IGxlc3Mgcmlza3kgYW5kIGludmFzaXZlIHRvIHRoZSByYWRlb24gZHJpdmVyIGxvZ2ljLgo+Pj4K Pj4+IEFncmVlLiBXZWxsIHRoZSBiaWdnZXN0IHByb2JsZW0gSSBzZWUgaXMgdGhhdCBleGNsdXNp dmUgc2VtYXBob3JlIEkgbmVlZAo+Pj4gdG8gdGFrZSB3aGVuIGFueXRoaW5nIGNhbGxzIGludG8g dGhlIGRyaXZlci4gRm9yIHRoZSBmZW5jZSBjb2RlIEkgbmVlZCB0bwo+Pj4gbW92ZSB0aGF0IGRv d24gaW50byB0aGUgZmVuY2UtPnNpZ25hbGVkIGhhbmRsZXIsIGNhdXNlIHRoYXQgbm93IGNhbiBi ZQo+Pj4gY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgZHJpdmVyLgo+Pj4KPj4+IE1hYXJ0ZW4gc29s dmVkIHRoaXMgYnkgdGVsbGluZyB0aGUgZHJpdmVyIGluIHRoZSBsb2NrdXAgaGFuZGxlciAod2hl cmUgd2UKPj4+IGdyYWIgdGhlIHdyaXRlIHNpZGUgb2YgdGhlIGV4Y2x1c2l2ZSBsb2NrKSB0aGF0 IGFsbCBpbnRlcnJ1cHRzIGFyZSBhbHJlYWR5Cj4+PiBlbmFibGVkLCBzbyB0aGF0IGZlbmNlLT5z aWduYWxlZCBob3BlZnVsbHkgd291bGRuJ3QgbWVzcyB3aXRoIHRoZSBoYXJkd2FyZQo+Pj4gYXQg YWxsLiBXaGlsZSB0aGlzIHByb2JhYmx5IHdvcmtzLCBpdCBqdXN0IGxlYXZlcyBtZSB3aXRoIGEg ZmVlbGluZyB0aGF0IHdlCj4+PiBhcmUgZG9pbmcgc29tZXRoaW5nIHdyb25nIGhlcmUuCj4+Cj4+ IFRoZXJlIGlzIHVuZm9ydHVuYXRlbHkgbm8gZ2xvYmFsIG1lY2hhbmlzbSB0byBzYXkgJ3RoaXMg Y2FyZCBpcyBsb2NrZWQgdXAsCj4+IHBsZWFzZSBkb24ndCBjYWxsIGludG8gYW55IG9mIG15IGZl bmNlcycsIGFuZCBJIGRvbid0IGFzc29jaWF0ZSBmZW5jZXMgd2l0aAo+PiBkZXZpY2VzLCBhbmQg cmFkZW9uIGRvZXNuJ3Qga2VlcCBhIGdsb2JhbCBsaXN0IG9mIGZlbmNlcy4KPj4gSWYgYWxsIG9m IHRoYXQgZXhpc3RlZCwgaXQgd291bGQgY29tcGxpY2F0ZSB0aGUgaW50ZXJmYWNlIGFuZCBpdHMg Y2FsbGVycwo+PiBhIGxvdCwgd2hpbGUgSSBsaWtlIHRvIGtlZXAgdGhpbmdzIHNpbXBsZS4KPj4g U28gSSBkaWQgdGhlIGJlc3QgSSBjb3VsZCwgYW5kIHNpbXBseSBwcmV2ZW50ZWQgdGhlIGZlbmNl IGNhbGxzIGZyb20KPj4gZmlkZGxpbmcgd2l0aCB0aGUgaGFyZHdhcmUuIEZvcnR1bmF0ZWx5IGdw dSBsb2NrdXAgaXMgbm90IGEgY29tbW9uCj4+IG9wZXJhdGlvbi4gOi0pCj4+Cj4+IH5NYWFydGVu Cj4+Cj4+Cj4KPiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f Xwo+IGRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKPiBkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Au b3JnCj4gaHR0cDovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1k ZXZlbApfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmkt ZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cDov L2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=