From patchwork Wed Jul 3 19:17:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guilherme G. Piccoli" X-Patchwork-Id: 1127126 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45f9qm2bM0z9s3Z; Thu, 4 Jul 2019 05:18:12 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hiklc-0005Y8-L1; Wed, 03 Jul 2019 19:18:08 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hikla-0005XY-Ea for kernel-team@lists.ubuntu.com; Wed, 03 Jul 2019 19:18:06 +0000 Received: from mail-qt1-f199.google.com ([209.85.160.199]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hikla-0002uL-0m for kernel-team@lists.ubuntu.com; Wed, 03 Jul 2019 19:18:06 +0000 Received: by mail-qt1-f199.google.com with SMTP id y19so4229683qtm.0 for ; Wed, 03 Jul 2019 12:18:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lHw4JtznQc9AmcLGuZ/h8105qVUtSzOZytlYF4yAN6g=; b=WOPuJjSXe3mkWk9nhPtsPpjKqOiCFleoshR2FXR3i1yPxEkLdohjdfcu+1W+lK3lKH QRIE0uLBXSGJkd9Yxcp43ziG/DiYHmuJ3SaZzguRU2o4jERiYpPAuT0y9DG71W8b5QJx XIOhHksYazTJo7+FiGr/gIPYve1kfZYSOO41t2XH8IGsRD5KVd+ansGL8cGAxs2MSqiG g0mQrPpZt1WM8vBjqqI+tkj7U9AtuRX5C7RZqjB+UFfxLkYjGIQd6qRcoxgbHJu8fKl6 lDyacdM7v11tYRAnKQHzaSxgZNIB7PQrEsh6HKueJZilNWHO9HNb8a1gMJPkiSXhz3NL Q4iw== X-Gm-Message-State: APjAAAWiovzFpaS+h//vMn6Lqk6epgPiR/qmwu2R/1VutaiAozzZEsnD zsi73lRUSQq+baW04BFMBgy932wOc/4oTFuMvxt0w5zRmW4ekS0/niy3IBQYqO4qWp2R4eGG6Lv ivDEOxZBjZUKY4adNoRf6hOapK50YGlzRioAoKBSI/g== X-Received: by 2002:a05:620a:12ca:: with SMTP id e10mr32902520qkl.237.1562181485194; Wed, 03 Jul 2019 12:18:05 -0700 (PDT) X-Google-Smtp-Source: APXvYqz38BdjEcrDHYbtQW/yltKsDojKkgNltxJ8tF4j7MnfvffIoJCrJrXWYjkq22QgS4VaCOUFXw== X-Received: by 2002:a05:620a:12ca:: with SMTP id e10mr32902499qkl.237.1562181484861; Wed, 03 Jul 2019 12:18:04 -0700 (PDT) Received: from localhost ([179.110.97.158]) by smtp.gmail.com with ESMTPSA id a54sm1386050qtk.85.2019.07.03.12.18.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Jul 2019 12:18:04 -0700 (PDT) From: "Guilherme G. Piccoli" To: gpiccoli@canonical.com, kernel-team@lists.ubuntu.com Subject: [SRU X][PATCH 1/1] bnx2x: Prevent ptp_task to be rescheduled indefinitely Date: Wed, 3 Jul 2019 16:17:54 -0300 Message-Id: <20190703191754.7029-3-gpiccoli@canonical.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190703191754.7029-1-gpiccoli@canonical.com> References: <20190703191754.7029-1-gpiccoli@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1832082 Currently bnx2x ptp worker tries to read a register with timestamp information in case of TX packet timestamping and in case it fails, the routine reschedules itself indefinitely. This was reported as a kworker always at 100% of CPU usage, which was narrowed down to be bnx2x ptp_task. By following the ioctl handler, we could narrow down the problem to an NTP tool (chrony) requesting HW timestamping from bnx2x NIC with RX filter zeroed; this isn't reproducible for example with ptp4l (from linuxptp) since this tool requests a supported RX filter. It seems NIC FW timestamp mechanism cannot work well with RX_FILTER_NONE - driver's PTP filter init routine skips a register write to the adapter if there's not a supported filter request. This patch addresses the problem of bnx2x ptp thread's everlasting reschedule by retrying the register read 10 times; between the read attempts the thread sleeps for an increasing amount of time starting in 1ms to give FW some time to perform the timestamping. If it still fails after all retries, we bail out in order to prevent an unbound resource consumption from bnx2x. The patch also adds an ethtool statistic for accounting the skipped TX timestamp packets and it reduces the priority of timestamping error messages to prevent log flooding. The code was tested using both linuxptp and chrony. Reported-and-tested-by: Przemyslaw Hausman Suggested-by: Sudarsana Reddy Kalluru Signed-off-by: Guilherme G. Piccoli Acked-by: Sudarsana Reddy Kalluru Signed-off-by: David S. Miller (backported from commit 3c91f25c2f72ba6001775a5932857c1d2131c531 linux-net) [gpiccoli: - context adjustment; - used old "STATS_FLAGS_FUNC" instead of bool in bnx2x_stats_arr(); - used pr_err_once() instead of netdev_err_once() due to the lack of the latter in v4.4;] Signed-off-by: Guilherme G. Piccoli --- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 ++- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 4 ++- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 33 ++++++++++++++----- .../net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 3 ++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 745702208cad..5d1796ab3403 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3916,9 +3916,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { if (!(bp->flags & TX_TIMESTAMPING_EN)) { + bp->eth_stats.ptp_skip_tx_ts++; BNX2X_ERR("Tx timestamping was not enabled, this packet will not be timestamped\n"); } else if (bp->ptp_tx_skb) { - BNX2X_ERR("The device supports only a single outstanding packet to timestamp, this packet will not be timestamped\n"); + bp->eth_stats.ptp_skip_tx_ts++; + pr_err_once("[%s] Device supports only a single outstanding packet to timestamp, this packet won't be timestamped\n", netdev_name(bp->dev)); } else { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; /* schedule check for Tx timestamp */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c56b61dce2d1..055b6bcca703 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -184,7 +184,9 @@ static const struct { { STATS_OFFSET32(driver_filtered_tx_pkt), 4, STATS_FLAGS_FUNC, "driver_filtered_tx_pkt" }, { STATS_OFFSET32(eee_tx_lpi), - 4, STATS_FLAGS_PORT, "Tx LPI entry count"} + 4, STATS_FLAGS_PORT, "Tx LPI entry count"}, + { STATS_OFFSET32(ptp_skip_tx_ts), + 4, STATS_FLAGS_FUNC, "ptp_skipped_tx_tstamp" }, }; #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c8130fef5230..91610f0e1328 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -15100,11 +15100,24 @@ static void bnx2x_ptp_task(struct work_struct *work) u32 val_seq; u64 timestamp, ns; struct skb_shared_hwtstamps shhwtstamps; + bool bail = true; + int i; - /* Read Tx timestamp registers */ - val_seq = REG_RD(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_SEQID : - NIG_REG_P0_TLLH_PTP_BUF_SEQID); - if (val_seq & 0x10000) { + /* FW may take a while to complete timestamping; try a bit and if it's + * still not complete, may indicate an error state - bail out then. + */ + for (i = 0; i < 10; i++) { + /* Read Tx timestamp registers */ + val_seq = REG_RD(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_SEQID : + NIG_REG_P0_TLLH_PTP_BUF_SEQID); + if (val_seq & 0x10000) { + bail = false; + break; + } + msleep(1 << i); + } + + if (!bail) { /* There is a valid timestamp value */ timestamp = REG_RD(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_TS_MSB : NIG_REG_P0_TLLH_PTP_BUF_TS_MSB); @@ -15119,16 +15132,18 @@ static void bnx2x_ptp_task(struct work_struct *work) memset(&shhwtstamps, 0, sizeof(shhwtstamps)); shhwtstamps.hwtstamp = ns_to_ktime(ns); skb_tstamp_tx(bp->ptp_tx_skb, &shhwtstamps); - dev_kfree_skb_any(bp->ptp_tx_skb); - bp->ptp_tx_skb = NULL; DP(BNX2X_MSG_PTP, "Tx timestamp, timestamp cycles = %llu, ns = %llu\n", timestamp, ns); } else { - DP(BNX2X_MSG_PTP, "There is no valid Tx timestamp yet\n"); - /* Reschedule to keep checking for a valid timestamp value */ - schedule_work(&bp->ptp_task); + DP(BNX2X_MSG_PTP, + "Tx timestamp is not recorded (register read=%u)\n", + val_seq); + bp->eth_stats.ptp_skip_tx_ts++; } + + dev_kfree_skb_any(bp->ptp_tx_skb); + bp->ptp_tx_skb = NULL; } void bnx2x_set_rx_ts(struct bnx2x *bp, struct sk_buff *skb) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index b2644ed13d06..d55e63692cf3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -207,6 +207,9 @@ struct bnx2x_eth_stats { u32 driver_filtered_tx_pkt; /* src: Clear-on-Read register; Will not survive PMF Migration */ u32 eee_tx_lpi; + + /* PTP */ + u32 ptp_skip_tx_ts; }; struct bnx2x_eth_q_stats {