From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from us-smtp-2.mimecast.com ([207.211.31.81] helo=us-smtp-delivery-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCLs8-0000ak-7E for ath10k@lists.infradead.org; Mon, 23 Sep 2019 10:47:15 +0000 Received: by mail-lj1-f199.google.com with SMTP id j6so2862023ljb.19 for ; Mon, 23 Sep 2019 03:47:05 -0700 (PDT) From: Toke =?utf-8?Q?H=C3=B8iland-J=C3=B8rgensen?= Subject: Re: [PATCH 2/4] mac80211: defer txqs removal from rbtree In-Reply-To: <2935b00bf3e29ad8b2738fe98dc24a76@codeaurora.org> References: <1568639388-27291-1-git-send-email-yiboz@codeaurora.org> <1568639388-27291-2-git-send-email-yiboz@codeaurora.org> <87pnjyiq7o.fsf@toke.dk> <87sgothmpy.fsf@toke.dk> <8cdece5c030fd95817fb099021c38613@codeaurora.org> <87tv98fu6l.fsf@toke.dk> <1b4ab006d9b5c88035845aaac193ef48@codeaurora.org> <8736gre3bm.fsf@toke.dk> <198124204167325252fcfcd65e3f2733@codeaurora.org> <87ftkp7uuz.fsf@toke.dk> <4574cce4079f8dab2b2bf223431a6eae@codeaurora.org> <877e617qg2.fsf@toke.dk> <910d9bb5f9016b29fb2aaeb0b89bac38@codeaurora.org> <874l157nrt.fsf@toke.dk> <2935b00bf3e29ad8b2738fe98dc24a76@codeaurora.org> Date: Mon, 23 Sep 2019 12:47:01 +0200 Message-ID: <87lfuf5ly2.fsf@toke.dk> MIME-Version: 1.0 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "ath10k" Errors-To: ath10k-bounces+kvalo=adurom.com@lists.infradead.org To: Yibo Zhao Cc: linux-wireless-owner@vger.kernel.org, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org WWlibyBaaGFvIDx5aWJvekBjb2RlYXVyb3JhLm9yZz4gd3JpdGVzOgoKPiBPbiAyMDE5LTA5LTIx IDIyOjAwLCBUb2tlIEjDuGlsYW5kLUrDuHJnZW5zZW4gd3JvdGU6Cj4+IFlpYm8gWmhhbyA8eWli b3pAY29kZWF1cm9yYS5vcmc+IHdyaXRlczoKPj4gCj4+PiBPbiAyMDE5LTA5LTIxIDIxOjAyLCBU b2tlIEjDuGlsYW5kLUrDuHJnZW5zZW4gd3JvdGU6Cj4+Pj4gWWlibyBaaGFvIDx5aWJvekBjb2Rl YXVyb3JhLm9yZz4gd3JpdGVzOgo+Pj4+IAo+Pj4+PiBPbiAyMDE5LTA5LTIxIDE5OjI3LCBUb2tl IEjDuGlsYW5kLUrDuHJnZW5zZW4gd3JvdGU6Cj4+Pj4+PiBZaWJvIFpoYW8gPHlpYm96QGNvZGVh dXJvcmEub3JnPiB3cml0ZXM6Cj4+Pj4+PiAKPj4+Pj4+PiBPbiAyMDE5LTA5LTIwIDE3OjE1LCBU b2tlIEjDuGlsYW5kLUrDuHJnZW5zZW4gd3JvdGU6Cj4+Pj4+Pj4+IFlpYm8gWmhhbyA8eWlib3pA Y29kZWF1cm9yYS5vcmc+IHdyaXRlczoKPj4+Pj4+Pj4gCj4+Pj4+Pj4+PiBPbiAyMDE5LTA5LTE5 IDE4OjM3LCBUb2tlIEjDuGlsYW5kLUrDuHJnZW5zZW4gd3JvdGU6Cj4+Pj4+Pj4+Pj4gWWlibyBa aGFvIDx5aWJvekBjb2RlYXVyb3JhLm9yZz4gd3JpdGVzOgo+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+ PiBPbiAyMDE5LTA5LTE4IDE5OjIzLCBUb2tlIEjDuGlsYW5kLUrDuHJnZW5zZW4gd3JvdGU6Cj4+ Pj4+Pj4+Pj4+PiBZaWJvIFpoYW8gPHlpYm96QGNvZGVhdXJvcmEub3JnPiB3cml0ZXM6Cj4+Pj4+ Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+PiBPbiAyMDE5LTA5LTE4IDA1OjEwLCBUb2tlIEjDuGlsYW5k LUrDuHJnZW5zZW4gd3JvdGU6Cj4+Pj4+Pj4+Pj4+Pj4+IFlpYm8gWmhhbyA8eWlib3pAY29kZWF1 cm9yYS5vcmc+IHdyaXRlczoKPj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+Pj4+PiBJbiBhIGxv b3AgdHhxcyBkZXF1ZXVlIHNjZW5hcmlvLCBpZiB0aGUgZmlyc3QgdHhxIGluIHRoZQo+Pj4+Pj4+ Pj4+Pj4+Pj4gcmJ0cmVlCj4+Pj4+Pj4+Pj4+Pj4+PiBnZXRzCj4+Pj4+Pj4+Pj4+Pj4+PiByZW1v dmVkIGZyb20gcmJ0cmVlIGltbWVkaWF0ZWx5IGluIHRoZQo+Pj4+Pj4+Pj4+Pj4+Pj4gaWVlZTgw MjExX3JldHVybl90eHEoKSwKPj4+Pj4+Pj4+Pj4+Pj4+IHRoZQo+Pj4+Pj4+Pj4+Pj4+Pj4gbG9v cCB3aWxsIGJyZWFrIHNvb24gaW4gdGhlIGllZWU4MDIxMV9uZXh0X3R4cSgpIGR1ZSB0bwo+Pj4+ Pj4+Pj4+Pj4+Pj4gc2NoZWR1bGVfcG9zCj4+Pj4+Pj4+Pj4+Pj4+PiBub3QgbGVhZGluZyB0byB0 aGUgc2Vjb25kIHR4cSBpbiB0aGUgcmJ0cmVlLiBUaHVzLCAKPj4+Pj4+Pj4+Pj4+Pj4+IGRlZmVy aW5nCj4+Pj4+Pj4+Pj4+Pj4+PiB0aGUKPj4+Pj4+Pj4+Pj4+Pj4+IHJlbW92YWwgcmlnaHQgYmVm b3JlIHRoZSBlbmQgb2YgdGhpcyBzY2hlZHVsZSByb3VuZC4KPj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+ Pj4+Pj4+Pj4+Pj4gQ28tZGV2ZWxvcGVkLWJ5OiBZaWJvIFpoYW8gPHlpYm96QGNvZGVhdXJvcmEu b3JnPgo+Pj4+Pj4+Pj4+Pj4+Pj4gU2lnbmVkLW9mZi1ieTogWWlibyBaaGFvIDx5aWJvekBjb2Rl YXVyb3JhLm9yZz4KPj4+Pj4+Pj4+Pj4+Pj4+IFNpZ25lZC1vZmYtYnk6IFRva2UgSMO4aWxhbmQt SsO4cmdlbnNlbiA8dG9rZUB0b2tlLmRrPgo+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+Pj4g SSBkaWRuJ3Qgd3JpdGUgdGhpcyBwYXRjaCwgc28gcGxlYXNlIGRvbid0IHVzZSBteSBzaWduLW9m Zi4KPj4+Pj4+Pj4+Pj4+Pj4gSSdsbAo+Pj4+Pj4+Pj4+Pj4+PiBhZGQKPj4+Pj4+Pj4+Pj4+Pj4g YWNrIG9yIHJldmlldyB0YWdzIGFzIGFwcHJvcHJpYXRlIGluIHJlcGx5OyBidXQgYSBmZXcKPj4+ Pj4+Pj4+Pj4+Pj4gY29tbWVudHMKPj4+Pj4+Pj4+Pj4+Pj4gZmlyc3Q6Cj4+Pj4+Pj4+Pj4+Pj4+ IAo+Pj4+Pj4+Pj4+Pj4+Pj4gLS0tCj4+Pj4+Pj4+Pj4+Pj4+PiAgaW5jbHVkZS9uZXQvbWFjODAy MTEuaCAgICAgfCAxNiArKysrKysrKysrLS0KPj4+Pj4+Pj4+Pj4+Pj4+ICBuZXQvbWFjODAyMTEv aWVlZTgwMjExX2kuaCB8ICAzICsrKwo+Pj4+Pj4+Pj4+Pj4+Pj4gIG5ldC9tYWM4MDIxMS9tYWlu LmMgICAgICAgIHwgIDYgKysrKysKPj4+Pj4+Pj4+Pj4+Pj4+ICBuZXQvbWFjODAyMTEvdHguYyAg ICAgICAgICB8IDYzCj4+Pj4+Pj4+Pj4+Pj4+PiArKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrLS0tCj4+Pj4+Pj4+Pj4+Pj4+PiAgNCBmaWxlcyBjaGFuZ2VkLCA4MyBp bnNlcnRpb25zKCspLCA1IGRlbGV0aW9ucygtKQo+Pj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+ Pj4+PiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9uZXQvbWFjODAyMTEuaCAKPj4+Pj4+Pj4+Pj4+Pj4+ IGIvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAo+Pj4+Pj4+Pj4+Pj4+Pj4gaW5kZXggYWMyZWQ4ZS4u YmE1YTM0NSAxMDA2NDQKPj4+Pj4+Pj4+Pj4+Pj4+IC0tLSBhL2luY2x1ZGUvbmV0L21hYzgwMjEx LmgKPj4+Pj4+Pj4+Pj4+Pj4+ICsrKyBiL2luY2x1ZGUvbmV0L21hYzgwMjExLmgKPj4+Pj4+Pj4+ Pj4+Pj4+IEBAIC05MjUsNiArOTI1LDggQEAgc3RydWN0IGllZWU4MDIxMV90eF9yYXRlIHsKPj4+ Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gICNkZWZpbmUgSUVFRTgwMjExX01BWF9UWF9S RVRSWQkJMzEKPj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gKyNkZWZpbmUgSUVFRTgw MjExX0FJUlRJTUVfVFhRX1JNX0NIS19JTlRWX0lOX01TIDEwMAo+Pj4+Pj4+Pj4+Pj4+Pj4gKwo+ Pj4+Pj4+Pj4+Pj4+Pj4gIHN0YXRpYyBpbmxpbmUgdm9pZCBpZWVlODAyMTFfcmF0ZV9zZXRfdmh0 KHN0cnVjdAo+Pj4+Pj4+Pj4+Pj4+Pj4gaWVlZTgwMjExX3R4X3JhdGUKPj4+Pj4+Pj4+Pj4+Pj4+ ICpyYXRlLAo+Pj4+Pj4+Pj4+Pj4+Pj4gIAkJCQkJICB1OCBtY3MsIHU4IG5zcykKPj4+Pj4+Pj4+ Pj4+Pj4+ICB7Cj4+Pj4+Pj4+Pj4+Pj4+PiBAQCAtNjIzMiw3ICs2MjM0LDggQEAgc3RydWN0IHNr X2J1ZmYKPj4+Pj4+Pj4+Pj4+Pj4+ICppZWVlODAyMTFfdHhfZGVxdWV1ZShzdHJ1Y3QKPj4+Pj4+ Pj4+Pj4+Pj4+IGllZWU4MDIxMV9odyAqaHcsCj4+Pj4+Pj4+Pj4+Pj4+PiAgICogQGFjOiBBQyBu dW1iZXIgdG8gcmV0dXJuIHBhY2tldHMgZnJvbS4KPj4+Pj4+Pj4+Pj4+Pj4+ICAgKgo+Pj4+Pj4+ Pj4+Pj4+Pj4gICAqIFNob3VsZCBvbmx5IGJlIGNhbGxlZCBiZXR3ZWVuIGNhbGxzIHRvCj4+Pj4+ Pj4+Pj4+Pj4+PiBpZWVlODAyMTFfdHhxX3NjaGVkdWxlX3N0YXJ0KCkKPj4+Pj4+Pj4+Pj4+Pj4+ IC0gKiBhbmQgaWVlZTgwMjExX3R4cV9zY2hlZHVsZV9lbmQoKS4KPj4+Pj4+Pj4+Pj4+Pj4+ICsg KiBhbmQgaWVlZTgwMjExX3R4cV9zY2hlZHVsZV9lbmQoKS4gSWYgdGhlIHR4cSBpcyBlbXB0eSwK Pj4+Pj4+Pj4+Pj4+Pj4+IGl0Cj4+Pj4+Pj4+Pj4+Pj4+PiB3aWxsCj4+Pj4+Pj4+Pj4+Pj4+PiBi ZQo+Pj4+Pj4+Pj4+Pj4+Pj4gYWRkZWQKPj4+Pj4+Pj4+Pj4+Pj4+ICsgKiB0byBhIHJlbW92ZSBs aXN0IGFuZCBnZXQgcmVtb3ZlZCBsYXRlci4KPj4+Pj4+Pj4+Pj4+Pj4+ICAgKiBSZXR1cm5zIHRo ZSBuZXh0IHR4cSBpZiBzdWNjZXNzZnVsLCAlTlVMTCBpZiBubyBxdWV1ZSAKPj4+Pj4+Pj4+Pj4+ Pj4+IGlzCj4+Pj4+Pj4+Pj4+Pj4+PiBlbGlnaWJsZS4KPj4+Pj4+Pj4+Pj4+Pj4+IElmIGEgdHhx Cj4+Pj4+Pj4+Pj4+Pj4+PiAgICogaXMgcmV0dXJuZWQsIGl0IHNob3VsZCBiZSByZXR1cm5lZCB3 aXRoCj4+Pj4+Pj4+Pj4+Pj4+PiBpZWVlODAyMTFfcmV0dXJuX3R4cSgpCj4+Pj4+Pj4+Pj4+Pj4+ PiBhZnRlciB0aGUKPj4+Pj4+Pj4+Pj4+Pj4+ICAgKiBkcml2ZXIgaGFzIGZpbmlzaGVkIHNjaGVk dWxpbmcgaXQuCj4+Pj4+Pj4+Pj4+Pj4+PiBAQCAtNjI2OCw3ICs2MjcxLDggQEAgdm9pZAo+Pj4+ Pj4+Pj4+Pj4+Pj4gaWVlZTgwMjExX3R4cV9zY2hlZHVsZV9zdGFydChzdHJ1Y3QKPj4+Pj4+Pj4+ Pj4+Pj4+IGllZWU4MDIxMV9odyAqaHcsIHU4IGFjKQo+Pj4+Pj4+Pj4+Pj4+Pj4gICAqIEBodzog cG9pbnRlciBhcyBvYnRhaW5lZCBmcm9tIGllZWU4MDIxMV9hbGxvY19odygpCj4+Pj4+Pj4+Pj4+ Pj4+PiAgICogQGFjOiBBQyBudW1iZXIgdG8gYWNxdWlyZSBsb2NrcyBmb3IKPj4+Pj4+Pj4+Pj4+ Pj4+ICAgKgo+Pj4+Pj4+Pj4+Pj4+Pj4gLSAqIFJlbGVhc2UgbG9ja3MgcHJldmlvdXNseSBhY3F1 aXJlZCBieQo+Pj4+Pj4+Pj4+Pj4+Pj4gaWVlZTgwMjExX3R4cV9zY2hlZHVsZV9lbmQoKS4KPj4+ Pj4+Pj4+Pj4+Pj4+ICsgKiBSZWxlYXNlIGxvY2tzIHByZXZpb3VzbHkgYWNxdWlyZWQgYnkKPj4+ Pj4+Pj4+Pj4+Pj4+IGllZWU4MDIxMV90eHFfc2NoZWR1bGVfZW5kKCkuCj4+Pj4+Pj4+Pj4+Pj4+ PiBDaGVjawo+Pj4+Pj4+Pj4+Pj4+Pj4gKyAqIGFuZCByZW1vdmUgdGhlIGVtcHR5IHR4cSBmcm9t IHJiLXRyZWUuCj4+Pj4+Pj4+Pj4+Pj4+PiAgICovCj4+Pj4+Pj4+Pj4+Pj4+PiAgdm9pZCBpZWVl ODAyMTFfdHhxX3NjaGVkdWxlX2VuZChzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywgCj4+Pj4+Pj4+ Pj4+Pj4+PiB1OAo+Pj4+Pj4+Pj4+Pj4+Pj4gYWMpCj4+Pj4+Pj4+Pj4+Pj4+PiAgCV9fcmVsZWFz ZXModHhxX2xvY2spOwo+Pj4+Pj4+Pj4+Pj4+Pj4gQEAgLTYyODcsNiArNjI5MSwxNCBAQCB2b2lk IGllZWU4MDIxMV9zY2hlZHVsZV90eHEoc3RydWN0Cj4+Pj4+Pj4+Pj4+Pj4+PiBpZWVlODAyMTFf aHcKPj4+Pj4+Pj4+Pj4+Pj4+ICpodywgc3RydWN0IGllZWU4MDIxMV90eHEgKnR4cSkKPj4+Pj4+ Pj4+Pj4+Pj4+ICAJX19hY3F1aXJlcyh0eHFfbG9jaykgX19yZWxlYXNlcyh0eHFfbG9jayk7Cj4+ Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+Pj4+ICAvKioKPj4+Pj4+Pj4+Pj4+Pj4+ICsgKiBp ZWVlODAyMTFfdHhxc19jaGVjayAtIENoZWNrIHR4cXMgd2FpdGluZyBmb3IgcmVtb3ZhbAo+Pj4+ Pj4+Pj4+Pj4+Pj4gKyAqCj4+Pj4+Pj4+Pj4+Pj4+PiArICogQHRtcjogcG9pbnRlciBhcyBvYnRh aW5lZCBmcm9tIGxvY2FsCj4+Pj4+Pj4+Pj4+Pj4+PiArICoKPj4+Pj4+Pj4+Pj4+Pj4+ICsgKi8K Pj4+Pj4+Pj4+Pj4+Pj4+ICt2b2lkIGllZWU4MDIxMV90eHFzX2NoZWNrKHN0cnVjdCB0aW1lcl9s aXN0ICp0bXIpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwo+Pj4+Pj4+Pj4+Pj4+Pj4gKy8qKgo+Pj4+Pj4+ Pj4+Pj4+Pj4gICAqIGllZWU4MDIxMV90eHFfbWF5X3RyYW5zbWl0IC0gY2hlY2sgd2hldGhlciBU WFEgaXMKPj4+Pj4+Pj4+Pj4+Pj4+IGFsbG93ZWQKPj4+Pj4+Pj4+Pj4+Pj4+IHRvCj4+Pj4+Pj4+ Pj4+Pj4+PiB0cmFuc21pdAo+Pj4+Pj4+Pj4+Pj4+Pj4gICAqCj4+Pj4+Pj4+Pj4+Pj4+PiAgICog VGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGNoZWNrIHdoZXRoZXIgZ2l2ZW4gdHhxIGlzCj4+Pj4+ Pj4+Pj4+Pj4+PiBhbGxvd2VkCj4+Pj4+Pj4+Pj4+Pj4+PiB0bwo+Pj4+Pj4+Pj4+Pj4+Pj4gdHJh bnNtaXQgYnkKPj4+Pj4+Pj4+Pj4+Pj4+IGRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEvaWVlZTgw MjExX2kuaAo+Pj4+Pj4+Pj4+Pj4+Pj4gYi9uZXQvbWFjODAyMTEvaWVlZTgwMjExX2kuaAo+Pj4+ Pj4+Pj4+Pj4+Pj4gaW5kZXggYTQ1NTZmOS4uNDlhYTE0M2UgMTAwNjQ0Cj4+Pj4+Pj4+Pj4+Pj4+ PiAtLS0gYS9uZXQvbWFjODAyMTEvaWVlZTgwMjExX2kuaAo+Pj4+Pj4+Pj4+Pj4+Pj4gKysrIGIv bmV0L21hYzgwMjExL2llZWU4MDIxMV9pLmgKPj4+Pj4+Pj4+Pj4+Pj4+IEBAIC04NDcsNiArODQ3 LDcgQEAgc3RydWN0IHR4cV9pbmZvIHsKPj4+Pj4+Pj4+Pj4+Pj4+ICAJc3RydWN0IGNvZGVsX3N0 YXRzIGNzdGF0czsKPj4+Pj4+Pj4+Pj4+Pj4+ICAJc3RydWN0IHNrX2J1ZmZfaGVhZCBmcmFnczsK Pj4+Pj4+Pj4+Pj4+Pj4+ICAJc3RydWN0IHJiX25vZGUgc2NoZWR1bGVfb3JkZXI7Cj4+Pj4+Pj4+ Pj4+Pj4+PiArCXN0cnVjdCBsaXN0X2hlYWQgY2FuZGlkYXRlOwo+Pj4+Pj4+Pj4+Pj4+Pj4gIAl1 bnNpZ25lZCBsb25nIGZsYWdzOwo+Pj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+Pj4+PiAgCS8q IGtlZXAgbGFzdCEgKi8KPj4+Pj4+Pj4+Pj4+Pj4+IEBAIC0xMTQ1LDYgKzExNDYsOCBAQCBzdHJ1 Y3QgaWVlZTgwMjExX2xvY2FsIHsKPj4+Pj4+Pj4+Pj4+Pj4+ICAJdTY0IGFpcnRpbWVfdl90W0lF RUU4MDIxMV9OVU1fQUNTXTsKPj4+Pj4+Pj4+Pj4+Pj4+ICAJdTY0IGFpcnRpbWVfd2VpZ2h0X3N1 bVtJRUVFODAyMTFfTlVNX0FDU107Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+Pj4+ICsJ c3RydWN0IGxpc3RfaGVhZCByZW1vdmVfbGlzdFtJRUVFODAyMTFfTlVNX0FDU107Cj4+Pj4+Pj4+ Pj4+Pj4+PiArCXN0cnVjdCB0aW1lcl9saXN0IHJlbW92ZV90aW1lcjsKPj4+Pj4+Pj4+Pj4+Pj4+ ICAJdTE2IGFpcnRpbWVfZmxhZ3M7Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+Pj4+ICAJ Y29uc3Qgc3RydWN0IGllZWU4MDIxMV9vcHMgKm9wczsKPj4+Pj4+Pj4+Pj4+Pj4+IGRpZmYgLS1n aXQgYS9uZXQvbWFjODAyMTEvbWFpbi5jIGIvbmV0L21hYzgwMjExL21haW4uYwo+Pj4+Pj4+Pj4+ Pj4+Pj4gaW5kZXggZTlmZmE4ZS4uNzhmZTI0YSAxMDA2NDQKPj4+Pj4+Pj4+Pj4+Pj4+IC0tLSBh L25ldC9tYWM4MDIxMS9tYWluLmMKPj4+Pj4+Pj4+Pj4+Pj4+ICsrKyBiL25ldC9tYWM4MDIxMS9t YWluLmMKPj4+Pj4+Pj4+Pj4+Pj4+IEBAIC02NjcsMTAgKzY2NywxNSBAQCBzdHJ1Y3QgaWVlZTgw MjExX2h3Cj4+Pj4+Pj4+Pj4+Pj4+PiAqaWVlZTgwMjExX2FsbG9jX2h3X25tKHNpemVfdCBwcml2 X2RhdGFfbGVuLAo+Pj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+Pj4+PiAgCWZvciAoaSA9IDA7 IGkgPCBJRUVFODAyMTFfTlVNX0FDUzsgaSsrKSB7Cj4+Pj4+Pj4+Pj4+Pj4+PiAgCQlsb2NhbC0+ YWN0aXZlX3R4cXNbaV0gPSBSQl9ST09UX0NBQ0hFRDsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJCUlOSVRf TElTVF9IRUFEKCZsb2NhbC0+cmVtb3ZlX2xpc3RbaV0pOwo+Pj4+Pj4+Pj4+Pj4+Pj4gIAkJc3Bp bl9sb2NrX2luaXQoJmxvY2FsLT5hY3RpdmVfdHhxX2xvY2tbaV0pOwo+Pj4+Pj4+Pj4+Pj4+Pj4g IAl9Cj4+Pj4+Pj4+Pj4+Pj4+PiAgCWxvY2FsLT5haXJ0aW1lX2ZsYWdzID0gQUlSVElNRV9VU0Vf VFggfCBBSVJUSU1FX1VTRV9SWDsKPj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gKwl0 aW1lcl9zZXR1cCgmbG9jYWwtPnJlbW92ZV90aW1lciwgaWVlZTgwMjExX3R4cXNfY2hlY2ssCj4+ Pj4+Pj4+Pj4+Pj4+PiAwKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJbW9kX3RpbWVyKCZsb2NhbC0+cmVt b3ZlX3RpbWVyLAo+Pj4+Pj4+Pj4+Pj4+Pj4gKwkJICBqaWZmaWVzICsKPj4+Pj4+Pj4+Pj4+Pj4+ IG1zZWNzX3RvX2ppZmZpZXMoSUVFRTgwMjExX0FJUlRJTUVfVFhRX1JNX0NIS19JTlRWX0lOX01T KSk7Cj4+Pj4+Pj4+Pj4+Pj4+PiArCj4+Pj4+Pj4+Pj4+Pj4+PiAgCUlOSVRfTElTVF9IRUFEKCZs b2NhbC0+Y2hhbmN0eF9saXN0KTsKPj4+Pj4+Pj4+Pj4+Pj4+ICAJbXV0ZXhfaW5pdCgmbG9jYWwt PmNoYW5jdHhfbXR4KTsKPj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gQEAgLTEzMDUs NiArMTMxMCw3IEBAIHZvaWQgaWVlZTgwMjExX3VucmVnaXN0ZXJfaHcoc3RydWN0Cj4+Pj4+Pj4+ Pj4+Pj4+PiBpZWVlODAyMTFfaHcKPj4+Pj4+Pj4+Pj4+Pj4+ICpodykKPj4+Pj4+Pj4+Pj4+Pj4+ ICAJdGFza2xldF9raWxsKCZsb2NhbC0+dHhfcGVuZGluZ190YXNrbGV0KTsKPj4+Pj4+Pj4+Pj4+ Pj4+ICAJdGFza2xldF9raWxsKCZsb2NhbC0+dGFza2xldCk7Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+ Pj4+Pj4+Pj4+Pj4+ICsJZGVsX3RpbWVyX3N5bmMoJmxvY2FsLT5yZW1vdmVfdGltZXIpOwo+Pj4+ Pj4+Pj4+Pj4+Pj4gICNpZmRlZiBDT05GSUdfSU5FVAo+Pj4+Pj4+Pj4+Pj4+Pj4gIAl1bnJlZ2lz dGVyX2luZXRhZGRyX25vdGlmaWVyKCZsb2NhbC0+aWZhX25vdGlmaWVyKTsKPj4+Pj4+Pj4+Pj4+ Pj4+ICAjZW5kaWYKPj4+Pj4+Pj4+Pj4+Pj4+IGRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEvdHgu YyBiL25ldC9tYWM4MDIxMS90eC5jCj4+Pj4+Pj4+Pj4+Pj4+PiBpbmRleCBkMDBiYWFhLi40MmNh MDEwIDEwMDY0NAo+Pj4+Pj4+Pj4+Pj4+Pj4gLS0tIGEvbmV0L21hYzgwMjExL3R4LmMKPj4+Pj4+ Pj4+Pj4+Pj4+ICsrKyBiL25ldC9tYWM4MDIxMS90eC5jCj4+Pj4+Pj4+Pj4+Pj4+PiBAQCAtMTQ1 MCw2ICsxNDUwLDcgQEAgdm9pZCBpZWVlODAyMTFfdHhxX2luaXQoc3RydWN0Cj4+Pj4+Pj4+Pj4+ Pj4+PiBpZWVlODAyMTFfc3ViX2lmX2RhdGEgKnNkYXRhLAo+Pj4+Pj4+Pj4+Pj4+Pj4gIAljb2Rl bF9zdGF0c19pbml0KCZ0eHFpLT5jc3RhdHMpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gIAlfX3NrYl9xdWV1 ZV9oZWFkX2luaXQoJnR4cWktPmZyYWdzKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICAJUkJfQ0xFQVJfTk9E RSgmdHhxaS0+c2NoZWR1bGVfb3JkZXIpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlJTklUX0xJU1RfSEVB RCgmdHhxaS0+Y2FuZGlkYXRlKTsKPj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gIAl0 eHFpLT50eHEudmlmID0gJnNkYXRhLT52aWY7Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+ Pj4+IEBAIC0zNzI0LDYgKzM3MjUsOSBAQCB2b2lkIGllZWU4MDIxMV9zY2hlZHVsZV90eHEoc3Ry dWN0Cj4+Pj4+Pj4+Pj4+Pj4+PiBpZWVlODAyMTFfaHcKPj4+Pj4+Pj4+Pj4+Pj4+ICpodywKPj4+ Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gIAlzcGluX2xvY2tfYmgoJmxvY2FsLT5hY3Rp dmVfdHhxX2xvY2tbYWNdKTsKPj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlpZiAo IWxpc3RfZW1wdHkoJnR4cWktPmNhbmRpZGF0ZSkpCj4+Pj4+Pj4+Pj4+Pj4+PiArCQlsaXN0X2Rl bF9pbml0KCZ0eHFpLT5jYW5kaWRhdGUpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwo+Pj4+Pj4+Pj4+Pj4+ Pj4gIAlpZiAoIVJCX0VNUFRZX05PREUoJnR4cWktPnNjaGVkdWxlX29yZGVyKSkKPj4+Pj4+Pj4+ Pj4+Pj4+ICAJCWdvdG8gb3V0Owo+Pj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+Pj4+PiBAQCAt Mzc4Myw2ICszNzg3LDIwIEBAIHN0YXRpYyB2b2lkCj4+Pj4+Pj4+Pj4+Pj4+PiBfX2llZWU4MDIx MV91bnNjaGVkdWxlX3R4cShzdHJ1Y3QKPj4+Pj4+Pj4+Pj4+Pj4+IGllZWU4MDIxMV9odyAqaHcs Cj4+Pj4+Pj4+Pj4+Pj4+PiAgCVJCX0NMRUFSX05PREUoJnR4cWktPnNjaGVkdWxlX29yZGVyKTsK Pj4+Pj4+Pj4+Pj4+Pj4+ICB9Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+Pj4+ICt2b2lk IGllZWU4MDIxMV9yZW1vdmVfdHhxKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LAo+Pj4+Pj4+Pj4+ Pj4+Pj4gKwkJCSAgc3RydWN0IGllZWU4MDIxMV90eHEgKnR4cSkKPj4+Pj4+Pj4+Pj4+Pj4+ICt7 Cj4+Pj4+Pj4+Pj4+Pj4+PiArCXN0cnVjdCBpZWVlODAyMTFfbG9jYWwgKmxvY2FsID0gaHdfdG9f bG9jYWwoaHcpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlzdHJ1Y3QgdHhxX2luZm8gKnR4cWkgPSB0b190 eHFfaW5mbyh0eHEpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlsb2NrZGVw X2Fzc2VydF9oZWxkKCZsb2NhbC0+YWN0aXZlX3R4cV9sb2NrW3R4cS0+YWNdKTsKPj4+Pj4+Pj4+ Pj4+Pj4+ICsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJaWYgKCFSQl9FTVBUWV9OT0RFKCZ0eHFpLT5zY2hl ZHVsZV9vcmRlcikpIHsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJCV9faWVlZTgwMjExX3Vuc2NoZWR1bGVf dHhxKGh3LCB0eHEpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwkJbGlzdF9kZWxfaW5pdCgmdHhxaS0+Y2Fu ZGlkYXRlKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJfQo+Pj4+Pj4+Pj4+Pj4+Pj4gK30KPj4+Pj4+Pj4+ Pj4+Pj4+ICsKPj4+Pj4+Pj4+Pj4+Pj4+ICB2b2lkIGllZWU4MDIxMV91bnNjaGVkdWxlX3R4cShz dHJ1Y3QgaWVlZTgwMjExX2h3ICpodywKPj4+Pj4+Pj4+Pj4+Pj4+ICAJCQkgICAgICBzdHJ1Y3Qg aWVlZTgwMjExX3R4cSAqdHhxKQo+Pj4+Pj4+Pj4+Pj4+Pj4gIAlfX2FjcXVpcmVzKHR4cV9sb2Nr KSBfX3JlbGVhc2VzKHR4cV9sb2NrKQo+Pj4+Pj4+Pj4+Pj4+Pj4gQEAgLTM3OTAsNyArMzgwOCw3 IEBAIHZvaWQgaWVlZTgwMjExX3Vuc2NoZWR1bGVfdHhxKHN0cnVjdAo+Pj4+Pj4+Pj4+Pj4+Pj4g aWVlZTgwMjExX2h3ICpodywKPj4+Pj4+Pj4+Pj4+Pj4+ICAJc3RydWN0IGllZWU4MDIxMV9sb2Nh bCAqbG9jYWwgPSBod190b19sb2NhbChodyk7Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+ Pj4+ICAJc3Bpbl9sb2NrX2JoKCZsb2NhbC0+YWN0aXZlX3R4cV9sb2NrW3R4cS0+YWNdKTsKPj4+ Pj4+Pj4+Pj4+Pj4+IC0JX19pZWVlODAyMTFfdW5zY2hlZHVsZV90eHEoaHcsIHR4cSk7Cj4+Pj4+ Pj4+Pj4+Pj4+PiArCWllZWU4MDIxMV9yZW1vdmVfdHhxKGh3LCB0eHEpOwo+Pj4+Pj4+Pj4+Pj4+ Pj4gIAlzcGluX3VubG9ja19iaCgmbG9jYWwtPmFjdGl2ZV90eHFfbG9ja1t0eHEtPmFjXSk7Cj4+ Pj4+Pj4+Pj4+Pj4+PiAgfQo+Pj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+Pj4+PiBAQCAtMzgw MywxMSArMzgyMSw0OCBAQCB2b2lkIGllZWU4MDIxMV9yZXR1cm5fdHhxKHN0cnVjdAo+Pj4+Pj4+ Pj4+Pj4+Pj4gaWVlZTgwMjExX2h3Cj4+Pj4+Pj4+Pj4+Pj4+PiAqaHcsCj4+Pj4+Pj4+Pj4+Pj4+ PiAgCWxvY2tkZXBfYXNzZXJ0X2hlbGQoJmxvY2FsLT5hY3RpdmVfdHhxX2xvY2tbdHhxLT5hY10p Owo+Pj4+Pj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4+Pj4+PiAgCWlmICghUkJfRU1QVFlfTk9ERSgm dHhxaS0+c2NoZWR1bGVfb3JkZXIpICYmCj4+Pj4+Pj4+Pj4+Pj4+PiAtCSAgICAoc2tiX3F1ZXVl X2VtcHR5KCZ0eHFpLT5mcmFncykgJiYKPj4+Pj4+Pj4+Pj4+Pj4+ICF0eHFpLT50aW4uYmFja2xv Z19wYWNrZXRzKSkKPj4+Pj4+Pj4+Pj4+Pj4+IC0JCV9faWVlZTgwMjExX3Vuc2NoZWR1bGVfdHhx KGh3LCB0eHEpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwkJIXR4cV9oYXNfcXVldWUoJnR4cWktPnR4cSkg JiYKPj4+Pj4+Pj4+Pj4+Pj4+ICsJCWxpc3RfZW1wdHkoJnR4cWktPmNhbmRpZGF0ZSkpCj4+Pj4+ Pj4+Pj4+Pj4+PiArCQlsaXN0X2FkZF90YWlsKCZ0eHFpLT5jYW5kaWRhdGUsCj4+Pj4+Pj4+Pj4+ Pj4+PiAmbG9jYWwtPnJlbW92ZV9saXN0W3R4cS0+YWNdKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICsKPj4+ Pj4+Pj4+Pj4+Pj4+ICB9Cj4+Pj4+Pj4+Pj4+Pj4+PiAgRVhQT1JUX1NZTUJPTChpZWVlODAyMTFf cmV0dXJuX3R4cSk7Cj4+Pj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+Pj4+ICt2b2lkIF9faWVl ZTgwMjExX2NoZWNrX3R4cXMoc3RydWN0IGllZWU4MDIxMV9sb2NhbCAKPj4+Pj4+Pj4+Pj4+Pj4+ ICpsb2NhbCwKPj4+Pj4+Pj4+Pj4+Pj4+IGludAo+Pj4+Pj4+Pj4+Pj4+Pj4gYWMpCj4+Pj4+Pj4+ Pj4+Pj4+PiArewo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlzdHJ1Y3QgdHhxX2luZm8gKml0ZXIsICp0bXA7 Cj4+Pj4+Pj4+Pj4+Pj4+PiArCXN0cnVjdCBzdGFfaW5mbyAqc3RhOwo+Pj4+Pj4+Pj4+Pj4+Pj4g Kwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlsb2NrZGVwX2Fzc2VydF9oZWxkKCZsb2NhbC0+YWN0aXZlX3R4 cV9sb2NrW2FjXSk7Cj4+Pj4+Pj4+Pj4+Pj4+PiArCj4+Pj4+Pj4+Pj4+Pj4+PiArCWxpc3RfZm9y X2VhY2hfZW50cnlfc2FmZShpdGVyLCB0bXAsCj4+Pj4+Pj4+Pj4+Pj4+PiAmbG9jYWwtPnJlbW92 ZV9saXN0W2FjXSwKPj4+Pj4+Pj4+Pj4+Pj4+ICsJCQkJIGNhbmRpZGF0ZSkgewo+Pj4+Pj4+Pj4+ Pj4+Pj4gKwkJc3RhID0gY29udGFpbmVyX29mKGl0ZXItPnR4cS5zdGEsIHN0cnVjdCBzdGFfaW5m bywgCj4+Pj4+Pj4+Pj4+Pj4+PiBzdGEpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwo+Pj4+Pj4+Pj4+Pj4+ Pj4gKwkJaWYgKHR4cV9oYXNfcXVldWUoJml0ZXItPnR4cSkpCj4+Pj4+Pj4+Pj4+Pj4+PiArCQkJ bGlzdF9kZWxfaW5pdCgmaXRlci0+Y2FuZGlkYXRlKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJCWVsc2UK Pj4+Pj4+Pj4+Pj4+Pj4+ICsJCQlpZWVlODAyMTFfcmVtb3ZlX3R4cSgmbG9jYWwtPmh3LCAmaXRl ci0+dHhxKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJfQo+Pj4+Pj4+Pj4+Pj4+Pj4gK30KPj4+Pj4+Pj4+ Pj4+Pj4+ICsKPj4+Pj4+Pj4+Pj4+Pj4+ICt2b2lkIGllZWU4MDIxMV90eHFzX2NoZWNrKHN0cnVj dCB0aW1lcl9saXN0ICp0KQo+Pj4+Pj4+Pj4+Pj4+Pj4gK3sKPj4+Pj4+Pj4+Pj4+Pj4+ICsJc3Ry dWN0IGllZWU4MDIxMV9sb2NhbCAqbG9jYWwgPSBmcm9tX3RpbWVyKGxvY2FsLCB0LAo+Pj4+Pj4+ Pj4+Pj4+Pj4gcmVtb3ZlX3RpbWVyKTsKPj4+Pj4+Pj4+Pj4+Pj4+ICsJc3RydWN0IHR4cV9pbmZv ICppdGVyLCAqdG1wOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwlzdHJ1Y3Qgc3RhX2luZm8gKnN0YTsKPj4+ Pj4+Pj4+Pj4+Pj4+ICsJaW50IGFjOwo+Pj4+Pj4+Pj4+Pj4+Pj4gKwo+Pj4+Pj4+Pj4+Pj4+Pj4g Kwlmb3IgKGFjID0gMDsgYWMgPCBJRUVFODAyMTFfTlVNX0FDUzsgYWMrKykgewo+Pj4+Pj4+Pj4+ Pj4+Pj4gKwkJc3Bpbl9sb2NrX2JoKCZsb2NhbC0+YWN0aXZlX3R4cV9sb2NrW2FjXSk7Cj4+Pj4+ Pj4+Pj4+Pj4+PiArCQlfX2llZWU4MDIxMV9jaGVja190eHFzKGxvY2FsLCBhYyk7Cj4+Pj4+Pj4+ Pj4+Pj4+PiArCQlzcGluX3VubG9ja19iaCgmbG9jYWwtPmFjdGl2ZV90eHFfbG9ja1thY10pOwo+ Pj4+Pj4+Pj4+Pj4+Pj4gKwl9Cj4+Pj4+Pj4+Pj4+Pj4+PiArCj4+Pj4+Pj4+Pj4+Pj4+PiArCW1v ZF90aW1lcigmbG9jYWwtPnJlbW92ZV90aW1lciwKPj4+Pj4+Pj4+Pj4+Pj4+ICsJCSAgamlmZmll cyArCj4+Pj4+Pj4+Pj4+Pj4+PiBtc2Vjc190b19qaWZmaWVzKElFRUU4MDIxMV9BSVJUSU1FX1RY UV9STV9DSEtfSU5UVl9JTl9NUykpOwo+Pj4+Pj4+Pj4+Pj4+Pj4gK30KPj4+Pj4+Pj4+Pj4+Pj4g Cj4+Pj4+Pj4+Pj4+Pj4+IEknbGwgYXNrIHRoZSBzYW1lIGFzIEkgZGlkIGxhc3QgdGltZSAod2hl cmUgeW91IHRvbGQgbWUgdG8KPj4+Pj4+Pj4+Pj4+Pj4gaG9sZAo+Pj4+Pj4+Pj4+Pj4+PiBvZmYK Pj4+Pj4+Pj4+Pj4+Pj4gdW50aWwgdGhpcyByb3VuZCk6Cj4+Pj4+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+ Pj4+Pj4+PiBXaHkgZG8geW91IG5lZWQgdGhlIHRpbWVyIGFuZCB0aGUgcGVyaW9kaWMgY2hlY2s/ IElmIFRYUXMgCj4+Pj4+Pj4+Pj4+Pj4+IGFyZQo+Pj4+Pj4+Pj4+Pj4+PiBhZGRlZAo+Pj4+Pj4+ Pj4+Pj4+PiB0bwo+Pj4+Pj4+Pj4+Pj4+PiB0aGUgcmVtb3ZlIGxpc3QgZHVyaW5nIHRoZSBzY2hl ZHVsaW5nIHJ1biwgYW5kCj4+Pj4+Pj4+Pj4+Pj4+IF9faWVlZTgwMjExX2NoZWNrX3R4cXMoKQo+ Pj4+Pj4+Pj4+Pj4+PiBpcyBydW4gZnJvbSBzY2hlZHVsZV9lbmQoKSwgaXNuJ3QgdGhhdCBzdWZm aWNpZW50IHRvIGNsZWFyCj4+Pj4+Pj4+Pj4+Pj4+IHRoZQo+Pj4+Pj4+Pj4+Pj4+PiBsaXN0Pwo+ Pj4+Pj4+Pj4+Pj4+IElzIGl0IHBvc3NpYmxlIHRoYXQgYSB0eHEgaXMgbm90IGFkZGVkIHRvIHRo ZSByZW1vdmUgbGlzdCAKPj4+Pj4+Pj4+Pj4+PiBidXQKPj4+Pj4+Pj4+Pj4+PiB0aGVuCj4+Pj4+ Pj4+Pj4+Pj4gcGFja2V0cyBpbiBpdCBhcmUgZHJvcHBlZCBieSBmcV9jb2RlbCBhbGdvPyBMaWtl IHRoZSBzdGF0aW9uCj4+Pj4+Pj4+Pj4+Pj4gZGlzY29ubmVjdHMKPj4+Pj4+Pj4+Pj4+PiB3aXRo b3V0IGFueSBub3RpZmljYXRpb24uCj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+Pj4+IFdlbGwgYXMg bG9uZyBhcyBhbGwgdGhlIG90aGVyIGNsZWFudXAgcGF0aHMgY2FsbCBkaXJlY3RseSAKPj4+Pj4+ Pj4+Pj4+IGludG8KPj4+Pj4+Pj4+Pj4+IF9fdW5zY2hlZHVsZV90eHEoKSwgdGhhdCBzaG91bGQg cmVtb3ZlIHN0YXRpb25zIGZyb20gdGhlCj4+Pj4+Pj4+Pj4+PiBzY2hlZHVsZXIKPj4+Pj4+Pj4+ Pj4+IHdoZW4KPj4+Pj4+Pj4+Pj4+IHRoZXkgZGlzY29ubmVjdCBldGMuCj4+Pj4+Pj4+Pj4+IFll cywgdGhlIGRpc2Nvbm5lY3Qgc2NlbmFyaW8gaXMgYSBiYWQgZXhhbXBsZS4gTXkgY29uY2VybiBp cywKPj4+Pj4+Pj4+Pj4gc2F5LAo+Pj4+Pj4+Pj4+PiB3ZQo+Pj4+Pj4+Pj4+PiBoYXZlIDEwIHN0 YXRpb25zIGFuZCBvbmx5IG9uZSBvZiB0aGVtIGlzIGFzc2lnbmVkIGEgdmVyeSBzbWFsbAo+Pj4+ Pj4+Pj4+PiB3ZWlnaHQKPj4+Pj4+Pj4+Pj4gY29tcGFyZWQgd2l0aCB0aGF0IG9mIG90aGVycy4g U3VwcG9zZSwgYWZ0ZXIgaXRzIGNoYW5jZSBvZiBUeCwKPj4+Pj4+Pj4+Pj4gaXQKPj4+Pj4+Pj4+ Pj4gaXMKPj4+Pj4+Pj4+Pj4gbW9zdCBsaWtlbHkgdG8gYmUgcGxhY2VkIGluIHRoZSByaWdodG1v c3Qoc3RpbGwgaGFzIHNvbWUgCj4+Pj4+Pj4+Pj4+IHBhY2tldHMKPj4+Pj4+Pj4+Pj4gaW4KPj4+ Pj4+Pj4+Pj4gdGhlCj4+Pj4+Pj4+Pj4+IHR4cSkgYW5kIG5vIG1vcmUgaW5jb21pbmcgZGF0YSBm b3IgaXQuIFRoZSByZW1haW5pbmcgcGFja2V0cyAKPj4+Pj4+Pj4+Pj4gaW4KPj4+Pj4+Pj4+Pj4g dHhxCj4+Pj4+Pj4+Pj4+IHdpbGwKPj4+Pj4+Pj4+Pj4gYmUgZHJvcHBlZCBkdWUgdG8gdGltZW91 dCBhbGdvIGluIGNvZGVsKGNvcnJlY3QgbWUgaWYgSSBhbQo+Pj4+Pj4+Pj4+PiB3cm9uZykKPj4+ Pj4+Pj4+Pj4gYnV0Cj4+Pj4+Pj4+Pj4+IHRoaXMgZW1wdHkgdHhxIHdpbGwgc3RheSBvbiB0aGUg cmJ0cmVlIHVudGlsIG90aGVyIHR4cXMgZ2V0Cj4+Pj4+Pj4+Pj4+IGRyYWluZWQKPj4+Pj4+Pj4+ Pj4gb3IKPj4+Pj4+Pj4+Pj4gZ2xvYmFsIHZ0IGNhdGNoIHVwIHdpdGggaXRzIHZ0LiBUaGUgc3Rh eWluZyB0aW1lIGNvdWxkIGJlIGxvbmcKPj4+Pj4+Pj4+Pj4gaWYKPj4+Pj4+Pj4+Pj4gd2VpZ2h0 Cj4+Pj4+Pj4+Pj4+IGlzIGV4dHJlbWVseSBzbWFsbC4gVGhlbiBkbyB3ZSBuZWVkIHRpbWVyIHRv IGNoZWNrIG9yIGFueSAKPj4+Pj4+Pj4+Pj4gb3RoZXIKPj4+Pj4+Pj4+Pj4gYmV0dGVyCj4+Pj4+ Pj4+Pj4+IHNvbHV0aW9uPwo+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+IEFoLCBJIHNlZSB3aGF0IHlv dSBtZWFuLiBObywgSSBkb24ndCB0aGluayB0aGlzIHdpbGwgYmUgYQo+Pj4+Pj4+Pj4+IHByb2Js ZW07Cj4+Pj4+Pj4+Pj4gdGhlCj4+Pj4+Pj4+Pj4gc2NlbmFyaW8geW91J3JlIGRlc2NyaWJpbmcg d291bGQgcGxheSBvdXQgbGlrZSB0aGlzOgo+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+IDEuIFN0YXRp b24gZW5kcyB0cmFuc21pdHRpbmcsIHN0aWxsIGhhcyBhIHNpbmdsZSBwYWNrZXQgcXVldWVkLAo+ Pj4+Pj4+Pj4+IGdldHMKPj4+Pj4+Pj4+PiAgICBtb3ZlZCB0byB0aGUgZW5kIG9mIHRoZSByYnRy ZWUgKGFuZCBzdGF5cyB0aGVyZSBmb3IgYSAKPj4+Pj4+Pj4+PiB3aGlsZSkuCj4+Pj4+Pj4+Pj4g Cj4+Pj4+Pj4+Pj4gMi4gV2hlbiB3ZSBmaW5hbGx5IGdldCB0byB0aGUgcG9pbnQgd2hlcmUgdGhp cyBzdGF0aW9uIGdldHMKPj4+Pj4+Pj4+PiBhbm90aGVyCj4+Pj4+Pj4+Pj4gICAgY2hhbmNlIHRv IHRyYW5zbWl0LCB0aGUgQ29EZWwgZHJvcCB0aW1lciB0cmlnZ2VycyBhbmQgdGhlIAo+Pj4+Pj4+ Pj4+IGxhc3QKPj4+Pj4+Pj4+PiBwYWNrZXQKPj4+Pj4+Pj4+PiAgICBpcyBkcm9wcGVkWzBdLiBU aGlzIG1lYW5zIHRoYXQgdGhlIHF1ZXVlIHdpbGwganVzdCBiZSBlbXB0eQo+Pj4+Pj4+Pj4+ICAg IChhbmQgaWVlZTgwMjExX3R4X2RlcXVldWUoKSB3aWxsIHJldHVybiBOVUxMKS4KPj4+Pj4+Pj4+ PiAKPj4+Pj4+Pj4+PiAzLiBCZWNhdXNlIHRoZSBxdWV1ZSBpcyBlbXB0eSwgaWVlZTgwMjExX3Jl dHVybl90eHEoKSB3aWxsIG5vdAo+Pj4+Pj4+Pj4+IHB1dAo+Pj4+Pj4+Pj4+IGl0Cj4+Pj4+Pj4+ Pj4gICAgYmFjayBvbiB0aGUgcmJ0cmVlLgo+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+IENydWNpYWxs eSwgaW4gMi4gdGhlIENvRGVsIGFsZ29yaXRobSBkb2Vzbid0IGtpY2sgaW4gdW50aWwgdGhlCj4+ Pj4+Pj4+Pj4gcG9pbnQKPj4+Pj4+Pj4+PiBvZgo+Pj4+Pj4+Pj4+IHBhY2tldCBkZXF1ZXVlLiBC dXQgZXZlbiBpZiBhbiBlbXB0eSBxdWV1ZSBzdGF5cyBvbiB0aGUgcmJ0cmVlCj4+Pj4+Pj4+Pj4g Zm9yCj4+Pj4+Pj4+Pj4gYQo+Pj4+Pj4+Pj4+IHdoaWxlLCB0aGVyZSBpcyBubyBoYXJtIGluIHRo YXQ6IGV2ZW50dWFsbHkgaXQgd2lsbCBnZXQgaXRzIAo+Pj4+Pj4+Pj4+IHR1cm4sCj4+Pj4+Pj4+ Pj4gaXQKPj4+Pj4+Pj4+PiB3aWxsIHR1cm4gb3V0IHRvIGJlIGVtcHR5LCBhbmQganVzdCBiZSBz a2lwcGVkIG92ZXIuCj4+Pj4+Pj4+PiBUaGVuIHRoYXQgd2lsbCBiZSBmaW5lLiBUaGFua3MgZm9y IHRoZSBleHBsYW5hdGlvbiBvZiB0aGUgCj4+Pj4+Pj4+PiBkcm9wcGluZwo+Pj4+Pj4+Pj4gcGFy dAo+Pj4+Pj4+Pj4gaW4gQ29EZWwgYWxnb3JpdGhtLgo+Pj4+Pj4+PiAKPj4+Pj4+Pj4gWXVwLCB0 aGluayBzby4gQW5kIHlvdSdyZSB3ZWxjb21lIDopCj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+IFRoZSBp c3N1ZSB3ZSBuZWVkIHRvIGJlIGNvbmNlcm5lZCBhYm91dCBpcyB0aGUgb3Bwb3NpdGU6IElmIHdl Cj4+Pj4+Pj4+Pj4gaGF2ZQo+Pj4+Pj4+Pj4+IGEKPj4+Pj4+Pj4+PiBxdWV1ZSB0aGF0ICpkb2Vz KiBoYXZlIHBhY2tldHMgcXVldWVkLCBidXQgd2hpY2ggaXMgKm5vdCoKPj4+Pj4+Pj4+PiBzY2hl ZHVsZWQKPj4+Pj4+Pj4+PiBmb3IKPj4+Pj4+Pj4+PiB0cmFuc21pc3Npb24sIHRoYXQgd2lsbCBz dGFsbCBUWC4KPj4+Pj4+Pj4+IElzIGl0IGJ5IGRlc2lnbiBzaW5jZSBpdHMgdnQgaXMgbW9yZSB0 aGFuIGdsb2JhbCB2dCwgcmlnaHQ/IFRoZQo+Pj4+Pj4+Pj4gbGF0dGVuY3kKPj4+Pj4+Pj4+IG1h eSBzb21laG93IGdldCBpbXBhY3RlZCB0aG91Z2guCj4+Pj4+Pj4+IAo+Pj4+Pj4+PiBXZWxsLCBp dCBzaG91bGQgc3RpbGwgc3RheSBvbiB0aGUgcmJ0cmVlIGFzIGxvbmcgYXMgaXQgaGFzIAo+Pj4+ Pj4+PiBwYWNrZXRzCj4+Pj4+Pj4+IHF1ZXVlZC4gV2UgZG9uJ3QgaGF2ZSBhIGNoZWNrIGFueXdo ZXJlIHRoYXQgcmVzY2hlZHVsZXMgVFhRcyAKPj4+Pj4+Pj4gd2hvc2UKPj4+Pj4+Pj4gdl90Cj4+ Pj4+Pj4+IGRyb3BzIGJlbG93IGdsb2JhbCB2X3QuLi4KPj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4gWzBd IENvRGVsIGluIG1vc3QgY2FzZXMgb25seSBkcm9wcyBhIHNpbmdsZSBwYWNrZXQgYXQgYSB0aW1l LCAKPj4+Pj4+Pj4+PiBzbwo+Pj4+Pj4+Pj4+IGl0Cj4+Pj4+Pj4+Pj4gd2lsbAo+Pj4+Pj4+Pj4+ IG5vdCBjbGVhciBvdXQgYW4gZW50aXJlIHF1ZXVlIHdpdGggbXVsdGlwbGUgcGFja2V0cyBpbiBv bmUgZ28uCj4+Pj4+Pj4+Pj4gQnV0Cj4+Pj4+Pj4+Pj4geW91Cj4+Pj4+Pj4+Pj4gYXJlIHJpZ2h0 IHRoYXQgaXQgY291bGQgY29uY2VpdmFibHkgZHJvcCB0aGUgbGFzdCBwYWNrZXQgaW4gYQo+Pj4+ Pj4+Pj4+IHF1ZXVlLgo+Pj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4gV2Ugb25seSBuZWVkIHRvIGRl ZmVyIHJlbW92YWwgaW5zaWRlIGEgc2luZ2xlICJzY2hlZHVsaW5nCj4+Pj4+Pj4+Pj4+PiByb3Vu ZCIKPj4+Pj4+Pj4+Pj4+IChpLmUuLAo+Pj4+Pj4+Pj4+Pj4gYmV0d2VlbiBhIHBhaXIgb2YgaWVl ZTgwMjExX3R4cV9zY2hlZHVsZV9zdGFydC9lbmQuIFNvIGlmIHdlCj4+Pj4+Pj4+Pj4+PiBqdXN0 Cj4+Pj4+Pj4+Pj4+PiB3YWxrCj4+Pj4+Pj4+Pj4+PiB0aGUgcmVtb3ZlIGxpc3QgaW4gc2NoZWR1 bGVfZW5kKCkgd2Ugc2hvdWxkIGJlIGVub3VnaCwgbm8/Cj4+Pj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+ Pj4+IEhtbSwgb3IgbWF5YmUgYSBzaW1wbGVyIHdheSB0byBmaXggdGhlIG9yaWdpbmFsIGlzc3Vl IGlzIGp1c3QKPj4+Pj4+Pj4+Pj4+IHRvCj4+Pj4+Pj4+Pj4+PiBoYXZlCj4+Pj4+Pj4+Pj4+PiB1 bnNjaGVkdWxlX3R4cSgpIHVwZGF0ZSB0aGUgc2NoZWR1bGVfcG9zKCkgcG9pbnRlcj8KPj4+Pj4+ Pj4+Pj4+IAo+Pj4+Pj4+Pj4+Pj4gSS5lLiwgdW5zY2hlZHVsZV90eHEgY2hlY2tzIGlmIHRoZSB0 eHEgYmVpbmcgcmVtb3ZlZCBpcwo+Pj4+Pj4+Pj4+Pj4gY3VycmVudGx5Cj4+Pj4+Pj4+Pj4+PiBi ZWluZwo+Pj4+Pj4+Pj4+Pj4gcG9pbnRlZCB0byBieSBzY2hlZHVsZV9wb3NbYWNdLCBhbmQgaWYg aXQgaXMsIGl0IHVwZGF0ZXMKPj4+Pj4+Pj4+Pj4+IHNjaGVkdWxlX3Bvcwo+Pj4+Pj4+Pj4+Pj4g dG8KPj4+Pj4+Pj4+Pj4+IGJlIHRoZSByYl9uZXh0IG9mIHRoZSBjdXJyZW50IHZhbHVlPwo+Pj4+ Pj4+Pj4+PiBBY3R1YWxseSwgaWYgc2NoZWR1bGVfcG9zIGlzIHVwZGF0ZWQgdG8gcmJfbmV4dCBv ZiB0aGUgY3VycmVudAo+Pj4+Pj4+Pj4+PiB2YWx1ZSwKPj4+Pj4+Pj4+Pj4gdGhlbiBpbiB0aGUg bmV4dF90eHEoKSB3aGVyZSB3ZSBhcmUgZ29pbmcgdG8gdXNlIHJiX25leHQgYWdhaW4KPj4+Pj4+ Pj4+Pj4gYW5kCj4+Pj4+Pj4+Pj4+IGZpbmFsbHkgcGljayB0aGUgbmV4dCBub2RlIG9mIHRoZSBu b2RlIHdlIHJlYWxseSB3YW50LiBJcyBpdAo+Pj4+Pj4+Pj4+PiBmaW5lCj4+Pj4+Pj4+Pj4+IHRv Cj4+Pj4+Pj4+Pj4+IHVwZGF0ZSBzY2hlZHVsZV9wb3MgdG8gTlVMTD8KPj4+Pj4+Pj4+PiAKPj4+ Pj4+Pj4+PiBIbW0sIHllYWgsIGdvb2QgcG9pbnQuCj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4gSWYg d2UgZG8gZW5kIHVwIHNldHRpbmcgc2NoZWR1bGVfcG9zIHRvIE5VTEwgaW4gdGhlIG1pZGRsZSBv ZiBhCj4+Pj4+Pj4+Pj4gc2NoZWR1bGluZyByb3VuZCwgdGhhdCB3aWxsIG1ha2UgbmV4dF90eHEo KSAic3RhcnQgb3ZlciIsIGFuZCAKPj4+Pj4+Pj4+PiBkbwo+Pj4+Pj4+Pj4+IGFub3RoZXIKPj4+ Pj4+Pj4+PiBsb29wIHRocm91Z2ggdGhlIHdob2xlIHRoaW5nLiBJIGd1ZXNzIHdlIG1heSBiZSBh YmxlIGhpdCBhIGNhc2UKPj4+Pj4+Pj4+PiB3aGVyZQo+Pj4+Pj4+Pj4+IHRoaW5ncyBjYW4gb3Nj aWxsYXRlIGJhY2sgYW5kIGZvcnRoIGJldHdlZW4gYWRkaXRpb24gYW5kIAo+Pj4+Pj4+Pj4+IHJl bW92YWwKPj4+Pj4+Pj4+PiByZXN1bHRpbmcgaW4gYW4gaW5maW5pdGUgbG9vcD8gTm90IHN1cmUs IGJ1dCBhdCBsZWFzdCBJIGNhbid0Cj4+Pj4+Pj4+Pj4gc2VlbQo+Pj4+Pj4+Pj4+IHRvCj4+Pj4+ Pj4+Pj4gY29udmluY2UgbXlzZWxmIHRoYXQgdGhpcyBjYW4ndCBoYXBwZW4uCj4+Pj4+Pj4+PiAK Pj4+Pj4+Pj4+IEFzIHRoZSBsb29wIG9mIG5leHRfdHhxIHVuZGVyIGxvY2sgcHJvdGVjdGlvbiBh cyBiZWxvdywKPj4+Pj4+Pj4+IAo+Pj4+Pj4+Pj4gdHhxX3NjaGVkdWxlX3N0YXJ0KCk7Cj4+Pj4+ Pj4+PiB3aGlsZSh0eHE9bmV4dF90eHEoKSl7Cj4+Pj4+Pj4+PiAuLi4KPj4+Pj4+Pj4+IHJldHVy bl90eHEodHhxKTsKPj4+Pj4+Pj4+IH0KPj4+Pj4+Pj4+IHR4cV9zY2hlZHVsZV9lbmQoKTsKPj4+ Pj4+Pj4+IAo+Pj4+Pj4+Pj4gSSBkbyBub3Qgc2VlIGFueSBjaGFuY2Ugb2YgYWRkaXRpb24sIG5v Pwo+Pj4+Pj4+PiAKPj4+Pj4+Pj4gQXMgeW91IG5vdGVkIGluIHlvdXIgb3RoZXIgZW1haWwsIEZl bGl4IHJlZHVjZWQgdGhlIGxvY2tpbmcuIEFuZAo+Pj4+Pj4+PiB5ZWFoLAo+Pj4+Pj4+PiB3ZSBu ZWVkIHRvIHJlYmFzZSB0aGlzIHNlcmllcyB0byBhbHNvIGluY29ycG9yYXRlIHRoYXQuIEkgZmln dXJlIAo+Pj4+Pj4+PiBJCj4+Pj4+Pj4+IGNhbgo+Pj4+Pj4+PiBzZW5kIGFuIHVwZGF0ZWQgdmVy c2lvbiBvZiB0aGUgZmlyc3QgcGF0Y2ggaW4gdGhlIHNlcmllcyBvbmNlIAo+Pj4+Pj4+PiB3ZSd2 ZQo+Pj4+Pj4+PiB3b3JrZWQgb3V0IHRoZSByZW1haW5pbmcgaXNzdWVzIHdpdGggeW91ciBmb2xs b3ctdXAgcGF0Y2hlcy4KPj4+Pj4+Pj4gCj4+Pj4+Pj4gT2gsIEkgd2FzIHRoaW5raW5nIHdlIHdl cmUgZGlzY3Vzc2luZyB3aXRob3V0IGxvY2tpbmcgcmVkdWNlZC4gCj4+Pj4+Pj4gWWVzLAo+Pj4+ Pj4+IEkKPj4+Pj4+PiBhbHNvIGFncmVlIHRoZXJlIG1pZ2h0IGJlIGEgY2FzZSBjYXVzaW5nIGlu ZmluaXRlIGxvb3AuIFdpdGggCj4+Pj4+Pj4gbG9ja2luZwo+Pj4+Pj4+IHJlZHVjZWQsIHRoZSB0 cmVlIGNhbiBiZSBhZGp1c3RlZCBiZXR3ZWVuIG5leHRfdHhxKCkgYW5kCj4+Pj4+Pj4gcmV0dXJu X3R4cSgpCj4+Pj4+Pj4gaW4KPj4+Pj4+PiB0aGUgbG9vcCBzaXR1YXRpb24uIEZvciBmdXJ0aGVy IGRpc2N1c3Npb24sIGxldCAncyBjb25zaWRlciwKPj4+Pj4+PiAxKSB0aGUgdHJlZSBzdGFydHMg bGlrZToKPj4+Pj4+PiAgICAgICAgIEEtPkItPkMtPkQtPkUKPj4+Pj4+PiAyKSB0aGVuIG5leHRf dHhxKCkgcmV0dXJucyBBIGZvciBkZXF1ZXVpbmcKPj4+Pj4+PiAzKSBkcml2ZXIgZGVxdWV1ZXMg QSBhbmQgZHJhaW5lcyBBIHdpdGhvdXQgYW55IGFjdGl2ZSB0eHEgbG9ja2VkCj4+Pj4+Pj4gbWVh bmluZwo+Pj4+Pj4+IHRoZSB0cmVlIGNvdWxkIGJlIGNoYW5nZWQgdXBvbiBUeCBjb21wZWxldGlv bi4KPj4+Pj4+PiA0KSB0aGVuIGluIHJldHVybl90eHEoKSwgdGhlIHRyZWUgY291bGQgYmUsCj4+ Pj4+Pj4gICAgICAgICBpICAgQS0+Qi0+Qy0+RC0+RSDvvIhBIGlzIGVtcHR5LCBhbmQgbWF5YmUg c29vbiBiZSBhZGRlZCAKPj4+Pj4+PiBiYWNrCj4+Pj4+Pj4gYmVmb3JlIHRoZSBsb29wIGVuZO+8 iQo+Pj4+Pj4+ICAgICAgICAgaWkgIEItPkMtPkEtPkQtPkUg77yIQSBpcyBlbXB0eSwgYW5kIG1h eWJlIHNvb24gYmUgYWRkZWQgCj4+Pj4+Pj4gYmFjawo+Pj4+Pj4+IGJlZm9yZSB0aGUgbG9vcCBl bmTvvIkKPj4+Pj4+PiAgICAgICAgIGlpaSBCLT5DLT5ELT5FLT5BIO+8iEEgaXMgZW1wdHksIGFu ZCBtYXliZSBzb29uIGJlIGFkZGVkIAo+Pj4+Pj4+IGJhY2sKPj4+Pj4+PiBiZWZvcmUgdGhlIGxv b3AgZW5kKQo+Pj4+Pj4+IAo+Pj4+Pj4+IHdpdGggdGhpcyBjaGFuZ2U6Cj4+Pj4+Pj4gICBsb2Nh bC0+c2NoZWR1bGVfcG9zW2FjXSA9IHJiX25leHQobm9kZSkgPzogcmJfcHJldihub2RlKTsKPj4+ Pj4+PiAKPj4+Pj4+PiBmb3IgY2FzZSBpLCBsb2NhbC0+c2NoZWR1bGVfcG9zW2FjXSBpcyByYl9u ZXh0KEEpIHdoaWNoIGlzIEIsIGFuZCAKPj4+Pj4+PiBpbgo+Pj4+Pj4+IG5leHRfdHhxKCksIHJi X25leHQoQikgaXMgd2hhdCB3ZSByZXR1cm5zIHdoaWNoIGFjdHVhbGx5IGlzIEMgYW5kIAo+Pj4+ Pj4+IEIKPj4+Pj4+PiBpcwo+Pj4+Pj4+IHNraXBwZWQsIG5vPwo+Pj4+Pj4+IAo+Pj4+Pj4+IFNp bWlsaWFyIGZvciBjYXNlIGlpLCB3ZSBza2lwIEIsIEMsIEQuCj4+Pj4+PiAKPj4+Pj4+IFl1cCwg SSB0aGluayB5b3UncmUgcmlnaHQuIEJ1dCBpZiB3ZSBjYW4gZml4IHRoaXMgYnkgbWFraW5nCj4+ Pj4+PiBpZWVlODAyMTFfcmVzb3J0X3R4cSgpIGF3YXJlIG9mIHRoZSBzY2hlZHVsZV9wb3MgYXMg d2VsbCwgbm8/IEkuZS4sCj4+Pj4+PiBpZgo+Pj4+Pj4gcmVzb3J0X3R4cSgpIGFjdHMgb24gdGhl IHR4cSB0aGF0J3MgY3VycmVudGx5IGluIHNjaGVkdWxlX3BvcywgaXQKPj4+Pj4+IHdpbGwKPj4+ Pj4+IHVwZGF0ZSBzY2hlZHVsZSBwb3Mgd2l0aCB0aGUgc2FtZSByYl9uZXh0KG5vZGUpID86IHJi X3ByZXYobm9kZSk7Cj4+Pj4+PiAob3B0aW9uYWxseSBhZnRlciBjaGVja2luZyB0aGF0IHRoZSBw b3NpdGlvbiBvZiB0aGUgbm9kZSBpcyAKPj4+Pj4+IGFjdHVhbGx5Cj4+Pj4+PiBnb2luZyB0byBj aGFuZ2UpLgo+Pj4+PiBTb3JyeSwgcGxlYXNlIGlnb3JlIGxhc3QgZW1haWwgc2VudCBieSBtaXN0 YWtlLgo+Pj4+PiAKPj4+Pj4gSSBkb24ndCB0aGluayBpdCBtYWtlcyBhbnkgZGlmZmVyZW5jZSB3 aXRoIHRoYXQgaW4gdW5zY2hlZHVsZV90eHEoKS4KPj4+Pj4gRm9yCj4+Pj4+IGNhc2UgaSwgaXQg ZmluYWxseSBwaWNrcyBDIGFzIHdlbGwgaW4gbmV4dF90eHEoKS4gRm9yIG5leHRfdHhxKCksCj4+ Pj4+IHNjaGVkdWxlX3BvcyBtZWFucyBwcmV2aW91cyBjYW5kaWRhdGUgbm9kZSB3aGVyZWFzIHdp dGggeW91ciBjaGFuZ2UsCj4+Pj4+IGl0Cj4+Pj4+IGxvb2tzIGxpa2Ugc2NoZWR1bGVfcG9zIGlz IGN1cnJlbnQgY2FuZGlkYXRlIG5vZGUgaW5zdGVhZC4KPj4+PiAKPj4+PiBIbW0sIHRoYXQgd2Fz IG5vdCBhY3R1YWxseSB3aGF0IEkgd2FzIHRoaW5raW5nLCBidXQgeWVhaCBJIHRoaW5rIAo+Pj4+ IHlvdSdyZQo+Pj4+IHJpZ2h0IHRoYXQgaXQgd291bGQgYmUgZWFzaWVyIHRvIGp1c3QgY2hhbmdl IGl0IHNvIHNjaGVkdWxlX3BvcyBpcwo+Pj4+IHBvaW50aW5nIHRvIHRoZSBuZXh0IGFuZCBub3Qg dGhlIGN1cnJlbnQgdHhxIHdlIHdhbnQgdG8gc2NoZWR1bGUuCj4+PiBTbyBkbyB5b3UgbWVhbiB3 ZSBjYW4gY2hhbmdlIG5leHRfdHhxIGxpa2UgdGhpcywKPj4+IAo+Pj4gICBzdHJ1Y3QgaWVlZTgw MjExX3R4cSAqaWVlZTgwMjExX25leHRfdHhxKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LCB1OAo+ Pj4gYWMpCj4+PiAgIHsKPj4+ICAgCXN0cnVjdCBpZWVlODAyMTFfbG9jYWwgKmxvY2FsID0gaHdf dG9fbG9jYWwoaHcpOwo+Pj4gCXN0cnVjdCByYl9ub2RlICpub2RlID0gbG9jYWwtPnNjaGVkdWxl X3Bvc1thY107Cj4+PiAgIAlzdHJ1Y3QgdHhxX2luZm8gKnR4cWkgPSBOVUxMOwo+Pj4gCWJvb2wg Zmlyc3QgPSBmYWxzZTsKPj4+IAo+Pj4gICAJbG9ja2RlcF9hc3NlcnRfaGVsZCgmbG9jYWwtPmFj dGl2ZV90eHFfbG9ja1thY10pOwo+Pj4gCj4+PiAJaWYgKCFub2RlKSB7Cj4+PiAJICAgICAgICBu b2RlID0gcmJfZmlyc3RfY2FjaGVkKCZsb2NhbC0+YWN0aXZlX3R4cXNbYWNdKTsKPj4+IAkJZmly c3QgPSB0cnVlOwo+Pj4gLQl9IGVsc2UKPj4+IC0JCW5vZGUgPSByYl9uZXh0KG5vZGUpOwo+Pj4g KyAgICAgICB9Cj4+PiArCj4+PiAJaWYgKCFub2RlKQo+Pj4gICAJCXJldHVybiBOVUxMOwo+PiAK Pj4gQWgsIG5vLCBub3cgSSByZW1lbWJlciB3aHkgdGhpcyBkaWRuJ3Qgd29yayBhbmQgSSB3ZW50 IHdpdGggdGhlIG90aGVyCj4+IGFwcHJvYWNoOiBJZiB5b3UgbWFrZSB0aGlzIGNoYW5nZSwgeW91 IGFsc28gaGF2ZSB0byBoYXZlIHRoaXMgYXQgdGhlCj4+IGVuZDoKPj4gCj4+IGxvY2FsLT5zY2hl ZHVsZV9wb3NbYWNdID0gcmJfbmV4dChub2RlKTsKPj4gCj4+IAo+PiBCdXQgdGhpcyBtZWFucyB3 ZSBjYW4gbm8gbG9uZ2VyIGRpc3Rpbmd1aXNoIGJldHdlZW4gaGF2aW5nIGdvbmUgdGhyb3VnaAo+ PiB0aGUgd2hvbGUgdGhpbmcgKHNvIHJiX25leHQoKSByZXR1cm5zIE5VTEwpLCBvciBzdGFydGlu ZyBvdXQgd2l0aAo+PiBub3RoaW5nLgo+PiAKPj4gU28sIGluc3RlYWQgd2UgbmVlZCB0byBrZWVw IG5leHRfdHhxKCkgdGhlIHdheSBpdCBpcywgYW5kIGp1c3QgYWRkCj4KPiBSaWdodCwgc2hvdWxk IGtlZXAgbmV4dF90eHEoKSB0aGUgd2F5IGl0IGlzLgo+Cj4+IAo+PiBsb2NhbC0+c2NoZWR1bGVf cG9zW2FjXSA9IHJiX3ByZXYobm9kZSk7Cj4+IAo+PiB3aGVuZXZlciB3ZSByZW1vdmUgYSBub2Rl IChib3RoIGluIHJldHVybl90eHEoKSBhbmQgcmVzb3J0X3R4cSgpKS4KPgo+IEFncmVlLCBhbmQg YWxzbyB3ZSBtYXkgbmVlZCB0byBjb25zaWRlciBjYXNlIGxpa2UgQSBpcyByZW1vdmVkIGFuZCBz b29uIAo+IGJlIGFkZGVkIGJhY2sganVzdCB0aGUgc2FtZSBhcyBpaSksCj4gICAgICAgICBCLT5D LT5BLT5ELT5FCj4gdGhlbiBCIGlzIHNjaGVkdWxlLCByZW1vdmVkIGFuZCBzb29uIGFkZGVkIGJh Y2ssCj4gICAgICAgICBDLT5BLT5CLT5ELT5FCj4gQSBhbmQgQiB3aWxsIGhhdmUgYSBzZWNvbmQg Y2hhbmNlIHRvIGJlIHNjaGVkdWxlZCBhbmQgdGhpcyBtYXkgaGFwcGVuIHRvIAo+IG90aGVycyBh cyB3ZWxsIGxlYWRpbmcgdG8gdGhlIGluZmluaXRlIGxvb3AgYXMgeW91IGhhdmUgbWVudGlvbmVk IAo+IHByZXZpb3VzbHksIHNvIGRvIHdlIG5lZWQgdG8gbWFpbnRhaW4gYSBzY2hlZHVsZV9yb3Vu ZCBsaWtlIHdlIGRvIGluIAo+IERSUj8gTGlrZSwKPiAgICAgIC0gSWYgdGhlIG5vZGUgaXMgaW4g dGhlIHNhbWUgcm91bmQsIGJ5IHBhc3Mgc2NoZWR1bGUsIGdvIHRvIAo+IHJiX25leHQoKSwgZWl0 aGVyIGNvbnRpbnVlIGxvb3AgdGhpcyByb3VuZCBvciBlbmQgdGhpcyByb3VuZC4KPiAgICAgIC0g SW5jcmVhc2UgdGhlIHNjaGVkdWxlX3JvdW5kIGF0IHRoZSBzY2hlZHVsZV9zdGFydCgpIG9ubHkg d2hlbiB0aGUgCj4gc2NoZWR1bGVfcG9zIGlzIE5VTEwuCgpIbW0sIHllYWgsIEkgZ3Vlc3Mgd2Ug Y291bGQgZW5kIHVwIHdpdGggYSBsb29wIGxpa2UgdGhhdCBhcyB3ZWxsLgpLZWVwaW5nIHRoZSBz Y2hlZHVsZV9yb3VuZCB3b3VsZCBiZSBhIHdheSB0byBmaXggaXQsIGJ1dCBJJ20gbm90IHN1cmUg d2UKc2hvdWxkIGp1c3Qgc2tpcCB0aGF0IHN0YXRpb247IG1heWJlIHdlIHNob3VsZCBqdXN0IGVu ZCB0aGUgcm91bmQKaW5zdGVhZD8KCj4+Pj4gV2UnZCBzdGlsbCBuZWVkIGEgY2hlY2sgaW4gcmVz b3J0X3R4cSgpIHRoZW4sIGJ1dCBpdCB3b3VsZCBtYWtlIGl0IAo+Pj4+IHNhZmUKPj4+PiB0byB1 bnNjaGVkdWxlIGluIHJldHVybl90eHEoKS4uLgo+Pj4gWWVzLCBhZ3JlZSB3aXRoIHRoYXQuCj4+ PiAKPj4+IAo+Pj4+IAo+Pj4+Pj4+IEFsc28gSSBhbSB3b25kZXJpbmcgaWYgdGhlcmUgd2lsbCBi ZSBzb21lIFNNUCBpc3N1ZXMgcmVsYXRpbmcgd2l0aAo+Pj4+Pj4+IGxvY2FsLT5zY2hlZHVsZV9w b3NbYWNdLgo+Pj4+Pj4gCj4+Pj4+PiBOb3Qgc3VyZSB3aGF0IHlvdSBtZWFuIGJ5IHRoaXM/Cj4+ Pj4+IE15IGJhZC4gUGxlYXNlIGlnbm9yZSB0aGlzLgo+Pj4+PiAKPj4+Pj4gCj4+Pj4+PiAKPj4+ Pj4+Pj4+IEluIGF0aDEwaywgd2Ugd2lsbCB1c3VhbGx5IHB1c2ggcGFja2V0cyBvZiBmaXJzdCB0 eHEgYXMgbWFueSBhcyAKPj4+Pj4+Pj4+IHdlCj4+Pj4+Pj4+PiBjYW4KPj4+Pj4+Pj4+IHVudGls IGl0IGlzIGRyYWluZWQgYW5kIHRoZW4gbW92ZSB0byB0aGUgbmV4dCBvbmUuIFNvIGlmIGEgdHhx Cj4+Pj4+Pj4+PiBnZXRzCj4+Pj4+Pj4+PiByZW1vdmVkIGluIHRoZSByZXR1cm5fdHhxLCBpdCBz aG91bGQgYWx3YXlzIGJlIHRoZSBsZWZ0bW9zdC4gQW5kCj4+Pj4+Pj4+PiBkdXJpbmcgdGhpcyBw ZXJpb2QsIG5laXRoZXIgdnQgb2YgYW55IHN0YXRpb24gb3IgZ2xvYmFsIHZ0IGNhbiAKPj4+Pj4+ Pj4+IGJlCj4+Pj4+Pj4+PiB1cGRhdGVkIGR1ZSB0byBsb2NrIHByb3RlY3Rpb24uCj4+Pj4+Pj4+ PiAKPj4+Pj4+Pj4+PiAKPj4+Pj4+Pj4+PiBCdXQgaW4gdGhhdCBjYXNlLCB3ZSBjb3VsZCBmaXgg aXQgYnkganVzdCBjb25kaXRpb25hbGx5IAo+Pj4+Pj4+Pj4+IGFzc2lnbmluZwo+Pj4+Pj4+Pj4+ IGVpdGhlcgo+Pj4+Pj4+Pj4+IHJiX25leHQgb3IgcmJfcHJldiB0byB0aGUgc2NoZWR1bGVfcG9z IGluIHVuc2NoZWR1bGVfdHhxKCk/IAo+Pj4+Pj4+Pj4+IEkuZS4sCj4+Pj4+Pj4+Pj4gc29tZXRo aW5nIGxpa2U6Cj4+Pj4+Pj4+Pj4gCj4+Pj4+Pj4+Pj4gbG9jYWwtPnNjaGVkdWxlX3Bvc1thY10g PSByYl9uZXh0KG5vZGUpID86IHJiX3ByZXYobm9kZSk7Cj4+Pj4+Pj4+PiBJIGFtIG5vdCBzdXJl IEkgYW0gZ2V0dGluZyB5b3VyIHBvaW50LiBTdGlsbCBpbiBuZXh0X3R4cSwKPj4+Pj4+Pj4+IHNj aGVkdWxlX3Bvc1thY10gd2lsbCBsZWFkIHVzIHRvIHRoZSBuZXh0IG5vZGUgb2YgdGhlIG9uZSB3 ZSAKPj4+Pj4+Pj4+IHdhbnQuCj4+Pj4+Pj4+IAo+Pj4+Pj4+PiBUaGUgbG9naWMgaW4gbmV4dF90 eHEgaXMgZGlmZmVyZW50IHdoZW4gc2NoZWR1bGVfcG9zW2FjXSBpcyBOVUxMLAo+Pj4+Pj4+PiB2 cwo+Pj4+Pj4+PiB3aGVuIHJiX25leHQoc2NoZWR1bGVfcG9zW2FjXSkgaXMgTlVMTC4gVGhlIGZv cm1lciByZXN0YXJ0cyBhIG5ldwo+Pj4+Pj4+PiBzY2hlZHVsaW5nIHJvdW5kLCB3aGlsZSB0aGUg bGF0dGVyIGVuZHMgdGhlIGN1cnJlbnQgcm91bmQuCj4+Pj4+Pj4+IAo+Pj4+Pj4+PiAtVG9rZQo+ Pj4+Pj4+IAo+Pj4+Pj4+IC0tCj4+Pj4+Pj4gWWlibwo+Pj4+PiAKPj4+Pj4gLS0KPj4+Pj4gWWli bwo+Pj4gCj4+PiAtLQo+Pj4gWWlibwo+Cj4gLS0gCj4gWWlibwoKCl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmF0aDEwayBtYWlsaW5nIGxpc3QKYXRoMTBr QGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9s aXN0aW5mby9hdGgxMGsK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6D3EC04EBF for ; Mon, 23 Sep 2019 10:47:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7D7EC20867 for ; Mon, 23 Sep 2019 10:47:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Nis7W6gB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729779AbfIWKrL (ORCPT ); Mon, 23 Sep 2019 06:47:11 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:29944 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729775AbfIWKrL (ORCPT ); Mon, 23 Sep 2019 06:47:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1569235627; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nYzikjCT7dTo23BWW3L1NBBoKchfcEpE7CSmUGd35og=; b=Nis7W6gBdAxe9syDe1ayVpyL+Tcc2J+/yuGygsn2qQpuQezKU6j5ROTnBQWTkuJKTn6UXV 7DTgfNRznZBYgeyx9wpIpxPNGBpkxmIZy3cKpJKXJOcM8FhgEo4XL49QXluJBwg4C194C2 RpTYDIhtZC7MKngAxZjbwPWoz247Pz0= Received: from mail-lj1-f199.google.com (mail-lj1-f199.google.com [209.85.208.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-320-Cy51vbGPNPGbk6Wyc8lkdw-1; Mon, 23 Sep 2019 06:47:05 -0400 Received: by mail-lj1-f199.google.com with SMTP id p14so2851844ljh.22 for ; Mon, 23 Sep 2019 03:47:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version:content-transfer-encoding; bh=weKCkQvC8lSWrTDZoAsN1aWHQnDtLXu49du56bkUIrA=; b=uOQQqDPpLOiIR4EXTJzEQGfgu6Sq/7n6XFZP33B319yQfDNqv7YDoeOV2BUUtjmF/R UDkYWEK/4lRN6100yg2YuLTH1v24kso3+UPU4Thx7daCZO5yWVi9BanEfCMNQmySeFUD HtWnSNy/bxopyT3ybNr2B+laqMvlwWaCKfxYBuYCmxu4E5PJbAV4+B5iSMa9UwG6NNMS 7QxTUElGMe25Fv/o92doCedzQIOToFlSfdBb9OWJCHP+y7+XN02mx11xJFI4qYox3xdB 2Tno5Pb6cOsSED9fjYQgesergqh2Wsv/534SDzu0zC0yZQQq/drQMj8ggaGxIi/sdiU1 cHWg== X-Gm-Message-State: APjAAAUPOv/BiHsJXej/wr851NxLcwph1KG3B60sv7y5M4mT6bNAiFoo zJjUqGNMQXCltfSL5T6mLFtr6MyO+p6FSdeXUUPLqLyPPjmvSIQX2iKnPGGY7VF9e4KPoa3rzBq lg3wrpS4PtnYn24iymAEHjtTHglk= X-Received: by 2002:a2e:a0c5:: with SMTP id f5mr5216382ljm.114.1569235624284; Mon, 23 Sep 2019 03:47:04 -0700 (PDT) X-Google-Smtp-Source: APXvYqxkhMXNCZXmBASU2BFap4isQyXk7RfEPCTwf1GAoIfoUNAa0txK6a0GN6d4x5Vqv+efqjGMVg== X-Received: by 2002:a2e:a0c5:: with SMTP id f5mr5216357ljm.114.1569235623827; Mon, 23 Sep 2019 03:47:03 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id z18sm2201469ljh.17.2019.09.23.03.47.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Sep 2019 03:47:02 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id AEDDC1804C8; Mon, 23 Sep 2019 12:47:01 +0200 (CEST) From: Toke =?utf-8?Q?H=C3=B8iland-J=C3=B8rgensen?= To: Yibo Zhao Cc: ath10k@lists.infradead.org, linux-wireless@vger.kernel.org, linux-wireless-owner@vger.kernel.org Subject: Re: [PATCH 2/4] mac80211: defer txqs removal from rbtree In-Reply-To: <2935b00bf3e29ad8b2738fe98dc24a76@codeaurora.org> References: <1568639388-27291-1-git-send-email-yiboz@codeaurora.org> <1568639388-27291-2-git-send-email-yiboz@codeaurora.org> <87pnjyiq7o.fsf@toke.dk> <87sgothmpy.fsf@toke.dk> <8cdece5c030fd95817fb099021c38613@codeaurora.org> <87tv98fu6l.fsf@toke.dk> <1b4ab006d9b5c88035845aaac193ef48@codeaurora.org> <8736gre3bm.fsf@toke.dk> <198124204167325252fcfcd65e3f2733@codeaurora.org> <87ftkp7uuz.fsf@toke.dk> <4574cce4079f8dab2b2bf223431a6eae@codeaurora.org> <877e617qg2.fsf@toke.dk> <910d9bb5f9016b29fb2aaeb0b89bac38@codeaurora.org> <874l157nrt.fsf@toke.dk> <2935b00bf3e29ad8b2738fe98dc24a76@codeaurora.org> X-Clacks-Overhead: GNU Terry Pratchett Date: Mon, 23 Sep 2019 12:47:01 +0200 Message-ID: <87lfuf5ly2.fsf@toke.dk> MIME-Version: 1.0 X-MC-Unique: Cy51vbGPNPGbk6Wyc8lkdw-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Yibo Zhao writes: > On 2019-09-21 22:00, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >> Yibo Zhao writes: >>=20 >>> On 2019-09-21 21:02, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >>>> Yibo Zhao writes: >>>>=20 >>>>> On 2019-09-21 19:27, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >>>>>> Yibo Zhao writes: >>>>>>=20 >>>>>>> On 2019-09-20 17:15, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >>>>>>>> Yibo Zhao writes: >>>>>>>>=20 >>>>>>>>> On 2019-09-19 18:37, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >>>>>>>>>> Yibo Zhao writes: >>>>>>>>>>=20 >>>>>>>>>>> On 2019-09-18 19:23, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >>>>>>>>>>>> Yibo Zhao writes: >>>>>>>>>>>>=20 >>>>>>>>>>>>> On 2019-09-18 05:10, Toke H=C3=B8iland-J=C3=B8rgensen wrote: >>>>>>>>>>>>>> Yibo Zhao writes: >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> In a loop txqs dequeue scenario, if the first txq in the >>>>>>>>>>>>>>> rbtree >>>>>>>>>>>>>>> gets >>>>>>>>>>>>>>> removed from rbtree immediately in the >>>>>>>>>>>>>>> ieee80211_return_txq(), >>>>>>>>>>>>>>> the >>>>>>>>>>>>>>> loop will break soon in the ieee80211_next_txq() due to >>>>>>>>>>>>>>> schedule_pos >>>>>>>>>>>>>>> not leading to the second txq in the rbtree. Thus,=20 >>>>>>>>>>>>>>> defering >>>>>>>>>>>>>>> the >>>>>>>>>>>>>>> removal right before the end of this schedule round. >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> Co-developed-by: Yibo Zhao >>>>>>>>>>>>>>> Signed-off-by: Yibo Zhao >>>>>>>>>>>>>>> Signed-off-by: Toke H=C3=B8iland-J=C3=B8rgensen >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> I didn't write this patch, so please don't use my sign-off. >>>>>>>>>>>>>> I'll >>>>>>>>>>>>>> add >>>>>>>>>>>>>> ack or review tags as appropriate in reply; but a few >>>>>>>>>>>>>> comments >>>>>>>>>>>>>> first: >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> --- >>>>>>>>>>>>>>> include/net/mac80211.h | 16 ++++++++++-- >>>>>>>>>>>>>>> net/mac80211/ieee80211_i.h | 3 +++ >>>>>>>>>>>>>>> net/mac80211/main.c | 6 +++++ >>>>>>>>>>>>>>> net/mac80211/tx.c | 63 >>>>>>>>>>>>>>> +++++++++++++++++++++++++++++++++++++++++++--- >>>>>>>>>>>>>>> 4 files changed, 83 insertions(+), 5 deletions(-) >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> diff --git a/include/net/mac80211.h=20 >>>>>>>>>>>>>>> b/include/net/mac80211.h >>>>>>>>>>>>>>> index ac2ed8e..ba5a345 100644 >>>>>>>>>>>>>>> --- a/include/net/mac80211.h >>>>>>>>>>>>>>> +++ b/include/net/mac80211.h >>>>>>>>>>>>>>> @@ -925,6 +925,8 @@ struct ieee80211_tx_rate { >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> #define IEEE80211_MAX_TX_RETRY=09=0931 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +#define IEEE80211_AIRTIME_TXQ_RM_CHK_INTV_IN_MS 100 >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> static inline void ieee80211_rate_set_vht(struct >>>>>>>>>>>>>>> ieee80211_tx_rate >>>>>>>>>>>>>>> *rate, >>>>>>>>>>>>>>> =09=09=09=09=09 u8 mcs, u8 nss) >>>>>>>>>>>>>>> { >>>>>>>>>>>>>>> @@ -6232,7 +6234,8 @@ struct sk_buff >>>>>>>>>>>>>>> *ieee80211_tx_dequeue(struct >>>>>>>>>>>>>>> ieee80211_hw *hw, >>>>>>>>>>>>>>> * @ac: AC number to return packets from. >>>>>>>>>>>>>>> * >>>>>>>>>>>>>>> * Should only be called between calls to >>>>>>>>>>>>>>> ieee80211_txq_schedule_start() >>>>>>>>>>>>>>> - * and ieee80211_txq_schedule_end(). >>>>>>>>>>>>>>> + * and ieee80211_txq_schedule_end(). If the txq is empty, >>>>>>>>>>>>>>> it >>>>>>>>>>>>>>> will >>>>>>>>>>>>>>> be >>>>>>>>>>>>>>> added >>>>>>>>>>>>>>> + * to a remove list and get removed later. >>>>>>>>>>>>>>> * Returns the next txq if successful, %NULL if no queue= =20 >>>>>>>>>>>>>>> is >>>>>>>>>>>>>>> eligible. >>>>>>>>>>>>>>> If a txq >>>>>>>>>>>>>>> * is returned, it should be returned with >>>>>>>>>>>>>>> ieee80211_return_txq() >>>>>>>>>>>>>>> after the >>>>>>>>>>>>>>> * driver has finished scheduling it. >>>>>>>>>>>>>>> @@ -6268,7 +6271,8 @@ void >>>>>>>>>>>>>>> ieee80211_txq_schedule_start(struct >>>>>>>>>>>>>>> ieee80211_hw *hw, u8 ac) >>>>>>>>>>>>>>> * @hw: pointer as obtained from ieee80211_alloc_hw() >>>>>>>>>>>>>>> * @ac: AC number to acquire locks for >>>>>>>>>>>>>>> * >>>>>>>>>>>>>>> - * Release locks previously acquired by >>>>>>>>>>>>>>> ieee80211_txq_schedule_end(). >>>>>>>>>>>>>>> + * Release locks previously acquired by >>>>>>>>>>>>>>> ieee80211_txq_schedule_end(). >>>>>>>>>>>>>>> Check >>>>>>>>>>>>>>> + * and remove the empty txq from rb-tree. >>>>>>>>>>>>>>> */ >>>>>>>>>>>>>>> void ieee80211_txq_schedule_end(struct ieee80211_hw *hw,= =20 >>>>>>>>>>>>>>> u8 >>>>>>>>>>>>>>> ac) >>>>>>>>>>>>>>> =09__releases(txq_lock); >>>>>>>>>>>>>>> @@ -6287,6 +6291,14 @@ void ieee80211_schedule_txq(struct >>>>>>>>>>>>>>> ieee80211_hw >>>>>>>>>>>>>>> *hw, struct ieee80211_txq *txq) >>>>>>>>>>>>>>> =09__acquires(txq_lock) __releases(txq_lock); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> /** >>>>>>>>>>>>>>> + * ieee80211_txqs_check - Check txqs waiting for removal >>>>>>>>>>>>>>> + * >>>>>>>>>>>>>>> + * @tmr: pointer as obtained from local >>>>>>>>>>>>>>> + * >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> +void ieee80211_txqs_check(struct timer_list *tmr); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +/** >>>>>>>>>>>>>>> * ieee80211_txq_may_transmit - check whether TXQ is >>>>>>>>>>>>>>> allowed >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>> transmit >>>>>>>>>>>>>>> * >>>>>>>>>>>>>>> * This function is used to check whether given txq is >>>>>>>>>>>>>>> allowed >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>> transmit by >>>>>>>>>>>>>>> diff --git a/net/mac80211/ieee80211_i.h >>>>>>>>>>>>>>> b/net/mac80211/ieee80211_i.h >>>>>>>>>>>>>>> index a4556f9..49aa143e 100644 >>>>>>>>>>>>>>> --- a/net/mac80211/ieee80211_i.h >>>>>>>>>>>>>>> +++ b/net/mac80211/ieee80211_i.h >>>>>>>>>>>>>>> @@ -847,6 +847,7 @@ struct txq_info { >>>>>>>>>>>>>>> =09struct codel_stats cstats; >>>>>>>>>>>>>>> =09struct sk_buff_head frags; >>>>>>>>>>>>>>> =09struct rb_node schedule_order; >>>>>>>>>>>>>>> +=09struct list_head candidate; >>>>>>>>>>>>>>> =09unsigned long flags; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09/* keep last! */ >>>>>>>>>>>>>>> @@ -1145,6 +1146,8 @@ struct ieee80211_local { >>>>>>>>>>>>>>> =09u64 airtime_v_t[IEEE80211_NUM_ACS]; >>>>>>>>>>>>>>> =09u64 airtime_weight_sum[IEEE80211_NUM_ACS]; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +=09struct list_head remove_list[IEEE80211_NUM_ACS]; >>>>>>>>>>>>>>> +=09struct timer_list remove_timer; >>>>>>>>>>>>>>> =09u16 airtime_flags; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09const struct ieee80211_ops *ops; >>>>>>>>>>>>>>> diff --git a/net/mac80211/main.c b/net/mac80211/main.c >>>>>>>>>>>>>>> index e9ffa8e..78fe24a 100644 >>>>>>>>>>>>>>> --- a/net/mac80211/main.c >>>>>>>>>>>>>>> +++ b/net/mac80211/main.c >>>>>>>>>>>>>>> @@ -667,10 +667,15 @@ struct ieee80211_hw >>>>>>>>>>>>>>> *ieee80211_alloc_hw_nm(size_t priv_data_len, >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09for (i =3D 0; i < IEEE80211_NUM_ACS; i++) { >>>>>>>>>>>>>>> =09=09local->active_txqs[i] =3D RB_ROOT_CACHED; >>>>>>>>>>>>>>> +=09=09INIT_LIST_HEAD(&local->remove_list[i]); >>>>>>>>>>>>>>> =09=09spin_lock_init(&local->active_txq_lock[i]); >>>>>>>>>>>>>>> =09} >>>>>>>>>>>>>>> =09local->airtime_flags =3D AIRTIME_USE_TX | AIRTIME_USE_R= X; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +=09timer_setup(&local->remove_timer, ieee80211_txqs_check, >>>>>>>>>>>>>>> 0); >>>>>>>>>>>>>>> +=09mod_timer(&local->remove_timer, >>>>>>>>>>>>>>> +=09=09 jiffies + >>>>>>>>>>>>>>> msecs_to_jiffies(IEEE80211_AIRTIME_TXQ_RM_CHK_INTV_IN_MS)); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> =09INIT_LIST_HEAD(&local->chanctx_list); >>>>>>>>>>>>>>> =09mutex_init(&local->chanctx_mtx); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> @@ -1305,6 +1310,7 @@ void ieee80211_unregister_hw(struct >>>>>>>>>>>>>>> ieee80211_hw >>>>>>>>>>>>>>> *hw) >>>>>>>>>>>>>>> =09tasklet_kill(&local->tx_pending_tasklet); >>>>>>>>>>>>>>> =09tasklet_kill(&local->tasklet); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +=09del_timer_sync(&local->remove_timer); >>>>>>>>>>>>>>> #ifdef CONFIG_INET >>>>>>>>>>>>>>> =09unregister_inetaddr_notifier(&local->ifa_notifier); >>>>>>>>>>>>>>> #endif >>>>>>>>>>>>>>> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c >>>>>>>>>>>>>>> index d00baaa..42ca010 100644 >>>>>>>>>>>>>>> --- a/net/mac80211/tx.c >>>>>>>>>>>>>>> +++ b/net/mac80211/tx.c >>>>>>>>>>>>>>> @@ -1450,6 +1450,7 @@ void ieee80211_txq_init(struct >>>>>>>>>>>>>>> ieee80211_sub_if_data *sdata, >>>>>>>>>>>>>>> =09codel_stats_init(&txqi->cstats); >>>>>>>>>>>>>>> =09__skb_queue_head_init(&txqi->frags); >>>>>>>>>>>>>>> =09RB_CLEAR_NODE(&txqi->schedule_order); >>>>>>>>>>>>>>> +=09INIT_LIST_HEAD(&txqi->candidate); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09txqi->txq.vif =3D &sdata->vif; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> @@ -3724,6 +3725,9 @@ void ieee80211_schedule_txq(struct >>>>>>>>>>>>>>> ieee80211_hw >>>>>>>>>>>>>>> *hw, >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09spin_lock_bh(&local->active_txq_lock[ac]); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +=09if (!list_empty(&txqi->candidate)) >>>>>>>>>>>>>>> +=09=09list_del_init(&txqi->candidate); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> =09if (!RB_EMPTY_NODE(&txqi->schedule_order)) >>>>>>>>>>>>>>> =09=09goto out; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> @@ -3783,6 +3787,20 @@ static void >>>>>>>>>>>>>>> __ieee80211_unschedule_txq(struct >>>>>>>>>>>>>>> ieee80211_hw *hw, >>>>>>>>>>>>>>> =09RB_CLEAR_NODE(&txqi->schedule_order); >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +void ieee80211_remove_txq(struct ieee80211_hw *hw, >>>>>>>>>>>>>>> +=09=09=09 struct ieee80211_txq *txq) >>>>>>>>>>>>>>> +{ >>>>>>>>>>>>>>> +=09struct ieee80211_local *local =3D hw_to_local(hw); >>>>>>>>>>>>>>> +=09struct txq_info *txqi =3D to_txq_info(txq); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09lockdep_assert_held(&local->active_txq_lock[txq->ac]); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09if (!RB_EMPTY_NODE(&txqi->schedule_order)) { >>>>>>>>>>>>>>> +=09=09__ieee80211_unschedule_txq(hw, txq); >>>>>>>>>>>>>>> +=09=09list_del_init(&txqi->candidate); >>>>>>>>>>>>>>> +=09} >>>>>>>>>>>>>>> +} >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> void ieee80211_unschedule_txq(struct ieee80211_hw *hw, >>>>>>>>>>>>>>> =09=09=09 struct ieee80211_txq *txq) >>>>>>>>>>>>>>> =09__acquires(txq_lock) __releases(txq_lock) >>>>>>>>>>>>>>> @@ -3790,7 +3808,7 @@ void ieee80211_unschedule_txq(struct >>>>>>>>>>>>>>> ieee80211_hw *hw, >>>>>>>>>>>>>>> =09struct ieee80211_local *local =3D hw_to_local(hw); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09spin_lock_bh(&local->active_txq_lock[txq->ac]); >>>>>>>>>>>>>>> -=09__ieee80211_unschedule_txq(hw, txq); >>>>>>>>>>>>>>> +=09ieee80211_remove_txq(hw, txq); >>>>>>>>>>>>>>> =09spin_unlock_bh(&local->active_txq_lock[txq->ac]); >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> @@ -3803,11 +3821,48 @@ void ieee80211_return_txq(struct >>>>>>>>>>>>>>> ieee80211_hw >>>>>>>>>>>>>>> *hw, >>>>>>>>>>>>>>> =09lockdep_assert_held(&local->active_txq_lock[txq->ac]); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> =09if (!RB_EMPTY_NODE(&txqi->schedule_order) && >>>>>>>>>>>>>>> -=09 (skb_queue_empty(&txqi->frags) && >>>>>>>>>>>>>>> !txqi->tin.backlog_packets)) >>>>>>>>>>>>>>> -=09=09__ieee80211_unschedule_txq(hw, txq); >>>>>>>>>>>>>>> +=09=09!txq_has_queue(&txqi->txq) && >>>>>>>>>>>>>>> +=09=09list_empty(&txqi->candidate)) >>>>>>>>>>>>>>> +=09=09list_add_tail(&txqi->candidate, >>>>>>>>>>>>>>> &local->remove_list[txq->ac]); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> EXPORT_SYMBOL(ieee80211_return_txq); >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> +void __ieee80211_check_txqs(struct ieee80211_local=20 >>>>>>>>>>>>>>> *local, >>>>>>>>>>>>>>> int >>>>>>>>>>>>>>> ac) >>>>>>>>>>>>>>> +{ >>>>>>>>>>>>>>> +=09struct txq_info *iter, *tmp; >>>>>>>>>>>>>>> +=09struct sta_info *sta; >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09lockdep_assert_held(&local->active_txq_lock[ac]); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09list_for_each_entry_safe(iter, tmp, >>>>>>>>>>>>>>> &local->remove_list[ac], >>>>>>>>>>>>>>> +=09=09=09=09 candidate) { >>>>>>>>>>>>>>> +=09=09sta =3D container_of(iter->txq.sta, struct sta_info,= =20 >>>>>>>>>>>>>>> sta); >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09=09if (txq_has_queue(&iter->txq)) >>>>>>>>>>>>>>> +=09=09=09list_del_init(&iter->candidate); >>>>>>>>>>>>>>> +=09=09else >>>>>>>>>>>>>>> +=09=09=09ieee80211_remove_txq(&local->hw, &iter->txq); >>>>>>>>>>>>>>> +=09} >>>>>>>>>>>>>>> +} >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +void ieee80211_txqs_check(struct timer_list *t) >>>>>>>>>>>>>>> +{ >>>>>>>>>>>>>>> +=09struct ieee80211_local *local =3D from_timer(local, t, >>>>>>>>>>>>>>> remove_timer); >>>>>>>>>>>>>>> +=09struct txq_info *iter, *tmp; >>>>>>>>>>>>>>> +=09struct sta_info *sta; >>>>>>>>>>>>>>> +=09int ac; >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09for (ac =3D 0; ac < IEEE80211_NUM_ACS; ac++) { >>>>>>>>>>>>>>> +=09=09spin_lock_bh(&local->active_txq_lock[ac]); >>>>>>>>>>>>>>> +=09=09__ieee80211_check_txqs(local, ac); >>>>>>>>>>>>>>> +=09=09spin_unlock_bh(&local->active_txq_lock[ac]); >>>>>>>>>>>>>>> +=09} >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +=09mod_timer(&local->remove_timer, >>>>>>>>>>>>>>> +=09=09 jiffies + >>>>>>>>>>>>>>> msecs_to_jiffies(IEEE80211_AIRTIME_TXQ_RM_CHK_INTV_IN_MS)); >>>>>>>>>>>>>>> +} >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> I'll ask the same as I did last time (where you told me to >>>>>>>>>>>>>> hold >>>>>>>>>>>>>> off >>>>>>>>>>>>>> until this round): >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> Why do you need the timer and the periodic check? If TXQs=20 >>>>>>>>>>>>>> are >>>>>>>>>>>>>> added >>>>>>>>>>>>>> to >>>>>>>>>>>>>> the remove list during the scheduling run, and >>>>>>>>>>>>>> __ieee80211_check_txqs() >>>>>>>>>>>>>> is run from schedule_end(), isn't that sufficient to clear >>>>>>>>>>>>>> the >>>>>>>>>>>>>> list? >>>>>>>>>>>>> Is it possible that a txq is not added to the remove list=20 >>>>>>>>>>>>> but >>>>>>>>>>>>> then >>>>>>>>>>>>> packets in it are dropped by fq_codel algo? Like the station >>>>>>>>>>>>> disconnects >>>>>>>>>>>>> without any notification. >>>>>>>>>>>>=20 >>>>>>>>>>>> Well as long as all the other cleanup paths call directly=20 >>>>>>>>>>>> into >>>>>>>>>>>> __unschedule_txq(), that should remove stations from the >>>>>>>>>>>> scheduler >>>>>>>>>>>> when >>>>>>>>>>>> they disconnect etc. >>>>>>>>>>> Yes, the disconnect scenario is a bad example. My concern is, >>>>>>>>>>> say, >>>>>>>>>>> we >>>>>>>>>>> have 10 stations and only one of them is assigned a very small >>>>>>>>>>> weight >>>>>>>>>>> compared with that of others. Suppose, after its chance of Tx, >>>>>>>>>>> it >>>>>>>>>>> is >>>>>>>>>>> most likely to be placed in the rightmost(still has some=20 >>>>>>>>>>> packets >>>>>>>>>>> in >>>>>>>>>>> the >>>>>>>>>>> txq) and no more incoming data for it. The remaining packets=20 >>>>>>>>>>> in >>>>>>>>>>> txq >>>>>>>>>>> will >>>>>>>>>>> be dropped due to timeout algo in codel(correct me if I am >>>>>>>>>>> wrong) >>>>>>>>>>> but >>>>>>>>>>> this empty txq will stay on the rbtree until other txqs get >>>>>>>>>>> drained >>>>>>>>>>> or >>>>>>>>>>> global vt catch up with its vt. The staying time could be long >>>>>>>>>>> if >>>>>>>>>>> weight >>>>>>>>>>> is extremely small. Then do we need timer to check or any=20 >>>>>>>>>>> other >>>>>>>>>>> better >>>>>>>>>>> solution? >>>>>>>>>>=20 >>>>>>>>>> Ah, I see what you mean. No, I don't think this will be a >>>>>>>>>> problem; >>>>>>>>>> the >>>>>>>>>> scenario you're describing would play out like this: >>>>>>>>>>=20 >>>>>>>>>> 1. Station ends transmitting, still has a single packet queued, >>>>>>>>>> gets >>>>>>>>>> moved to the end of the rbtree (and stays there for a=20 >>>>>>>>>> while). >>>>>>>>>>=20 >>>>>>>>>> 2. When we finally get to the point where this station gets >>>>>>>>>> another >>>>>>>>>> chance to transmit, the CoDel drop timer triggers and the=20 >>>>>>>>>> last >>>>>>>>>> packet >>>>>>>>>> is dropped[0]. This means that the queue will just be empty >>>>>>>>>> (and ieee80211_tx_dequeue() will return NULL). >>>>>>>>>>=20 >>>>>>>>>> 3. Because the queue is empty, ieee80211_return_txq() will not >>>>>>>>>> put >>>>>>>>>> it >>>>>>>>>> back on the rbtree. >>>>>>>>>>=20 >>>>>>>>>> Crucially, in 2. the CoDel algorithm doesn't kick in until the >>>>>>>>>> point >>>>>>>>>> of >>>>>>>>>> packet dequeue. But even if an empty queue stays on the rbtree >>>>>>>>>> for >>>>>>>>>> a >>>>>>>>>> while, there is no harm in that: eventually it will get its=20 >>>>>>>>>> turn, >>>>>>>>>> it >>>>>>>>>> will turn out to be empty, and just be skipped over. >>>>>>>>> Then that will be fine. Thanks for the explanation of the=20 >>>>>>>>> dropping >>>>>>>>> part >>>>>>>>> in CoDel algorithm. >>>>>>>>=20 >>>>>>>> Yup, think so. And you're welcome :) >>>>>>>>=20 >>>>>>>>>> The issue we need to be concerned about is the opposite: If we >>>>>>>>>> have >>>>>>>>>> a >>>>>>>>>> queue that *does* have packets queued, but which is *not* >>>>>>>>>> scheduled >>>>>>>>>> for >>>>>>>>>> transmission, that will stall TX. >>>>>>>>> Is it by design since its vt is more than global vt, right? The >>>>>>>>> lattency >>>>>>>>> may somehow get impacted though. >>>>>>>>=20 >>>>>>>> Well, it should still stay on the rbtree as long as it has=20 >>>>>>>> packets >>>>>>>> queued. We don't have a check anywhere that reschedules TXQs=20 >>>>>>>> whose >>>>>>>> v_t >>>>>>>> drops below global v_t... >>>>>>>>=20 >>>>>>>>>> [0] CoDel in most cases only drops a single packet at a time,=20 >>>>>>>>>> so >>>>>>>>>> it >>>>>>>>>> will >>>>>>>>>> not clear out an entire queue with multiple packets in one go. >>>>>>>>>> But >>>>>>>>>> you >>>>>>>>>> are right that it could conceivably drop the last packet in a >>>>>>>>>> queue. >>>>>>>>>>=20 >>>>>>>>>>>> We only need to defer removal inside a single "scheduling >>>>>>>>>>>> round" >>>>>>>>>>>> (i.e., >>>>>>>>>>>> between a pair of ieee80211_txq_schedule_start/end. So if we >>>>>>>>>>>> just >>>>>>>>>>>> walk >>>>>>>>>>>> the remove list in schedule_end() we should be enough, no? >>>>>>>>>>>>=20 >>>>>>>>>>>> Hmm, or maybe a simpler way to fix the original issue is just >>>>>>>>>>>> to >>>>>>>>>>>> have >>>>>>>>>>>> unschedule_txq() update the schedule_pos() pointer? >>>>>>>>>>>>=20 >>>>>>>>>>>> I.e., unschedule_txq checks if the txq being removed is >>>>>>>>>>>> currently >>>>>>>>>>>> being >>>>>>>>>>>> pointed to by schedule_pos[ac], and if it is, it updates >>>>>>>>>>>> schedule_pos >>>>>>>>>>>> to >>>>>>>>>>>> be the rb_next of the current value? >>>>>>>>>>> Actually, if schedule_pos is updated to rb_next of the current >>>>>>>>>>> value, >>>>>>>>>>> then in the next_txq() where we are going to use rb_next again >>>>>>>>>>> and >>>>>>>>>>> finally pick the next node of the node we really want. Is it >>>>>>>>>>> fine >>>>>>>>>>> to >>>>>>>>>>> update schedule_pos to NULL? >>>>>>>>>>=20 >>>>>>>>>> Hmm, yeah, good point. >>>>>>>>>>=20 >>>>>>>>>> If we do end up setting schedule_pos to NULL in the middle of a >>>>>>>>>> scheduling round, that will make next_txq() "start over", and=20 >>>>>>>>>> do >>>>>>>>>> another >>>>>>>>>> loop through the whole thing. I guess we may be able hit a case >>>>>>>>>> where >>>>>>>>>> things can oscillate back and forth between addition and=20 >>>>>>>>>> removal >>>>>>>>>> resulting in an infinite loop? Not sure, but at least I can't >>>>>>>>>> seem >>>>>>>>>> to >>>>>>>>>> convince myself that this can't happen. >>>>>>>>>=20 >>>>>>>>> As the loop of next_txq under lock protection as below, >>>>>>>>>=20 >>>>>>>>> txq_schedule_start(); >>>>>>>>> while(txq=3Dnext_txq()){ >>>>>>>>> ... >>>>>>>>> return_txq(txq); >>>>>>>>> } >>>>>>>>> txq_schedule_end(); >>>>>>>>>=20 >>>>>>>>> I do not see any chance of addition, no? >>>>>>>>=20 >>>>>>>> As you noted in your other email, Felix reduced the locking. And >>>>>>>> yeah, >>>>>>>> we need to rebase this series to also incorporate that. I figure= =20 >>>>>>>> I >>>>>>>> can >>>>>>>> send an updated version of the first patch in the series once=20 >>>>>>>> we've >>>>>>>> worked out the remaining issues with your follow-up patches. >>>>>>>>=20 >>>>>>> Oh, I was thinking we were discussing without locking reduced.=20 >>>>>>> Yes, >>>>>>> I >>>>>>> also agree there might be a case causing infinite loop. With=20 >>>>>>> locking >>>>>>> reduced, the tree can be adjusted between next_txq() and >>>>>>> return_txq() >>>>>>> in >>>>>>> the loop situation. For further discussion, let 's consider, >>>>>>> 1) the tree starts like: >>>>>>> A->B->C->D->E >>>>>>> 2) then next_txq() returns A for dequeuing >>>>>>> 3) driver dequeues A and draines A without any active txq locked >>>>>>> meaning >>>>>>> the tree could be changed upon Tx compeletion. >>>>>>> 4) then in return_txq(), the tree could be, >>>>>>> i A->B->C->D->E =EF=BC=88A is empty, and maybe soon be ad= ded=20 >>>>>>> back >>>>>>> before the loop end=EF=BC=89 >>>>>>> ii B->C->A->D->E =EF=BC=88A is empty, and maybe soon be ad= ded=20 >>>>>>> back >>>>>>> before the loop end=EF=BC=89 >>>>>>> iii B->C->D->E->A =EF=BC=88A is empty, and maybe soon be ad= ded=20 >>>>>>> back >>>>>>> before the loop end) >>>>>>>=20 >>>>>>> with this change: >>>>>>> local->schedule_pos[ac] =3D rb_next(node) ?: rb_prev(node); >>>>>>>=20 >>>>>>> for case i, local->schedule_pos[ac] is rb_next(A) which is B, and= =20 >>>>>>> in >>>>>>> next_txq(), rb_next(B) is what we returns which actually is C and= =20 >>>>>>> B >>>>>>> is >>>>>>> skipped, no? >>>>>>>=20 >>>>>>> Similiar for case ii, we skip B, C, D. >>>>>>=20 >>>>>> Yup, I think you're right. But if we can fix this by making >>>>>> ieee80211_resort_txq() aware of the schedule_pos as well, no? I.e., >>>>>> if >>>>>> resort_txq() acts on the txq that's currently in schedule_pos, it >>>>>> will >>>>>> update schedule pos with the same rb_next(node) ?: rb_prev(node); >>>>>> (optionally after checking that the position of the node is=20 >>>>>> actually >>>>>> going to change). >>>>> Sorry, please igore last email sent by mistake. >>>>>=20 >>>>> I don't think it makes any difference with that in unschedule_txq(). >>>>> For >>>>> case i, it finally picks C as well in next_txq(). For next_txq(), >>>>> schedule_pos means previous candidate node whereas with your change, >>>>> it >>>>> looks like schedule_pos is current candidate node instead. >>>>=20 >>>> Hmm, that was not actually what I was thinking, but yeah I think=20 >>>> you're >>>> right that it would be easier to just change it so schedule_pos is >>>> pointing to the next and not the current txq we want to schedule. >>> So do you mean we can change next_txq like this, >>>=20 >>> struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 >>> ac) >>> { >>> =09struct ieee80211_local *local =3D hw_to_local(hw); >>> =09struct rb_node *node =3D local->schedule_pos[ac]; >>> =09struct txq_info *txqi =3D NULL; >>> =09bool first =3D false; >>>=20 >>> =09lockdep_assert_held(&local->active_txq_lock[ac]); >>>=20 >>> =09if (!node) { >>> =09 node =3D rb_first_cached(&local->active_txqs[ac]); >>> =09=09first =3D true; >>> -=09} else >>> -=09=09node =3D rb_next(node); >>> + } >>> + >>> =09if (!node) >>> =09=09return NULL; >>=20 >> Ah, no, now I remember why this didn't work and I went with the other >> approach: If you make this change, you also have to have this at the >> end: >>=20 >> local->schedule_pos[ac] =3D rb_next(node); >>=20 >>=20 >> But this means we can no longer distinguish between having gone through >> the whole thing (so rb_next() returns NULL), or starting out with >> nothing. >>=20 >> So, instead we need to keep next_txq() the way it is, and just add > > Right, should keep next_txq() the way it is. > >>=20 >> local->schedule_pos[ac] =3D rb_prev(node); >>=20 >> whenever we remove a node (both in return_txq() and resort_txq()). > > Agree, and also we may need to consider case like A is removed and soon= =20 > be added back just the same as ii), > B->C->A->D->E > then B is schedule, removed and soon added back, > C->A->B->D->E > A and B will have a second chance to be scheduled and this may happen to= =20 > others as well leading to the infinite loop as you have mentioned=20 > previously, so do we need to maintain a schedule_round like we do in=20 > DRR? Like, > - If the node is in the same round, by pass schedule, go to=20 > rb_next(), either continue loop this round or end this round. > - Increase the schedule_round at the schedule_start() only when the= =20 > schedule_pos is NULL. Hmm, yeah, I guess we could end up with a loop like that as well. Keeping the schedule_round would be a way to fix it, but I'm not sure we should just skip that station; maybe we should just end the round instead? >>>> We'd still need a check in resort_txq() then, but it would make it=20 >>>> safe >>>> to unschedule in return_txq()... >>> Yes, agree with that. >>>=20 >>>=20 >>>>=20 >>>>>>> Also I am wondering if there will be some SMP issues relating with >>>>>>> local->schedule_pos[ac]. >>>>>>=20 >>>>>> Not sure what you mean by this? >>>>> My bad. Please ignore this. >>>>>=20 >>>>>=20 >>>>>>=20 >>>>>>>>> In ath10k, we will usually push packets of first txq as many as= =20 >>>>>>>>> we >>>>>>>>> can >>>>>>>>> until it is drained and then move to the next one. So if a txq >>>>>>>>> gets >>>>>>>>> removed in the return_txq, it should always be the leftmost. And >>>>>>>>> during this period, neither vt of any station or global vt can=20 >>>>>>>>> be >>>>>>>>> updated due to lock protection. >>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>> But in that case, we could fix it by just conditionally=20 >>>>>>>>>> assigning >>>>>>>>>> either >>>>>>>>>> rb_next or rb_prev to the schedule_pos in unschedule_txq()?=20 >>>>>>>>>> I.e., >>>>>>>>>> something like: >>>>>>>>>>=20 >>>>>>>>>> local->schedule_pos[ac] =3D rb_next(node) ?: rb_prev(node); >>>>>>>>> I am not sure I am getting your point. Still in next_txq, >>>>>>>>> schedule_pos[ac] will lead us to the next node of the one we=20 >>>>>>>>> want. >>>>>>>>=20 >>>>>>>> The logic in next_txq is different when schedule_pos[ac] is NULL, >>>>>>>> vs >>>>>>>> when rb_next(schedule_pos[ac]) is NULL. The former restarts a new >>>>>>>> scheduling round, while the latter ends the current round. >>>>>>>>=20 >>>>>>>> -Toke >>>>>>>=20 >>>>>>> -- >>>>>>> Yibo >>>>>=20 >>>>> -- >>>>> Yibo >>>=20 >>> -- >>> Yibo > > --=20 > Yibo