From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bartlomiej Zolnierkiewicz Date: Wed, 12 Jul 2017 10:40:45 +0000 Subject: Re: [PATCH 1/4] fbcon: Make fbcon a built-time depency for fbdev Message-Id: <1829417.jhVqBZyytf@amdc3058> List-Id: References: <20170706125735.28299-1-daniel.vetter@ffwll.ch> <20170706125735.28299-2-daniel.vetter@ffwll.ch> In-Reply-To: <20170706125735.28299-2-daniel.vetter@ffwll.ch> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: Daniel Vetter Cc: linux-fbdev@vger.kernel.org, Sergey Senozhatsky , Intel Graphics Development , Steven Rostedt , DRI Development , Daniel Vetter , Alan Cox On Thursday, July 06, 2017 02:57:32 PM Daniel Vetter wrote: > There's a bunch of folks who're trying to make printk less > contended and faster, but there's a problem: printk uses the > console_lock, and the console lock has become the BKL for all things > fbdev/fbcon, which in turn pulled in half the drm subsystem under that > lock. That's awkward. > > There reasons for that is probably just a historical accident: > > - fbcon is a runtime option of fbdev, i.e. at runtime you can pick > whether your fbdev driver instances are used as kernel consoles. > Unfortunately this wasn't implemented with some module option, but > through some module loading magic: As long as you don't load > fbcon.ko, there's no fbdev console support, but loading it (in any > order wrt fbdev drivers) will create console instances for all fbdev > drivers. > > - This was implemented through a notifier chain. fbcon.ko enumerates > all fbdev instances at load time and also registers itself as > listener in the fbdev notifier. The fbdev core tries to register new > fbdev instances with fbcon using the notifier. > > - On top of that the modifier chain is also used at runtime by the > fbdev subsystem to e.g. control backlights for panels. > > - The problem is that the notifier puts a mutex locking context > between fbdev and fbcon, which mixes up the locking contexts for > both the runtime usage and the register time usage to notify fbcon. > And at runtime fbcon (through the fbdev core) might call into the > notifier from a printk critical section while console_lock is held. > > - This means console_lock must be an outer lock for the entire fbdev > subsystem, which also means it must be acquired when registering a > new framebuffer driver as the outermost lock since we might call > into fbcon (through the notifier) which would result in a locking > inversion if fbcon would acquire the console_lock from its notifier > callback (which it needs to register the console). > > - console_lock can be held anywhere, since printk can be called > anywhere, and through the above story, plus drm/kms being an fbdev > driver, we pull in a shocking amount of locking hiercharchy > underneath the console_lock. Which makes cleaning up printk really > hard (not even splitting console_lock into an rwsem is all that > useful due to this). > > There's various ways to address this, but the cleanest would be to > make fbcon a compile-time option, where fbdev directly calls the fbcon > register functions from register_framebuffer, or dummy static inline > versions if fbcon is disabled. Maybe augmented with a runtime knob to > disable fbcon, if that's needed (for debugging perhaps). > > But this could break some users who rely on the magic "loading > fbcon.ko enables/disables fbdev framebuffers at runtime" thing, even > if that's unlikely. Hence we must be careful: > > 1. Create a compile-time dependency between fbcon and fbdev in the > least minimal way. This is what this patch does. > > 2. Wait at least 1 year to give possible users time to scream about > how we broke their setup. Unlikely, since all distros make fbcon > compile-in, and embedded platforms only compile stuff they know they > need anyway. But still. > > 3. Convert the notifier to direct functions calls, with dummy static > inlines if fbcon is disabled. We'll still need the fb notifier for the > other uses (like backlights), but we can probably move it into the fb > core (atm it must be built-into vmlinux). > > 4. Push console_lock down the call-chain, until it is down in > console_register again. > > 5. Finally start to clean up and rework the printk/console locking. > > For context of this saga see > > commit 50e244cc793d511b86adea24972f3a7264cae114 > Author: Alan Cox > Date: Fri Jan 25 10:28:15 2013 +1000 > > fb: rework locking to fix lock ordering on takeover > > plus the pile of commits on top that tried to make this all work > without terminally upsetting lockdep. We've uncovered all this when > console_lock lockdep annotations where added in > > commit daee779718a319ff9f83e1ba3339334ac650bb22 > Author: Daniel Vetter > Date: Sat Sep 22 19:52:11 2012 +0200 > > console: implement lockdep support for console_lock > > On the patch itself: > - Switch CONFIG_FRAMEBUFFER_CONSOLE to be a boolean, using the overall > CONFIG_FB tristate to decided whether it should be a module or > built-in. > > - At first I thought I could force the build depency with just a dummy > symbol that fbcon.ko exports and fb.ko uses. But that leads to a > module depency cycle (it works fine when built-in). > > Since this tight binding is the entire goal the simplest solution is > to move all the fbcon modules (and there's a bunch of optinal > source-files which are each modules of their own, for no good > reason) into the overall fb.ko core module. That's a bit more than > what I would have liked to do in this patch, but oh well. > > Cc: Alan Cox > Cc: Sergey Senozhatsky > Cc: Linux Fbdev development list > Cc: Steven Rostedt > Cc: Bartlomiej Zolnierkiewicz > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Daniel Vetter Acked-by: Bartlomiej Zolnierkiewicz > --- > v2: Switch to building fbcon code into fb.ko right away because the > cheap trick leads to a module depency loop. > --- Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bartlomiej Zolnierkiewicz Subject: Re: [PATCH 1/4] fbcon: Make fbcon a built-time depency for fbdev Date: Wed, 12 Jul 2017 12:40:45 +0200 Message-ID: <1829417.jhVqBZyytf@amdc3058> References: <20170706125735.28299-1-daniel.vetter@ffwll.ch> <20170706125735.28299-2-daniel.vetter@ffwll.ch> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-reply-to: <20170706125735.28299-2-daniel.vetter@ffwll.ch> 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: linux-fbdev@vger.kernel.org, Sergey Senozhatsky , Intel Graphics Development , Steven Rostedt , DRI Development , Daniel Vetter , Alan Cox List-Id: dri-devel@lists.freedesktop.org T24gVGh1cnNkYXksIEp1bHkgMDYsIDIwMTcgMDI6NTc6MzIgUE0gRGFuaWVsIFZldHRlciB3cm90 ZToKPiBUaGVyZSdzIGEgYnVuY2ggb2YgZm9sa3Mgd2hvJ3JlIHRyeWluZyB0byBtYWtlIHByaW50 ayBsZXNzCj4gY29udGVuZGVkIGFuZCBmYXN0ZXIsIGJ1dCB0aGVyZSdzIGEgcHJvYmxlbTogcHJp bnRrIHVzZXMgdGhlCj4gY29uc29sZV9sb2NrLCBhbmQgdGhlIGNvbnNvbGUgbG9jayBoYXMgYmVj b21lIHRoZSBCS0wgZm9yIGFsbCB0aGluZ3MKPiBmYmRldi9mYmNvbiwgd2hpY2ggaW4gdHVybiBw dWxsZWQgaW4gaGFsZiB0aGUgZHJtIHN1YnN5c3RlbSB1bmRlciB0aGF0Cj4gbG9jay4gVGhhdCdz IGF3a3dhcmQuCj4gCj4gVGhlcmUgcmVhc29ucyBmb3IgdGhhdCBpcyBwcm9iYWJseSBqdXN0IGEg aGlzdG9yaWNhbCBhY2NpZGVudDoKPiAKPiAtIGZiY29uIGlzIGEgcnVudGltZSBvcHRpb24gb2Yg ZmJkZXYsIGkuZS4gYXQgcnVudGltZSB5b3UgY2FuIHBpY2sKPiAgIHdoZXRoZXIgeW91ciBmYmRl diBkcml2ZXIgaW5zdGFuY2VzIGFyZSB1c2VkIGFzIGtlcm5lbCBjb25zb2xlcy4KPiAgIFVuZm9y dHVuYXRlbHkgdGhpcyB3YXNuJ3QgaW1wbGVtZW50ZWQgd2l0aCBzb21lIG1vZHVsZSBvcHRpb24s IGJ1dAo+ICAgdGhyb3VnaCBzb21lIG1vZHVsZSBsb2FkaW5nIG1hZ2ljOiBBcyBsb25nIGFzIHlv dSBkb24ndCBsb2FkCj4gICBmYmNvbi5rbywgdGhlcmUncyBubyBmYmRldiBjb25zb2xlIHN1cHBv cnQsIGJ1dCBsb2FkaW5nIGl0IChpbiBhbnkKPiAgIG9yZGVyIHdydCBmYmRldiBkcml2ZXJzKSB3 aWxsIGNyZWF0ZSBjb25zb2xlIGluc3RhbmNlcyBmb3IgYWxsIGZiZGV2Cj4gICBkcml2ZXJzLgo+ IAo+IC0gVGhpcyB3YXMgaW1wbGVtZW50ZWQgdGhyb3VnaCBhIG5vdGlmaWVyIGNoYWluLiBmYmNv bi5rbyBlbnVtZXJhdGVzCj4gICBhbGwgZmJkZXYgaW5zdGFuY2VzIGF0IGxvYWQgdGltZSBhbmQg YWxzbyByZWdpc3RlcnMgaXRzZWxmIGFzCj4gICBsaXN0ZW5lciBpbiB0aGUgZmJkZXYgbm90aWZp ZXIuIFRoZSBmYmRldiBjb3JlIHRyaWVzIHRvIHJlZ2lzdGVyIG5ldwo+ICAgZmJkZXYgaW5zdGFu Y2VzIHdpdGggZmJjb24gdXNpbmcgdGhlIG5vdGlmaWVyLgo+IAo+IC0gT24gdG9wIG9mIHRoYXQg dGhlIG1vZGlmaWVyIGNoYWluIGlzIGFsc28gdXNlZCBhdCBydW50aW1lIGJ5IHRoZQo+ICAgZmJk ZXYgc3Vic3lzdGVtIHRvIGUuZy4gY29udHJvbCBiYWNrbGlnaHRzIGZvciBwYW5lbHMuCj4gCj4g LSBUaGUgcHJvYmxlbSBpcyB0aGF0IHRoZSBub3RpZmllciBwdXRzIGEgbXV0ZXggbG9ja2luZyBj b250ZXh0Cj4gICBiZXR3ZWVuIGZiZGV2IGFuZCBmYmNvbiwgd2hpY2ggbWl4ZXMgdXAgdGhlIGxv Y2tpbmcgY29udGV4dHMgZm9yCj4gICBib3RoIHRoZSBydW50aW1lIHVzYWdlIGFuZCB0aGUgcmVn aXN0ZXIgdGltZSB1c2FnZSB0byBub3RpZnkgZmJjb24uCj4gICBBbmQgYXQgcnVudGltZSBmYmNv biAodGhyb3VnaCB0aGUgZmJkZXYgY29yZSkgbWlnaHQgY2FsbCBpbnRvIHRoZQo+ICAgbm90aWZp ZXIgZnJvbSBhIHByaW50ayBjcml0aWNhbCBzZWN0aW9uIHdoaWxlIGNvbnNvbGVfbG9jayBpcyBo ZWxkLgo+IAo+IC0gVGhpcyBtZWFucyBjb25zb2xlX2xvY2sgbXVzdCBiZSBhbiBvdXRlciBsb2Nr IGZvciB0aGUgZW50aXJlIGZiZGV2Cj4gICBzdWJzeXN0ZW0sIHdoaWNoIGFsc28gbWVhbnMgaXQg bXVzdCBiZSBhY3F1aXJlZCB3aGVuIHJlZ2lzdGVyaW5nIGEKPiAgIG5ldyBmcmFtZWJ1ZmZlciBk cml2ZXIgYXMgdGhlIG91dGVybW9zdCBsb2NrIHNpbmNlIHdlIG1pZ2h0IGNhbGwKPiAgIGludG8g ZmJjb24gKHRocm91Z2ggdGhlIG5vdGlmaWVyKSB3aGljaCB3b3VsZCByZXN1bHQgaW4gYSBsb2Nr aW5nCj4gICBpbnZlcnNpb24gaWYgZmJjb24gd291bGQgYWNxdWlyZSB0aGUgY29uc29sZV9sb2Nr IGZyb20gaXRzIG5vdGlmaWVyCj4gICBjYWxsYmFjayAod2hpY2ggaXQgbmVlZHMgdG8gcmVnaXN0 ZXIgdGhlIGNvbnNvbGUpLgo+IAo+IC0gY29uc29sZV9sb2NrIGNhbiBiZSBoZWxkIGFueXdoZXJl LCBzaW5jZSBwcmludGsgY2FuIGJlIGNhbGxlZAo+ICAgYW55d2hlcmUsIGFuZCB0aHJvdWdoIHRo ZSBhYm92ZSBzdG9yeSwgcGx1cyBkcm0va21zIGJlaW5nIGFuIGZiZGV2Cj4gICBkcml2ZXIsIHdl IHB1bGwgaW4gYSBzaG9ja2luZyBhbW91bnQgb2YgbG9ja2luZyBoaWVyY2hhcmNoeQo+ICAgdW5k ZXJuZWF0aCB0aGUgY29uc29sZV9sb2NrLiBXaGljaCBtYWtlcyBjbGVhbmluZyB1cCBwcmludGsg cmVhbGx5Cj4gICBoYXJkIChub3QgZXZlbiBzcGxpdHRpbmcgY29uc29sZV9sb2NrIGludG8gYW4g cndzZW0gaXMgYWxsIHRoYXQKPiAgIHVzZWZ1bCBkdWUgdG8gdGhpcykuCj4gCj4gVGhlcmUncyB2 YXJpb3VzIHdheXMgdG8gYWRkcmVzcyB0aGlzLCBidXQgdGhlIGNsZWFuZXN0IHdvdWxkIGJlIHRv Cj4gbWFrZSBmYmNvbiBhIGNvbXBpbGUtdGltZSBvcHRpb24sIHdoZXJlIGZiZGV2IGRpcmVjdGx5 IGNhbGxzIHRoZSBmYmNvbgo+IHJlZ2lzdGVyIGZ1bmN0aW9ucyBmcm9tIHJlZ2lzdGVyX2ZyYW1l YnVmZmVyLCBvciBkdW1teSBzdGF0aWMgaW5saW5lCj4gdmVyc2lvbnMgaWYgZmJjb24gaXMgZGlz YWJsZWQuIE1heWJlIGF1Z21lbnRlZCB3aXRoIGEgcnVudGltZSBrbm9iIHRvCj4gZGlzYWJsZSBm YmNvbiwgaWYgdGhhdCdzIG5lZWRlZCAoZm9yIGRlYnVnZ2luZyBwZXJoYXBzKS4KPiAKPiBCdXQg dGhpcyBjb3VsZCBicmVhayBzb21lIHVzZXJzIHdobyByZWx5IG9uIHRoZSBtYWdpYyAibG9hZGlu Zwo+IGZiY29uLmtvIGVuYWJsZXMvZGlzYWJsZXMgZmJkZXYgZnJhbWVidWZmZXJzIGF0IHJ1bnRp bWUiIHRoaW5nLCBldmVuCj4gaWYgdGhhdCdzIHVubGlrZWx5LiBIZW5jZSB3ZSBtdXN0IGJlIGNh cmVmdWw6Cj4gCj4gMS4gQ3JlYXRlIGEgY29tcGlsZS10aW1lIGRlcGVuZGVuY3kgYmV0d2VlbiBm YmNvbiBhbmQgZmJkZXYgaW4gdGhlCj4gbGVhc3QgbWluaW1hbCB3YXkuIFRoaXMgaXMgd2hhdCB0 aGlzIHBhdGNoIGRvZXMuCj4gCj4gMi4gV2FpdCBhdCBsZWFzdCAxIHllYXIgdG8gZ2l2ZSBwb3Nz aWJsZSB1c2VycyB0aW1lIHRvIHNjcmVhbSBhYm91dAo+IGhvdyB3ZSBicm9rZSB0aGVpciBzZXR1 cC4gVW5saWtlbHksIHNpbmNlIGFsbCBkaXN0cm9zIG1ha2UgZmJjb24KPiBjb21waWxlLWluLCBh bmQgZW1iZWRkZWQgcGxhdGZvcm1zIG9ubHkgY29tcGlsZSBzdHVmZiB0aGV5IGtub3cgdGhleQo+ IG5lZWQgYW55d2F5LiBCdXQgc3RpbGwuCj4gCj4gMy4gQ29udmVydCB0aGUgbm90aWZpZXIgdG8g ZGlyZWN0IGZ1bmN0aW9ucyBjYWxscywgd2l0aCBkdW1teSBzdGF0aWMKPiBpbmxpbmVzIGlmIGZi Y29uIGlzIGRpc2FibGVkLiBXZSdsbCBzdGlsbCBuZWVkIHRoZSBmYiBub3RpZmllciBmb3IgdGhl Cj4gb3RoZXIgdXNlcyAobGlrZSBiYWNrbGlnaHRzKSwgYnV0IHdlIGNhbiBwcm9iYWJseSBtb3Zl IGl0IGludG8gdGhlIGZiCj4gY29yZSAoYXRtIGl0IG11c3QgYmUgYnVpbHQtaW50byB2bWxpbnV4 KS4KPiAKPiA0LiBQdXNoIGNvbnNvbGVfbG9jayBkb3duIHRoZSBjYWxsLWNoYWluLCB1bnRpbCBp dCBpcyBkb3duIGluCj4gY29uc29sZV9yZWdpc3RlciBhZ2Fpbi4KPiAKPiA1LiBGaW5hbGx5IHN0 YXJ0IHRvIGNsZWFuIHVwIGFuZCByZXdvcmsgdGhlIHByaW50ay9jb25zb2xlIGxvY2tpbmcuCj4g Cj4gRm9yIGNvbnRleHQgb2YgdGhpcyBzYWdhIHNlZQo+IAo+IGNvbW1pdCA1MGUyNDRjYzc5M2Q1 MTFiODZhZGVhMjQ5NzJmM2E3MjY0Y2FlMTE0Cj4gQXV0aG9yOiBBbGFuIENveCA8YWxhbkBsaW51 eC5pbnRlbC5jb20+Cj4gRGF0ZTogICBGcmkgSmFuIDI1IDEwOjI4OjE1IDIwMTMgKzEwMDAKPiAK PiAgICAgZmI6IHJld29yayBsb2NraW5nIHRvIGZpeCBsb2NrIG9yZGVyaW5nIG9uIHRha2VvdmVy Cj4gCj4gcGx1cyB0aGUgcGlsZSBvZiBjb21taXRzIG9uIHRvcCB0aGF0IHRyaWVkIHRvIG1ha2Ug dGhpcyBhbGwgd29yawo+IHdpdGhvdXQgdGVybWluYWxseSB1cHNldHRpbmcgbG9ja2RlcC4gV2Un dmUgdW5jb3ZlcmVkIGFsbCB0aGlzIHdoZW4KPiBjb25zb2xlX2xvY2sgbG9ja2RlcCBhbm5vdGF0 aW9ucyB3aGVyZSBhZGRlZCBpbgo+IAo+IGNvbW1pdCBkYWVlNzc5NzE4YTMxOWZmOWY4M2UxYmEz MzM5MzM0YWM2NTBiYjIyCj4gQXV0aG9yOiBEYW5pZWwgVmV0dGVyIDxkYW5pZWwudmV0dGVyQGZm d2xsLmNoPgo+IERhdGU6ICAgU2F0IFNlcCAyMiAxOTo1MjoxMSAyMDEyICswMjAwCj4gCj4gICAg IGNvbnNvbGU6IGltcGxlbWVudCBsb2NrZGVwIHN1cHBvcnQgZm9yIGNvbnNvbGVfbG9jawo+IAo+ IE9uIHRoZSBwYXRjaCBpdHNlbGY6Cj4gLSBTd2l0Y2ggQ09ORklHX0ZSQU1FQlVGRkVSX0NPTlNP TEUgdG8gYmUgYSBib29sZWFuLCB1c2luZyB0aGUgb3ZlcmFsbAo+ICAgQ09ORklHX0ZCIHRyaXN0 YXRlIHRvIGRlY2lkZWQgd2hldGhlciBpdCBzaG91bGQgYmUgYSBtb2R1bGUgb3IKPiAgIGJ1aWx0 LWluLgo+IAo+IC0gQXQgZmlyc3QgSSB0aG91Z2h0IEkgY291bGQgZm9yY2UgdGhlIGJ1aWxkIGRl cGVuY3kgd2l0aCBqdXN0IGEgZHVtbXkKPiAgIHN5bWJvbCB0aGF0IGZiY29uLmtvIGV4cG9ydHMg YW5kIGZiLmtvIHVzZXMuIEJ1dCB0aGF0IGxlYWRzIHRvIGEKPiAgIG1vZHVsZSBkZXBlbmN5IGN5 Y2xlIChpdCB3b3JrcyBmaW5lIHdoZW4gYnVpbHQtaW4pLgo+IAo+ICAgU2luY2UgdGhpcyB0aWdo dCBiaW5kaW5nIGlzIHRoZSBlbnRpcmUgZ29hbCB0aGUgc2ltcGxlc3Qgc29sdXRpb24gaXMKPiAg IHRvIG1vdmUgYWxsIHRoZSBmYmNvbiBtb2R1bGVzIChhbmQgdGhlcmUncyBhIGJ1bmNoIG9mIG9w dGluYWwKPiAgIHNvdXJjZS1maWxlcyB3aGljaCBhcmUgZWFjaCBtb2R1bGVzIG9mIHRoZWlyIG93 biwgZm9yIG5vIGdvb2QKPiAgIHJlYXNvbikgaW50byB0aGUgb3ZlcmFsbCBmYi5rbyBjb3JlIG1v ZHVsZS4gVGhhdCdzIGEgYml0IG1vcmUgdGhhbgo+ICAgd2hhdCBJIHdvdWxkIGhhdmUgbGlrZWQg dG8gZG8gaW4gdGhpcyBwYXRjaCwgYnV0IG9oIHdlbGwuCj4gCj4gQ2M6IEFsYW4gQ294IDxhbGFu QGx4b3JndWsudWt1dS5vcmcudWs+Cj4gQ2M6IFNlcmdleSBTZW5vemhhdHNreSA8c2VyZ2V5LnNl bm96aGF0c2t5LndvcmtAZ21haWwuY29tPgo+IENjOiBMaW51eCBGYmRldiBkZXZlbG9wbWVudCBs aXN0IDxsaW51eC1mYmRldkB2Z2VyLmtlcm5lbC5vcmc+Cj4gQ2M6IFN0ZXZlbiBSb3N0ZWR0IDxy b3N0ZWR0QGdvb2RtaXMub3JnPgo+IENjOiBCYXJ0bG9taWVqIFpvbG5pZXJraWV3aWN6IDxiLnpv bG5pZXJraWVAc2Ftc3VuZy5jb20+Cj4gQ2M6IGRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5v cmcKPiBTaWduZWQtb2ZmLWJ5OiBEYW5pZWwgVmV0dGVyIDxkYW5pZWwudmV0dGVyQGludGVsLmNv bT4KCkFja2VkLWJ5OiBCYXJ0bG9taWVqIFpvbG5pZXJraWV3aWN6IDxiLnpvbG5pZXJraWVAc2Ft c3VuZy5jb20+Cgo+IC0tLQo+IHYyOiBTd2l0Y2ggdG8gYnVpbGRpbmcgZmJjb24gY29kZSBpbnRv IGZiLmtvIHJpZ2h0IGF3YXkgYmVjYXVzZSB0aGUKPiBjaGVhcCB0cmljayBsZWFkcyB0byBhIG1v ZHVsZSBkZXBlbmN5IGxvb3AuCj4gLS0tCgpCZXN0IHJlZ2FyZHMsCi0tCkJhcnRsb21pZWogWm9s bmllcmtpZXdpY3oKU2Ftc3VuZyBSJkQgSW5zdGl0dXRlIFBvbGFuZApTYW1zdW5nIEVsZWN0cm9u aWNzCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmkt ZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6 Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK