From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757007AbdCUI02 (ORCPT ); Tue, 21 Mar 2017 04:26:28 -0400 Received: from mga05.intel.com ([192.55.52.43]:4388 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756171AbdCUI00 (ORCPT ); Tue, 21 Mar 2017 04:26:26 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,198,1486454400"; d="scan'208";a="836937113" From: Jani Nikula To: Arnd Bergmann , Daniel Vetter , David Airlie Cc: Arnd Bergmann , Mika Kuoppala , Ville =?utf-8?B?U3lyasOkbMOk?= , Chris Wilson , Imre Deak , Ander Conselvan de Oliveira , Robert Bragg , intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] drm/i915: use static const array for PICK macro In-Reply-To: <20170320215713.3086140-1-arnd@arndb.de> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo References: <20170320215713.3086140-1-arnd@arndb.de> Date: Tue, 21 Mar 2017 10:26:21 +0200 Message-ID: <877f3javde.fsf@intel.com> MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 20 Mar 2017, Arnd Bergmann wrote: > The varargs macro trick in _PIPE3/_PHY3/_PORT3 was meant as an optimization > to shrink the i915 kernel module by around 1000 bytes. Really, I didn't care one bit about the size shrink, I only cared about making it easier and less error prone to increase the number of args in a number of places. Maintainability and correctness were the goals. Just for the record. ;) Otherwise, this seems like an acceptable approach to me. Would be interesting to see what happens with this, and f4c3a88e5f04 ("drm/i915: Tighten mmio arrays for MIPI_PORT") reverted on top. BR, Jani. > However, the > downside is a size regression with CONFIG_KASAN, as I found from stack size > warnings with gcc-7.0.1: > > before: > drivers/gpu/drm/i915/intel_dpll_mgr.c: In function 'bxt_ddi_pll_get_hw_state': > drivers/gpu/drm/i915/intel_dpll_mgr.c:1644:1: error: the frame size of 176 bytes is larger than 100 bytes [-Werror=frame-larger-than=] > drivers/gpu/drm/i915/intel_dpll_mgr.c: In function 'bxt_ddi_pll_enable': > drivers/gpu/drm/i915/intel_dpll_mgr.c:1548:1: error: the frame size of 224 bytes is larger than 100 bytes [-Werror=frame-larger-than=] > > after: > drivers/gpu/drm/i915/intel_dpll_mgr.c: In function 'bxt_ddi_pll_get_hw_state': > drivers/gpu/drm/i915/intel_dpll_mgr.c:1644:1: error: the frame size of 1016 bytes is larger than 1000 bytes [-Werror=frame-larger-than=] > drivers/gpu/drm/i915/intel_dpll_mgr.c: In function 'bxt_ddi_pll_enable': > drivers/gpu/drm/i915/intel_dpll_mgr.c:1548:1: error: the frame size of 1960 bytes is larger than 1000 bytes [-Werror=frame-larger-than=] > > I also checked the module sizes and got with gcc-7.0.1 > > original: > text data bss dec hex filename > 2380830 1155436 4448 3540714 3606ea drivers/gpu/drm/i915/i915-kasan.o > 1298054 543692 2884 1844630 1c2596 drivers/gpu/drm/i915/i915-nokasan.o > > after ce64645d86ac: > text data bss dec hex filename > 2389515 1154476 4448 3548439 362517 drivers/gpu/drm/i915/i915-kasan.o > 1299639 543692 2884 1846215 1c2bc7 drivers/gpu/drm/i915/i915-nokasan.o > > with this patch: > text data bss dec hex filename > 2381275 1163884 4448 3549607 3629a7 drivers/gpu/drm/i915/i915-kasan.o > 1296038 543692 2884 1842614 1c1db6 drivers/gpu/drm/i915/i915-nokasan.o > > Actually showing a code size growth in .text both with and without kasan, > and my version gets most of it back at the expense of larger .data when > kasan is enabled. > > Fixes: ce64645d86ac ("drm/i915: use variadic macros and arrays to choose port/pipe based registers") > Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80114 > Cc: Jani Nikula > Signed-off-by: Arnd Bergmann > --- > drivers/gpu/drm/i915/i915_reg.h | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 04c8f69fcc62..39b53878a188 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -48,7 +48,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) > return !i915_mmio_reg_equal(reg, INVALID_MMIO_REG); > } > > -#define _PICK(__index, ...) (((const u32 []){ __VA_ARGS__ })[__index]) > +#define _PICK(__index, ...) ({static const u32 __arr[] = { __VA_ARGS__ }; __arr[__index];}) > > #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) > #define _MMIO_PIPE(pipe, a, b) _MMIO(_PIPE(pipe, a, b)) > @@ -2657,10 +2657,10 @@ enum skl_disp_power_wells { > /* > * Clock control & power management > */ > -#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014) > -#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018) > -#define _CHV_DPLL_C (dev_priv->info.display_mmio_offset + 0x6030) > -#define DPLL(pipe) _MMIO_PIPE3((pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C) > +#define _DPLL_A 0x6014 > +#define _DPLL_B 0x6018 > +#define _CHV_DPLL_C 0x6030 > +#define DPLL(pipe) _MMIO(dev_priv->info.display_mmio_offset + _PIPE3((pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C)) > > #define VGA0 _MMIO(0x6000) > #define VGA1 _MMIO(0x6004) > @@ -2756,10 +2756,10 @@ enum skl_disp_power_wells { > #define SDVO_MULTIPLIER_SHIFT_HIRES 4 > #define SDVO_MULTIPLIER_SHIFT_VGA 0 > > -#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c) > -#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020) > -#define _CHV_DPLL_C_MD (dev_priv->info.display_mmio_offset + 0x603c) > -#define DPLL_MD(pipe) _MMIO_PIPE3((pipe), _DPLL_A_MD, _DPLL_B_MD, _CHV_DPLL_C_MD) > +#define _DPLL_A_MD 0x601c > +#define _DPLL_B_MD 0x6020 > +#define _CHV_DPLL_C_MD 0x603c > +#define DPLL_MD(pipe) _MMIO(dev_priv->info.display_mmio_offset + _PIPE3((pipe), _DPLL_A_MD, _DPLL_B_MD, _CHV_DPLL_C_MD)) > > /* > * UDI pixel divider, controlling how many pixels are stuffed into a packet. -- Jani Nikula, Intel Open Source Technology Center From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jani Nikula Subject: Re: [PATCH] drm/i915: use static const array for PICK macro Date: Tue, 21 Mar 2017 10:26:21 +0200 Message-ID: <877f3javde.fsf@intel.com> References: <20170320215713.3086140-1-arnd@arndb.de> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20170320215713.3086140-1-arnd@arndb.de> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Daniel Vetter , David Airlie Cc: Ander Conselvan de Oliveira , Arnd Bergmann , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org T24gTW9uLCAyMCBNYXIgMjAxNywgQXJuZCBCZXJnbWFubiA8YXJuZEBhcm5kYi5kZT4gd3JvdGU6 Cj4gVGhlIHZhcmFyZ3MgbWFjcm8gdHJpY2sgaW4gX1BJUEUzL19QSFkzL19QT1JUMyB3YXMgbWVh bnQgYXMgYW4gb3B0aW1pemF0aW9uCj4gdG8gc2hyaW5rIHRoZSBpOTE1IGtlcm5lbCBtb2R1bGUg YnkgYXJvdW5kIDEwMDAgYnl0ZXMuCgpSZWFsbHksIEkgZGlkbid0IGNhcmUgb25lIGJpdCBhYm91 dCB0aGUgc2l6ZSBzaHJpbmssIEkgb25seSBjYXJlZCBhYm91dAptYWtpbmcgaXQgZWFzaWVyIGFu ZCBsZXNzIGVycm9yIHByb25lIHRvIGluY3JlYXNlIHRoZSBudW1iZXIgb2YgYXJncyBpbgphIG51 bWJlciBvZiBwbGFjZXMuIE1haW50YWluYWJpbGl0eSBhbmQgY29ycmVjdG5lc3Mgd2VyZSB0aGUg Z29hbHMuIEp1c3QKZm9yIHRoZSByZWNvcmQuIDspCgpPdGhlcndpc2UsIHRoaXMgc2VlbXMgbGlr ZSBhbiBhY2NlcHRhYmxlIGFwcHJvYWNoIHRvIG1lLiBXb3VsZCBiZQppbnRlcmVzdGluZyB0byBz ZWUgd2hhdCBoYXBwZW5zIHdpdGggdGhpcywgYW5kIGY0YzNhODhlNWYwNCAoImRybS9pOTE1OgpU aWdodGVuIG1taW8gYXJyYXlzIGZvciBNSVBJX1BPUlQiKSByZXZlcnRlZCBvbiB0b3AuCgpCUiwK SmFuaS4KCgoKPiBIb3dldmVyLCB0aGUKPiBkb3duc2lkZSBpcyBhIHNpemUgcmVncmVzc2lvbiB3 aXRoIENPTkZJR19LQVNBTiwgYXMgSSBmb3VuZCBmcm9tIHN0YWNrIHNpemUKPiB3YXJuaW5ncyB3 aXRoIGdjYy03LjAuMToKPgo+IGJlZm9yZToKPiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9k cGxsX21nci5jOiBJbiBmdW5jdGlvbiAnYnh0X2RkaV9wbGxfZ2V0X2h3X3N0YXRlJzoKPiBkcml2 ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcGxsX21nci5jOjE2NDQ6MTogZXJyb3I6IHRoZSBmcmFt ZSBzaXplIG9mIDE3NiBieXRlcyBpcyBsYXJnZXIgdGhhbiAxMDAgYnl0ZXMgWy1XZXJyb3I9ZnJh bWUtbGFyZ2VyLXRoYW49XQo+IGRyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2RwbGxfbWdyLmM6 IEluIGZ1bmN0aW9uICdieHRfZGRpX3BsbF9lbmFibGUnOgo+IGRyaXZlcnMvZ3B1L2RybS9pOTE1 L2ludGVsX2RwbGxfbWdyLmM6MTU0ODoxOiBlcnJvcjogdGhlIGZyYW1lIHNpemUgb2YgMjI0IGJ5 dGVzIGlzIGxhcmdlciB0aGFuIDEwMCBieXRlcyBbLVdlcnJvcj1mcmFtZS1sYXJnZXItdGhhbj1d Cj4KPiBhZnRlcjoKPiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcGxsX21nci5jOiBJbiBm dW5jdGlvbiAnYnh0X2RkaV9wbGxfZ2V0X2h3X3N0YXRlJzoKPiBkcml2ZXJzL2dwdS9kcm0vaTkx NS9pbnRlbF9kcGxsX21nci5jOjE2NDQ6MTogZXJyb3I6IHRoZSBmcmFtZSBzaXplIG9mIDEwMTYg Ynl0ZXMgaXMgbGFyZ2VyIHRoYW4gMTAwMCBieXRlcyBbLVdlcnJvcj1mcmFtZS1sYXJnZXItdGhh bj1dCj4gZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHBsbF9tZ3IuYzogSW4gZnVuY3Rpb24g J2J4dF9kZGlfcGxsX2VuYWJsZSc6Cj4gZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHBsbF9t Z3IuYzoxNTQ4OjE6IGVycm9yOiB0aGUgZnJhbWUgc2l6ZSBvZiAxOTYwIGJ5dGVzIGlzIGxhcmdl ciB0aGFuIDEwMDAgYnl0ZXMgWy1XZXJyb3I9ZnJhbWUtbGFyZ2VyLXRoYW49XQo+Cj4gSSBhbHNv IGNoZWNrZWQgdGhlIG1vZHVsZSBzaXplcyBhbmQgZ290IHdpdGggZ2NjLTcuMC4xCj4KPiBvcmln aW5hbDoKPiAgICB0ZXh0CSAgIGRhdGEJICAgIGJzcwkgICAgZGVjCSAgICBoZXgJZmlsZW5hbWUK PiAyMzgwODMwCTExNTU0MzYJICAgNDQ0OAkzNTQwNzE0CSAzNjA2ZWEJZHJpdmVycy9ncHUvZHJt L2k5MTUvaTkxNS1rYXNhbi5vCj4gMTI5ODA1NAkgNTQzNjkyCSAgIDI4ODQJMTg0NDYzMAkgMWMy NTk2CWRyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTUtbm9rYXNhbi5vCj4KPiBhZnRlciBjZTY0NjQ1 ZDg2YWM6Cj4gICAgdGV4dAkgICBkYXRhCSAgICBic3MJICAgIGRlYwkgICAgaGV4CWZpbGVuYW1l Cj4gMjM4OTUxNQkxMTU0NDc2CSAgIDQ0NDgJMzU0ODQzOQkgMzYyNTE3CWRyaXZlcnMvZ3B1L2Ry bS9pOTE1L2k5MTUta2FzYW4ubwo+IDEyOTk2MzkJIDU0MzY5MgkgICAyODg0CTE4NDYyMTUJIDFj MmJjNwlkcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1LW5va2FzYW4ubwo+Cj4gd2l0aCB0aGlzIHBh dGNoOgo+ICAgIHRleHQJICAgZGF0YQkgICAgYnNzCSAgICBkZWMJICAgIGhleAlmaWxlbmFtZQo+ IDIzODEyNzUJMTE2Mzg4NAkgICA0NDQ4CTM1NDk2MDcJIDM2MjlhNwlkcml2ZXJzL2dwdS9kcm0v aTkxNS9pOTE1LWthc2FuLm8KPiAxMjk2MDM4CSA1NDM2OTIJICAgMjg4NAkxODQyNjE0CSAxYzFk YjYJZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNS1ub2thc2FuLm8KPgo+IEFjdHVhbGx5IHNob3dp bmcgYSBjb2RlIHNpemUgZ3Jvd3RoIGluIC50ZXh0IGJvdGggd2l0aCBhbmQgd2l0aG91dCBrYXNh biwKPiBhbmQgbXkgdmVyc2lvbiBnZXRzIG1vc3Qgb2YgaXQgYmFjayBhdCB0aGUgZXhwZW5zZSBv ZiBsYXJnZXIgLmRhdGEgd2hlbgo+IGthc2FuIGlzIGVuYWJsZWQuCj4KPiBGaXhlczogY2U2NDY0 NWQ4NmFjICgiZHJtL2k5MTU6IHVzZSB2YXJpYWRpYyBtYWNyb3MgYW5kIGFycmF5cyB0byBjaG9v c2UgcG9ydC9waXBlIGJhc2VkIHJlZ2lzdGVycyIpCj4gTGluazogaHR0cHM6Ly9nY2MuZ251Lm9y Zy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9ODAxMTQKPiBDYzogSmFuaSBOaWt1bGEgPGphbmku bmlrdWxhQGxpbnV4LmludGVsLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBBcm5kIEJlcmdtYW5uIDxh cm5kQGFybmRiLmRlPgo+IC0tLQo+ICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X3JlZy5oIHwg MTggKysrKysrKysrLS0tLS0tLS0tCj4gIDEgZmlsZSBjaGFuZ2VkLCA5IGluc2VydGlvbnMoKyks IDkgZGVsZXRpb25zKC0pCj4KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkx NV9yZWcuaCBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfcmVnLmgKPiBpbmRleCAwNGM4ZjY5 ZmNjNjIuLjM5YjUzODc4YTE4OCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9p OTE1X3JlZy5oCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9yZWcuaAo+IEBAIC00 OCw3ICs0OCw3IEBAIHN0YXRpYyBpbmxpbmUgYm9vbCBpOTE1X21taW9fcmVnX3ZhbGlkKGk5MTVf cmVnX3QgcmVnKQo+ICAJcmV0dXJuICFpOTE1X21taW9fcmVnX2VxdWFsKHJlZywgSU5WQUxJRF9N TUlPX1JFRyk7Cj4gIH0KPiAgCj4gLSNkZWZpbmUgX1BJQ0soX19pbmRleCwgLi4uKSAoKChjb25z dCB1MzIgW10peyBfX1ZBX0FSR1NfXyB9KVtfX2luZGV4XSkKPiArI2RlZmluZSBfUElDSyhfX2lu ZGV4LCAuLi4pICh7c3RhdGljIGNvbnN0IHUzMiBfX2FycltdID0geyBfX1ZBX0FSR1NfXyB9OyBf X2FycltfX2luZGV4XTt9KQo+ICAKPiAgI2RlZmluZSBfUElQRShwaXBlLCBhLCBiKSAoKGEpICsg KHBpcGUpKigoYiktKGEpKSkKPiAgI2RlZmluZSBfTU1JT19QSVBFKHBpcGUsIGEsIGIpIF9NTUlP KF9QSVBFKHBpcGUsIGEsIGIpKQo+IEBAIC0yNjU3LDEwICsyNjU3LDEwIEBAIGVudW0gc2tsX2Rp c3BfcG93ZXJfd2VsbHMgewo+ICAvKgo+ICAgKiBDbG9jayBjb250cm9sICYgcG93ZXIgbWFuYWdl bWVudAo+ICAgKi8KPiAtI2RlZmluZSBfRFBMTF9BIChkZXZfcHJpdi0+aW5mby5kaXNwbGF5X21t aW9fb2Zmc2V0ICsgMHg2MDE0KQo+IC0jZGVmaW5lIF9EUExMX0IgKGRldl9wcml2LT5pbmZvLmRp c3BsYXlfbW1pb19vZmZzZXQgKyAweDYwMTgpCj4gLSNkZWZpbmUgX0NIVl9EUExMX0MgKGRldl9w cml2LT5pbmZvLmRpc3BsYXlfbW1pb19vZmZzZXQgKyAweDYwMzApCj4gLSNkZWZpbmUgRFBMTChw aXBlKSBfTU1JT19QSVBFMygocGlwZSksIF9EUExMX0EsIF9EUExMX0IsIF9DSFZfRFBMTF9DKQo+ ICsjZGVmaW5lIF9EUExMX0EJCQkweDYwMTQKPiArI2RlZmluZSBfRFBMTF9CCQkJMHg2MDE4Cj4g KyNkZWZpbmUgX0NIVl9EUExMX0MJCTB4NjAzMAo+ICsjZGVmaW5lIERQTEwocGlwZSkgX01NSU8o ZGV2X3ByaXYtPmluZm8uZGlzcGxheV9tbWlvX29mZnNldCArIF9QSVBFMygocGlwZSksIF9EUExM X0EsIF9EUExMX0IsIF9DSFZfRFBMTF9DKSkKPiAgCj4gICNkZWZpbmUgVkdBMAlfTU1JTygweDYw MDApCj4gICNkZWZpbmUgVkdBMQlfTU1JTygweDYwMDQpCj4gQEAgLTI3NTYsMTAgKzI3NTYsMTAg QEAgZW51bSBza2xfZGlzcF9wb3dlcl93ZWxscyB7Cj4gICNkZWZpbmUgICBTRFZPX01VTFRJUExJ RVJfU0hJRlRfSElSRVMJCTQKPiAgI2RlZmluZSAgIFNEVk9fTVVMVElQTElFUl9TSElGVF9WR0EJ CTAKPiAgCj4gLSNkZWZpbmUgX0RQTExfQV9NRCAoZGV2X3ByaXYtPmluZm8uZGlzcGxheV9tbWlv X29mZnNldCArIDB4NjAxYykKPiAtI2RlZmluZSBfRFBMTF9CX01EIChkZXZfcHJpdi0+aW5mby5k aXNwbGF5X21taW9fb2Zmc2V0ICsgMHg2MDIwKQo+IC0jZGVmaW5lIF9DSFZfRFBMTF9DX01EIChk ZXZfcHJpdi0+aW5mby5kaXNwbGF5X21taW9fb2Zmc2V0ICsgMHg2MDNjKQo+IC0jZGVmaW5lIERQ TExfTUQocGlwZSkgX01NSU9fUElQRTMoKHBpcGUpLCBfRFBMTF9BX01ELCBfRFBMTF9CX01ELCBf Q0hWX0RQTExfQ19NRCkKPiArI2RlZmluZSBfRFBMTF9BX01ECQkJCTB4NjAxYwo+ICsjZGVmaW5l IF9EUExMX0JfTUQJCQkJMHg2MDIwCj4gKyNkZWZpbmUgX0NIVl9EUExMX0NfTUQJCQkJMHg2MDNj Cj4gKyNkZWZpbmUgRFBMTF9NRChwaXBlKSBfTU1JTyhkZXZfcHJpdi0+aW5mby5kaXNwbGF5X21t aW9fb2Zmc2V0ICsgX1BJUEUzKChwaXBlKSwgX0RQTExfQV9NRCwgX0RQTExfQl9NRCwgX0NIVl9E UExMX0NfTUQpKQo+ICAKPiAgLyoKPiAgICogVURJIHBpeGVsIGRpdmlkZXIsIGNvbnRyb2xsaW5n IGhvdyBtYW55IHBpeGVscyBhcmUgc3R1ZmZlZCBpbnRvIGEgcGFja2V0LgoKLS0gCkphbmkgTmlr dWxhLCBJbnRlbCBPcGVuIFNvdXJjZSBUZWNobm9sb2d5IENlbnRlcgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpJbnRlbC1nZnggbWFpbGluZyBsaXN0Cklu dGVsLWdmeEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5v cmcvbWFpbG1hbi9saXN0aW5mby9pbnRlbC1nZngK