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 Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 93732CFD2F6 for ; Thu, 27 Nov 2025 07:31:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 51BA860B25; Thu, 27 Nov 2025 07:31:36 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id hR3ZjOI0SIDM; Thu, 27 Nov 2025 07:31:35 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 6FB9D60B30 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osuosl.org; s=default; t=1764228695; bh=RpZmbBbV4+WX6j/6UGWRyRIibQb/1sSDTXf0KZhOSqo=; h=From:To:Cc:Date:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=fNo7DyDQfnKLzrSt0LtYc6RfuIEYC402pnY0hi3aUzuffE/lTvXJdZOZVx9tjmDbz BG1u5KhaRREFWprZy+X2UWFtNuFerugrvUuSUE3GmnmNBLdxb1nECVFwe3cYhtLQSZ AL1wmuNPf8HOPjz/Xt9ya4RMqke2SaV912iRSdSfST0rZj/ScOWDRlbaQCAXTcPerb B3pNi2Xzd+lAV7NdW/BcnqRkv/GR0tMLbTMptP9S82EGVOWh1Op4G71D/WnlKNiX1o /4OdETNIqHKznH/dMxkXNe7aZlLpKUyNXG4nSy7mXogXvZhNPY0iVGJbgTUEEFjZN0 fJA2S74UJMQHw== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp3.osuosl.org (Postfix) with ESMTP id 6FB9D60B30; Thu, 27 Nov 2025 07:31:35 +0000 (UTC) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists1.osuosl.org (Postfix) with ESMTP id 1D8F6DE for ; Thu, 27 Nov 2025 07:31:34 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 047CD40210 for ; Thu, 27 Nov 2025 07:31:34 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id E1tsqdE8QBZs for ; Thu, 27 Nov 2025 07:31:33 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.198.163.12; helo=mgamail.intel.com; envelope-from=chwee.lin.choong@intel.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org 843FD40065 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 843FD40065 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) by smtp2.osuosl.org (Postfix) with ESMTPS id 843FD40065 for ; Thu, 27 Nov 2025 07:31:31 +0000 (UTC) X-CSE-ConnectionGUID: 63gMNx9ASEO7w0iViJfX8g== X-CSE-MsgGUID: aBWaWrRJSyWv68xSoUdKow== X-IronPort-AV: E=McAfee;i="6800,10657,11625"; a="70133706" X-IronPort-AV: E=Sophos;i="6.20,230,1758610800"; d="scan'208";a="70133706" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Nov 2025 23:31:31 -0800 X-CSE-ConnectionGUID: H9TNPFCSSpiXQUhEiAlhAQ== X-CSE-MsgGUID: dLEH+f6zSG26Rkgtl16qQg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.20,230,1758610800"; d="scan'208";a="197487869" Received: from p2dy149cchoong.png.intel.com ([10.107.243.50]) by fmviesa005.fm.intel.com with ESMTP; 26 Nov 2025 23:31:23 -0800 From: Chwee-Lin Choong To: Tony Nguyen , Przemek Kitszel , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Richard Cochran , Vinicius Costa Gomes Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Aleksandr Loktionov , Avi Shalev , Song Yoong Siang Date: Thu, 27 Nov 2025 23:11:37 +0800 Message-ID: <20251127151137.2883-1-chwee.lin.choong@intel.com> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1764228692; x=1795764692; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=djXtYfwiJE1XkDQF2b0MRN7mvLoJ5ybRSLF+cotldH8=; b=i6nWvBUFDzV60IveVG6na4ntcY8JdD1zIvN/oi4MFAjdWFnzXpD5rdse /Z/a+axOwilMMqPCVTgov8FfPaAyH5UhfAi1RZ63UO2CynLuBCs0eB/Dm /cVkokHpq5zzPoV/vYmM5xA82I/TeStgZlixhxMHsZ87cCOTaYKG6vsRe x0VPgkpOPTNIXVrz8uma9a9VFAjaZ36Kx7egOisSsiEPY4jAkN1cMgKPd QKZZsCtTUSkUWnGpH7M1TL02XUtg8DEBzV+6x9gQRmSxiES+oDU9YjNeJ LMouTOFePUUxcXE/cnggn0YzN76Wyg+aKdyZ8MEh+4rIwnDj9/NN0N4dE g==; X-Mailman-Original-Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=intel.com X-Mailman-Original-Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=i6nWvBUF Subject: [Intel-wired-lan] [PATCH iwl-net v3] igc: fix race condition in TX timestamp read for register 0 X-BeenThere: intel-wired-lan@osuosl.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-wired-lan-bounces@osuosl.org Sender: "Intel-wired-lan" The current HW bug workaround checks the TXTT_0 ready bit first, then reads TXSTMPL_0 twice (before and after reading TXSTMPH_0) to detect whether a new timestamp was captured by timestamp register 0 during the workaround. This sequence has a race: if a new timestamp is captured after checking the TXTT_0 bit but before the first TXSTMPL_0 read, the detection fails because both the “old” and “new” values come from the same timestamp. Fix by reading TXSTMPL_0 first to establish a baseline, then checking the TXTT_0 bit. This ensures any timestamp captured during the race window will be detected. Old sequence: 1. Check TXTT_0 ready bit 2. Read TXSTMPL_0 (baseline) 3. Read TXSTMPH_0 (interrupt workaround) 4. Read TXSTMPL_0 (detect changes vs baseline) New sequence: 1. Read TXSTMPL_0 (baseline) 2. Check TXTT_0 ready bit 3. Read TXSTMPH_0 (interrupt workaround) 4. Read TXSTMPL_0 (detect changes vs baseline) Fixes: c789ad7cbebc ("igc: Work around HW bug causing missing timestamps") Suggested-by: Avi Shalev Reviewed-by: Aleksandr Loktionov Signed-off-by: Song Yoong Siang Signed-off-by: Chwee-Lin Choong --- v1: https://patchwork.ozlabs.org/project/intel-wired-lan/patch/20250918183811.31270-1-chwee.lin.choong@intel.com/ v2: https://patchwork.ozlabs.org/project/intel-wired-lan/patch/20251127134927.2133-1-chwee.lin.choong@intel.com/ changelog: v1 -> v2 - Added detailed comments explaining the hardware bug workaround and race detection mechanism v2 -> v3 - Removed extra export file added by mistake --- drivers/net/ethernet/intel/igc/igc_ptp.c | 43 ++++++++++++++---------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index b7b46d863bee..7aae83c108fd 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -774,36 +774,43 @@ static void igc_ptp_tx_reg_to_stamp(struct igc_adapter *adapter, static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) { struct igc_hw *hw = &adapter->hw; + u32 txstmpl_old; u64 regval; u32 mask; int i; + /* Establish baseline of TXSTMPL_0 before checking TXTT_0. + * This baseline is used to detect if a new timestamp arrives in + * register 0 during the hardware bug workaround below. + */ + txstmpl_old = rd32(IGC_TXSTMPL); + mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY; if (mask & IGC_TSYNCTXCTL_TXTT_0) { regval = rd32(IGC_TXSTMPL); regval |= (u64)rd32(IGC_TXSTMPH) << 32; } else { - /* There's a bug in the hardware that could cause - * missing interrupts for TX timestamping. The issue - * is that for new interrupts to be triggered, the - * IGC_TXSTMPH_0 register must be read. + /* TXTT_0 not set - register 0 has no new timestamp initially. + * + * Hardware bug: Future timestamp interrupts won't fire unless + * TXSTMPH_0 is read, even if the timestamp was captured in + * registers 1-3. * - * To avoid discarding a valid timestamp that just - * happened at the "wrong" time, we need to confirm - * that there was no timestamp captured, we do that by - * assuming that no two timestamps in sequence have - * the same nanosecond value. + * Workaround: Read TXSTMPH_0 here to enable future interrupts. + * However, this read clears TXTT_0. If a timestamp arrives in + * register 0 after checking TXTT_0 but before this read, it + * would be lost. * - * So, we read the "low" register, read the "high" - * register (to latch a new timestamp) and read the - * "low" register again, if "old" and "new" versions - * of the "low" register are different, a valid - * timestamp was captured, we can read the "high" - * register again. + * To detect this race: We saved a baseline read of TXSTMPL_0 + * before TXTT_0 check. After performing the workaround read of + * TXSTMPH_0, we read TXSTMPL_0 again. Since consecutive + * timestamps never share the same nanosecond value, a change + * between the baseline and new TXSTMPL_0 indicates a timestamp + * arrived during the race window. If so, read the complete + * timestamp. */ - u32 txstmpl_old, txstmpl_new; + u32 txstmpl_new; - txstmpl_old = rd32(IGC_TXSTMPL); rd32(IGC_TXSTMPH); txstmpl_new = rd32(IGC_TXSTMPL); @@ -818,7 +825,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) done: /* Now that the problematic first register was handled, we can - * use retrieve the timestamps from the other registers + * retrieve the timestamps from the other registers * (starting from '1') with less complications. */ for (i = 1; i < IGC_MAX_TX_TSTAMP_REGS; i++) { -- 2.43.0