From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com ([134.134.136.65]:32812 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755945AbcBIKHe (ORCPT ); Tue, 9 Feb 2016 05:07:34 -0500 Date: Tue, 9 Feb 2016 12:07:27 +0200 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= To: Daniel Vetter Cc: Mario Kleiner , dri-devel@lists.freedesktop.org, linux@bernd-steinhauser.de, stable@vger.kernel.org, michel@daenzer.net, vbabka@suse.cz, daniel.vetter@ffwll.ch, alexander.deucher@amd.com, christian.koenig@amd.com Subject: Re: [PATCH 2/6] drm: Prevent vblank counter bumps > 1 with active vblank clients. Message-ID: <20160209100727.GG23290@intel.com> References: <1454894009-15466-1-git-send-email-mario.kleiner.de@gmail.com> <1454894009-15466-3-git-send-email-mario.kleiner.de@gmail.com> <20160209095638.GM11240@phenom.ffwll.local> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20160209095638.GM11240@phenom.ffwll.local> Sender: stable-owner@vger.kernel.org List-ID: On Tue, Feb 09, 2016 at 10:56:38AM +0100, Daniel Vetter wrote: > On Mon, Feb 08, 2016 at 02:13:25AM +0100, Mario Kleiner wrote: > > This fixes a regression introduced by the new drm_update_vblank_count() > > implementation in Linux 4.4: > > > > Restrict the bump of the software vblank counter in drm_update_vblank_count() > > to a safe maximum value of +1 whenever there is the possibility that > > concurrent readers of vblank timestamps could be active at the moment, > > as the current implementation of the timestamp caching and updating is > > not safe against concurrent readers for calls to store_vblank() with a > > bump of anything but +1. A bump != 1 would very likely return corrupted > > timestamps to userspace, because the same slot in the cache could > > be concurrently written by store_vblank() and read by one of those > > readers in a non-atomic fashion and without the read-retry logic > > detecting this collision. > > > > Concurrent readers can exist while drm_update_vblank_count() is called > > from the drm_vblank_off() or drm_vblank_on() functions or other non-vblank- > > irq callers. However, all those calls are happening with the vbl_lock > > locked thereby preventing a drm_vblank_get(), so the vblank refcount > > can't increase while drm_update_vblank_count() is executing. Therefore > > a zero vblank refcount during execution of that function signals that > > is safe for arbitrary counter bumps if called from outside vblank irq, > > whereas a non-zero count is not safe. > > > > Whenever the function is called from vblank irq, we have to assume concurrent > > readers could show up any time during its execution, even if the refcount > > is currently zero, as vblank irqs are usually only enabled due to the > > presence of readers, and because when it is called from vblank irq it > > can't hold the vbl_lock to protect it from sudden bumps in vblank refcount. > > Therefore also restrict bumps to +1 when the function is called from vblank > > irq. > > > > Such bumps of more than +1 can happen at other times than reenabling > > vblank irqs, e.g., when regular vblank interrupts get delayed by more > > than 1 frame due to long held locks, long irq off periods, realtime > > preemption on RT kernels, or system management interrupts. > > > > Signed-off-by: Mario Kleiner > > Cc: # 4.4+ > > Cc: michel@daenzer.net > > Cc: vbabka@suse.cz > > Cc: ville.syrjala@linux.intel.com > > Cc: daniel.vetter@ffwll.ch > > Cc: dri-devel@lists.freedesktop.org > > Cc: alexander.deucher@amd.com > > Cc: christian.koenig@amd.com > > Imo this is duct-tape. If we want to fix this up properly I think we > should just use a full-blown seqlock instead of our hand-rolled one. And > that could handle any increment at all. And I even fixed this [1] almost a half a year ago when I sent the original series, but that part got held hostage to the same seqlock argument. Perfect is the enemy of good. [1] https://lists.freedesktop.org/archives/intel-gfx/2015-September/075879.html > -Daniel > > > --- > > drivers/gpu/drm/drm_irq.c | 41 +++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 41 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c > > index bcb8528..aa2c74b 100644 > > --- a/drivers/gpu/drm/drm_irq.c > > +++ b/drivers/gpu/drm/drm_irq.c > > @@ -221,6 +221,47 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, > > diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; > > } > > > > + /* > > + * Restrict the bump of the software vblank counter to a safe maximum > > + * value of +1 whenever there is the possibility that concurrent readers > > + * of vblank timestamps could be active at the moment, as the current > > + * implementation of the timestamp caching and updating is not safe > > + * against concurrent readers for calls to store_vblank() with a bump > > + * of anything but +1. A bump != 1 would very likely return corrupted > > + * timestamps to userspace, because the same slot in the cache could > > + * be concurrently written by store_vblank() and read by one of those > > + * readers without the read-retry logic detecting the collision. > > + * > > + * Concurrent readers can exist when we are called from the > > + * drm_vblank_off() or drm_vblank_on() functions and other non-vblank- > > + * irq callers. However, all those calls to us are happening with the > > + * vbl_lock locked to prevent drm_vblank_get(), so the vblank refcount > > + * can't increase while we are executing. Therefore a zero refcount at > > + * this point is safe for arbitrary counter bumps if we are called > > + * outside vblank irq, a non-zero count is not 100% safe. Unfortunately > > + * we must also accept a refcount of 1, as whenever we are called from > > + * drm_vblank_get() -> drm_vblank_enable() the refcount will be 1 and > > + * we must let that one pass through in order to not lose vblank counts > > + * during vblank irq off - which would completely defeat the whole > > + * point of this routine. > > + * > > + * Whenever we are called from vblank irq, we have to assume concurrent > > + * readers exist or can show up any time during our execution, even if > > + * the refcount is currently zero, as vblank irqs are usually only > > + * enabled due to the presence of readers, and because when we are called > > + * from vblank irq we can't hold the vbl_lock to protect us from sudden > > + * bumps in vblank refcount. Therefore also restrict bumps to +1 when > > + * called from vblank irq. > > + */ > > + if ((diff > 1) && (atomic_read(&vblank->refcount) > 1 || > > + (flags & DRM_CALLED_FROM_VBLIRQ))) { > > + DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u " > > + "refcount %u, vblirq %u\n", pipe, diff, > > + atomic_read(&vblank->refcount), > > + (flags & DRM_CALLED_FROM_VBLIRQ) != 0); > > + diff = 1; > > + } > > + > > DRM_DEBUG_VBL("updating vblank count on crtc %u:" > > " current=%u, diff=%u, hw=%u hw_last=%u\n", > > pipe, vblank->count, diff, cur_vblank, vblank->last); > > -- > > 1.9.1 > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch -- Ville Syrj�l� Intel OTC From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= Subject: Re: [PATCH 2/6] drm: Prevent vblank counter bumps > 1 with active vblank clients. Date: Tue, 9 Feb 2016 12:07:27 +0200 Message-ID: <20160209100727.GG23290@intel.com> References: <1454894009-15466-1-git-send-email-mario.kleiner.de@gmail.com> <1454894009-15466-3-git-send-email-mario.kleiner.de@gmail.com> <20160209095638.GM11240@phenom.ffwll.local> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by gabe.freedesktop.org (Postfix) with ESMTP id B63066E116 for ; Tue, 9 Feb 2016 02:07:32 -0800 (PST) Content-Disposition: inline In-Reply-To: <20160209095638.GM11240@phenom.ffwll.local> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Daniel Vetter Cc: daniel.vetter@ffwll.ch, michel@daenzer.net, linux@bernd-steinhauser.de, stable@vger.kernel.org, dri-devel@lists.freedesktop.org, alexander.deucher@amd.com, christian.koenig@amd.com, vbabka@suse.cz List-Id: dri-devel@lists.freedesktop.org T24gVHVlLCBGZWIgMDksIDIwMTYgYXQgMTA6NTY6MzhBTSArMDEwMCwgRGFuaWVsIFZldHRlciB3 cm90ZToKPiBPbiBNb24sIEZlYiAwOCwgMjAxNiBhdCAwMjoxMzoyNUFNICswMTAwLCBNYXJpbyBL bGVpbmVyIHdyb3RlOgo+ID4gVGhpcyBmaXhlcyBhIHJlZ3Jlc3Npb24gaW50cm9kdWNlZCBieSB0 aGUgbmV3IGRybV91cGRhdGVfdmJsYW5rX2NvdW50KCkKPiA+IGltcGxlbWVudGF0aW9uIGluIExp bnV4IDQuNDoKPiA+IAo+ID4gUmVzdHJpY3QgdGhlIGJ1bXAgb2YgdGhlIHNvZnR3YXJlIHZibGFu ayBjb3VudGVyIGluIGRybV91cGRhdGVfdmJsYW5rX2NvdW50KCkKPiA+IHRvIGEgc2FmZSBtYXhp bXVtIHZhbHVlIG9mICsxIHdoZW5ldmVyIHRoZXJlIGlzIHRoZSBwb3NzaWJpbGl0eSB0aGF0Cj4g PiBjb25jdXJyZW50IHJlYWRlcnMgb2YgdmJsYW5rIHRpbWVzdGFtcHMgY291bGQgYmUgYWN0aXZl IGF0IHRoZSBtb21lbnQsCj4gPiBhcyB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUg dGltZXN0YW1wIGNhY2hpbmcgYW5kIHVwZGF0aW5nIGlzCj4gPiBub3Qgc2FmZSBhZ2FpbnN0IGNv bmN1cnJlbnQgcmVhZGVycyBmb3IgY2FsbHMgdG8gc3RvcmVfdmJsYW5rKCkgd2l0aCBhCj4gPiBi dW1wIG9mIGFueXRoaW5nIGJ1dCArMS4gQSBidW1wICE9IDEgd291bGQgdmVyeSBsaWtlbHkgcmV0 dXJuIGNvcnJ1cHRlZAo+ID4gdGltZXN0YW1wcyB0byB1c2Vyc3BhY2UsIGJlY2F1c2UgdGhlIHNh bWUgc2xvdCBpbiB0aGUgY2FjaGUgY291bGQKPiA+IGJlIGNvbmN1cnJlbnRseSB3cml0dGVuIGJ5 IHN0b3JlX3ZibGFuaygpIGFuZCByZWFkIGJ5IG9uZSBvZiB0aG9zZQo+ID4gcmVhZGVycyBpbiBh IG5vbi1hdG9taWMgZmFzaGlvbiBhbmQgd2l0aG91dCB0aGUgcmVhZC1yZXRyeSBsb2dpYwo+ID4g ZGV0ZWN0aW5nIHRoaXMgY29sbGlzaW9uLgo+ID4gCj4gPiBDb25jdXJyZW50IHJlYWRlcnMgY2Fu IGV4aXN0IHdoaWxlIGRybV91cGRhdGVfdmJsYW5rX2NvdW50KCkgaXMgY2FsbGVkCj4gPiBmcm9t IHRoZSBkcm1fdmJsYW5rX29mZigpIG9yIGRybV92Ymxhbmtfb24oKSBmdW5jdGlvbnMgb3Igb3Ro ZXIgbm9uLXZibGFuay0KPiA+IGlycSBjYWxsZXJzLiBIb3dldmVyLCBhbGwgdGhvc2UgY2FsbHMg YXJlIGhhcHBlbmluZyB3aXRoIHRoZSB2YmxfbG9jawo+ID4gbG9ja2VkIHRoZXJlYnkgcHJldmVu dGluZyBhIGRybV92YmxhbmtfZ2V0KCksIHNvIHRoZSB2YmxhbmsgcmVmY291bnQKPiA+IGNhbid0 IGluY3JlYXNlIHdoaWxlIGRybV91cGRhdGVfdmJsYW5rX2NvdW50KCkgaXMgZXhlY3V0aW5nLiBU aGVyZWZvcmUKPiA+IGEgemVybyB2YmxhbmsgcmVmY291bnQgZHVyaW5nIGV4ZWN1dGlvbiBvZiB0 aGF0IGZ1bmN0aW9uIHNpZ25hbHMgdGhhdAo+ID4gaXMgc2FmZSBmb3IgYXJiaXRyYXJ5IGNvdW50 ZXIgYnVtcHMgaWYgY2FsbGVkIGZyb20gb3V0c2lkZSB2YmxhbmsgaXJxLAo+ID4gd2hlcmVhcyBh IG5vbi16ZXJvIGNvdW50IGlzIG5vdCBzYWZlLgo+ID4gCj4gPiBXaGVuZXZlciB0aGUgZnVuY3Rp b24gaXMgY2FsbGVkIGZyb20gdmJsYW5rIGlycSwgd2UgaGF2ZSB0byBhc3N1bWUgY29uY3VycmVu dAo+ID4gcmVhZGVycyBjb3VsZCBzaG93IHVwIGFueSB0aW1lIGR1cmluZyBpdHMgZXhlY3V0aW9u LCBldmVuIGlmIHRoZSByZWZjb3VudAo+ID4gaXMgY3VycmVudGx5IHplcm8sIGFzIHZibGFuayBp cnFzIGFyZSB1c3VhbGx5IG9ubHkgZW5hYmxlZCBkdWUgdG8gdGhlCj4gPiBwcmVzZW5jZSBvZiBy ZWFkZXJzLCBhbmQgYmVjYXVzZSB3aGVuIGl0IGlzIGNhbGxlZCBmcm9tIHZibGFuayBpcnEgaXQK PiA+IGNhbid0IGhvbGQgdGhlIHZibF9sb2NrIHRvIHByb3RlY3QgaXQgZnJvbSBzdWRkZW4gYnVt cHMgaW4gdmJsYW5rIHJlZmNvdW50Lgo+ID4gVGhlcmVmb3JlIGFsc28gcmVzdHJpY3QgYnVtcHMg dG8gKzEgd2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIGZyb20gdmJsYW5rCj4gPiBpcnEuCj4g PiAKPiA+IFN1Y2ggYnVtcHMgb2YgbW9yZSB0aGFuICsxIGNhbiBoYXBwZW4gYXQgb3RoZXIgdGlt ZXMgdGhhbiByZWVuYWJsaW5nCj4gPiB2YmxhbmsgaXJxcywgZS5nLiwgd2hlbiByZWd1bGFyIHZi bGFuayBpbnRlcnJ1cHRzIGdldCBkZWxheWVkIGJ5IG1vcmUKPiA+IHRoYW4gMSBmcmFtZSBkdWUg dG8gbG9uZyBoZWxkIGxvY2tzLCBsb25nIGlycSBvZmYgcGVyaW9kcywgcmVhbHRpbWUKPiA+IHBy ZWVtcHRpb24gb24gUlQga2VybmVscywgb3Igc3lzdGVtIG1hbmFnZW1lbnQgaW50ZXJydXB0cy4K PiA+IAo+ID4gU2lnbmVkLW9mZi1ieTogTWFyaW8gS2xlaW5lciA8bWFyaW8ua2xlaW5lci5kZUBn bWFpbC5jb20+Cj4gPiBDYzogPHN0YWJsZUB2Z2VyLmtlcm5lbC5vcmc+ICMgNC40Kwo+ID4gQ2M6 IG1pY2hlbEBkYWVuemVyLm5ldAo+ID4gQ2M6IHZiYWJrYUBzdXNlLmN6Cj4gPiBDYzogdmlsbGUu c3lyamFsYUBsaW51eC5pbnRlbC5jb20KPiA+IENjOiBkYW5pZWwudmV0dGVyQGZmd2xsLmNoCj4g PiBDYzogZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwo+ID4gQ2M6IGFsZXhhbmRlci5k ZXVjaGVyQGFtZC5jb20KPiA+IENjOiBjaHJpc3RpYW4ua29lbmlnQGFtZC5jb20KPiAKPiBJbW8g dGhpcyBpcyBkdWN0LXRhcGUuIElmIHdlIHdhbnQgdG8gZml4IHRoaXMgdXAgcHJvcGVybHkgSSB0 aGluayB3ZQo+IHNob3VsZCBqdXN0IHVzZSBhIGZ1bGwtYmxvd24gc2VxbG9jayBpbnN0ZWFkIG9m IG91ciBoYW5kLXJvbGxlZCBvbmUuIEFuZAo+IHRoYXQgY291bGQgaGFuZGxlIGFueSBpbmNyZW1l bnQgYXQgYWxsLgoKQW5kIEkgZXZlbiBmaXhlZCB0aGlzIFsxXSBhbG1vc3QgYSBoYWxmIGEgeWVh ciBhZ28gd2hlbiBJIHNlbnQgdGhlCm9yaWdpbmFsIHNlcmllcywgYnV0IHRoYXQgcGFydCBnb3Qg aGVsZCBob3N0YWdlIHRvIHRoZSBzYW1lIHNlcWxvY2sKYXJndW1lbnQuIFBlcmZlY3QgaXMgdGhl IGVuZW15IG9mIGdvb2QuCgpbMV0gaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvYXJjaGl2 ZXMvaW50ZWwtZ2Z4LzIwMTUtU2VwdGVtYmVyLzA3NTg3OS5odG1sCgo+IC1EYW5pZWwKPiAKPiA+ IC0tLQo+ID4gIGRyaXZlcnMvZ3B1L2RybS9kcm1faXJxLmMgfCA0MSArKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKwo+ID4gIDEgZmlsZSBjaGFuZ2VkLCA0MSBpbnNlcnRp b25zKCspCj4gPiAKPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2lycS5jIGIv ZHJpdmVycy9ncHUvZHJtL2RybV9pcnEuYwo+ID4gaW5kZXggYmNiODUyOC4uYWEyYzc0YiAxMDA2 NDQKPiA+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9kcm1faXJxLmMKPiA+ICsrKyBiL2RyaXZlcnMv Z3B1L2RybS9kcm1faXJxLmMKPiA+IEBAIC0yMjEsNiArMjIxLDQ3IEBAIHN0YXRpYyB2b2lkIGRy bV91cGRhdGVfdmJsYW5rX2NvdW50KHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHVuc2lnbmVkIGlu dCBwaXBlLAo+ID4gIAkJZGlmZiA9IChmbGFncyAmIERSTV9DQUxMRURfRlJPTV9WQkxJUlEpICE9 IDA7Cj4gPiAgCX0KPiA+ICAKPiA+ICsJLyoKPiA+ICsJICogUmVzdHJpY3QgdGhlIGJ1bXAgb2Yg dGhlIHNvZnR3YXJlIHZibGFuayBjb3VudGVyIHRvIGEgc2FmZSBtYXhpbXVtCj4gPiArCSAqIHZh bHVlIG9mICsxIHdoZW5ldmVyIHRoZXJlIGlzIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGNvbmN1cnJl bnQgcmVhZGVycwo+ID4gKwkgKiBvZiB2YmxhbmsgdGltZXN0YW1wcyBjb3VsZCBiZSBhY3RpdmUg YXQgdGhlIG1vbWVudCwgYXMgdGhlIGN1cnJlbnQKPiA+ICsJICogaW1wbGVtZW50YXRpb24gb2Yg dGhlIHRpbWVzdGFtcCBjYWNoaW5nIGFuZCB1cGRhdGluZyBpcyBub3Qgc2FmZQo+ID4gKwkgKiBh Z2FpbnN0IGNvbmN1cnJlbnQgcmVhZGVycyBmb3IgY2FsbHMgdG8gc3RvcmVfdmJsYW5rKCkgd2l0 aCBhIGJ1bXAKPiA+ICsJICogb2YgYW55dGhpbmcgYnV0ICsxLiBBIGJ1bXAgIT0gMSB3b3VsZCB2 ZXJ5IGxpa2VseSByZXR1cm4gY29ycnVwdGVkCj4gPiArCSAqIHRpbWVzdGFtcHMgdG8gdXNlcnNw YWNlLCBiZWNhdXNlIHRoZSBzYW1lIHNsb3QgaW4gdGhlIGNhY2hlIGNvdWxkCj4gPiArCSAqIGJl IGNvbmN1cnJlbnRseSB3cml0dGVuIGJ5IHN0b3JlX3ZibGFuaygpIGFuZCByZWFkIGJ5IG9uZSBv ZiB0aG9zZQo+ID4gKwkgKiByZWFkZXJzIHdpdGhvdXQgdGhlIHJlYWQtcmV0cnkgbG9naWMgZGV0 ZWN0aW5nIHRoZSBjb2xsaXNpb24uCj4gPiArCSAqCj4gPiArCSAqIENvbmN1cnJlbnQgcmVhZGVy cyBjYW4gZXhpc3Qgd2hlbiB3ZSBhcmUgY2FsbGVkIGZyb20gdGhlCj4gPiArCSAqIGRybV92Ymxh bmtfb2ZmKCkgb3IgZHJtX3ZibGFua19vbigpIGZ1bmN0aW9ucyBhbmQgb3RoZXIgbm9uLXZibGFu ay0KPiA+ICsJICogaXJxIGNhbGxlcnMuIEhvd2V2ZXIsIGFsbCB0aG9zZSBjYWxscyB0byB1cyBh cmUgaGFwcGVuaW5nIHdpdGggdGhlCj4gPiArCSAqIHZibF9sb2NrIGxvY2tlZCB0byBwcmV2ZW50 IGRybV92YmxhbmtfZ2V0KCksIHNvIHRoZSB2YmxhbmsgcmVmY291bnQKPiA+ICsJICogY2FuJ3Qg aW5jcmVhc2Ugd2hpbGUgd2UgYXJlIGV4ZWN1dGluZy4gVGhlcmVmb3JlIGEgemVybyByZWZjb3Vu dCBhdAo+ID4gKwkgKiB0aGlzIHBvaW50IGlzIHNhZmUgZm9yIGFyYml0cmFyeSBjb3VudGVyIGJ1 bXBzIGlmIHdlIGFyZSBjYWxsZWQKPiA+ICsJICogb3V0c2lkZSB2YmxhbmsgaXJxLCBhIG5vbi16 ZXJvIGNvdW50IGlzIG5vdCAxMDAlIHNhZmUuIFVuZm9ydHVuYXRlbHkKPiA+ICsJICogd2UgbXVz dCBhbHNvIGFjY2VwdCBhIHJlZmNvdW50IG9mIDEsIGFzIHdoZW5ldmVyIHdlIGFyZSBjYWxsZWQg ZnJvbQo+ID4gKwkgKiBkcm1fdmJsYW5rX2dldCgpIC0+IGRybV92YmxhbmtfZW5hYmxlKCkgdGhl IHJlZmNvdW50IHdpbGwgYmUgMSBhbmQKPiA+ICsJICogd2UgbXVzdCBsZXQgdGhhdCBvbmUgcGFz cyB0aHJvdWdoIGluIG9yZGVyIHRvIG5vdCBsb3NlIHZibGFuayBjb3VudHMKPiA+ICsJICogZHVy aW5nIHZibGFuayBpcnEgb2ZmIC0gd2hpY2ggd291bGQgY29tcGxldGVseSBkZWZlYXQgdGhlIHdo b2xlCj4gPiArCSAqIHBvaW50IG9mIHRoaXMgcm91dGluZS4KPiA+ICsJICoKPiA+ICsJICogV2hl bmV2ZXIgd2UgYXJlIGNhbGxlZCBmcm9tIHZibGFuayBpcnEsIHdlIGhhdmUgdG8gYXNzdW1lIGNv bmN1cnJlbnQKPiA+ICsJICogcmVhZGVycyBleGlzdCBvciBjYW4gc2hvdyB1cCBhbnkgdGltZSBk dXJpbmcgb3VyIGV4ZWN1dGlvbiwgZXZlbiBpZgo+ID4gKwkgKiB0aGUgcmVmY291bnQgaXMgY3Vy cmVudGx5IHplcm8sIGFzIHZibGFuayBpcnFzIGFyZSB1c3VhbGx5IG9ubHkKPiA+ICsJICogZW5h YmxlZCBkdWUgdG8gdGhlIHByZXNlbmNlIG9mIHJlYWRlcnMsIGFuZCBiZWNhdXNlIHdoZW4gd2Ug YXJlIGNhbGxlZAo+ID4gKwkgKiBmcm9tIHZibGFuayBpcnEgd2UgY2FuJ3QgaG9sZCB0aGUgdmJs X2xvY2sgdG8gcHJvdGVjdCB1cyBmcm9tIHN1ZGRlbgo+ID4gKwkgKiBidW1wcyBpbiB2Ymxhbmsg cmVmY291bnQuIFRoZXJlZm9yZSBhbHNvIHJlc3RyaWN0IGJ1bXBzIHRvICsxIHdoZW4KPiA+ICsJ ICogY2FsbGVkIGZyb20gdmJsYW5rIGlycS4KPiA+ICsJICovCj4gPiArCWlmICgoZGlmZiA+IDEp ICYmIChhdG9taWNfcmVhZCgmdmJsYW5rLT5yZWZjb3VudCkgPiAxIHx8Cj4gPiArCSAgICAoZmxh Z3MgJiBEUk1fQ0FMTEVEX0ZST01fVkJMSVJRKSkpIHsKPiA+ICsJCURSTV9ERUJVR19WQkwoImNs YW1waW5nIHZibGFuayBidW1wIHRvIDEgb24gY3J0YyAldTogZGlmZnI9JXUgIgo+ID4gKwkJCSAg ICAgICJyZWZjb3VudCAldSwgdmJsaXJxICV1XG4iLCBwaXBlLCBkaWZmLAo+ID4gKwkJCSAgICAg IGF0b21pY19yZWFkKCZ2YmxhbmstPnJlZmNvdW50KSwKPiA+ICsJCQkgICAgICAoZmxhZ3MgJiBE Uk1fQ0FMTEVEX0ZST01fVkJMSVJRKSAhPSAwKTsKPiA+ICsJCWRpZmYgPSAxOwo+ID4gKwl9Cj4g PiArCj4gPiAgCURSTV9ERUJVR19WQkwoInVwZGF0aW5nIHZibGFuayBjb3VudCBvbiBjcnRjICV1 OiIKPiA+ICAJCSAgICAgICIgY3VycmVudD0ldSwgZGlmZj0ldSwgaHc9JXUgaHdfbGFzdD0ldVxu IiwKPiA+ICAJCSAgICAgIHBpcGUsIHZibGFuay0+Y291bnQsIGRpZmYsIGN1cl92YmxhbmssIHZi bGFuay0+bGFzdCk7Cj4gPiAtLSAKPiA+IDEuOS4xCj4gPiAKPiAKPiAtLSAKPiBEYW5pZWwgVmV0 dGVyCj4gU29mdHdhcmUgRW5naW5lZXIsIEludGVsIENvcnBvcmF0aW9uCj4gaHR0cDovL2Jsb2cu ZmZ3bGwuY2gKCi0tIApWaWxsZSBTeXJqw6Rsw6QKSW50ZWwgT1RDCl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJp LWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9y Zy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=