From mboxrd@z Thu Jan 1 00:00:00 1970 From: jszhang@marvell.com (Jisheng Zhang) Date: Tue, 21 Feb 2017 12:37:40 +0800 Subject: [PATCH net-next v3 0/4] net: mvneta: improve rx/tx performance In-Reply-To: <877f4laqog.fsf@free-electrons.com> References: <20170220125344.3555-1-jszhang@marvell.com> <877f4laqog.fsf@free-electrons.com> Message-ID: <20170221123726.2db7db19@xhacker> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Gregory, On Mon, 20 Feb 2017 15:21:35 +0100 Gregory CLEMENT wrote: > Hi Jisheng, > > On lun., f?vr. 20 2017, Jisheng Zhang wrote: > > > In hot code path such as mvneta_rx_swbm(), we access fields of rx_desc > > and tx_desc. These DMA descs are allocated by dma_alloc_coherent, they > > are uncacheable if the device isn't cache coherent, reading from > > uncached memory is fairly slow. > > > > patch1 reuses the read out status to getting status field of rx_desc > > again. > > > > patch2 avoids getting buf_phys_addr from rx_desc again in > > mvneta_rx_hwbm by reusing the phys_addr variable. > > > > patch3 avoids reading from tx_desc as much as possible by store what > > we need in local variable. > > > > We get the following performance data on Marvell BG4CT Platforms > > (tested with iperf): > > > > before the patch: > > sending 1GB in mvneta_tx()(disabled TSO) costs 793553760ns > > > > after the patch: > > sending 1GB in mvneta_tx()(disabled TSO) costs 719953800ns > > > > we saved 9.2% time. > > > > patch4 uses cacheable memory to store the rx buffer DMA address. > > > > We get the following performance data on Marvell BG4CT Platforms > > (tested with iperf): > > > > before the patch: > > recving 1GB in mvneta_rx_swbm() costs 1492659600 ns > > > > after the patch: > > recving 1GB in mvneta_rx_swbm() costs 1421565640 ns > > Could you explain who you get this number? Thanks for your review. The measurement is simple: record how much time we spent in mvneta_rx_swbm() for receiving 1GB data, something as below: mvneta_rx_swbm() { static u64 total_time; u64 t1, t2; static u64 count; t1 = sched_clock(); ... if (rcvd_pkts) { ... t2 = sched_clock() - t1; total_time += t2; count += rcvd_bytes;; if (count >= 0x40000000) { printk("!!!! %lld %lld\n", total_time, count); total_time = 0; count = 0; } ... } > > receiving 1GB in 1.42 second means having a bandwidth of > 8/1.42=5.63 Gb/s, that means that you are using at least a 10Gb > interface. hmmm, we just measured the time spent in mvneta_rx_swbm(), so we can't solve the bandwidth as 8/1.42, what do you think? > > When I used iperf I didn't have this kind of granularity: > iperf -c 192.168.10.1 -n 1024M > ------------------------------------------------------------ > Client connecting to 192.168.10.19, TCP port 5001 > TCP window size: 43.8 KByte (default) > ------------------------------------------------------------ > [ 3] local 192.168.10.28 port 53086 connected with 192.168.10.1 port 5001 > [ ID] Interval Transfer Bandwidth > [ 3] 0.0- 9.1 sec 1.00 GBytes 942 Mbits/sec > > Also without HWBM enabled (so with the same configuration of your test), > I didn't noticed any improvement with the patch set applied. But at >>From bandwidth point of view, yes, there's no improvement. But from cpu time/load point of view, I do see a trivial improvement. Could you also did a simple test from your side to see whether we have similar improvement data? Thanks, Jisheng > least I didn't see any regression with or without HWBM. > > Gregory > > > > > We saved 4.76% time. > > > > Basically, patch1 and patch4 do what Arnd mentioned in [1]. > > > > Hi Arnd, > > > > I added "Suggested-by you" tag, I hope you don't mind ;) > > > > Thanks > > > > [1] https://www.spinics.net/lists/netdev/msg405889.html > > > > Since v2: > > - add Gregory's ack to patch1 > > - only get rx buffer DMA address from cacheable memory for mvneta_rx_swbm() > > - add patch 2 to read rx_desc->buf_phys_addr once in mvneta_rx_hwbm() > > - add patch 3 to avoid reading from tx_desc as much as possible > > > > Since v1: > > - correct the performance data typo > > > > > > Jisheng Zhang (4): > > net: mvneta: avoid getting status from rx_desc as much as possible > > net: mvneta: avoid getting buf_phys_addr from rx_desc again > > net: mvneta: avoid reading from tx_desc as much as possible > > net: mvneta: Use cacheable memory to store the rx buffer DMA address > > > > drivers/net/ethernet/marvell/mvneta.c | 80 +++++++++++++++++++---------------- > > 1 file changed, 43 insertions(+), 37 deletions(-) > > > > -- > > 2.11.0 > > > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751191AbdBUEoP convert rfc822-to-8bit (ORCPT ); Mon, 20 Feb 2017 23:44:15 -0500 Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]:59278 "EHLO mx0b-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751008AbdBUEmy (ORCPT ); Mon, 20 Feb 2017 23:42:54 -0500 Date: Tue, 21 Feb 2017 12:37:40 +0800 From: Jisheng Zhang To: Gregory CLEMENT CC: , , , , , , Subject: Re: [PATCH net-next v3 0/4] net: mvneta: improve rx/tx performance Message-ID: <20170221123726.2db7db19@xhacker> In-Reply-To: <877f4laqog.fsf@free-electrons.com> References: <20170220125344.3555-1-jszhang@marvell.com> <877f4laqog.fsf@free-electrons.com> X-Mailer: Claws Mail 3.14.1 (GTK+ 2.24.31; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8BIT X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-02-21_02:,, signatures=0 X-Proofpoint-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1702210047 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Gregory, On Mon, 20 Feb 2017 15:21:35 +0100 Gregory CLEMENT wrote: > Hi Jisheng, > > On lun., févr. 20 2017, Jisheng Zhang wrote: > > > In hot code path such as mvneta_rx_swbm(), we access fields of rx_desc > > and tx_desc. These DMA descs are allocated by dma_alloc_coherent, they > > are uncacheable if the device isn't cache coherent, reading from > > uncached memory is fairly slow. > > > > patch1 reuses the read out status to getting status field of rx_desc > > again. > > > > patch2 avoids getting buf_phys_addr from rx_desc again in > > mvneta_rx_hwbm by reusing the phys_addr variable. > > > > patch3 avoids reading from tx_desc as much as possible by store what > > we need in local variable. > > > > We get the following performance data on Marvell BG4CT Platforms > > (tested with iperf): > > > > before the patch: > > sending 1GB in mvneta_tx()(disabled TSO) costs 793553760ns > > > > after the patch: > > sending 1GB in mvneta_tx()(disabled TSO) costs 719953800ns > > > > we saved 9.2% time. > > > > patch4 uses cacheable memory to store the rx buffer DMA address. > > > > We get the following performance data on Marvell BG4CT Platforms > > (tested with iperf): > > > > before the patch: > > recving 1GB in mvneta_rx_swbm() costs 1492659600 ns > > > > after the patch: > > recving 1GB in mvneta_rx_swbm() costs 1421565640 ns > > Could you explain who you get this number? Thanks for your review. The measurement is simple: record how much time we spent in mvneta_rx_swbm() for receiving 1GB data, something as below: mvneta_rx_swbm() { static u64 total_time; u64 t1, t2; static u64 count; t1 = sched_clock(); ... if (rcvd_pkts) { ... t2 = sched_clock() - t1; total_time += t2; count += rcvd_bytes;; if (count >= 0x40000000) { printk("!!!! %lld %lld\n", total_time, count); total_time = 0; count = 0; } ... } > > receiving 1GB in 1.42 second means having a bandwidth of > 8/1.42=5.63 Gb/s, that means that you are using at least a 10Gb > interface. hmmm, we just measured the time spent in mvneta_rx_swbm(), so we can't solve the bandwidth as 8/1.42, what do you think? > > When I used iperf I didn't have this kind of granularity: > iperf -c 192.168.10.1 -n 1024M > ------------------------------------------------------------ > Client connecting to 192.168.10.19, TCP port 5001 > TCP window size: 43.8 KByte (default) > ------------------------------------------------------------ > [ 3] local 192.168.10.28 port 53086 connected with 192.168.10.1 port 5001 > [ ID] Interval Transfer Bandwidth > [ 3] 0.0- 9.1 sec 1.00 GBytes 942 Mbits/sec > > Also without HWBM enabled (so with the same configuration of your test), > I didn't noticed any improvement with the patch set applied. But at >>From bandwidth point of view, yes, there's no improvement. But from cpu time/load point of view, I do see a trivial improvement. Could you also did a simple test from your side to see whether we have similar improvement data? Thanks, Jisheng > least I didn't see any regression with or without HWBM. > > Gregory > > > > > We saved 4.76% time. > > > > Basically, patch1 and patch4 do what Arnd mentioned in [1]. > > > > Hi Arnd, > > > > I added "Suggested-by you" tag, I hope you don't mind ;) > > > > Thanks > > > > [1] https://www.spinics.net/lists/netdev/msg405889.html > > > > Since v2: > > - add Gregory's ack to patch1 > > - only get rx buffer DMA address from cacheable memory for mvneta_rx_swbm() > > - add patch 2 to read rx_desc->buf_phys_addr once in mvneta_rx_hwbm() > > - add patch 3 to avoid reading from tx_desc as much as possible > > > > Since v1: > > - correct the performance data typo > > > > > > Jisheng Zhang (4): > > net: mvneta: avoid getting status from rx_desc as much as possible > > net: mvneta: avoid getting buf_phys_addr from rx_desc again > > net: mvneta: avoid reading from tx_desc as much as possible > > net: mvneta: Use cacheable memory to store the rx buffer DMA address > > > > drivers/net/ethernet/marvell/mvneta.c | 80 +++++++++++++++++++---------------- > > 1 file changed, 43 insertions(+), 37 deletions(-) > > > > -- > > 2.11.0 > > > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jisheng Zhang Subject: Re: [PATCH net-next v3 0/4] net: mvneta: improve rx/tx performance Date: Tue, 21 Feb 2017 12:37:40 +0800 Message-ID: <20170221123726.2db7db19@xhacker> References: <20170220125344.3555-1-jszhang@marvell.com> <877f4laqog.fsf@free-electrons.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: thomas.petazzoni@free-electrons.com, arnd@arndb.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, mw@semihalf.com, davem@davemloft.net, linux-arm-kernel@lists.infradead.org To: Gregory CLEMENT Return-path: In-Reply-To: <877f4laqog.fsf@free-electrons.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org List-Id: netdev.vger.kernel.org SGkgR3JlZ29yeSwKCk9uIE1vbiwgMjAgRmViIDIwMTcgMTU6MjE6MzUgKzAxMDAgR3JlZ29yeSBD TEVNRU5UIHdyb3RlOgoKPiBIaSBKaXNoZW5nLAo+ICAKPiAgT24gbHVuLiwgZsOpdnIuIDIwIDIw MTcsIEppc2hlbmcgWmhhbmcgPGpzemhhbmdAbWFydmVsbC5jb20+IHdyb3RlOgo+IAo+ID4gSW4g aG90IGNvZGUgcGF0aCBzdWNoIGFzIG12bmV0YV9yeF9zd2JtKCksIHdlIGFjY2VzcyBmaWVsZHMg b2YgcnhfZGVzYwo+ID4gYW5kIHR4X2Rlc2MuIFRoZXNlIERNQSBkZXNjcyBhcmUgYWxsb2NhdGVk IGJ5IGRtYV9hbGxvY19jb2hlcmVudCwgdGhleQo+ID4gYXJlIHVuY2FjaGVhYmxlIGlmIHRoZSBk ZXZpY2UgaXNuJ3QgY2FjaGUgY29oZXJlbnQsIHJlYWRpbmcgZnJvbQo+ID4gdW5jYWNoZWQgbWVt b3J5IGlzIGZhaXJseSBzbG93Lgo+ID4KPiA+IHBhdGNoMSByZXVzZXMgdGhlIHJlYWQgb3V0IHN0 YXR1cyB0byBnZXR0aW5nIHN0YXR1cyBmaWVsZCBvZiByeF9kZXNjCj4gPiBhZ2Fpbi4KPiA+Cj4g PiBwYXRjaDIgYXZvaWRzIGdldHRpbmcgYnVmX3BoeXNfYWRkciBmcm9tIHJ4X2Rlc2MgYWdhaW4g aW4KPiA+IG12bmV0YV9yeF9od2JtIGJ5IHJldXNpbmcgdGhlIHBoeXNfYWRkciB2YXJpYWJsZS4K PiA+Cj4gPiBwYXRjaDMgYXZvaWRzIHJlYWRpbmcgZnJvbSB0eF9kZXNjIGFzIG11Y2ggYXMgcG9z c2libGUgYnkgc3RvcmUgd2hhdAo+ID4gd2UgbmVlZCBpbiBsb2NhbCB2YXJpYWJsZS4KPiA+Cj4g PiBXZSBnZXQgdGhlIGZvbGxvd2luZyBwZXJmb3JtYW5jZSBkYXRhIG9uIE1hcnZlbGwgQkc0Q1Qg UGxhdGZvcm1zCj4gPiAodGVzdGVkIHdpdGggaXBlcmYpOgo+ID4KPiA+IGJlZm9yZSB0aGUgcGF0 Y2g6Cj4gPiBzZW5kaW5nIDFHQiBpbiBtdm5ldGFfdHgoKShkaXNhYmxlZCBUU08pIGNvc3RzIDc5 MzU1Mzc2MG5zCj4gPgo+ID4gYWZ0ZXIgdGhlIHBhdGNoOgo+ID4gc2VuZGluZyAxR0IgaW4gbXZu ZXRhX3R4KCkoZGlzYWJsZWQgVFNPKSBjb3N0cyA3MTk5NTM4MDBucwo+ID4KPiA+IHdlIHNhdmVk IDkuMiUgdGltZS4KPiA+Cj4gPiBwYXRjaDQgdXNlcyBjYWNoZWFibGUgbWVtb3J5IHRvIHN0b3Jl IHRoZSByeCBidWZmZXIgRE1BIGFkZHJlc3MuCj4gPgo+ID4gV2UgZ2V0IHRoZSBmb2xsb3dpbmcg cGVyZm9ybWFuY2UgZGF0YSBvbiBNYXJ2ZWxsIEJHNENUIFBsYXRmb3Jtcwo+ID4gKHRlc3RlZCB3 aXRoIGlwZXJmKToKPiA+Cj4gPiBiZWZvcmUgdGhlIHBhdGNoOgo+ID4gcmVjdmluZyAxR0IgaW4g bXZuZXRhX3J4X3N3Ym0oKSBjb3N0cyAxNDkyNjU5NjAwIG5zCj4gPgo+ID4gYWZ0ZXIgdGhlIHBh dGNoOgo+ID4gcmVjdmluZyAxR0IgaW4gbXZuZXRhX3J4X3N3Ym0oKSBjb3N0cyAxNDIxNTY1NjQw IG5zICAKPiAKPiBDb3VsZCB5b3UgZXhwbGFpbiB3aG8geW91IGdldCB0aGlzIG51bWJlcj8KClRo YW5rcyBmb3IgeW91ciByZXZpZXcuCgpUaGUgbWVhc3VyZW1lbnQgaXMgc2ltcGxlOiByZWNvcmQg aG93IG11Y2ggdGltZSB3ZSBzcGVudCBpbiBtdm5ldGFfcnhfc3dibSgpCmZvciByZWNlaXZpbmcg MUdCIGRhdGEsIHNvbWV0aGluZyBhcyBiZWxvdzoKCm12bmV0YV9yeF9zd2JtKCkKewoJc3RhdGlj IHU2NCB0b3RhbF90aW1lOwoJdTY0IHQxLCB0MjsKCXN0YXRpYyB1NjQgY291bnQ7CgoJdDEgPSBz Y2hlZF9jbG9jaygpOwoJLi4uCgoJaWYgKHJjdmRfcGt0cykgewoJCS4uLgoJCXQyID0gc2NoZWRf Y2xvY2soKSAtIHQxOwoJCXRvdGFsX3RpbWUgKz0gdDI7CgkJY291bnQgKz0gcmN2ZF9ieXRlczs7 CgkJaWYgKGNvdW50ID49IDB4NDAwMDAwMDApIHsKCQkJcHJpbnRrKCIhISEhICVsbGQgJWxsZFxu IiwgdG90YWxfdGltZSwgY291bnQpOwoJCQl0b3RhbF90aW1lID0gMDsKCQkJY291bnQgPSAwOwoJ CX0KCS4uLgp9Cgo+IAo+IHJlY2VpdmluZyAxR0IgaW4gMS40MiBzZWNvbmQgbWVhbnMgaGF2aW5n IGEgYmFuZHdpZHRoIG9mCj4gOC8xLjQyPTUuNjMgR2IvcywgdGhhdCBtZWFucyB0aGF0IHlvdSBh cmUgdXNpbmcgYXQgbGVhc3QgYSAxMEdiCj4gaW50ZXJmYWNlLgoKaG1tbSwgd2UganVzdCBtZWFz dXJlZCB0aGUgdGltZSBzcGVudCBpbiBtdm5ldGFfcnhfc3dibSgpLCBzbyB3ZSBjYW4ndCBzb2x2 ZQp0aGUgYmFuZHdpZHRoIGFzIDgvMS40Miwgd2hhdCBkbyB5b3UgdGhpbms/Cgo+IAo+IFdoZW4g SSB1c2VkIGlwZXJmIEkgZGlkbid0IGhhdmUgdGhpcyBraW5kIG9mIGdyYW51bGFyaXR5Ogo+IGlw ZXJmIC1jIDE5Mi4xNjguMTAuMSAtbiAxMDI0TQo+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+IENsaWVudCBjb25uZWN0aW5nIHRv IDE5Mi4xNjguMTAuMTksIFRDUCBwb3J0IDUwMDEKPiBUQ1Agd2luZG93IHNpemU6IDQzLjggS0J5 dGUgKGRlZmF1bHQpCj4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tCj4gWyAgM10gbG9jYWwgMTkyLjE2OC4xMC4yOCBwb3J0IDUzMDg2 IGNvbm5lY3RlZCB3aXRoIDE5Mi4xNjguMTAuMSBwb3J0IDUwMDEKPiBbIElEXSBJbnRlcnZhbCAg ICAgICBUcmFuc2ZlciAgICAgQmFuZHdpZHRoCj4gWyAgM10gIDAuMC0gOS4xIHNlYyAgMS4wMCBH Qnl0ZXMgICA5NDIgTWJpdHMvc2VjCj4gCj4gQWxzbyB3aXRob3V0IEhXQk0gZW5hYmxlZCAoc28g d2l0aCB0aGUgc2FtZSBjb25maWd1cmF0aW9uIG9mIHlvdXIgdGVzdCksCj4gSSBkaWRuJ3Qgbm90 aWNlZCBhbnkgaW1wcm92ZW1lbnQgd2l0aCB0aGUgcGF0Y2ggc2V0IGFwcGxpZWQuIEJ1dCBhdAoK RnJvbSBiYW5kd2lkdGggcG9pbnQgb2YgdmlldywgeWVzLCB0aGVyZSdzIG5vIGltcHJvdmVtZW50 LiBCdXQgZnJvbSBjcHUKdGltZS9sb2FkIHBvaW50IG9mIHZpZXcsIEkgZG8gc2VlIGEgdHJpdmlh bCBpbXByb3ZlbWVudC4gQ291bGQgeW91IGFsc28KZGlkIGEgc2ltcGxlIHRlc3QgZnJvbSB5b3Vy IHNpZGUgdG8gc2VlIHdoZXRoZXIgd2UgaGF2ZSBzaW1pbGFyIGltcHJvdmVtZW50CmRhdGE/CgpU aGFua3MsCkppc2hlbmcKCgoKPiBsZWFzdCBJIGRpZG4ndCBzZWUgYW55IHJlZ3Jlc3Npb24gd2l0 aCBvciB3aXRob3V0IEhXQk0uCj4gCj4gR3JlZ29yeQo+IAo+ID4KPiA+IFdlIHNhdmVkIDQuNzYl IHRpbWUuCj4gPgo+ID4gQmFzaWNhbGx5LCBwYXRjaDEgYW5kIHBhdGNoNCBkbyB3aGF0IEFybmQg bWVudGlvbmVkIGluIFsxXS4KPiA+Cj4gPiBIaSBBcm5kLAo+ID4KPiA+IEkgYWRkZWQgIlN1Z2dl c3RlZC1ieSB5b3UiIHRhZywgSSBob3BlIHlvdSBkb24ndCBtaW5kIDspCj4gPgo+ID4gVGhhbmtz Cj4gPgo+ID4gWzFdIGh0dHBzOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL25ldGRldi9tc2c0MDU4 ODkuaHRtbAo+ID4KPiA+IFNpbmNlIHYyOgo+ID4gICAtIGFkZCBHcmVnb3J5J3MgYWNrIHRvIHBh dGNoMQo+ID4gICAtIG9ubHkgZ2V0IHJ4IGJ1ZmZlciBETUEgYWRkcmVzcyBmcm9tIGNhY2hlYWJs ZSBtZW1vcnkgZm9yIG12bmV0YV9yeF9zd2JtKCkKPiA+ICAgLSBhZGQgcGF0Y2ggMiB0byByZWFk IHJ4X2Rlc2MtPmJ1Zl9waHlzX2FkZHIgb25jZSBpbiBtdm5ldGFfcnhfaHdibSgpCj4gPiAgIC0g YWRkIHBhdGNoIDMgdG8gYXZvaWQgcmVhZGluZyBmcm9tIHR4X2Rlc2MgYXMgbXVjaCBhcyBwb3Nz aWJsZQo+ID4KPiA+IFNpbmNlIHYxOgo+ID4gICAtIGNvcnJlY3QgdGhlIHBlcmZvcm1hbmNlIGRh dGEgdHlwbwo+ID4KPiA+Cj4gPiBKaXNoZW5nIFpoYW5nICg0KToKPiA+ICAgbmV0OiBtdm5ldGE6 IGF2b2lkIGdldHRpbmcgc3RhdHVzIGZyb20gcnhfZGVzYyBhcyBtdWNoIGFzIHBvc3NpYmxlCj4g PiAgIG5ldDogbXZuZXRhOiBhdm9pZCBnZXR0aW5nIGJ1Zl9waHlzX2FkZHIgZnJvbSByeF9kZXNj IGFnYWluCj4gPiAgIG5ldDogbXZuZXRhOiBhdm9pZCByZWFkaW5nIGZyb20gdHhfZGVzYyBhcyBt dWNoIGFzIHBvc3NpYmxlCj4gPiAgIG5ldDogbXZuZXRhOiBVc2UgY2FjaGVhYmxlIG1lbW9yeSB0 byBzdG9yZSB0aGUgcnggYnVmZmVyIERNQSBhZGRyZXNzCj4gPgo+ID4gIGRyaXZlcnMvbmV0L2V0 aGVybmV0L21hcnZlbGwvbXZuZXRhLmMgfCA4MCArKysrKysrKysrKysrKysrKysrLS0tLS0tLS0t LS0tLS0tLQo+ID4gIDEgZmlsZSBjaGFuZ2VkLCA0MyBpbnNlcnRpb25zKCspLCAzNyBkZWxldGlv bnMoLSkKPiA+Cj4gPiAtLSAKPiA+IDIuMTEuMAo+ID4gIAo+IAoKCl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBs aXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5m cmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK