[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <166256558150.1434226.3657678401785942330.stgit@firesoul>
Date: Wed, 07 Sep 2022 17:46:21 +0200
From: Jesper Dangaard Brouer <brouer@...hat.com>
To: bpf@...r.kernel.org
Cc: Jesper Dangaard Brouer <brouer@...hat.com>, netdev@...r.kernel.org,
xdp-hints@...-project.net, larysa.zaremba@...el.com,
memxor@...il.com, Lorenzo Bianconi <lorenzo@...nel.org>,
mtahhan@...hat.com,
Alexei Starovoitov <alexei.starovoitov@...il.com>,
Daniel Borkmann <borkmann@...earbox.net>,
Andrii Nakryiko <andrii.nakryiko@...il.com>,
dave@...cker.co.uk, Magnus Karlsson <magnus.karlsson@...el.com>,
bjorn@...nel.org
Subject: [PATCH RFCv2 bpf-next 16/18] ixgbe: add rx timestamp xdp hints
support
From: Maryam Tahhan <mtahhan@...hat.com>
Enable rx timestamp xdp-hints for ixgbe. Similar to i40e.
Signed-off-by: Maryam Tahhan <mtahhan@...hat.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@...hat.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 37 +++++++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 82 ++++++++++++++++---------
3 files changed, 90 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5369a97ff5ec..97b3fbd2de28 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1023,6 +1023,8 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
void ixgbe_ptp_tx_hang(struct ixgbe_adapter *adapter);
void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *, struct sk_buff *);
void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *, struct sk_buff *skb);
+u64 ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter, u64 timestamp);
+u64 ixgbe_ptp_rx_hwtstamp_raw(struct ixgbe_adapter *adapter);
static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
union ixgbe_adv_rx_desc *rx_desc,
struct sk_buff *skb)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0c8ee19e6d44..dc371b4c65bb 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -68,7 +68,18 @@ struct xdp_hints_ixgbe {
struct xdp_hints_common common;
};
+struct xdp_hints_ixgbe_timestamp {
+ u64 rx_timestamp;
+ struct xdp_hints_ixgbe base;
+};
+
+/* Extending xdp_hints_flags */
+enum xdp_hints_flags_driver {
+ HINT_FLAG_RX_TIMESTAMP = BIT(16),
+};
+
u64 btf_id_xdp_hints_ixgbe;
+u64 btf_id_xdp_hints_ixgbe_timestamp;
static const char ixgbe_overheat_msg[] = "Network adapter has been stopped because it has over heated. Restart the computer. If the problem persists, power off the system and replace the adapter";
@@ -1797,6 +1808,8 @@ static inline void ixgbe_process_xdp_hints(struct ixgbe_ring *ring,
u32 btf_id = btf_id_xdp_hints_ixgbe;
u32 btf_sz = sizeof(*xdp_hints);
u32 f1 = 0, f2, f3, f4, f5 = 0;
+ u32 flags = ring->q_vector->adapter->flags;
+ struct ixgbe_q_vector *q_vector = ring->q_vector;
if (!(ring->netdev->features & NETIF_F_XDP_HINTS)) {
xdp_buff_clear_hints_flags(xdp);
@@ -1810,6 +1823,25 @@ static inline void ixgbe_process_xdp_hints(struct ixgbe_ring *ring,
xdp_hints = xdp->data - btf_sz;
common = &xdp_hints->common;
+ if (q_vector && q_vector->adapter) {
+ if (unlikely(flags & IXGBE_FLAG_RX_HWTSTAMP_ENABLED)) {
+ u64 regval = 0, ns = 0;
+ struct xdp_hints_ixgbe_timestamp *hints;
+
+ regval = ixgbe_ptp_rx_hwtstamp_raw(q_vector->adapter);
+ if (regval) {
+ ns = ixgbe_ptp_convert_to_hwtstamp(q_vector->adapter, regval);
+ if (ns) {
+ btf_id = btf_id_xdp_hints_ixgbe_timestamp;
+ btf_sz = sizeof(*hints);
+ hints = xdp->data - btf_sz;
+ hints->rx_timestamp = ns_to_ktime(ns);
+ f1 = HINT_FLAG_RX_TIMESTAMP;
+ }
+ }
+ }
+ }
+
f2 = ixgbe_rx_hash_xdp(ring, rx_desc, xdp_hints, pkt_info);
f3 = ixgbe_rx_checksum_xdp(ring, rx_desc, xdp_hints, pkt_info);
f4 = xdp_hints_set_rxq(common, ring->queue_index);
@@ -11665,7 +11697,10 @@ static struct pci_driver ixgbe_driver = {
static void ixgbe_this_module_btf_lookups(struct btf *btf)
{
- btf_id_xdp_hints_ixgbe = btf_get_module_btf_full_id(btf, "xdp_hints_ixgbe");
+ btf_id_xdp_hints_ixgbe = btf_get_module_btf_full_id(btf,
+ "xdp_hints_ixgbe");
+ btf_id_xdp_hints_ixgbe_timestamp = btf_get_module_btf_full_id(btf,
+ "xdp_hints_ixgbe_timestamp");
}
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 9f06896a049b..561265b2816e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -379,11 +379,11 @@ static u64 ixgbe_ptp_read_82599(const struct cyclecounter *cc)
/**
* ixgbe_ptp_convert_to_hwtstamp - convert register value to hw timestamp
* @adapter: private adapter structure
- * @hwtstamp: stack timestamp structure
* @timestamp: unsigned 64bit system time value
*
- * We need to convert the adapter's RX/TXSTMP registers into a hwtstamp value
- * which can be used by the stack's ptp functions.
+ * We need to convert the adapter's RX/TXSTMP registers into a ns value
+ * which can be converted later to a hwtstamp to be used by the stack's
+ * ptp functions.
*
* The lock is used to protect consistency of the cyclecounter and the SYSTIME
* registers. However, it does not need to protect against the Rx or Tx
@@ -393,16 +393,13 @@ static u64 ixgbe_ptp_read_82599(const struct cyclecounter *cc)
* In addition to the timestamp in hardware, some controllers need a software
* overflow cyclecounter, and this function takes this into account as well.
**/
-static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter,
- struct skb_shared_hwtstamps *hwtstamp,
- u64 timestamp)
+u64 ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter,
+ u64 timestamp)
{
unsigned long flags;
struct timespec64 systime;
u64 ns;
- memset(hwtstamp, 0, sizeof(*hwtstamp));
-
switch (adapter->hw.mac.type) {
/* X550 and later hardware supposedly represent time using a seconds
* and nanoseconds counter, instead of raw 64bits nanoseconds. We need
@@ -433,7 +430,7 @@ static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter,
ns = timecounter_cyc2time(&adapter->hw_tc, timestamp);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
- hwtstamp->hwtstamp = ns_to_ktime(ns);
+ return ns;
}
/**
@@ -820,11 +817,13 @@ static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter)
struct sk_buff *skb = adapter->ptp_tx_skb;
struct ixgbe_hw *hw = &adapter->hw;
struct skb_shared_hwtstamps shhwtstamps;
- u64 regval = 0;
+ u64 regval = 0, ns = 0;
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32;
- ixgbe_ptp_convert_to_hwtstamp(adapter, &shhwtstamps, regval);
+ ns = ixgbe_ptp_convert_to_hwtstamp(adapter, regval);
+ if (ns)
+ shhwtstamps.hwtstamp = ns_to_ktime(ns);
/* Handle cleanup of the ptp_tx_skb ourselves, and unlock the state
* bit prior to notifying the stack via skb_tstamp_tx(). This prevents
@@ -892,6 +891,10 @@ void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb)
{
__le64 regval;
+ u64 ns = 0;
+ struct skb_shared_hwtstamps *hwtstamp = skb_hwtstamps(skb);
+
+ memset(hwtstamp, 0, sizeof(*hwtstamp));
/* copy the bits out of the skb, and then trim the skb length */
skb_copy_bits(skb, skb->len - IXGBE_TS_HDR_LEN, ®val,
@@ -904,8 +907,35 @@ void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *q_vector,
* DWORD: N N + 1 N + 2
* Field: End of Packet SYSTIMH SYSTIML
*/
- ixgbe_ptp_convert_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb),
- le64_to_cpu(regval));
+ ns = ixgbe_ptp_convert_to_hwtstamp(q_vector->adapter, le64_to_cpu(regval));
+ if (ns)
+ hwtstamp->hwtstamp = ns_to_ktime(ns);
+}
+
+/**
+ * ixgbe_ptp_rx_hwtstamp_raw - utility function which returns the RX time stamp
+ * @adapter: the private adapter struct
+ *
+ * If the timestamp is valid, we return the raw value, else return 0;
+ */
+u64 ixgbe_ptp_rx_hwtstamp_raw(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 tsyncrxctl;
+ u64 regval = 0;
+
+ /* Read the tsyncrxctl register afterwards in order to prevent taking an
+ * I/O hit on every packet.
+ */
+
+ tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+ if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
+ return 0;
+
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
+
+ return regval;
}
/**
@@ -921,29 +951,21 @@ void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb)
{
struct ixgbe_adapter *adapter;
- struct ixgbe_hw *hw;
- u64 regval = 0;
- u32 tsyncrxctl;
+ u64 regval = 0, ns = 0;
+ struct skb_shared_hwtstamps *hwtstamp = skb_hwtstamps(skb);
/* we cannot process timestamps on a ring without a q_vector */
if (!q_vector || !q_vector->adapter)
return;
+ memset(hwtstamp, 0, sizeof(*hwtstamp));
adapter = q_vector->adapter;
- hw = &adapter->hw;
-
- /* Read the tsyncrxctl register afterwards in order to prevent taking an
- * I/O hit on every packet.
- */
-
- tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
- if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
- return;
-
- regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
- regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
-
- ixgbe_ptp_convert_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
+ regval = ixgbe_ptp_rx_hwtstamp_raw(adapter);
+ if (regval) {
+ ns = ixgbe_ptp_convert_to_hwtstamp(adapter, regval);
+ if (ns)
+ hwtstamp->hwtstamp = ns_to_ktime(ns);
+ }
}
/**
Powered by blists - more mailing lists