From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755241AbeDCJJP (ORCPT ); Tue, 3 Apr 2018 05:09:15 -0400 Received: from mail-wm0-f52.google.com ([74.125.82.52]:56245 "EHLO mail-wm0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753441AbeDCJJN (ORCPT ); Tue, 3 Apr 2018 05:09:13 -0400 X-Google-Smtp-Source: AIpwx48GAXQv29E3xQM/x0Ooyh3P1tYfEKNyCzx5Zw919+kFP0xENGoe9hNsK39IzJMsMu9m8z/YHQ== Date: Tue, 3 Apr 2018 11:09:09 +0200 From: Daniel Vetter To: christian.koenig@amd.com Cc: linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 4/8] dma-buf: add peer2peer flag Message-ID: <20180403090909.GN3881@phenom.ffwll.local> Mail-Followup-To: christian.koenig@amd.com, linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org References: <20180325110000.2238-1-christian.koenig@amd.com> <20180325110000.2238-4-christian.koenig@amd.com> <20180329065753.GD3881@phenom.ffwll.local> <8b823458-8bdc-3217-572b-509a28aae742@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <8b823458-8bdc-3217-572b-509a28aae742@gmail.com> X-Operating-System: Linux phenom 4.15.0-1-amd64 User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 29, 2018 at 01:34:24PM +0200, Christian König wrote: > Am 29.03.2018 um 08:57 schrieb Daniel Vetter: > > On Sun, Mar 25, 2018 at 12:59:56PM +0200, Christian König wrote: > > > Add a peer2peer flag noting that the importer can deal with device > > > resources which are not backed by pages. > > > > > > Signed-off-by: Christian König > > Um strictly speaking they all should, but ttm never bothered to use the > > real interfaces but just hacked around the provided sg list, grabbing the > > underlying struct pages, then rebuilding&remapping the sg list again. > > Actually that isn't correct. TTM converts them to a dma address array > because drivers need it like this (at least nouveau, radeon and amdgpu). > > I've fixed radeon and amdgpu to be able to deal without it and mailed with > Ben about nouveau, but the outcome is they don't really know. > > TTM itself doesn't have any need for the pages on imported BOs (you can't > mmap them anyway), the real underlying problem is that sg tables doesn't > provide what drivers need. > > I think we could rather easily fix sg tables, but that is a totally separate > task. Looking at patch 8, the sg table seems perfectly sufficient to convey the right dma addresses to the importer. Ofcourse the exporter has to set up the right kind of iommu mappings to make this work. > > The entire point of using sg lists was exactly to allow this use case of > > peer2peer dma (or well in general have special exporters which managed > > memory/IO ranges not backed by struct page). So essentially you're having > > a "I'm totally not broken flag" here. > > No, independent of needed struct page pointers we need to note if the > exporter can handle peer2peer stuff from the hardware side in general. > > So what I've did is just to set peer2peer allowed on the importer because of > the driver needs and clear it in the exporter if the hardware can't handle > that. The only thing the importer seems to do is call the pci_peer_traffic_supported, which the exporter could call too. What am I missing (since the sturct_page stuff sounds like it's fixed already by you)? -Daniel > > I think a better approach would be if we add a requires_struct_page or so, > > and annotate the current importers accordingly. Or we just fix them up (it > > is all in shared ttm code after all, I think everyone else got this > > right). > > I would rather not bed on that. > > Christian. > > > -Daniel > > > > > --- > > > drivers/dma-buf/dma-buf.c | 1 + > > > include/linux/dma-buf.h | 4 ++++ > > > 2 files changed, 5 insertions(+) > > > > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > > > index ffaa2f9a9c2c..f420225f93c6 100644 > > > --- a/drivers/dma-buf/dma-buf.c > > > +++ b/drivers/dma-buf/dma-buf.c > > > @@ -565,6 +565,7 @@ struct dma_buf_attachment *dma_buf_attach(const struct dma_buf_attach_info *info > > > attach->dev = info->dev; > > > attach->dmabuf = dmabuf; > > > + attach->peer2peer = info->peer2peer; > > > attach->priv = info->priv; > > > attach->invalidate = info->invalidate; > > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > > > index 15dd8598bff1..1ef50bd9bc5b 100644 > > > --- a/include/linux/dma-buf.h > > > +++ b/include/linux/dma-buf.h > > > @@ -313,6 +313,7 @@ struct dma_buf { > > > * @dmabuf: buffer for this attachment. > > > * @dev: device attached to the buffer. > > > * @node: list of dma_buf_attachment. > > > + * @peer2peer: true if the importer can handle peer resources without pages. > > > * @priv: exporter specific attachment data. > > > * > > > * This structure holds the attachment information between the dma_buf buffer > > > @@ -328,6 +329,7 @@ struct dma_buf_attachment { > > > struct dma_buf *dmabuf; > > > struct device *dev; > > > struct list_head node; > > > + bool peer2peer; > > > void *priv; > > > /** > > > @@ -392,6 +394,7 @@ struct dma_buf_export_info { > > > * @dmabuf: the exported dma_buf > > > * @dev: the device which wants to import the attachment > > > * @priv: private data of importer to this attachment > > > + * @peer2peer: true if the importer can handle peer resources without pages > > > * @invalidate: callback to use for invalidating mappings > > > * > > > * This structure holds the information required to attach to a buffer. Used > > > @@ -401,6 +404,7 @@ struct dma_buf_attach_info { > > > struct dma_buf *dmabuf; > > > struct device *dev; > > > void *priv; > > > + bool peer2peer; > > > void (*invalidate)(struct dma_buf_attachment *attach); > > > }; > > > -- > > > 2.14.1 > > > > > > _______________________________________________ > > > dri-devel mailing list > > > dri-devel@lists.freedesktop.org > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH 4/8] dma-buf: add peer2peer flag Date: Tue, 3 Apr 2018 11:09:09 +0200 Message-ID: <20180403090909.GN3881@phenom.ffwll.local> References: <20180325110000.2238-1-christian.koenig@amd.com> <20180325110000.2238-4-christian.koenig@amd.com> <20180329065753.GD3881@phenom.ffwll.local> <8b823458-8bdc-3217-572b-509a28aae742@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Content-Disposition: inline In-Reply-To: <8b823458-8bdc-3217-572b-509a28aae742-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: amd-gfx-bounces-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Sender: "amd-gfx" To: christian.koenig-5C7GfCeVMHo@public.gmane.org Cc: linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, linux-media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org List-Id: dri-devel@lists.freedesktop.org T24gVGh1LCBNYXIgMjksIDIwMTggYXQgMDE6MzQ6MjRQTSArMDIwMCwgQ2hyaXN0aWFuIEvDtm5p ZyB3cm90ZToKPiBBbSAyOS4wMy4yMDE4IHVtIDA4OjU3IHNjaHJpZWIgRGFuaWVsIFZldHRlcjoK PiA+IE9uIFN1biwgTWFyIDI1LCAyMDE4IGF0IDEyOjU5OjU2UE0gKzAyMDAsIENocmlzdGlhbiBL w7ZuaWcgd3JvdGU6Cj4gPiA+IEFkZCBhIHBlZXIycGVlciBmbGFnIG5vdGluZyB0aGF0IHRoZSBp bXBvcnRlciBjYW4gZGVhbCB3aXRoIGRldmljZQo+ID4gPiByZXNvdXJjZXMgd2hpY2ggYXJlIG5v dCBiYWNrZWQgYnkgcGFnZXMuCj4gPiA+IAo+ID4gPiBTaWduZWQtb2ZmLWJ5OiBDaHJpc3RpYW4g S8O2bmlnIDxjaHJpc3RpYW4ua29lbmlnQGFtZC5jb20+Cj4gPiBVbSBzdHJpY3RseSBzcGVha2lu ZyB0aGV5IGFsbCBzaG91bGQsIGJ1dCB0dG0gbmV2ZXIgYm90aGVyZWQgdG8gdXNlIHRoZQo+ID4g cmVhbCBpbnRlcmZhY2VzIGJ1dCBqdXN0IGhhY2tlZCBhcm91bmQgdGhlIHByb3ZpZGVkIHNnIGxp c3QsIGdyYWJiaW5nIHRoZQo+ID4gdW5kZXJseWluZyBzdHJ1Y3QgcGFnZXMsIHRoZW4gcmVidWls ZGluZyZyZW1hcHBpbmcgdGhlIHNnIGxpc3QgYWdhaW4uCj4gCj4gQWN0dWFsbHkgdGhhdCBpc24n dCBjb3JyZWN0LiBUVE0gY29udmVydHMgdGhlbSB0byBhIGRtYSBhZGRyZXNzIGFycmF5Cj4gYmVj YXVzZSBkcml2ZXJzIG5lZWQgaXQgbGlrZSB0aGlzIChhdCBsZWFzdCBub3V2ZWF1LCByYWRlb24g YW5kIGFtZGdwdSkuCj4gCj4gSSd2ZSBmaXhlZCByYWRlb24gYW5kIGFtZGdwdSB0byBiZSBhYmxl IHRvIGRlYWwgd2l0aG91dCBpdCBhbmQgbWFpbGVkIHdpdGgKPiBCZW4gYWJvdXQgbm91dmVhdSwg YnV0IHRoZSBvdXRjb21lIGlzIHRoZXkgZG9uJ3QgcmVhbGx5IGtub3cuCj4gCj4gVFRNIGl0c2Vs ZiBkb2Vzbid0IGhhdmUgYW55IG5lZWQgZm9yIHRoZSBwYWdlcyBvbiBpbXBvcnRlZCBCT3MgKHlv dSBjYW4ndAo+IG1tYXAgdGhlbSBhbnl3YXkpLCB0aGUgcmVhbCB1bmRlcmx5aW5nIHByb2JsZW0g aXMgdGhhdCBzZyB0YWJsZXMgZG9lc24ndAo+IHByb3ZpZGUgd2hhdCBkcml2ZXJzIG5lZWQuCj4g Cj4gSSB0aGluayB3ZSBjb3VsZCByYXRoZXIgZWFzaWx5IGZpeCBzZyB0YWJsZXMsIGJ1dCB0aGF0 IGlzIGEgdG90YWxseSBzZXBhcmF0ZQo+IHRhc2suCgpMb29raW5nIGF0IHBhdGNoIDgsIHRoZSBz ZyB0YWJsZSBzZWVtcyBwZXJmZWN0bHkgc3VmZmljaWVudCB0byBjb252ZXkgdGhlCnJpZ2h0IGRt YSBhZGRyZXNzZXMgdG8gdGhlIGltcG9ydGVyLiBPZmNvdXJzZSB0aGUgZXhwb3J0ZXIgaGFzIHRv IHNldCB1cAp0aGUgcmlnaHQga2luZCBvZiBpb21tdSBtYXBwaW5ncyB0byBtYWtlIHRoaXMgd29y ay4KCj4gPiBUaGUgZW50aXJlIHBvaW50IG9mIHVzaW5nIHNnIGxpc3RzIHdhcyBleGFjdGx5IHRv IGFsbG93IHRoaXMgdXNlIGNhc2Ugb2YKPiA+IHBlZXIycGVlciBkbWEgKG9yIHdlbGwgaW4gZ2Vu ZXJhbCBoYXZlIHNwZWNpYWwgZXhwb3J0ZXJzIHdoaWNoIG1hbmFnZWQKPiA+IG1lbW9yeS9JTyBy YW5nZXMgbm90IGJhY2tlZCBieSBzdHJ1Y3QgcGFnZSkuIFNvIGVzc2VudGlhbGx5IHlvdSdyZSBo YXZpbmcKPiA+IGEgIkknbSB0b3RhbGx5IG5vdCBicm9rZW4gZmxhZyIgaGVyZS4KPiAKPiBObywg aW5kZXBlbmRlbnQgb2YgbmVlZGVkIHN0cnVjdCBwYWdlIHBvaW50ZXJzIHdlIG5lZWQgdG8gbm90 ZSBpZiB0aGUKPiBleHBvcnRlciBjYW4gaGFuZGxlIHBlZXIycGVlciBzdHVmZiBmcm9tIHRoZSBo YXJkd2FyZSBzaWRlIGluIGdlbmVyYWwuCj4gCj4gU28gd2hhdCBJJ3ZlIGRpZCBpcyBqdXN0IHRv IHNldCBwZWVyMnBlZXIgYWxsb3dlZCBvbiB0aGUgaW1wb3J0ZXIgYmVjYXVzZSBvZgo+IHRoZSBk cml2ZXIgbmVlZHMgYW5kIGNsZWFyIGl0IGluIHRoZSBleHBvcnRlciBpZiB0aGUgaGFyZHdhcmUg Y2FuJ3QgaGFuZGxlCj4gdGhhdC4KClRoZSBvbmx5IHRoaW5nIHRoZSBpbXBvcnRlciBzZWVtcyB0 byBkbyBpcyBjYWxsIHRoZQpwY2lfcGVlcl90cmFmZmljX3N1cHBvcnRlZCwgd2hpY2ggdGhlIGV4 cG9ydGVyIGNvdWxkIGNhbGwgdG9vLiBXaGF0IGFtIEkKbWlzc2luZyAoc2luY2UgdGhlIHN0dXJj dF9wYWdlIHN0dWZmIHNvdW5kcyBsaWtlIGl0J3MgZml4ZWQgYWxyZWFkeSBieQp5b3UpPwotRGFu aWVsCgo+ID4gSSB0aGluayBhIGJldHRlciBhcHByb2FjaCB3b3VsZCBiZSBpZiB3ZSBhZGQgYSBy ZXF1aXJlc19zdHJ1Y3RfcGFnZSBvciBzbywKPiA+IGFuZCBhbm5vdGF0ZSB0aGUgY3VycmVudCBp bXBvcnRlcnMgYWNjb3JkaW5nbHkuIE9yIHdlIGp1c3QgZml4IHRoZW0gdXAgKGl0Cj4gPiBpcyBh bGwgaW4gc2hhcmVkIHR0bSBjb2RlIGFmdGVyIGFsbCwgSSB0aGluayBldmVyeW9uZSBlbHNlIGdv dCB0aGlzCj4gPiByaWdodCkuCj4gCj4gSSB3b3VsZCByYXRoZXIgbm90IGJlZCBvbiB0aGF0Lgo+ IAo+IENocmlzdGlhbi4KPiAKPiA+IC1EYW5pZWwKPiA+IAo+ID4gPiAtLS0KPiA+ID4gICBkcml2 ZXJzL2RtYS1idWYvZG1hLWJ1Zi5jIHwgMSArCj4gPiA+ICAgaW5jbHVkZS9saW51eC9kbWEtYnVm LmggICB8IDQgKysrKwo+ID4gPiAgIDIgZmlsZXMgY2hhbmdlZCwgNSBpbnNlcnRpb25zKCspCj4g PiA+IAo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9kbWEtYnVmL2RtYS1idWYuYyBiL2RyaXZl cnMvZG1hLWJ1Zi9kbWEtYnVmLmMKPiA+ID4gaW5kZXggZmZhYTJmOWE5YzJjLi5mNDIwMjI1Zjkz YzYgMTAwNjQ0Cj4gPiA+IC0tLSBhL2RyaXZlcnMvZG1hLWJ1Zi9kbWEtYnVmLmMKPiA+ID4gKysr IGIvZHJpdmVycy9kbWEtYnVmL2RtYS1idWYuYwo+ID4gPiBAQCAtNTY1LDYgKzU2NSw3IEBAIHN0 cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQgKmRtYV9idWZfYXR0YWNoKGNvbnN0IHN0cnVjdCBkbWFf YnVmX2F0dGFjaF9pbmZvICppbmZvCj4gPiA+ICAgCWF0dGFjaC0+ZGV2ID0gaW5mby0+ZGV2Owo+ ID4gPiAgIAlhdHRhY2gtPmRtYWJ1ZiA9IGRtYWJ1ZjsKPiA+ID4gKwlhdHRhY2gtPnBlZXIycGVl ciA9IGluZm8tPnBlZXIycGVlcjsKPiA+ID4gICAJYXR0YWNoLT5wcml2ID0gaW5mby0+cHJpdjsK PiA+ID4gICAJYXR0YWNoLT5pbnZhbGlkYXRlID0gaW5mby0+aW52YWxpZGF0ZTsKPiA+ID4gZGlm ZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvZG1hLWJ1Zi5oIGIvaW5jbHVkZS9saW51eC9kbWEtYnVm LmgKPiA+ID4gaW5kZXggMTVkZDg1OThiZmYxLi4xZWY1MGJkOWJjNWIgMTAwNjQ0Cj4gPiA+IC0t LSBhL2luY2x1ZGUvbGludXgvZG1hLWJ1Zi5oCj4gPiA+ICsrKyBiL2luY2x1ZGUvbGludXgvZG1h LWJ1Zi5oCj4gPiA+IEBAIC0zMTMsNiArMzEzLDcgQEAgc3RydWN0IGRtYV9idWYgewo+ID4gPiAg ICAqIEBkbWFidWY6IGJ1ZmZlciBmb3IgdGhpcyBhdHRhY2htZW50Lgo+ID4gPiAgICAqIEBkZXY6 IGRldmljZSBhdHRhY2hlZCB0byB0aGUgYnVmZmVyLgo+ID4gPiAgICAqIEBub2RlOiBsaXN0IG9m IGRtYV9idWZfYXR0YWNobWVudC4KPiA+ID4gKyAqIEBwZWVyMnBlZXI6IHRydWUgaWYgdGhlIGlt cG9ydGVyIGNhbiBoYW5kbGUgcGVlciByZXNvdXJjZXMgd2l0aG91dCBwYWdlcy4KPiA+ID4gICAg KiBAcHJpdjogZXhwb3J0ZXIgc3BlY2lmaWMgYXR0YWNobWVudCBkYXRhLgo+ID4gPiAgICAqCj4g PiA+ICAgICogVGhpcyBzdHJ1Y3R1cmUgaG9sZHMgdGhlIGF0dGFjaG1lbnQgaW5mb3JtYXRpb24g YmV0d2VlbiB0aGUgZG1hX2J1ZiBidWZmZXIKPiA+ID4gQEAgLTMyOCw2ICszMjksNyBAQCBzdHJ1 Y3QgZG1hX2J1Zl9hdHRhY2htZW50IHsKPiA+ID4gICAJc3RydWN0IGRtYV9idWYgKmRtYWJ1ZjsK PiA+ID4gICAJc3RydWN0IGRldmljZSAqZGV2Owo+ID4gPiAgIAlzdHJ1Y3QgbGlzdF9oZWFkIG5v ZGU7Cj4gPiA+ICsJYm9vbCBwZWVyMnBlZXI7Cj4gPiA+ICAgCXZvaWQgKnByaXY7Cj4gPiA+ICAg CS8qKgo+ID4gPiBAQCAtMzkyLDYgKzM5NCw3IEBAIHN0cnVjdCBkbWFfYnVmX2V4cG9ydF9pbmZv IHsKPiA+ID4gICAgKiBAZG1hYnVmOgl0aGUgZXhwb3J0ZWQgZG1hX2J1Zgo+ID4gPiAgICAqIEBk ZXY6CXRoZSBkZXZpY2Ugd2hpY2ggd2FudHMgdG8gaW1wb3J0IHRoZSBhdHRhY2htZW50Cj4gPiA+ ICAgICogQHByaXY6CXByaXZhdGUgZGF0YSBvZiBpbXBvcnRlciB0byB0aGlzIGF0dGFjaG1lbnQK PiA+ID4gKyAqIEBwZWVyMnBlZXI6CXRydWUgaWYgdGhlIGltcG9ydGVyIGNhbiBoYW5kbGUgcGVl ciByZXNvdXJjZXMgd2l0aG91dCBwYWdlcwo+ID4gPiAgICAqIEBpbnZhbGlkYXRlOgljYWxsYmFj ayB0byB1c2UgZm9yIGludmFsaWRhdGluZyBtYXBwaW5ncwo+ID4gPiAgICAqCj4gPiA+ICAgICog VGhpcyBzdHJ1Y3R1cmUgaG9sZHMgdGhlIGluZm9ybWF0aW9uIHJlcXVpcmVkIHRvIGF0dGFjaCB0 byBhIGJ1ZmZlci4gVXNlZAo+ID4gPiBAQCAtNDAxLDYgKzQwNCw3IEBAIHN0cnVjdCBkbWFfYnVm X2F0dGFjaF9pbmZvIHsKPiA+ID4gICAJc3RydWN0IGRtYV9idWYgKmRtYWJ1ZjsKPiA+ID4gICAJ c3RydWN0IGRldmljZSAqZGV2Owo+ID4gPiAgIAl2b2lkICpwcml2Owo+ID4gPiArCWJvb2wgcGVl cjJwZWVyOwo+ID4gPiAgIAl2b2lkICgqaW52YWxpZGF0ZSkoc3RydWN0IGRtYV9idWZfYXR0YWNo bWVudCAqYXR0YWNoKTsKPiA+ID4gICB9Owo+ID4gPiAtLSAKPiA+ID4gMi4xNC4xCj4gPiA+IAo+ ID4gPiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+ID4g PiBkcmktZGV2ZWwgbWFpbGluZyBsaXN0Cj4gPiA+IGRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3Rv cC5vcmcKPiA+ID4gaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5m by9kcmktZGV2ZWwKPiAKPiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwo+IGRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKPiBkcmktZGV2ZWxAbGlzdHMuZnJlZWRl c2t0b3Aub3JnCj4gaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5m by9kcmktZGV2ZWwKCi0tIApEYW5pZWwgVmV0dGVyClNvZnR3YXJlIEVuZ2luZWVyLCBJbnRlbCBD b3Jwb3JhdGlvbgpodHRwOi8vYmxvZy5mZndsbC5jaApfX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fXwphbWQtZ2Z4IG1haWxpbmcgbGlzdAphbWQtZ2Z4QGxpc3Rz LmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2FtZC1nZngK