From: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
To: intel-wired-lan@osuosl.org
Cc: vladimir.oltean@nxp.com, anthony.l.nguyen@intel.com,
tee.min.tan@linux.intel.com
Subject: [Intel-wired-lan] [PATCH iwl-net v3] igc: Add TransmissionOverrun counter
Date: Thu, 1 Jun 2023 08:59:25 +0800 [thread overview]
Message-ID: <20230601005925.30473-1-muhammad.husaini.zulkifli@intel.com> (raw)
Add TransmissionOverrun as per defined by IEEE 802.1Q Bridges.
TransmissionOverrun counter shall be incremented if the implementation
detects that a frame from a given queue is still being transmitted by
the MAC when that gate-close event for that queue occurs.
This counter is utilised by the Certification conformance test to
inform the user application whether any packets are currently being
transmitted on a particular queue during a gate-close event.
Intel Discrete I225/I226 have a mechanism to not transmit a packets if
the gate open time is insufficient for the packet transmission by setting
the Strict_End bit. Thus, it is expected for this counter to be always
zero at this moment.
Inspired from enetc_taprio_stats() and enetc_taprio_tc_stats(), now
driver also report the tx_overruns counter per traffic class.
User can get this counter by using below command:
1) ethtool -S <interface> | grep Transmit_overruns
2) tc -s qdisc show dev <interface> root
3) tc -s class show dev <interface>
Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
---
V2 -> V3: Included new infra xstats to report back the counter to qdisc
V1 -> V2: Change per-queue stats. Driver still remains adding the
statistic independently.
---
---
drivers/net/ethernet/intel/igc/igc.h | 1 +
drivers/net/ethernet/intel/igc/igc_ethtool.c | 4 ++-
drivers/net/ethernet/intel/igc/igc_main.c | 38 ++++++++++++++++++++
drivers/net/ethernet/intel/igc/igc_tsn.c | 10 ++++++
4 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index cb5751fab03c9..2a13e62b75d60 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -46,6 +46,7 @@ struct igc_tx_queue_stats {
u64 bytes;
u64 restart_queue;
u64 restart_queue2;
+ u64 tx_overruns;
};
struct igc_rx_queue_stats {
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 0e2cb00622d1a..6a10ae1474fc5 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -112,7 +112,7 @@ static const char igc_gstrings_test[][ETH_GSTRING_LEN] = {
(sizeof(igc_gstrings_net_stats) / sizeof(struct igc_stats))
#define IGC_RX_QUEUE_STATS_LEN \
(sizeof(struct igc_rx_queue_stats) / sizeof(u64))
-#define IGC_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */
+#define IGC_TX_QUEUE_STATS_LEN 4 /* packets, bytes, restart_queue, tx_overruns */
#define IGC_QUEUE_STATS_LEN \
((((struct igc_adapter *)netdev_priv(netdev))->num_rx_queues * \
IGC_RX_QUEUE_STATS_LEN) + \
@@ -781,6 +781,7 @@ static void igc_ethtool_get_strings(struct net_device *netdev, u32 stringset,
ethtool_sprintf(&p, "tx_queue_%u_packets", i);
ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
ethtool_sprintf(&p, "tx_queue_%u_restart", i);
+ ethtool_sprintf(&p, "tx_queue_%u_Transmit_overruns", i);
}
for (i = 0; i < adapter->num_rx_queues; i++) {
ethtool_sprintf(&p, "rx_queue_%u_packets", i);
@@ -850,6 +851,7 @@ static void igc_ethtool_get_stats(struct net_device *netdev,
restart2 = ring->tx_stats.restart_queue2;
} while (u64_stats_fetch_retry(&ring->tx_syncp2, start));
data[i + 2] += restart2;
+ data[i + 3] = ring->tx_stats.tx_overruns;
i += IGC_TX_QUEUE_STATS_LEN;
}
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index aa9f23b7f0c1a..056925a7bcdd8 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6109,11 +6109,43 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)
ring->start_time = 0;
ring->end_time = NSEC_PER_SEC;
ring->max_sdu = 0;
+ ring->tx_stats.tx_overruns = 0;
}
return 0;
}
+static void igc_taprio_stats(struct net_device *dev,
+ struct tc_taprio_qopt_stats *stats)
+{
+ struct igc_adapter *adapter = netdev_priv(dev);
+ u64 tx_overruns = 0;
+ int i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct igc_ring *tx_ring = adapter->tx_ring[i];
+
+ tx_overruns += tx_ring->tx_stats.tx_overruns;
+ }
+
+ stats->tx_overruns = tx_overruns;
+}
+
+static void igc_taprio_tc_stats(struct net_device *dev,
+ struct tc_taprio_qopt_tc_stats *tc_stats)
+{
+ struct tc_taprio_qopt_stats *stats = &tc_stats->stats;
+ struct igc_adapter *adapter = netdev_priv(dev);
+ struct igc_ring *tx_ring;
+ int tc = tc_stats->tc;
+ int txq;
+
+ txq = dev->tc_to_txq[tc].offset;
+ tx_ring = adapter->tx_ring[txq];
+
+ stats->tx_overruns = tx_ring->tx_stats.tx_overruns;
+}
+
static int igc_save_qbv_schedule(struct igc_adapter *adapter,
struct tc_taprio_qopt_offload *qopt)
{
@@ -6130,6 +6162,12 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
case TAPRIO_CMD_DESTROY:
adapter->qbv_enable = false;
break;
+ case TAPRIO_CMD_STATS:
+ igc_taprio_stats(adapter->netdev, &qopt->stats);
+ return 0;
+ case TAPRIO_CMD_TC_STATS:
+ igc_taprio_tc_stats(adapter->netdev, &qopt->tc_stats);
+ return 0;
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
index 6b299b83e7ef2..342530d11aae9 100644
--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
+++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
@@ -136,6 +136,16 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
txqctl |= IGC_TXQCTL_STRICT_CYCLE |
IGC_TXQCTL_STRICT_END;
+ /* If it notices that a frame from a particular queue is still
+ * being transmitted by MAC, tx_overruns shall be increased.
+ * But currently driver setting Strict_End bit which indicate
+ * that packet from the queue can be transmitted only if they
+ * are expected to be completed before the windows of the
+ * queue is ended. Thus, this counter will always be zero when
+ * Strict_End is set.
+ */
+ ring->tx_stats.tx_overruns = 0;
+
if (ring->launchtime_enable)
txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
--
2.17.1
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
next reply other threads:[~2023-06-01 1:01 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-01 0:59 Muhammad Husaini Zulkifli [this message]
2023-06-01 1:29 ` [Intel-wired-lan] [PATCH iwl-net v3] igc: Add TransmissionOverrun counter Zulkifli, Muhammad Husaini
2023-06-06 14:02 ` Vladimir Oltean
2023-06-09 17:10 ` Zulkifli, Muhammad Husaini
2023-06-09 17:38 ` Vladimir Oltean
2023-06-12 3:50 ` Zulkifli, Muhammad Husaini
2023-06-12 14:28 ` Vladimir Oltean
2023-06-13 15:38 ` Zulkifli, Muhammad Husaini
2023-06-13 15:41 ` Vladimir Oltean
2023-06-14 1:07 ` Zulkifli, Muhammad Husaini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230601005925.30473-1-muhammad.husaini.zulkifli@intel.com \
--to=muhammad.husaini.zulkifli@intel.com \
--cc=anthony.l.nguyen@intel.com \
--cc=intel-wired-lan@osuosl.org \
--cc=tee.min.tan@linux.intel.com \
--cc=vladimir.oltean@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox