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.9 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 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 5397ACA9EA0 for ; Tue, 22 Oct 2019 13:30:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1384121872 for ; Tue, 22 Oct 2019 13:30:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="BlARM/1M" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732063AbfJVNaa (ORCPT ); Tue, 22 Oct 2019 09:30:30 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:25498 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2388750AbfJVNa1 (ORCPT ); Tue, 22 Oct 2019 09:30:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571751025; 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=8j0wkIG/n3Pn2frywYSAeHgtGYV8WmAncGnP3lyGfSg=; b=BlARM/1MFXUUuulxFFrzQa01BlNbpcDnQ4+uWFU1F/feQ/cF25iewav0g3mDGvNVNvDSQ+ obpoD1JNTFDS85HgBaTTgjDCyHZOhK13HF1D9HDHl4uBFhloPoPLYkMU05SaacS5YmTWaz EGTpb2sfXoJRv54s+ayyD3m/Jik7UCs= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-349-YvIKtnQHPtu-zSHdtffKQA-1; Tue, 22 Oct 2019 09:30:21 -0400 Received: by mail-wm1-f71.google.com with SMTP id b10so2165954wmh.6 for ; Tue, 22 Oct 2019 06:30:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=2qo/nx07Ah1p2ugoqTnOJxA1uaujhd1Rtj5smQoRK98=; b=ETJeUP/aUZzMYz+ifbZHQRnf0lF4r/UTuuxx2N9XuvN/t8TQ0rgQMbhSKF+mvJtNva ManAr8p9nCpiJAwXZ8+Hph9E/n1KdaJOPNImXkoi5cV11eeFuxaJ1CD5hFmsIiVkaXHD oevxYDYe6Nmh5PvMsuE3e2X1MUVASr13b74JqA1/+9HgAIhnFOyIzbn8HpKEvOXmRN/x 2wYgmg3IeH/9fUwdY2ofUv8Yguq8uRkBb1rYYbX0FsglNkl4kEnssYvwOn+th08/jM2x SkA09W0WOKoTzW7TNNjnGhJYCTKNZ5vtErNk5DT4AQchNxrHjIFW1hm2U3oOcPctk6AT R0ew== X-Gm-Message-State: APjAAAWbC6cnodCPDAgGnGerXANaSpWfmxkKIa2sMz6IlTg952aP8hhU vRSSKz0I5shtb0hbp/kzQ+QhwZHmPevzplSt0qYZ3o+u/Q+Wg6pOyB0b1hg8sVHIgBOIgCMalOg TRuA5cNEIWjhUAapnULDDtAG+V5g= X-Received: by 2002:a1c:4e:: with SMTP id 75mr3208962wma.104.1571751020384; Tue, 22 Oct 2019 06:30:20 -0700 (PDT) X-Google-Smtp-Source: APXvYqyeOPSYph83QHoOGZO6AAVtzZ+j8BkgeNAdIehNDd7aACXjjIShSCRPltheVlt0yl+016QBHg== X-Received: by 2002:a1c:4e:: with SMTP id 75mr3208910wma.104.1571751019806; Tue, 22 Oct 2019 06:30:19 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a00:7660:6da:443::2]) by smtp.gmail.com with ESMTPSA id z13sm21358158wrm.64.2019.10.22.06.30.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2019 06:30:19 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 880B31804B1; Tue, 22 Oct 2019 15:30:18 +0200 (CEST) Subject: [PATCH v5 3/4] mac80211: Implement Airtime-based Queue Limit (AQL) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Johannes Berg Cc: linux-wireless@vger.kernel.org, make-wifi-fast@lists.bufferbloat.net, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau , Kan Yan , Rajkumar Manoharan , Kevin Hayes Date: Tue, 22 Oct 2019 15:30:18 +0200 Message-ID: <157175101846.104114.3665681248825910161.stgit@toke.dk> In-Reply-To: <157175101518.104114.6722791270722911023.stgit@toke.dk> References: <157175101518.104114.6722791270722911023.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: YvIKtnQHPtu-zSHdtffKQA-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 From: Kan Yan In order for the Fq_CoDel algorithm integrated in mac80211 layer to operate effectively to control excessive queueing latency, the CoDel algorithm requires an accurate measure of how long packets stays in the queue, AKA sojourn time. The sojourn time measured at the mac80211 layer doesn't include queueing latency in the lower layer (firmware/hardware) and CoDel expects lower layer to have a short queue. However, most 802.11ac chipsets offload tasks such TX aggregation to firmware or hardware, thus have a deep lower layer queue. Without a mechanism to control the lower layer queue size, packets only stay in mac80211 layer transiently before being sent to firmware queue. As a result, the sojourn time measured by CoDel in the mac80211 layer is almost always lower than the CoDel latency target, hence CoDel does little to control the latency, even when the lower layer queue causes excessive latency. The Byte Queue Limits (BQL) mechanism is commonly used to address the similar issue with wired network interface. However, this method cannot be applied directly to the wireless network interface. "Bytes" is not a suitable measure of queue depth in the wireless network, as the data rate can vary dramatically from station to station in the same network, from a few Mbps to over Gbps. This patch implements an Airtime-based Queue Limit (AQL) to make CoDel work effectively with wireless drivers that utilized firmware/hardware offloading. AQL allows each txq to release just enough packets to the lower layer to form 1-2 large aggregations to keep hardware fully utilized and retains the rest of the frames in mac80211 layer to be controlled by the CoDel algorithm. Signed-off-by: Kan Yan [ Toke: Keep API to set pending airtime internal, fix nits in commit msg ] Signed-off-by: Toke H=C3=B8iland-J=C3=B8rgensen --- include/net/cfg80211.h | 7 ++++ include/net/mac80211.h | 12 +++++++ net/mac80211/debugfs.c | 78 ++++++++++++++++++++++++++++++++++++++++= ++++ net/mac80211/debugfs_sta.c | 43 +++++++++++++++++++----- net/mac80211/ieee80211_i.h | 4 ++ net/mac80211/main.c | 9 +++++ net/mac80211/sta_info.c | 32 ++++++++++++++++++ net/mac80211/sta_info.h | 8 +++++ net/mac80211/tx.c | 46 ++++++++++++++++++++++++-- 9 files changed, 225 insertions(+), 14 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ff45c3e1abff..8d50c0a60dbd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2602,6 +2602,13 @@ enum wiphy_params_flags { =20 #define IEEE80211_DEFAULT_AIRTIME_WEIGHT=09256 =20 +/* The per TXQ device queue limit in airtime */ +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L=094000 +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H=098000 + +/* The per interface airtime threshold to switch to lower queue limit */ +#define IEEE80211_AQL_THRESHOLD=09=09=0924000 + /** * struct cfg80211_pmksa - PMK Security Association * diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 8a3e0544a026..2bc0f2538a36 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -5565,6 +5565,18 @@ void ieee80211_send_eosp_nullfunc(struct ieee80211_s= ta *pubsta, int tid); void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, =09=09=09=09 u32 tx_airtime, u32 rx_airtime); =20 +/** + * ieee80211_txq_airtime_check - check if a txq can send frame to device + * + * @hw: pointer obtained from ieee80211_alloc_hw() + * @txq: pointer obtained from station or virtual interface + * + * Return true if the AQL's airtime limit has not been reached and the txq= can + * continue to send more packets to the device. Otherwise return false. + */ +bool +ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq = *txq); + /** * ieee80211_iter_keys - iterate keys programmed into the device * @hw: pointer obtained from ieee80211_alloc_hw() diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 568b3b276931..d77ea0e51c1d 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -148,6 +148,80 @@ static const struct file_operations aqm_ops =3D { =09.llseek =3D default_llseek, }; =20 +static ssize_t aql_txq_limit_read(struct file *file, +=09=09=09=09 char __user *user_buf, +=09=09=09=09 size_t count, +=09=09=09=09 loff_t *ppos) +{ +=09struct ieee80211_local *local =3D file->private_data; +=09char buf[400]; +=09int len =3D 0; + +=09len =3D scnprintf(buf, sizeof(buf), +=09=09=09"AC=09AQL limit low=09AQL limit high\n" +=09=09=09"VO=09%u=09=09%u\n" +=09=09=09"VI=09%u=09=09%u\n" +=09=09=09"BE=09%u=09=09%u\n" +=09=09=09"BK=09%u=09=09%u\n", +=09=09=09local->aql_txq_limit_low[IEEE80211_AC_VO], +=09=09=09local->aql_txq_limit_high[IEEE80211_AC_VO], +=09=09=09local->aql_txq_limit_low[IEEE80211_AC_VI], +=09=09=09local->aql_txq_limit_high[IEEE80211_AC_VI], +=09=09=09local->aql_txq_limit_low[IEEE80211_AC_BE], +=09=09=09local->aql_txq_limit_high[IEEE80211_AC_BE], +=09=09=09local->aql_txq_limit_low[IEEE80211_AC_BK], +=09=09=09local->aql_txq_limit_high[IEEE80211_AC_BK]); +=09return simple_read_from_buffer(user_buf, count, ppos, +=09=09=09=09 buf, len); +} + +static ssize_t aql_txq_limit_write(struct file *file, +=09=09=09=09 const char __user *user_buf, +=09=09=09=09 size_t count, +=09=09=09=09 loff_t *ppos) +{ +=09struct ieee80211_local *local =3D file->private_data; +=09char buf[100]; +=09size_t len; +=09u32 ac, q_limit_low, q_limit_high; +=09struct sta_info *sta; + +=09if (count > sizeof(buf)) +=09=09return -EINVAL; + +=09if (copy_from_user(buf, user_buf, count)) +=09=09return -EFAULT; + +=09buf[sizeof(buf) - 1] =3D 0; +=09len =3D strlen(buf); +=09if (len > 0 && buf[len - 1] =3D=3D '\n') +=09=09buf[len - 1] =3D 0; + +=09if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) !=3D 3) +=09=09return -EINVAL; + +=09if (ac >=3D IEEE80211_NUM_ACS) +=09=09return -EINVAL; + +=09local->aql_txq_limit_low[ac] =3D q_limit_low; +=09local->aql_txq_limit_high[ac] =3D q_limit_high; + +=09mutex_lock(&local->sta_mtx); +=09list_for_each_entry(sta, &local->sta_list, list) { +=09=09sta->airtime[ac].aql_limit_low =3D q_limit_low; +=09=09sta->airtime[ac].aql_limit_high =3D q_limit_high; +=09} +=09mutex_unlock(&local->sta_mtx); +=09return count; +} + +static const struct file_operations aql_txq_limit_ops =3D { +=09.write =3D aql_txq_limit_write, +=09.read =3D aql_txq_limit_read, +=09.open =3D simple_open, +=09.llseek =3D default_llseek, +}; + static ssize_t force_tx_status_read(struct file *file, =09=09=09=09 char __user *user_buf, =09=09=09=09 size_t count, @@ -441,6 +515,10 @@ void debugfs_hw_add(struct ieee80211_local *local) =09debugfs_create_u16("airtime_flags", 0600, =09=09=09 phyd, &local->airtime_flags); =20 +=09DEBUGFS_ADD(aql_txq_limit); +=09debugfs_create_u32("aql_threshold", 0600, +=09=09=09 phyd, &local->aql_threshold); + =09statsd =3D debugfs_create_dir("statistics", phyd); =20 =09/* if the dir failed, don't put all the other things into the root! */ diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index c8ad20c28c43..9f9b8f5ed86a 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -197,10 +197,12 @@ static ssize_t sta_airtime_read(struct file *file, ch= ar __user *userbuf, { =09struct sta_info *sta =3D file->private_data; =09struct ieee80211_local *local =3D sta->sdata->local; -=09size_t bufsz =3D 200; +=09size_t bufsz =3D 400; =09char *buf =3D kzalloc(bufsz, GFP_KERNEL), *p =3D buf; =09u64 rx_airtime =3D 0, tx_airtime =3D 0; =09s64 deficit[IEEE80211_NUM_ACS]; +=09u32 q_depth[IEEE80211_NUM_ACS]; +=09u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS]; =09ssize_t rv; =09int ac; =20 @@ -212,19 +214,22 @@ static ssize_t sta_airtime_read(struct file *file, ch= ar __user *userbuf, =09=09rx_airtime +=3D sta->airtime[ac].rx_airtime; =09=09tx_airtime +=3D sta->airtime[ac].tx_airtime; =09=09deficit[ac] =3D sta->airtime[ac].deficit; +=09=09q_limit_l[ac] =3D sta->airtime[ac].aql_limit_low; +=09=09q_limit_h[ac] =3D sta->airtime[ac].aql_limit_high; +=09=09q_depth[ac] =3D sta->airtime[ac].aql_tx_pending; =09=09spin_unlock_bh(&local->active_txq_lock[ac]); =09} =20 =09p +=3D scnprintf(p, bufsz + buf - p, =09=09"RX: %llu us\nTX: %llu us\nWeight: %u\n" -=09=09"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", -=09=09rx_airtime, -=09=09tx_airtime, -=09=09sta->airtime_weight, -=09=09deficit[0], -=09=09deficit[1], -=09=09deficit[2], -=09=09deficit[3]); +=09=09"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n" +=09=09"Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n" +=09=09"Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n", +=09=09rx_airtime, tx_airtime, sta->airtime_weight, +=09=09deficit[0], deficit[1], deficit[2], deficit[3], +=09=09q_depth[0], q_depth[1], q_depth[2], q_depth[3], +=09=09q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1], +=09=09q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]), =20 =09rv =3D simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); =09kfree(buf); @@ -236,7 +241,25 @@ static ssize_t sta_airtime_write(struct file *file, co= nst char __user *userbuf, { =09struct sta_info *sta =3D file->private_data; =09struct ieee80211_local *local =3D sta->sdata->local; -=09int ac; +=09u32 ac, q_limit_l, q_limit_h; +=09char _buf[100] =3D {}, *buf =3D _buf; + +=09if (count > sizeof(_buf)) +=09=09return -EINVAL; + +=09if (copy_from_user(buf, userbuf, count)) +=09=09return -EFAULT; + +=09buf[sizeof(_buf) - 1] =3D '\0'; +=09if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h) +=09 !=3D 3) +=09=09return -EINVAL; + +=09if (ac >=3D IEEE80211_NUM_ACS) +=09=09return -EINVAL; + +=09sta->airtime[ac].aql_limit_low =3D q_limit_l; +=09sta->airtime[ac].aql_limit_high =3D q_limit_h; =20 =09for (ac =3D 0; ac < IEEE80211_NUM_ACS; ac++) { =09=09spin_lock_bh(&local->active_txq_lock[ac]); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 225ea4e3cd76..6fa690757388 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1142,6 +1142,10 @@ struct ieee80211_local { =09u16 schedule_round[IEEE80211_NUM_ACS]; =20 =09u16 airtime_flags; +=09u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; +=09u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; +=09u32 aql_threshold; +=09u32 aql_total_pending_airtime; =20 =09const struct ieee80211_ops *ops; =20 diff --git a/net/mac80211/main.c b/net/mac80211/main.c index aba094b4ccfc..0792c9b9c850 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -667,8 +667,15 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv= _data_len, =09for (i =3D 0; i < IEEE80211_NUM_ACS; i++) { =09=09INIT_LIST_HEAD(&local->active_txqs[i]); =09=09spin_lock_init(&local->active_txq_lock[i]); +=09=09local->aql_txq_limit_low[i] =3D IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; +=09=09local->aql_txq_limit_high[i] =3D +=09=09=09IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; =09} -=09local->airtime_flags =3D AIRTIME_USE_TX | AIRTIME_USE_RX; + +=09local->airtime_flags =3D AIRTIME_USE_TX | +=09=09=09 AIRTIME_USE_RX | +=09=09=09 AIRTIME_USE_AQL; +=09local->aql_threshold =3D IEEE80211_AQL_THRESHOLD; =20 =09INIT_LIST_HEAD(&local->chanctx_list); =09mutex_init(&local->chanctx_mtx); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index bd11fef2139f..64bacf4f068c 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -396,6 +396,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if= _data *sdata, =09=09skb_queue_head_init(&sta->ps_tx_buf[i]); =09=09skb_queue_head_init(&sta->tx_filtered[i]); =09=09sta->airtime[i].deficit =3D sta->airtime_weight; +=09=09sta->airtime[i].aql_tx_pending =3D 0; +=09=09sta->airtime[i].aql_limit_low =3D local->aql_txq_limit_low[i]; +=09=09sta->airtime[i].aql_limit_high =3D local->aql_txq_limit_high[i]; =09} =20 =09for (i =3D 0; i < IEEE80211_NUM_TIDS; i++) @@ -1893,6 +1896,35 @@ void ieee80211_sta_register_airtime(struct ieee80211= _sta *pubsta, u8 tid, } EXPORT_SYMBOL(ieee80211_sta_register_airtime); =20 +void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, +=09=09=09=09=09 struct sta_info *sta, u8 ac, +=09=09=09=09=09 u16 tx_airtime, bool tx_completed) +{ +=09spin_lock_bh(&local->active_txq_lock[ac]); +=09if (tx_completed) { +=09=09if (sta) { +=09=09=09if (WARN_ONCE(sta->airtime[ac].aql_tx_pending < tx_airtime, +=09=09=09=09 "TXQ pending airtime underflow: %u, %u", +=09=09=09=09 sta->airtime[ac].aql_tx_pending, tx_airtime)) +=09=09=09=09sta->airtime[ac].aql_tx_pending =3D 0; +=09=09=09else +=09=09=09=09sta->airtime[ac].aql_tx_pending -=3D tx_airtime; +=09=09} + +=09=09if (WARN_ONCE(local->aql_total_pending_airtime < tx_airtime, +=09=09=09 "Device pending airtime underflow: %u, %u", +=09=09=09 local->aql_total_pending_airtime, tx_airtime)) +=09=09=09local->aql_total_pending_airtime =3D 0; +=09=09else +=09=09=09local->aql_total_pending_airtime -=3D tx_airtime; +=09} else { +=09=09if (sta) +=09=09=09sta->airtime[ac].aql_tx_pending +=3D tx_airtime; +=09=09local->aql_total_pending_airtime +=3D tx_airtime; +=09} +=09spin_unlock_bh(&local->active_txq_lock[ac]); +} + int sta_info_move_state(struct sta_info *sta, =09=09=09enum ieee80211_sta_state new_state) { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 369c2dddce52..4e4d76e81b0f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -127,13 +127,21 @@ enum ieee80211_agg_stop_reason { /* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */ #define AIRTIME_USE_TX=09=09BIT(0) #define AIRTIME_USE_RX=09=09BIT(1) +#define AIRTIME_USE_AQL=09=09BIT(2) =20 struct airtime_info { =09u64 rx_airtime; =09u64 tx_airtime; =09s64 deficit; +=09u32 aql_tx_pending; /* Estimated airtime for frames pending in queue */ +=09u32 aql_limit_low; +=09u32 aql_limit_high; }; =20 +void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, +=09=09=09=09=09 struct sta_info *sta, u8 ac, +=09=09=09=09=09 u16 tx_airtime, bool tx_completed); + struct sta_info; =20 /** diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a16c2f863702..12653d873b8c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3665,7 +3665,8 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee8= 0211_hw *hw, u8 ac) { =09struct ieee80211_local *local =3D hw_to_local(hw); =09struct ieee80211_txq *ret =3D NULL; -=09struct txq_info *txqi =3D NULL; +=09struct txq_info *txqi =3D NULL, *head =3D NULL; +=09bool found_eligible_txq =3D false; =20 =09spin_lock_bh(&local->active_txq_lock[ac]); =20 @@ -3676,13 +3677,26 @@ struct ieee80211_txq *ieee80211_next_txq(struct iee= e80211_hw *hw, u8 ac) =09if (!txqi) =09=09goto out; =20 +=09if (txqi =3D=3D head && !found_eligible_txq) +=09=09goto out; + +=09if (!head) +=09=09head =3D txqi; + =09if (txqi->txq.sta) { =09=09struct sta_info *sta =3D container_of(txqi->txq.sta, -=09=09=09=09=09=09struct sta_info, sta); +=09=09=09=09=09=09 struct sta_info, sta); +=09=09bool aql_check =3D ieee80211_txq_airtime_check(hw, &txqi->txq); +=09=09s64 deficit =3D sta->airtime[txqi->txq.ac].deficit; + +=09=09if (aql_check) +=09=09=09found_eligible_txq =3D true; =20 -=09=09if (sta->airtime[txqi->txq.ac].deficit < 0) { +=09=09if (deficit < 0) =09=09=09sta->airtime[txqi->txq.ac].deficit +=3D =09=09=09=09sta->airtime_weight; + +=09=09if (deficit < 0 || !aql_check) { =09=09=09list_move_tail(&txqi->schedule_order, =09=09=09=09 &local->active_txqs[txqi->txq.ac]); =09=09=09goto begin; @@ -3736,6 +3750,32 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *h= w, } EXPORT_SYMBOL(__ieee80211_schedule_txq); =20 +bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, +=09=09=09=09 struct ieee80211_txq *txq) +{ +=09struct sta_info *sta; +=09struct ieee80211_local *local =3D hw_to_local(hw); + +=09if (!(local->airtime_flags & AIRTIME_USE_AQL)) +=09=09return true; + +=09if (!txq->sta) +=09=09return true; + +=09sta =3D container_of(txq->sta, struct sta_info, sta); +=09if (sta->airtime[txq->ac].aql_tx_pending < +=09 sta->airtime[txq->ac].aql_limit_low) +=09=09return true; + +=09if (local->aql_total_pending_airtime < local->aql_threshold && +=09 sta->airtime[txq->ac].aql_tx_pending < +=09 sta->airtime[txq->ac].aql_limit_high) +=09=09return true; + +=09return false; +} +EXPORT_SYMBOL(ieee80211_txq_airtime_check); + bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, =09=09=09=09struct ieee80211_txq *txq) { 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.3 #3 (Red Hat Linux)) id 1iMuF1-0008HR-0A for ath10k@lists.infradead.org; Tue, 22 Oct 2019 13:30:30 +0000 Received: by mail-wm1-f71.google.com with SMTP id a81so3891200wma.4 for ; Tue, 22 Oct 2019 06:30:21 -0700 (PDT) Subject: [PATCH v5 3/4] mac80211: Implement Airtime-based Queue Limit (AQL) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Tue, 22 Oct 2019 15:30:18 +0200 Message-ID: <157175101846.104114.3665681248825910161.stgit@toke.dk> In-Reply-To: <157175101518.104114.6722791270722911023.stgit@toke.dk> References: <157175101518.104114.6722791270722911023.stgit@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: Johannes Berg Cc: Kan Yan , Rajkumar Manoharan , Kevin Hayes , make-wifi-fast@lists.bufferbloat.net, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau RnJvbTogS2FuIFlhbiA8a3lhbkBnb29nbGUuY29tPgoKSW4gb3JkZXIgZm9yIHRoZSBGcV9Db0Rl bCBhbGdvcml0aG0gaW50ZWdyYXRlZCBpbiBtYWM4MDIxMSBsYXllciB0byBvcGVyYXRlCmVmZmVj dGl2ZWx5IHRvIGNvbnRyb2wgZXhjZXNzaXZlIHF1ZXVlaW5nIGxhdGVuY3ksIHRoZSBDb0RlbCBh bGdvcml0aG0KcmVxdWlyZXMgYW4gYWNjdXJhdGUgbWVhc3VyZSBvZiBob3cgbG9uZyBwYWNrZXRz IHN0YXlzIGluIHRoZSBxdWV1ZSwgQUtBCnNvam91cm4gdGltZS4gVGhlIHNvam91cm4gdGltZSBt ZWFzdXJlZCBhdCB0aGUgbWFjODAyMTEgbGF5ZXIgZG9lc24ndAppbmNsdWRlIHF1ZXVlaW5nIGxh dGVuY3kgaW4gdGhlIGxvd2VyIGxheWVyIChmaXJtd2FyZS9oYXJkd2FyZSkgYW5kIENvRGVsCmV4 cGVjdHMgbG93ZXIgbGF5ZXIgdG8gaGF2ZSBhIHNob3J0IHF1ZXVlLiBIb3dldmVyLCBtb3N0IDgw Mi4xMWFjIGNoaXBzZXRzCm9mZmxvYWQgdGFza3Mgc3VjaCBUWCBhZ2dyZWdhdGlvbiB0byBmaXJt d2FyZSBvciBoYXJkd2FyZSwgdGh1cyBoYXZlIGEgZGVlcApsb3dlciBsYXllciBxdWV1ZS4KCldp dGhvdXQgYSBtZWNoYW5pc20gdG8gY29udHJvbCB0aGUgbG93ZXIgbGF5ZXIgcXVldWUgc2l6ZSwg cGFja2V0cyBvbmx5CnN0YXkgaW4gbWFjODAyMTEgbGF5ZXIgdHJhbnNpZW50bHkgYmVmb3JlIGJl aW5nIHNlbnQgdG8gZmlybXdhcmUgcXVldWUuCkFzIGEgcmVzdWx0LCB0aGUgc29qb3VybiB0aW1l IG1lYXN1cmVkIGJ5IENvRGVsIGluIHRoZSBtYWM4MDIxMSBsYXllciBpcwphbG1vc3QgYWx3YXlz IGxvd2VyIHRoYW4gdGhlIENvRGVsIGxhdGVuY3kgdGFyZ2V0LCBoZW5jZSBDb0RlbCBkb2VzIGxp dHRsZQp0byBjb250cm9sIHRoZSBsYXRlbmN5LCBldmVuIHdoZW4gdGhlIGxvd2VyIGxheWVyIHF1 ZXVlIGNhdXNlcyBleGNlc3NpdmUKbGF0ZW5jeS4KClRoZSBCeXRlIFF1ZXVlIExpbWl0cyAoQlFM KSBtZWNoYW5pc20gaXMgY29tbW9ubHkgdXNlZCB0byBhZGRyZXNzIHRoZQpzaW1pbGFyIGlzc3Vl IHdpdGggd2lyZWQgbmV0d29yayBpbnRlcmZhY2UuIEhvd2V2ZXIsIHRoaXMgbWV0aG9kIGNhbm5v dCBiZQphcHBsaWVkIGRpcmVjdGx5IHRvIHRoZSB3aXJlbGVzcyBuZXR3b3JrIGludGVyZmFjZS4g IkJ5dGVzIiBpcyBub3QgYQpzdWl0YWJsZSBtZWFzdXJlIG9mIHF1ZXVlIGRlcHRoIGluIHRoZSB3 aXJlbGVzcyBuZXR3b3JrLCBhcyB0aGUgZGF0YSByYXRlCmNhbiB2YXJ5IGRyYW1hdGljYWxseSBm cm9tIHN0YXRpb24gdG8gc3RhdGlvbiBpbiB0aGUgc2FtZSBuZXR3b3JrLCBmcm9tIGEKZmV3IE1i cHMgdG8gb3ZlciBHYnBzLgoKVGhpcyBwYXRjaCBpbXBsZW1lbnRzIGFuIEFpcnRpbWUtYmFzZWQg UXVldWUgTGltaXQgKEFRTCkgdG8gbWFrZSBDb0RlbCB3b3JrCmVmZmVjdGl2ZWx5IHdpdGggd2ly ZWxlc3MgZHJpdmVycyB0aGF0IHV0aWxpemVkIGZpcm13YXJlL2hhcmR3YXJlCm9mZmxvYWRpbmcu IEFRTCBhbGxvd3MgZWFjaCB0eHEgdG8gcmVsZWFzZSBqdXN0IGVub3VnaCBwYWNrZXRzIHRvIHRo ZSBsb3dlcgpsYXllciB0byBmb3JtIDEtMiBsYXJnZSBhZ2dyZWdhdGlvbnMgdG8ga2VlcCBoYXJk d2FyZSBmdWxseSB1dGlsaXplZCBhbmQKcmV0YWlucyB0aGUgcmVzdCBvZiB0aGUgZnJhbWVzIGlu IG1hYzgwMjExIGxheWVyIHRvIGJlIGNvbnRyb2xsZWQgYnkgdGhlCkNvRGVsIGFsZ29yaXRobS4K ClNpZ25lZC1vZmYtYnk6IEthbiBZYW4gPGt5YW5AZ29vZ2xlLmNvbT4KWyBUb2tlOiBLZWVwIEFQ SSB0byBzZXQgcGVuZGluZyBhaXJ0aW1lIGludGVybmFsLCBmaXggbml0cyBpbiBjb21taXQgbXNn IF0KU2lnbmVkLW9mZi1ieTogVG9rZSBIw7hpbGFuZC1Kw7hyZ2Vuc2VuIDx0b2tlQHJlZGhhdC5j b20+Ci0tLQogaW5jbHVkZS9uZXQvY2ZnODAyMTEuaCAgICAgfCAgICA3ICsrKysKIGluY2x1ZGUv bmV0L21hYzgwMjExLmggICAgIHwgICAxMiArKysrKysrCiBuZXQvbWFjODAyMTEvZGVidWdmcy5j ICAgICB8ICAgNzggKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysK IG5ldC9tYWM4MDIxMS9kZWJ1Z2ZzX3N0YS5jIHwgICA0MyArKysrKysrKysrKysrKysrKysrLS0t LS0KIG5ldC9tYWM4MDIxMS9pZWVlODAyMTFfaS5oIHwgICAgNCArKwogbmV0L21hYzgwMjExL21h aW4uYyAgICAgICAgfCAgICA5ICsrKysrCiBuZXQvbWFjODAyMTEvc3RhX2luZm8uYyAgICB8ICAg MzIgKysrKysrKysrKysrKysrKysrCiBuZXQvbWFjODAyMTEvc3RhX2luZm8uaCAgICB8ICAgIDgg KysrKysKIG5ldC9tYWM4MDIxMS90eC5jICAgICAgICAgIHwgICA0NiArKysrKysrKysrKysrKysr KysrKysrKystLQogOSBmaWxlcyBjaGFuZ2VkLCAyMjUgaW5zZXJ0aW9ucygrKSwgMTQgZGVsZXRp b25zKC0pCgpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9uZXQvY2ZnODAyMTEuaCBiL2luY2x1ZGUvbmV0 L2NmZzgwMjExLmgKaW5kZXggZmY0NWMzZTFhYmZmLi44ZDUwYzBhNjBkYmQgMTAwNjQ0Ci0tLSBh L2luY2x1ZGUvbmV0L2NmZzgwMjExLmgKKysrIGIvaW5jbHVkZS9uZXQvY2ZnODAyMTEuaApAQCAt MjYwMiw2ICsyNjAyLDEzIEBAIGVudW0gd2lwaHlfcGFyYW1zX2ZsYWdzIHsKIAogI2RlZmluZSBJ RUVFODAyMTFfREVGQVVMVF9BSVJUSU1FX1dFSUdIVAkyNTYKIAorLyogVGhlIHBlciBUWFEgZGV2 aWNlIHF1ZXVlIGxpbWl0IGluIGFpcnRpbWUgKi8KKyNkZWZpbmUgSUVFRTgwMjExX0RFRkFVTFRf QVFMX1RYUV9MSU1JVF9MCTQwMDAKKyNkZWZpbmUgSUVFRTgwMjExX0RFRkFVTFRfQVFMX1RYUV9M SU1JVF9ICTgwMDAKKworLyogVGhlIHBlciBpbnRlcmZhY2UgYWlydGltZSB0aHJlc2hvbGQgdG8g c3dpdGNoIHRvIGxvd2VyIHF1ZXVlIGxpbWl0ICovCisjZGVmaW5lIElFRUU4MDIxMV9BUUxfVEhS RVNIT0xECQkJMjQwMDAKKwogLyoqCiAgKiBzdHJ1Y3QgY2ZnODAyMTFfcG1rc2EgLSBQTUsgU2Vj dXJpdHkgQXNzb2NpYXRpb24KICAqCmRpZmYgLS1naXQgYS9pbmNsdWRlL25ldC9tYWM4MDIxMS5o IGIvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAppbmRleCA4YTNlMDU0NGEwMjYuLjJiYzBmMjUzOGEz NiAxMDA2NDQKLS0tIGEvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAorKysgYi9pbmNsdWRlL25ldC9t YWM4MDIxMS5oCkBAIC01NTY1LDYgKzU1NjUsMTggQEAgdm9pZCBpZWVlODAyMTFfc2VuZF9lb3Nw X251bGxmdW5jKHN0cnVjdCBpZWVlODAyMTFfc3RhICpwdWJzdGEsIGludCB0aWQpOwogdm9pZCBp ZWVlODAyMTFfc3RhX3JlZ2lzdGVyX2FpcnRpbWUoc3RydWN0IGllZWU4MDIxMV9zdGEgKnB1YnN0 YSwgdTggdGlkLAogCQkJCSAgICB1MzIgdHhfYWlydGltZSwgdTMyIHJ4X2FpcnRpbWUpOwogCisv KioKKyAqIGllZWU4MDIxMV90eHFfYWlydGltZV9jaGVjayAtIGNoZWNrIGlmIGEgdHhxIGNhbiBz ZW5kIGZyYW1lIHRvIGRldmljZQorICoKKyAqIEBodzogcG9pbnRlciBvYnRhaW5lZCBmcm9tIGll ZWU4MDIxMV9hbGxvY19odygpCisgKiBAdHhxOiBwb2ludGVyIG9idGFpbmVkIGZyb20gc3RhdGlv biBvciB2aXJ0dWFsIGludGVyZmFjZQorICoKKyAqIFJldHVybiB0cnVlIGlmIHRoZSBBUUwncyBh aXJ0aW1lIGxpbWl0IGhhcyBub3QgYmVlbiByZWFjaGVkIGFuZCB0aGUgdHhxIGNhbgorICogY29u dGludWUgdG8gc2VuZCBtb3JlIHBhY2tldHMgdG8gdGhlIGRldmljZS4gT3RoZXJ3aXNlIHJldHVy biBmYWxzZS4KKyAqLworYm9vbAoraWVlZTgwMjExX3R4cV9haXJ0aW1lX2NoZWNrKHN0cnVjdCBp ZWVlODAyMTFfaHcgKmh3LCBzdHJ1Y3QgaWVlZTgwMjExX3R4cSAqdHhxKTsKKwogLyoqCiAgKiBp ZWVlODAyMTFfaXRlcl9rZXlzIC0gaXRlcmF0ZSBrZXlzIHByb2dyYW1tZWQgaW50byB0aGUgZGV2 aWNlCiAgKiBAaHc6IHBvaW50ZXIgb2J0YWluZWQgZnJvbSBpZWVlODAyMTFfYWxsb2NfaHcoKQpk aWZmIC0tZ2l0IGEvbmV0L21hYzgwMjExL2RlYnVnZnMuYyBiL25ldC9tYWM4MDIxMS9kZWJ1Z2Zz LmMKaW5kZXggNTY4YjNiMjc2OTMxLi5kNzdlYTBlNTFjMWQgMTAwNjQ0Ci0tLSBhL25ldC9tYWM4 MDIxMS9kZWJ1Z2ZzLmMKKysrIGIvbmV0L21hYzgwMjExL2RlYnVnZnMuYwpAQCAtMTQ4LDYgKzE0 OCw4MCBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBhcW1fb3BzID0gewog CS5sbHNlZWsgPSBkZWZhdWx0X2xsc2VlaywKIH07CiAKK3N0YXRpYyBzc2l6ZV90IGFxbF90eHFf bGltaXRfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwKKwkJCQkgIGNoYXIgX191c2VyICp1c2VyX2J1 ZiwKKwkJCQkgIHNpemVfdCBjb3VudCwKKwkJCQkgIGxvZmZfdCAqcHBvcykKK3sKKwlzdHJ1Y3Qg aWVlZTgwMjExX2xvY2FsICpsb2NhbCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKKwljaGFyIGJ1Zls0 MDBdOworCWludCBsZW4gPSAwOworCisJbGVuID0gc2NucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1Ziks CisJCQkiQUMJQVFMIGxpbWl0IGxvdwlBUUwgbGltaXQgaGlnaFxuIgorCQkJIlZPCSV1CQkldVxu IgorCQkJIlZJCSV1CQkldVxuIgorCQkJIkJFCSV1CQkldVxuIgorCQkJIkJLCSV1CQkldVxuIiwK KwkJCWxvY2FsLT5hcWxfdHhxX2xpbWl0X2xvd1tJRUVFODAyMTFfQUNfVk9dLAorCQkJbG9jYWwt PmFxbF90eHFfbGltaXRfaGlnaFtJRUVFODAyMTFfQUNfVk9dLAorCQkJbG9jYWwtPmFxbF90eHFf bGltaXRfbG93W0lFRUU4MDIxMV9BQ19WSV0sCisJCQlsb2NhbC0+YXFsX3R4cV9saW1pdF9oaWdo W0lFRUU4MDIxMV9BQ19WSV0sCisJCQlsb2NhbC0+YXFsX3R4cV9saW1pdF9sb3dbSUVFRTgwMjEx X0FDX0JFXSwKKwkJCWxvY2FsLT5hcWxfdHhxX2xpbWl0X2hpZ2hbSUVFRTgwMjExX0FDX0JFXSwK KwkJCWxvY2FsLT5hcWxfdHhxX2xpbWl0X2xvd1tJRUVFODAyMTFfQUNfQktdLAorCQkJbG9jYWwt PmFxbF90eHFfbGltaXRfaGlnaFtJRUVFODAyMTFfQUNfQktdKTsKKwlyZXR1cm4gc2ltcGxlX3Jl YWRfZnJvbV9idWZmZXIodXNlcl9idWYsIGNvdW50LCBwcG9zLAorCQkJCSAgICAgICBidWYsIGxl bik7Cit9CisKK3N0YXRpYyBzc2l6ZV90IGFxbF90eHFfbGltaXRfd3JpdGUoc3RydWN0IGZpbGUg KmZpbGUsCisJCQkJICAgY29uc3QgY2hhciBfX3VzZXIgKnVzZXJfYnVmLAorCQkJCSAgIHNpemVf dCBjb3VudCwKKwkJCQkgICBsb2ZmX3QgKnBwb3MpCit7CisJc3RydWN0IGllZWU4MDIxMV9sb2Nh bCAqbG9jYWwgPSBmaWxlLT5wcml2YXRlX2RhdGE7CisJY2hhciBidWZbMTAwXTsKKwlzaXplX3Qg bGVuOworCXUzMiBhYywgcV9saW1pdF9sb3csIHFfbGltaXRfaGlnaDsKKwlzdHJ1Y3Qgc3RhX2lu Zm8gKnN0YTsKKworCWlmIChjb3VudCA+IHNpemVvZihidWYpKQorCQlyZXR1cm4gLUVJTlZBTDsK KworCWlmIChjb3B5X2Zyb21fdXNlcihidWYsIHVzZXJfYnVmLCBjb3VudCkpCisJCXJldHVybiAt RUZBVUxUOworCisJYnVmW3NpemVvZihidWYpIC0gMV0gPSAwOworCWxlbiA9IHN0cmxlbihidWYp OworCWlmIChsZW4gPiAwICYmIGJ1ZltsZW4gLSAxXSA9PSAnXG4nKQorCQlidWZbbGVuIC0gMV0g PSAwOworCisJaWYgKHNzY2FuZihidWYsICIldSAldSAldSIsICZhYywgJnFfbGltaXRfbG93LCAm cV9saW1pdF9oaWdoKSAhPSAzKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWlmIChhYyA+PSBJRUVF ODAyMTFfTlVNX0FDUykKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlsb2NhbC0+YXFsX3R4cV9saW1p dF9sb3dbYWNdID0gcV9saW1pdF9sb3c7CisJbG9jYWwtPmFxbF90eHFfbGltaXRfaGlnaFthY10g PSBxX2xpbWl0X2hpZ2g7CisKKwltdXRleF9sb2NrKCZsb2NhbC0+c3RhX210eCk7CisJbGlzdF9m b3JfZWFjaF9lbnRyeShzdGEsICZsb2NhbC0+c3RhX2xpc3QsIGxpc3QpIHsKKwkJc3RhLT5haXJ0 aW1lW2FjXS5hcWxfbGltaXRfbG93ID0gcV9saW1pdF9sb3c7CisJCXN0YS0+YWlydGltZVthY10u YXFsX2xpbWl0X2hpZ2ggPSBxX2xpbWl0X2hpZ2g7CisJfQorCW11dGV4X3VubG9jaygmbG9jYWwt PnN0YV9tdHgpOworCXJldHVybiBjb3VudDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxl X29wZXJhdGlvbnMgYXFsX3R4cV9saW1pdF9vcHMgPSB7CisJLndyaXRlID0gYXFsX3R4cV9saW1p dF93cml0ZSwKKwkucmVhZCA9IGFxbF90eHFfbGltaXRfcmVhZCwKKwkub3BlbiA9IHNpbXBsZV9v cGVuLAorCS5sbHNlZWsgPSBkZWZhdWx0X2xsc2VlaywKK307CisKIHN0YXRpYyBzc2l6ZV90IGZv cmNlX3R4X3N0YXR1c19yZWFkKHN0cnVjdCBmaWxlICpmaWxlLAogCQkJCSAgICBjaGFyIF9fdXNl ciAqdXNlcl9idWYsCiAJCQkJICAgIHNpemVfdCBjb3VudCwKQEAgLTQ0MSw2ICs1MTUsMTAgQEAg dm9pZCBkZWJ1Z2ZzX2h3X2FkZChzdHJ1Y3QgaWVlZTgwMjExX2xvY2FsICpsb2NhbCkKIAlkZWJ1 Z2ZzX2NyZWF0ZV91MTYoImFpcnRpbWVfZmxhZ3MiLCAwNjAwLAogCQkJICAgcGh5ZCwgJmxvY2Fs LT5haXJ0aW1lX2ZsYWdzKTsKIAorCURFQlVHRlNfQUREKGFxbF90eHFfbGltaXQpOworCWRlYnVn ZnNfY3JlYXRlX3UzMigiYXFsX3RocmVzaG9sZCIsIDA2MDAsCisJCQkgICBwaHlkLCAmbG9jYWwt PmFxbF90aHJlc2hvbGQpOworCiAJc3RhdHNkID0gZGVidWdmc19jcmVhdGVfZGlyKCJzdGF0aXN0 aWNzIiwgcGh5ZCk7CiAKIAkvKiBpZiB0aGUgZGlyIGZhaWxlZCwgZG9uJ3QgcHV0IGFsbCB0aGUg b3RoZXIgdGhpbmdzIGludG8gdGhlIHJvb3QhICovCmRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEv ZGVidWdmc19zdGEuYyBiL25ldC9tYWM4MDIxMS9kZWJ1Z2ZzX3N0YS5jCmluZGV4IGM4YWQyMGMy OGM0My4uOWY5YjhmNWVkODZhIDEwMDY0NAotLS0gYS9uZXQvbWFjODAyMTEvZGVidWdmc19zdGEu YworKysgYi9uZXQvbWFjODAyMTEvZGVidWdmc19zdGEuYwpAQCAtMTk3LDEwICsxOTcsMTIgQEAg c3RhdGljIHNzaXplX3Qgc3RhX2FpcnRpbWVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBf X3VzZXIgKnVzZXJidWYsCiB7CiAJc3RydWN0IHN0YV9pbmZvICpzdGEgPSBmaWxlLT5wcml2YXRl X2RhdGE7CiAJc3RydWN0IGllZWU4MDIxMV9sb2NhbCAqbG9jYWwgPSBzdGEtPnNkYXRhLT5sb2Nh bDsKLQlzaXplX3QgYnVmc3ogPSAyMDA7CisJc2l6ZV90IGJ1ZnN6ID0gNDAwOwogCWNoYXIgKmJ1 ZiA9IGt6YWxsb2MoYnVmc3osIEdGUF9LRVJORUwpLCAqcCA9IGJ1ZjsKIAl1NjQgcnhfYWlydGlt ZSA9IDAsIHR4X2FpcnRpbWUgPSAwOwogCXM2NCBkZWZpY2l0W0lFRUU4MDIxMV9OVU1fQUNTXTsK Kwl1MzIgcV9kZXB0aFtJRUVFODAyMTFfTlVNX0FDU107CisJdTMyIHFfbGltaXRfbFtJRUVFODAy MTFfTlVNX0FDU10sIHFfbGltaXRfaFtJRUVFODAyMTFfTlVNX0FDU107CiAJc3NpemVfdCBydjsK IAlpbnQgYWM7CiAKQEAgLTIxMiwxOSArMjE0LDIyIEBAIHN0YXRpYyBzc2l6ZV90IHN0YV9haXJ0 aW1lX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICp1c2VyYnVmLAogCQlyeF9h aXJ0aW1lICs9IHN0YS0+YWlydGltZVthY10ucnhfYWlydGltZTsKIAkJdHhfYWlydGltZSArPSBz dGEtPmFpcnRpbWVbYWNdLnR4X2FpcnRpbWU7CiAJCWRlZmljaXRbYWNdID0gc3RhLT5haXJ0aW1l W2FjXS5kZWZpY2l0OworCQlxX2xpbWl0X2xbYWNdID0gc3RhLT5haXJ0aW1lW2FjXS5hcWxfbGlt aXRfbG93OworCQlxX2xpbWl0X2hbYWNdID0gc3RhLT5haXJ0aW1lW2FjXS5hcWxfbGltaXRfaGln aDsKKwkJcV9kZXB0aFthY10gPSBzdGEtPmFpcnRpbWVbYWNdLmFxbF90eF9wZW5kaW5nOwogCQlz cGluX3VubG9ja19iaCgmbG9jYWwtPmFjdGl2ZV90eHFfbG9ja1thY10pOwogCX0KIAogCXAgKz0g c2NucHJpbnRmKHAsIGJ1ZnN6ICsgYnVmIC0gcCwKIAkJIlJYOiAlbGx1IHVzXG5UWDogJWxsdSB1 c1xuV2VpZ2h0OiAldVxuIgotCQkiRGVmaWNpdDogVk86ICVsbGQgdXMgVkk6ICVsbGQgdXMgQkU6 ICVsbGQgdXMgQks6ICVsbGQgdXNcbiIsCi0JCXJ4X2FpcnRpbWUsCi0JCXR4X2FpcnRpbWUsCi0J CXN0YS0+YWlydGltZV93ZWlnaHQsCi0JCWRlZmljaXRbMF0sCi0JCWRlZmljaXRbMV0sCi0JCWRl ZmljaXRbMl0sCi0JCWRlZmljaXRbM10pOworCQkiRGVmaWNpdDogVk86ICVsbGQgdXMgVkk6ICVs bGQgdXMgQkU6ICVsbGQgdXMgQks6ICVsbGQgdXNcbiIKKwkJIlEgZGVwdGg6IFZPOiAldSB1cyBW STogJXUgdXMgQkU6ICV1IHVzIEJLOiAldSB1c1xuIgorCQkiUSBsaW1pdFtsb3cvaGlnaF06IFZP OiAldS8ldSBWSTogJXUvJXUgQkU6ICV1LyV1IEJLOiAldS8ldVxuIiwKKwkJcnhfYWlydGltZSwg dHhfYWlydGltZSwgc3RhLT5haXJ0aW1lX3dlaWdodCwKKwkJZGVmaWNpdFswXSwgZGVmaWNpdFsx XSwgZGVmaWNpdFsyXSwgZGVmaWNpdFszXSwKKwkJcV9kZXB0aFswXSwgcV9kZXB0aFsxXSwgcV9k ZXB0aFsyXSwgcV9kZXB0aFszXSwKKwkJcV9saW1pdF9sWzBdLCBxX2xpbWl0X2hbMF0sIHFfbGlt aXRfbFsxXSwgcV9saW1pdF9oWzFdLAorCQlxX2xpbWl0X2xbMl0sIHFfbGltaXRfaFsyXSwgcV9s aW1pdF9sWzNdLCBxX2xpbWl0X2hbM10pLAogCiAJcnYgPSBzaW1wbGVfcmVhZF9mcm9tX2J1ZmZl cih1c2VyYnVmLCBjb3VudCwgcHBvcywgYnVmLCBwIC0gYnVmKTsKIAlrZnJlZShidWYpOwpAQCAt MjM2LDcgKzI0MSwyNSBAQCBzdGF0aWMgc3NpemVfdCBzdGFfYWlydGltZV93cml0ZShzdHJ1Y3Qg ZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKnVzZXJidWYsCiB7CiAJc3RydWN0IHN0YV9p bmZvICpzdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CiAJc3RydWN0IGllZWU4MDIxMV9sb2NhbCAq bG9jYWwgPSBzdGEtPnNkYXRhLT5sb2NhbDsKLQlpbnQgYWM7CisJdTMyIGFjLCBxX2xpbWl0X2ws IHFfbGltaXRfaDsKKwljaGFyIF9idWZbMTAwXSA9IHt9LCAqYnVmID0gX2J1ZjsKKworCWlmIChj b3VudCA+IHNpemVvZihfYnVmKSkKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlpZiAoY29weV9mcm9t X3VzZXIoYnVmLCB1c2VyYnVmLCBjb3VudCkpCisJCXJldHVybiAtRUZBVUxUOworCisJYnVmW3Np emVvZihfYnVmKSAtIDFdID0gJ1wwJzsKKwlpZiAoc3NjYW5mKGJ1ZiwgInF1ZXVlIGxpbWl0ICV1 ICV1ICV1IiwgJmFjLCAmcV9saW1pdF9sLCAmcV9saW1pdF9oKQorCSAgICAhPSAzKQorCQlyZXR1 cm4gLUVJTlZBTDsKKworCWlmIChhYyA+PSBJRUVFODAyMTFfTlVNX0FDUykKKwkJcmV0dXJuIC1F SU5WQUw7CisKKwlzdGEtPmFpcnRpbWVbYWNdLmFxbF9saW1pdF9sb3cgPSBxX2xpbWl0X2w7CisJ c3RhLT5haXJ0aW1lW2FjXS5hcWxfbGltaXRfaGlnaCA9IHFfbGltaXRfaDsKIAogCWZvciAoYWMg PSAwOyBhYyA8IElFRUU4MDIxMV9OVU1fQUNTOyBhYysrKSB7CiAJCXNwaW5fbG9ja19iaCgmbG9j YWwtPmFjdGl2ZV90eHFfbG9ja1thY10pOwpkaWZmIC0tZ2l0IGEvbmV0L21hYzgwMjExL2llZWU4 MDIxMV9pLmggYi9uZXQvbWFjODAyMTEvaWVlZTgwMjExX2kuaAppbmRleCAyMjVlYTRlM2NkNzYu LjZmYTY5MDc1NzM4OCAxMDA2NDQKLS0tIGEvbmV0L21hYzgwMjExL2llZWU4MDIxMV9pLmgKKysr IGIvbmV0L21hYzgwMjExL2llZWU4MDIxMV9pLmgKQEAgLTExNDIsNiArMTE0MiwxMCBAQCBzdHJ1 Y3QgaWVlZTgwMjExX2xvY2FsIHsKIAl1MTYgc2NoZWR1bGVfcm91bmRbSUVFRTgwMjExX05VTV9B Q1NdOwogCiAJdTE2IGFpcnRpbWVfZmxhZ3M7CisJdTMyIGFxbF90eHFfbGltaXRfbG93W0lFRUU4 MDIxMV9OVU1fQUNTXTsKKwl1MzIgYXFsX3R4cV9saW1pdF9oaWdoW0lFRUU4MDIxMV9OVU1fQUNT XTsKKwl1MzIgYXFsX3RocmVzaG9sZDsKKwl1MzIgYXFsX3RvdGFsX3BlbmRpbmdfYWlydGltZTsK IAogCWNvbnN0IHN0cnVjdCBpZWVlODAyMTFfb3BzICpvcHM7CiAKZGlmZiAtLWdpdCBhL25ldC9t YWM4MDIxMS9tYWluLmMgYi9uZXQvbWFjODAyMTEvbWFpbi5jCmluZGV4IGFiYTA5NGI0Y2NmYy4u MDc5MmM5YjljODUwIDEwMDY0NAotLS0gYS9uZXQvbWFjODAyMTEvbWFpbi5jCisrKyBiL25ldC9t YWM4MDIxMS9tYWluLmMKQEAgLTY2Nyw4ICs2NjcsMTUgQEAgc3RydWN0IGllZWU4MDIxMV9odyAq aWVlZTgwMjExX2FsbG9jX2h3X25tKHNpemVfdCBwcml2X2RhdGFfbGVuLAogCWZvciAoaSA9IDA7 IGkgPCBJRUVFODAyMTFfTlVNX0FDUzsgaSsrKSB7CiAJCUlOSVRfTElTVF9IRUFEKCZsb2NhbC0+ YWN0aXZlX3R4cXNbaV0pOwogCQlzcGluX2xvY2tfaW5pdCgmbG9jYWwtPmFjdGl2ZV90eHFfbG9j a1tpXSk7CisJCWxvY2FsLT5hcWxfdHhxX2xpbWl0X2xvd1tpXSA9IElFRUU4MDIxMV9ERUZBVUxU X0FRTF9UWFFfTElNSVRfTDsKKwkJbG9jYWwtPmFxbF90eHFfbGltaXRfaGlnaFtpXSA9CisJCQlJ RUVFODAyMTFfREVGQVVMVF9BUUxfVFhRX0xJTUlUX0g7CiAJfQotCWxvY2FsLT5haXJ0aW1lX2Zs YWdzID0gQUlSVElNRV9VU0VfVFggfCBBSVJUSU1FX1VTRV9SWDsKKworCWxvY2FsLT5haXJ0aW1l X2ZsYWdzID0gQUlSVElNRV9VU0VfVFggfAorCQkJICAgICAgIEFJUlRJTUVfVVNFX1JYIHwKKwkJ CSAgICAgICBBSVJUSU1FX1VTRV9BUUw7CisJbG9jYWwtPmFxbF90aHJlc2hvbGQgPSBJRUVFODAy MTFfQVFMX1RIUkVTSE9MRDsKIAogCUlOSVRfTElTVF9IRUFEKCZsb2NhbC0+Y2hhbmN0eF9saXN0 KTsKIAltdXRleF9pbml0KCZsb2NhbC0+Y2hhbmN0eF9tdHgpOwpkaWZmIC0tZ2l0IGEvbmV0L21h YzgwMjExL3N0YV9pbmZvLmMgYi9uZXQvbWFjODAyMTEvc3RhX2luZm8uYwppbmRleCBiZDExZmVm MjEzOWYuLjY0YmFjZjRmMDY4YyAxMDA2NDQKLS0tIGEvbmV0L21hYzgwMjExL3N0YV9pbmZvLmMK KysrIGIvbmV0L21hYzgwMjExL3N0YV9pbmZvLmMKQEAgLTM5Niw2ICszOTYsOSBAQCBzdHJ1Y3Qg c3RhX2luZm8gKnN0YV9pbmZvX2FsbG9jKHN0cnVjdCBpZWVlODAyMTFfc3ViX2lmX2RhdGEgKnNk YXRhLAogCQlza2JfcXVldWVfaGVhZF9pbml0KCZzdGEtPnBzX3R4X2J1ZltpXSk7CiAJCXNrYl9x dWV1ZV9oZWFkX2luaXQoJnN0YS0+dHhfZmlsdGVyZWRbaV0pOwogCQlzdGEtPmFpcnRpbWVbaV0u ZGVmaWNpdCA9IHN0YS0+YWlydGltZV93ZWlnaHQ7CisJCXN0YS0+YWlydGltZVtpXS5hcWxfdHhf cGVuZGluZyA9IDA7CisJCXN0YS0+YWlydGltZVtpXS5hcWxfbGltaXRfbG93ID0gbG9jYWwtPmFx bF90eHFfbGltaXRfbG93W2ldOworCQlzdGEtPmFpcnRpbWVbaV0uYXFsX2xpbWl0X2hpZ2ggPSBs b2NhbC0+YXFsX3R4cV9saW1pdF9oaWdoW2ldOwogCX0KIAogCWZvciAoaSA9IDA7IGkgPCBJRUVF ODAyMTFfTlVNX1RJRFM7IGkrKykKQEAgLTE4OTMsNiArMTg5NiwzNSBAQCB2b2lkIGllZWU4MDIx MV9zdGFfcmVnaXN0ZXJfYWlydGltZShzdHJ1Y3QgaWVlZTgwMjExX3N0YSAqcHVic3RhLCB1OCB0 aWQsCiB9CiBFWFBPUlRfU1lNQk9MKGllZWU4MDIxMV9zdGFfcmVnaXN0ZXJfYWlydGltZSk7CiAK K3ZvaWQgaWVlZTgwMjExX3N0YV91cGRhdGVfcGVuZGluZ19haXJ0aW1lKHN0cnVjdCBpZWVlODAy MTFfbG9jYWwgKmxvY2FsLAorCQkJCQkgIHN0cnVjdCBzdGFfaW5mbyAqc3RhLCB1OCBhYywKKwkJ CQkJICB1MTYgdHhfYWlydGltZSwgYm9vbCB0eF9jb21wbGV0ZWQpCit7CisJc3Bpbl9sb2NrX2Jo KCZsb2NhbC0+YWN0aXZlX3R4cV9sb2NrW2FjXSk7CisJaWYgKHR4X2NvbXBsZXRlZCkgeworCQlp ZiAoc3RhKSB7CisJCQlpZiAoV0FSTl9PTkNFKHN0YS0+YWlydGltZVthY10uYXFsX3R4X3BlbmRp bmcgPCB0eF9haXJ0aW1lLAorCQkJCSAgICAgICJUWFEgcGVuZGluZyBhaXJ0aW1lIHVuZGVyZmxv dzogJXUsICV1IiwKKwkJCQkgICAgICBzdGEtPmFpcnRpbWVbYWNdLmFxbF90eF9wZW5kaW5nLCB0 eF9haXJ0aW1lKSkKKwkJCQlzdGEtPmFpcnRpbWVbYWNdLmFxbF90eF9wZW5kaW5nID0gMDsKKwkJ CWVsc2UKKwkJCQlzdGEtPmFpcnRpbWVbYWNdLmFxbF90eF9wZW5kaW5nIC09IHR4X2FpcnRpbWU7 CisJCX0KKworCQlpZiAoV0FSTl9PTkNFKGxvY2FsLT5hcWxfdG90YWxfcGVuZGluZ19haXJ0aW1l IDwgdHhfYWlydGltZSwKKwkJCSAgICAgICJEZXZpY2UgcGVuZGluZyBhaXJ0aW1lIHVuZGVyZmxv dzogJXUsICV1IiwKKwkJCSAgICAgIGxvY2FsLT5hcWxfdG90YWxfcGVuZGluZ19haXJ0aW1lLCB0 eF9haXJ0aW1lKSkKKwkJCWxvY2FsLT5hcWxfdG90YWxfcGVuZGluZ19haXJ0aW1lID0gMDsKKwkJ ZWxzZQorCQkJbG9jYWwtPmFxbF90b3RhbF9wZW5kaW5nX2FpcnRpbWUgLT0gdHhfYWlydGltZTsK Kwl9IGVsc2UgeworCQlpZiAoc3RhKQorCQkJc3RhLT5haXJ0aW1lW2FjXS5hcWxfdHhfcGVuZGlu ZyArPSB0eF9haXJ0aW1lOworCQlsb2NhbC0+YXFsX3RvdGFsX3BlbmRpbmdfYWlydGltZSArPSB0 eF9haXJ0aW1lOworCX0KKwlzcGluX3VubG9ja19iaCgmbG9jYWwtPmFjdGl2ZV90eHFfbG9ja1th Y10pOworfQorCiBpbnQgc3RhX2luZm9fbW92ZV9zdGF0ZShzdHJ1Y3Qgc3RhX2luZm8gKnN0YSwK IAkJCWVudW0gaWVlZTgwMjExX3N0YV9zdGF0ZSBuZXdfc3RhdGUpCiB7CmRpZmYgLS1naXQgYS9u ZXQvbWFjODAyMTEvc3RhX2luZm8uaCBiL25ldC9tYWM4MDIxMS9zdGFfaW5mby5oCmluZGV4IDM2 OWMyZGRkY2U1Mi4uNGU0ZDc2ZTgxYjBmIDEwMDY0NAotLS0gYS9uZXQvbWFjODAyMTEvc3RhX2lu Zm8uaAorKysgYi9uZXQvbWFjODAyMTEvc3RhX2luZm8uaApAQCAtMTI3LDEzICsxMjcsMjEgQEAg ZW51bSBpZWVlODAyMTFfYWdnX3N0b3BfcmVhc29uIHsKIC8qIERlYnVnZnMgZmxhZ3MgdG8gZW5h YmxlL2Rpc2FibGUgdXNlIG9mIFJYL1RYIGFpcnRpbWUgaW4gc2NoZWR1bGVyICovCiAjZGVmaW5l IEFJUlRJTUVfVVNFX1RYCQlCSVQoMCkKICNkZWZpbmUgQUlSVElNRV9VU0VfUlgJCUJJVCgxKQor I2RlZmluZSBBSVJUSU1FX1VTRV9BUUwJCUJJVCgyKQogCiBzdHJ1Y3QgYWlydGltZV9pbmZvIHsK IAl1NjQgcnhfYWlydGltZTsKIAl1NjQgdHhfYWlydGltZTsKIAlzNjQgZGVmaWNpdDsKKwl1MzIg YXFsX3R4X3BlbmRpbmc7IC8qIEVzdGltYXRlZCBhaXJ0aW1lIGZvciBmcmFtZXMgcGVuZGluZyBp biBxdWV1ZSAqLworCXUzMiBhcWxfbGltaXRfbG93OworCXUzMiBhcWxfbGltaXRfaGlnaDsKIH07 CiAKK3ZvaWQgaWVlZTgwMjExX3N0YV91cGRhdGVfcGVuZGluZ19haXJ0aW1lKHN0cnVjdCBpZWVl ODAyMTFfbG9jYWwgKmxvY2FsLAorCQkJCQkgIHN0cnVjdCBzdGFfaW5mbyAqc3RhLCB1OCBhYywK KwkJCQkJICB1MTYgdHhfYWlydGltZSwgYm9vbCB0eF9jb21wbGV0ZWQpOworCiBzdHJ1Y3Qgc3Rh X2luZm87CiAKIC8qKgpkaWZmIC0tZ2l0IGEvbmV0L21hYzgwMjExL3R4LmMgYi9uZXQvbWFjODAy MTEvdHguYwppbmRleCBhMTZjMmY4NjM3MDIuLjEyNjUzZDg3M2I4YyAxMDA2NDQKLS0tIGEvbmV0 L21hYzgwMjExL3R4LmMKKysrIGIvbmV0L21hYzgwMjExL3R4LmMKQEAgLTM2NjUsNyArMzY2NSw4 IEBAIHN0cnVjdCBpZWVlODAyMTFfdHhxICppZWVlODAyMTFfbmV4dF90eHEoc3RydWN0IGllZWU4 MDIxMV9odyAqaHcsIHU4IGFjKQogewogCXN0cnVjdCBpZWVlODAyMTFfbG9jYWwgKmxvY2FsID0g aHdfdG9fbG9jYWwoaHcpOwogCXN0cnVjdCBpZWVlODAyMTFfdHhxICpyZXQgPSBOVUxMOwotCXN0 cnVjdCB0eHFfaW5mbyAqdHhxaSA9IE5VTEw7CisJc3RydWN0IHR4cV9pbmZvICp0eHFpID0gTlVM TCwgKmhlYWQgPSBOVUxMOworCWJvb2wgZm91bmRfZWxpZ2libGVfdHhxID0gZmFsc2U7CiAKIAlz cGluX2xvY2tfYmgoJmxvY2FsLT5hY3RpdmVfdHhxX2xvY2tbYWNdKTsKIApAQCAtMzY3NiwxMyAr MzY3NywyNiBAQCBzdHJ1Y3QgaWVlZTgwMjExX3R4cSAqaWVlZTgwMjExX25leHRfdHhxKHN0cnVj dCBpZWVlODAyMTFfaHcgKmh3LCB1OCBhYykKIAlpZiAoIXR4cWkpCiAJCWdvdG8gb3V0OwogCisJ aWYgKHR4cWkgPT0gaGVhZCAmJiAhZm91bmRfZWxpZ2libGVfdHhxKQorCQlnb3RvIG91dDsKKwor CWlmICghaGVhZCkKKwkJaGVhZCA9IHR4cWk7CisKIAlpZiAodHhxaS0+dHhxLnN0YSkgewogCQlz dHJ1Y3Qgc3RhX2luZm8gKnN0YSA9IGNvbnRhaW5lcl9vZih0eHFpLT50eHEuc3RhLAotCQkJCQkJ c3RydWN0IHN0YV9pbmZvLCBzdGEpOworCQkJCQkJICAgIHN0cnVjdCBzdGFfaW5mbywgc3RhKTsK KwkJYm9vbCBhcWxfY2hlY2sgPSBpZWVlODAyMTFfdHhxX2FpcnRpbWVfY2hlY2soaHcsICZ0eHFp LT50eHEpOworCQlzNjQgZGVmaWNpdCA9IHN0YS0+YWlydGltZVt0eHFpLT50eHEuYWNdLmRlZmlj aXQ7CisKKwkJaWYgKGFxbF9jaGVjaykKKwkJCWZvdW5kX2VsaWdpYmxlX3R4cSA9IHRydWU7CiAK LQkJaWYgKHN0YS0+YWlydGltZVt0eHFpLT50eHEuYWNdLmRlZmljaXQgPCAwKSB7CisJCWlmIChk ZWZpY2l0IDwgMCkKIAkJCXN0YS0+YWlydGltZVt0eHFpLT50eHEuYWNdLmRlZmljaXQgKz0KIAkJ CQlzdGEtPmFpcnRpbWVfd2VpZ2h0OworCisJCWlmIChkZWZpY2l0IDwgMCB8fCAhYXFsX2NoZWNr KSB7CiAJCQlsaXN0X21vdmVfdGFpbCgmdHhxaS0+c2NoZWR1bGVfb3JkZXIsCiAJCQkJICAgICAg ICZsb2NhbC0+YWN0aXZlX3R4cXNbdHhxaS0+dHhxLmFjXSk7CiAJCQlnb3RvIGJlZ2luOwpAQCAt MzczNiw2ICszNzUwLDMyIEBAIHZvaWQgX19pZWVlODAyMTFfc2NoZWR1bGVfdHhxKHN0cnVjdCBp ZWVlODAyMTFfaHcgKmh3LAogfQogRVhQT1JUX1NZTUJPTChfX2llZWU4MDIxMV9zY2hlZHVsZV90 eHEpOwogCitib29sIGllZWU4MDIxMV90eHFfYWlydGltZV9jaGVjayhzdHJ1Y3QgaWVlZTgwMjEx X2h3ICpodywKKwkJCQkgc3RydWN0IGllZWU4MDIxMV90eHEgKnR4cSkKK3sKKwlzdHJ1Y3Qgc3Rh X2luZm8gKnN0YTsKKwlzdHJ1Y3QgaWVlZTgwMjExX2xvY2FsICpsb2NhbCA9IGh3X3RvX2xvY2Fs KGh3KTsKKworCWlmICghKGxvY2FsLT5haXJ0aW1lX2ZsYWdzICYgQUlSVElNRV9VU0VfQVFMKSkK KwkJcmV0dXJuIHRydWU7CisKKwlpZiAoIXR4cS0+c3RhKQorCQlyZXR1cm4gdHJ1ZTsKKworCXN0 YSA9IGNvbnRhaW5lcl9vZih0eHEtPnN0YSwgc3RydWN0IHN0YV9pbmZvLCBzdGEpOworCWlmIChz dGEtPmFpcnRpbWVbdHhxLT5hY10uYXFsX3R4X3BlbmRpbmcgPAorCSAgICBzdGEtPmFpcnRpbWVb dHhxLT5hY10uYXFsX2xpbWl0X2xvdykKKwkJcmV0dXJuIHRydWU7CisKKwlpZiAobG9jYWwtPmFx bF90b3RhbF9wZW5kaW5nX2FpcnRpbWUgPCBsb2NhbC0+YXFsX3RocmVzaG9sZCAmJgorCSAgICBz dGEtPmFpcnRpbWVbdHhxLT5hY10uYXFsX3R4X3BlbmRpbmcgPAorCSAgICBzdGEtPmFpcnRpbWVb dHhxLT5hY10uYXFsX2xpbWl0X2hpZ2gpCisJCXJldHVybiB0cnVlOworCisJcmV0dXJuIGZhbHNl OworfQorRVhQT1JUX1NZTUJPTChpZWVlODAyMTFfdHhxX2FpcnRpbWVfY2hlY2spOworCiBib29s IGllZWU4MDIxMV90eHFfbWF5X3RyYW5zbWl0KHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LAogCQkJ CXN0cnVjdCBpZWVlODAyMTFfdHhxICp0eHEpCiB7CgoKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KYXRoMTBrIG1haWxpbmcgbGlzdAphdGgxMGtAbGlzdHMu aW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZv L2F0aDEwawo=