From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=185.203.200.13 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792578485; b=m1HbcWbjYE3vELZx27SPvTk0QtBSNNpmMdnUcPuXewHWfiY/nuZR+O9kwGiJJaxzsOe5 ER14OZWne9H4iI38w1g5X8UHJuAwgFL+o6NRnh9Q6WP2uX+jqqPN9/3Cv96ncFNmGUyqA xctXBSBhggT9JSB6wS/F2ARepG+NBN71SdnOj5GyTHT4qh4OefK1CdNfPidnnpy88ggcu Okl3iQIozEZE7jRb2isOjjtnOIeOc67C5zCKlWmzJHpGX8UTG1RC0OF5T7latsth3Q2Sp YEemnpmy7k3DkW3b60LVQH4VtZShv0OWtimZOjDKXtQ0fXtNUpiv1HiSUhvEUPg5uCg== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792578485; h=DMARC-Filter:Received:DKIM-Signature:Received:Received:From:To:Cc: Subject:Date:Message-ID:X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=hJUTVHoadBGvzH+rQjnuezS2fRQEQHVqgM4qIFKm3wk=; b=YAviXhK+AcFBNRnBBAEmEc6ZnMHk6qQmHiOK29sFpmoGfNmMr1XJ4UJ/rpQo0/zkX/ab aJSbY/vkLqAyMktdUw03rqrpe0+qbvUATAjzdb6CI3r39tHRIJUUrTGin7oYIDFjvrIC1 IJM5TyBLwnkaVz1d5bZpXGDBPmNARcveH5XrJc0mTvsGaAaeaz62AZOZmf4l+ZNdiQS4e cyOicsRAKTlHVTApRWly5roHazM62akR4UXnpc3N7N4yDzex/mHL2ePER4ydVxMptural M3CUbJPlQScNrlvZJrhOAE6zMhk1mpcdSPhs2GH39E9VbL2PjITSByMvWuX/bBZ51iA== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; dkim=pass header.d=pengutronix.de header.i=@pengutronix.de header.a=rsa-sha256 header.s=20260414 header.b="WA+C/3N4"; arc=pass header.oldest-pass=0 smtp.remote-ip=185.203.200.13 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CB1A606A32C; Wed, 21 Oct 2026 10:28:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 1CB1A606A32C Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=pengutronix.de header.i=@pengutronix.de header.a=rsa-sha256 header.s=20260414 header.b=WA+C/3N4 Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 89BA5202922; Wed, 21 Oct 2026 12:27:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pengutronix.de; s=20260414; t=1792578479; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hJUTVHoadBGvzH+rQjnuezS2fRQEQHVqgM4qIFKm3wk=; b=WA+C/3N4WGEjJByn15NCjm0um2vX1YAegJ7FMXn+wjQ+56IZE1fpN+0lxtZretbdDJm9qh +2MYoG9SMO92nCKemuvm+LQxJuVnVF1HMOiqi2p1oDCuQt0cESug1yBRf8UbsDKym0tGPB WREe+52BGPHzOYbgp0/ayRzCEZrd4U7tYSA4RqlEQTFQUCLEkBc5iU/qpOOdT3iG8L4TBn UcoEsqrA2JgqUmq1C0LHWuK0sRAZI2KjyK85bZ9UUE5pA+fmqI1+vnuC8+dqs6w0dBQEEZ n590ox6Pae7LWdGKjM6gVnXuGybAkK/Fxl0p3pVIf9ikYiEMeMs9D6NBVH8oww== ARC-Seal: i=1; s=20260414; d=pengutronix.de; t=1792578479; a=rsa-sha256; cv=none; b=eUJGXwPh+pvo9hcyyzMYbgtH9rKKSyWaejvFMkubmvUGBNf2W8io1Zh6bH9oSmFYc7ulS/ B5F3GKrGNdv7qktcSmJo74z099XTuC/0a9niDV28PPQnpO3GUc3ygjOEEkaKqtGrlcHXA9 IWKWHQSFuCzR9w5ajuhI0BrNlqWxOdIPkNEDqEaCBqEiq7vj7BrVkbOWvCoTUkmHFPxHzp u8CBqk8FmkHKMSC9qBW95WpxBFvmMl0SIxWRDmUMDFdSUCY1NDv0Fm2qgvOZEJBUihQDUm slLWYz3lHXM9lMpxrYE8MD22qNoLuv5BI+EPLpJO3UbkwcRQHj3c97WCNRZ5cQ== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=relay-from-drehscheibe.grey.stw.pengutronix.de smtp.mailfrom=mkl@pengutronix.de ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=pengutronix.de; s=20260414; t=1792578479; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hJUTVHoadBGvzH+rQjnuezS2fRQEQHVqgM4qIFKm3wk=; b=YKM2z3DxEAh59uGDp4rEELqPQKO+4gOvreo2El0DtCcsEdDJAL7oAfh8qDNeaICW/cY0uw Vix1FmZFLgvwQOa6d7ghVWJwuFruv0UcCqkz5NRmSSbx4LCamUgvPicsVGYKpNTGiE69iK 1wycMIBSTqZi75LKQtYxCqmSlZbDVLb/FbjDKx/Qtz1PxTvBg3FxJ0g+YEqWJJgE2yh1Zs 2A3bkcy9H8OvTxi+4grIZM9bb2zzJyd4VfzFjAYlUlRGpU2aYNvCCy/NF8XQkun99u0s+y SPQTsejWlVOPM3uvm1hdqmn/dOWrfJqXFibQxAEU6b4BJuqyubey5UPHC4N02A== Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1xJTY7-000Xjp-1R; Wed, 21 Oct 2026 12:27:59 +0200 Received: from blackshift.org (p4ffb23c7.dip0.t-ipconnect.de [79.251.35.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519MLKEM768 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 320205CAFDD; Wed, 21 Oct 2026 10:27:59 +0000 (UTC) From: Marc Kleine-Budde To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, linux-can@vger.kernel.org, kernel@pengutronix.de, Runyu Xiao , stable@vger.kernel.org, Oliver Hartkopp , Marc Kleine-Budde Subject: [PATCH net-next 06/11] can: proc: reset pkg_stats atomics individually Date: Wed, 21 Oct 2026 12:24:37 +0200 Message-ID: <20261021102756.1900679-7-mkl@pengutronix.de> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261021102756.1900679-1-mkl@pengutronix.de> References: <20261021102756.1900679-1-mkl@pengutronix.de> X-Mailing-List: netdev@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Runyu Xiao Commit 80b5f90158d1 ("can: statistics: use atomic access in hot path") converted several members of struct can_pkg_stats to atomic_long_t and updated the hot TX/RX and procfs read paths to use atomic_long_*() helpers. However, can_init_stats() still clears the whole struct with memset(). can_init_stats() is reached from can_stat_update() in timer context and also from the procfs reset path. Those paths can run while the TX/RX hot paths are concurrently updating rx_frames, tx_frames, matches and their *_delta counters. Hitting the whole-struct memset() in that window performs plain writes to fields that otherwise follow an atomic_long_t access contract, which can lose or mix live statistics updates. This issue was found by source-level API-misuse analysis looking for whole-object resets left behind after atomic_long_t conversions, then manually audited on Linux v6.18.21. Replace the whole-struct memset() with a helper that resets the atomic_long_t counters via atomic_long_set() and clears the derived scalar statistics explicitly. This preserves the existing reset semantics for scalar fields while restoring atomic access discipline for the live counters. Build-tested by compiling net/can/proc.o on x86_64 netdev/main. Runtime-tested with a QEMU + vcan setup on Linux v6.18.21 by driving concurrent traffic and reset_stats reads, which reproduced inconsistent exported statistics before the fix. [Hartkopp] can_stat_update() also read the *_delta counters at the beginning and cleared them with atomic_long_set() at the end. Increments from the hot path in between were lost for both the current and the next interval. Use atomic_long_xchg() to fetch and clear the *_delta counters in one atomic step instead. Fixes: 80b5f90158d1 ("can: statistics: use atomic access in hot path") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao Acked-by: Oliver Hartkopp Signed-off-by: Oliver Hartkopp Link: https://patch.msgid.link/20261020203257.230955-2-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde --- net/can/proc.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/net/can/proc.c b/net/can/proc.c index de4d05ae3459..70104f13077e 100644 --- a/net/can/proc.c +++ b/net/can/proc.c @@ -76,16 +76,39 @@ static const char rx_list_name[][8] = { * af_can statistics stuff */ +static void can_reset_pkg_stats(struct can_pkg_stats *pkg_stats) +{ + atomic_long_set(&pkg_stats->rx_frames, 0); + atomic_long_set(&pkg_stats->tx_frames, 0); + atomic_long_set(&pkg_stats->matches, 0); + + pkg_stats->total_rx_rate = 0; + pkg_stats->total_tx_rate = 0; + pkg_stats->total_rx_match_ratio = 0; + + pkg_stats->current_rx_rate = 0; + pkg_stats->current_tx_rate = 0; + pkg_stats->current_rx_match_ratio = 0; + + pkg_stats->max_rx_rate = 0; + pkg_stats->max_tx_rate = 0; + pkg_stats->max_rx_match_ratio = 0; + + atomic_long_set(&pkg_stats->rx_frames_delta, 0); + atomic_long_set(&pkg_stats->tx_frames_delta, 0); + atomic_long_set(&pkg_stats->matches_delta, 0); +} + static void can_init_stats(struct net *net) { struct can_pkg_stats *pkg_stats = net->can.pkg_stats; struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats; /* - * This memset function is called from a timer context (when + * This stats reset is called from a timer context (when * can_stattimer is active which is the default) OR in a process * context (reading the proc_fs when can_stattimer is disabled). */ - memset(pkg_stats, 0, sizeof(struct can_pkg_stats)); + can_reset_pkg_stats(pkg_stats); pkg_stats->jiffies_init = jiffies; rcv_lists_stats->stats_reset++; @@ -121,9 +144,10 @@ void can_stat_update(struct timer_list *t) long rx_frames = atomic_long_read(&pkg_stats->rx_frames); long tx_frames = atomic_long_read(&pkg_stats->tx_frames); long matches = atomic_long_read(&pkg_stats->matches); - long rx_frames_delta = atomic_long_read(&pkg_stats->rx_frames_delta); - long tx_frames_delta = atomic_long_read(&pkg_stats->tx_frames_delta); - long matches_delta = atomic_long_read(&pkg_stats->matches_delta); + /* fetch and clear values for 'current rate' calculation */ + long rx_frames_delta = atomic_long_xchg(&pkg_stats->rx_frames_delta, 0); + long tx_frames_delta = atomic_long_xchg(&pkg_stats->tx_frames_delta, 0); + long matches_delta = atomic_long_xchg(&pkg_stats->matches_delta, 0); /* restart counting in timer context on user request */ if (user_reset) @@ -172,11 +196,6 @@ void can_stat_update(struct timer_list *t) if (pkg_stats->max_rx_match_ratio < pkg_stats->current_rx_match_ratio) pkg_stats->max_rx_match_ratio = pkg_stats->current_rx_match_ratio; - /* clear values for 'current rate' calculation */ - atomic_long_set(&pkg_stats->tx_frames_delta, 0); - atomic_long_set(&pkg_stats->rx_frames_delta, 0); - atomic_long_set(&pkg_stats->matches_delta, 0); - /* restart timer (one second) */ mod_timer(&net->can.stattimer, round_jiffies(jiffies + HZ)); } -- 2.53.0