From patchwork Fri Oct 13 13:59:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavan Chebbi X-Patchwork-Id: 13420931 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9C8E015E94 for ; Fri, 13 Oct 2023 13:58:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="eMJEWclI" Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B609395 for ; Fri, 13 Oct 2023 06:57:59 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1c8a1541233so16559245ad.1 for ; Fri, 13 Oct 2023 06:57:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1697205479; x=1697810279; darn=vger.kernel.org; h=mime-version:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=jsX0nrgmp+XOc5zRs9vYOic8Z/e92RdpDpf/C0GLLg0=; b=eMJEWclIiPnstADOHKKRK8YEXICqiRA14mj931FPUTAwj3thTBu7D71WrS87fXDfgs UDYaBmo7Y70sZ7LAdtswIro57yeU7LsXqEfXbM5VsneGnTHKVyNSqrXwfX81orPL31dU Qc8rYkcqts6CjZFLHSOWKFm5TAiVbaSh3N+S0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697205479; x=1697810279; h=mime-version:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=jsX0nrgmp+XOc5zRs9vYOic8Z/e92RdpDpf/C0GLLg0=; b=geIsBppyPkCEZqf5ZkV9hIOWU74DWvGEGLttU4DRa0RDePMLhIz0YY9hwPzxBJSMiz jeSNEwkt0kYAI7G2vN1vJ+mBifOo2R2WZ/QddETJbMFogAaugm2sQrAYM6ERTKKRHUAZ OTNOsgtz4R+PQ8lMndfo7BWYAlYSYqmiAbKKdYdd14S/inlbduR/j5ELBczLyv9u5EYo pTclbpJwnx6UD7z77IkwaH4+UKgi3OiWZr8FnPtzdkJrawthEZ9L+1UCJulfwVbZQF8A SNava4clqo+LgYV7EYC8qFN+GUasGd3FkHYnkxp20weAevAHIH6EyDckiKO9EHhZn8e3 dq4Q== X-Gm-Message-State: AOJu0Yx3huTZBTTM/frjnYTbMCqIJe8hhzGNhKUGOdD9huGpXcN7ByC7 jiZpe4u2nPUJvdB29DrEQQopNNUaw5sf1fO90RU= X-Google-Smtp-Source: AGHT+IHAImDP0NkoHsOj6oFauOleS9S0hCNUI1TAQ6hwuvaKwBbB7aA6t2SxAu0DlwZPhx21d8jlhw== X-Received: by 2002:a17:902:e809:b0:1c0:6e92:8cc5 with SMTP id u9-20020a170902e80900b001c06e928cc5mr25184667plg.17.1697205478931; Fri, 13 Oct 2023 06:57:58 -0700 (PDT) Received: from PC-MID-R740.dhcp.broadcom.net ([192.19.234.250]) by smtp.gmail.com with ESMTPSA id iy3-20020a170903130300b001bf11cf2e21sm3933201plb.210.2023.10.13.06.57.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Oct 2023 06:57:56 -0700 (PDT) From: Pavan Chebbi To: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org Cc: michael.chan@broadcom.com, gospo@broadcom.com, pabeni@redhat.com, edumazet@google.com, richardcochran@gmail.com, Pavan Chebbi , Simon White , Kalesh AP Subject: [PATCH net-next] tg3: Improve PTP TX timestamping logic Date: Fri, 13 Oct 2023 06:59:19 -0700 Message-Id: <20231013135919.408357-1-pavan.chebbi@broadcom.com> X-Mailer: git-send-email 2.39.1 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MIME_NO_TEXT, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org When we are trying to timestamp a TX packet, there may be occasions when the TX timestamp register is still not updated with the latest timestamp even if the timestamp packet descriptor is marked as complete. This usually happens in cases where the system is under stress or flow control is affecting the transmit side. We will solve this problem by saving the snapshot of the timestamp register when we are posting the TX descriptor. At this time, the register contains previously timestamped packet's value and valid timestamp of the current packet must be different than this. Upon completion of the current descriptor, we will check if the timestamp register is updated or not before timestamping the skb. If not updated, we will schedule the ptp worker to fetch the updated time later and timestamp the skb. Also now we restrict number of outstanding PTP TX packet requests to 1. Reported-by: Simon White Link: https://lore.kernel.org/netdev/CACKFLikGdN9XPtWk-fdrzxdcD=+bv-GHBvfVfSpJzHY7hrW39g@mail.gmail.com/ Signed-off-by: Pavan Chebbi Signed-off-by: Michael Chan Reviewed-by: Andy Gospodarek Reviewed-by: Kalesh AP --- drivers/net/ethernet/broadcom/tg3.c | 81 +++++++++++++++++++++++------ drivers/net/ethernet/broadcom/tg3.h | 3 ++ 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 14b311196b8f..59896bbf9e73 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6314,6 +6314,46 @@ static int tg3_ptp_enable(struct ptp_clock_info *ptp, return -EOPNOTSUPP; } +static void tg3_hwclock_to_timestamp(struct tg3 *tp, u64 hwclock, + struct skb_shared_hwtstamps *timestamp) +{ + memset(timestamp, 0, sizeof(struct skb_shared_hwtstamps)); + timestamp->hwtstamp = ns_to_ktime((hwclock & TG3_TSTAMP_MASK) + + tp->ptp_adjust); +} + +static void tg3_read_tx_tstamp(struct tg3 *tp, u64 *hwclock) +{ + *hwclock = tr32(TG3_TX_TSTAMP_LSB); + *hwclock |= (u64)tr32(TG3_TX_TSTAMP_MSB) << 32; +} + +static long tg3_ptp_ts_aux_work(struct ptp_clock_info *ptp) +{ + struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); + struct skb_shared_hwtstamps timestamp; + u64 hwclock; + + if (tp->ptp_txts_retrycnt > 2) + goto done; + + tg3_read_tx_tstamp(tp, &hwclock); + + if (hwclock != tp->pre_tx_ts) { + tg3_hwclock_to_timestamp(tp, hwclock, ×tamp); + skb_tstamp_tx(tp->tx_tstamp_skb, ×tamp); + goto done; + } + tp->ptp_txts_retrycnt++; + return HZ / 10; +done: + dev_consume_skb_any(tp->tx_tstamp_skb); + tp->tx_tstamp_skb = NULL; + tp->ptp_txts_retrycnt = 0; + tp->pre_tx_ts = 0; + return -1; +} + static const struct ptp_clock_info tg3_ptp_caps = { .owner = THIS_MODULE, .name = "tg3 clock", @@ -6325,19 +6365,12 @@ static const struct ptp_clock_info tg3_ptp_caps = { .pps = 0, .adjfine = tg3_ptp_adjfine, .adjtime = tg3_ptp_adjtime, + .do_aux_work = tg3_ptp_ts_aux_work, .gettimex64 = tg3_ptp_gettimex, .settime64 = tg3_ptp_settime, .enable = tg3_ptp_enable, }; -static void tg3_hwclock_to_timestamp(struct tg3 *tp, u64 hwclock, - struct skb_shared_hwtstamps *timestamp) -{ - memset(timestamp, 0, sizeof(struct skb_shared_hwtstamps)); - timestamp->hwtstamp = ns_to_ktime((hwclock & TG3_TSTAMP_MASK) + - tp->ptp_adjust); -} - /* tp->lock must be held */ static void tg3_ptp_init(struct tg3 *tp) { @@ -6368,6 +6401,8 @@ static void tg3_ptp_fini(struct tg3 *tp) ptp_clock_unregister(tp->ptp_clock); tp->ptp_clock = NULL; tp->ptp_adjust = 0; + dev_consume_skb_any(tp->tx_tstamp_skb); + tp->tx_tstamp_skb = NULL; } static inline int tg3_irq_sync(struct tg3 *tp) @@ -6538,6 +6573,7 @@ static void tg3_tx(struct tg3_napi *tnapi) while (sw_idx != hw_idx) { struct tg3_tx_ring_info *ri = &tnapi->tx_buffers[sw_idx]; + bool complete_skb_later = false; struct sk_buff *skb = ri->skb; int i, tx_bug = 0; @@ -6548,12 +6584,17 @@ static void tg3_tx(struct tg3_napi *tnapi) if (tnapi->tx_ring[sw_idx].len_flags & TXD_FLAG_HWTSTAMP) { struct skb_shared_hwtstamps timestamp; - u64 hwclock = tr32(TG3_TX_TSTAMP_LSB); - hwclock |= (u64)tr32(TG3_TX_TSTAMP_MSB) << 32; - - tg3_hwclock_to_timestamp(tp, hwclock, ×tamp); + u64 hwclock; - skb_tstamp_tx(skb, ×tamp); + tg3_read_tx_tstamp(tp, &hwclock); + if (hwclock != tp->pre_tx_ts) { + tg3_hwclock_to_timestamp(tp, hwclock, ×tamp); + skb_tstamp_tx(skb, ×tamp); + tp->pre_tx_ts = 0; + } else { + tp->tx_tstamp_skb = skb; + complete_skb_later = true; + } } dma_unmap_single(&tp->pdev->dev, dma_unmap_addr(ri, mapping), @@ -6591,7 +6632,10 @@ static void tg3_tx(struct tg3_napi *tnapi) pkts_compl++; bytes_compl += skb->len; - dev_consume_skb_any(skb); + if (!complete_skb_later) + dev_consume_skb_any(skb); + else + ptp_schedule_worker(tp->ptp_clock, 0); if (unlikely(tx_bug)) { tg3_tx_recover(tp); @@ -8028,8 +8072,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) if ((unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) && tg3_flag(tp, TX_TSTAMP_EN)) { - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - base_flags |= TXD_FLAG_HWTSTAMP; + tg3_full_lock(tp, 0); + if (!tp->pre_tx_ts) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + base_flags |= TXD_FLAG_HWTSTAMP; + tg3_read_tx_tstamp(tp, &tp->pre_tx_ts); + } + tg3_full_unlock(tp); } len = skb_headlen(skb); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 1000c894064f..ae5c01bd1110 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -3190,6 +3190,7 @@ struct tg3 { struct ptp_clock_info ptp_info; struct ptp_clock *ptp_clock; s64 ptp_adjust; + u8 ptp_txts_retrycnt; /* begin "tx thread" cacheline section */ void (*write32_tx_mbox) (struct tg3 *, u32, @@ -3372,6 +3373,8 @@ struct tg3 { struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; struct work_struct reset_task; + struct sk_buff *tx_tstamp_skb; + u64 pre_tx_ts; int nvram_lock_cnt; u32 nvram_size;