Received: by 2002:a05:6602:18e:0:0:0:0 with SMTP id m14csp2440559ioo; Sat, 28 May 2022 13:47:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyYWqeYVLzy6a2Oh5qlrLF1r7ZuAv5fd/gVJuy1yibKvqircj+Frv0oRGxiWx00lqbIFRdY X-Received: by 2002:a17:902:db12:b0:160:df9e:99fa with SMTP id m18-20020a170902db1200b00160df9e99famr15180289plx.108.1653770841175; Sat, 28 May 2022 13:47:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1653770841; cv=none; d=google.com; s=arc-20160816; b=y7TuUgNqXqj0m0zIWPJBIuMvnLPUVcWUJLf5eOFYUkFDUWSoHPUR+5SaGZ59MVhfjR GN6laRnq35qh4Wt21uSxu7ZyhZVhzm5M6jvUN8yP0xjwmh+YE6iN9Ti4Etv7tyUqrdKE 1a4VUmtLMRP57OOc2t8ouzfBfFF7ChPZkF2iOOv52m1dmCIQwiu69Fe5+Gy+DaKJ744x sUy+raUylBTYPdsW445VTOV8tz3/ep3XclRwM5lTb1rgLOPDkGdDs+L+eril9RGm0JHe 759zmuHRrwppeZkaWbQme+vKsog2lypG1v7tNw1f//q0/OI4Xbw96qdAGN3+orXMglCt /B2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=pRb8ZqgqF8AvvI7Ut4kAtfhG3/ph6FAi+ZwaBJ7f/iU=; b=Bz826na2Zj/wfNW4o7b50Y0cMPIuOepL6SlTtTtIFBRw/wHqrhGVPF3ZU0tnwKHcHt DvPoJVh0MM9ge250iAdxvomwoXUz3hM4vq/1FDTBgK1krWfHJzu1uyPDRz+cyvWq/yhi rJ3XB7jnZW32Y55IgatWkBrzJ6APj/CS8Eb8Um128m2DvTbbQU/VtXDRs+JXUxMywLb+ ssu5WXCsLByjunmyAxMBLc7K0UkvwHi7j53izz5GPF/rwbrT5kwl1qgtZ6YgylAvTRXs KyT3SnIFhUrsLnel4rS/2e2j8t/ta+Zjyvf2e62X0kmdvOHo/KJgz1hatIuJGz/5v5uU Xm6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@nbd.name header.s=20160729 header.b=PP55yxdj; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id l6-20020a17090a598600b001e2d9da0658si297094pji.146.2022.05.28.13.47.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 May 2022 13:47:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=fail header.i=@nbd.name header.s=20160729 header.b=PP55yxdj; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id EB2BF17EF4D; Sat, 28 May 2022 12:48:40 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229752AbiE1TI0 (ORCPT + 67 others); Sat, 28 May 2022 15:08:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229506AbiE1TIX (ORCPT ); Sat, 28 May 2022 15:08:23 -0400 Received: from nbd.name (nbd.name [IPv6:2a01:4f8:221:3d45::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7095366CA6 for ; Sat, 28 May 2022 12:08:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject :Cc:To:From:Sender:Reply-To:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=pRb8ZqgqF8AvvI7Ut4kAtfhG3/ph6FAi+ZwaBJ7f/iU=; b=PP55yxdjhspQmevAEXrnmaD4as vqbRpcp4J0UZQEInBIrItZMrs7lvjYCrWEWqjSDYWywxF7qTiX6xEaGmqd4l1Xg4+sd8wZQ2dveMa 1hppZrp2Y9j62qr37eSrl7zOj+A1TY3AEMRthSHlc6tKwcr62YFBeMTc+gCBo2PPjkN0=; Received: from p200300daa70ef20028a6398bc2612af0.dip0.t-ipconnect.de ([2003:da:a70e:f200:28a6:398b:c261:2af0] helo=Maecks.lan) by ds12 with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1nv1n7-0000FH-6e; Sat, 28 May 2022 21:08:01 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Subject: [RFC/RFT 1/2] mac80211: fix overflow issues in airtime fairness code Date: Sat, 28 May 2022 21:07:55 +0200 Message-Id: <20220528190756.31029-1-nbd@nbd.name> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RDNS_NONE, SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The airtime weight calculation overflows with a default weight value of 256 whenever more than 8ms worth of airtime is reported. Bigger weight values impose even smaller limits on maximum airtime values. This can mess up airtime based calculations for drivers that don't report per-PPDU airtime values, but batch up values instead. Fix this by reordering multiplications/shifts and by reducing unnecessary intermediate precision (which was lost in a later stage anyway). The new shift value limits the maximum weight to 4096, which should be more than enough. Any values bigger than that will be clamped to the upper limit. Signed-off-by: Felix Fietkau --- net/mac80211/ieee80211_i.h | 42 ++++++++++++-------------------------- net/mac80211/sta_info.c | 11 ++++------ 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 86ef0a46a68c..5ca4c2c6aa3c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1677,50 +1677,34 @@ static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq) /* To avoid divisions in the fast path, we keep pre-computed reciprocals for * airtime weight calculations. There are two different weights to keep track * of: The per-station weight and the sum of weights per phy. - * - * For the per-station weights (kept in airtime_info below), we use 32-bit - * reciprocals with a devisor of 2^19. This lets us keep the multiplications and - * divisions for the station weights as 32-bit operations at the cost of a bit - * of rounding error for high weights; but the choice of divisor keeps rounding - * errors <10% for weights <2^15, assuming no more than 8ms of airtime is - * reported at a time. - * - * For the per-phy sum of weights the values can get higher, so we use 64-bit - * operations for those with a 32-bit divisor, which should avoid any - * significant rounding errors. + * The per-sta shift value supports weight values of 1-4096 */ -#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL -#define IEEE80211_RECIPROCAL_SHIFT_64 32 -#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U -#define IEEE80211_RECIPROCAL_SHIFT_32 19 +#define IEEE80211_RECIPROCAL_SHIFT_SUM 24 +#define IEEE80211_RECIPROCAL_SHIFT_STA 12 +#define IEEE80211_WEIGHT_SHIFT 8 -static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight) +static inline void airtime_weight_set(struct airtime_info *air_info, u32 weight) { + weight = min_t(u32, weight, BIT(IEEE80211_RECIPROCAL_SHIFT_STA)); if (air_info->weight == weight) return; air_info->weight = weight; - if (weight) { - air_info->weight_reciprocal = - IEEE80211_RECIPROCAL_DIVISOR_32 / weight; - } else { - air_info->weight_reciprocal = 0; - } + if (weight) + weight = BIT(IEEE80211_RECIPROCAL_SHIFT_STA) / weight; + air_info->weight_reciprocal = weight; } static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched, - int weight_sum) + u32 weight_sum) { if (air_sched->weight_sum == weight_sum) return; air_sched->weight_sum = weight_sum; - if (air_sched->weight_sum) { - air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64; - do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum); - } else { - air_sched->weight_sum_reciprocal = 0; - } + if (weight_sum) + weight_sum = BIT(IEEE80211_RECIPROCAL_SHIFT_SUM) / weight_sum; + air_sched->weight_sum_reciprocal = weight_sum; } /* A problem when trying to enforce airtime fairness is that we want to divide diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index e04a0905e941..b843b0ac6360 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1919,9 +1919,6 @@ void ieee80211_register_airtime(struct ieee80211_txq *txq, if (local->airtime_flags & AIRTIME_USE_RX) airtime += rx_airtime; - /* Weights scale so the unit weight is 256 */ - airtime <<= 8; - spin_lock_bh(&air_sched->lock); air_info->tx_airtime += tx_airtime; @@ -1936,10 +1933,10 @@ void ieee80211_register_airtime(struct ieee80211_txq *txq, } /* Round the calculation of global vt */ - air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) * - weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64; - air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) * - air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32; + air_sched->v_t += ((u64)airtime * weight_sum_reciprocal) >> + (IEEE80211_RECIPROCAL_SHIFT_SUM - IEEE80211_WEIGHT_SHIFT); + air_info->v_t += (airtime * air_info->weight_reciprocal) >> + (IEEE80211_RECIPROCAL_SHIFT_STA - IEEE80211_WEIGHT_SHIFT); ieee80211_resort_txq(&local->hw, txq); spin_unlock_bh(&air_sched->lock); -- 2.36.1