DPDK patches and discussions
 help / color / mirror / Atom feed
From: Harman Kalra <hkalra@marvell.com>
To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>,
	Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>,
	Vamsi Krishna Attunuru <vattunuru@marvell.com>,
	Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
Cc: "dev@dpdk.org" <dev@dpdk.org>, Harman Kalra <hkalra@marvell.com>
Subject: [dpdk-dev] [PATCH v3 2/2] net/octeontx2: support read clock API
Date: Sun, 28 Jul 2019 09:09:45 +0000	[thread overview]
Message-ID: <1564304876-13274-2-git-send-email-hkalra@marvell.com> (raw)
In-Reply-To: <1564304876-13274-1-git-send-email-hkalra@marvell.com>

This patch implements read clock api whose purpose is to return
raw clock ticks. Using this API real time ticks spent in
processing a packet can be known:
    <read_clock val at any time> - mbuf->timestamp

Calling mbox for reading raw clock ticks in fastpath is very
expensive so its value is derived from time stamp counter(tsc)
using freq multipler (ratio of raw clock ticks and tsc) and clock
delta (by how much tsc is lagging from raw clock value).

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
V3:
* Moved most implementation in otx2_ptp.c keeping
otx2_ethdev.c cleaner.
* Removed ptp enable check in read_clock op fastpath.

V2:
* More detailed commit message
* changed rdtsc to tsc (timestamp counter)
* Initialized a variable to zero only when needed
* changed done label to fail

 drivers/common/octeontx2/otx2_mbox.h |   2 +
 drivers/net/octeontx2/otx2_ethdev.c  |  16 ++++-
 drivers/net/octeontx2/otx2_ethdev.h  |   5 ++
 drivers/net/octeontx2/otx2_ptp.c     | 100 +++++++++++++++++++++++++++
 4 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/drivers/common/octeontx2/otx2_mbox.h b/drivers/common/octeontx2/otx2_mbox.h
index c0bb676b2..b2c59c86e 100644
--- a/drivers/common/octeontx2/otx2_mbox.h
+++ b/drivers/common/octeontx2/otx2_mbox.h
@@ -1354,11 +1354,13 @@ struct ptp_req {
 	struct mbox_msghdr hdr;
 	uint8_t __otx2_io op;
 	int64_t __otx2_io scaled_ppm;
+	uint8_t __otx2_io is_pmu;
 };
 
 struct ptp_rsp {
 	struct mbox_msghdr hdr;
 	uint64_t __otx2_io clk;
+	uint64_t __otx2_io tsc;
 };
 
 struct get_hw_cap_rsp {
diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c
index 595c8003a..3fb7bd93f 100644
--- a/drivers/net/octeontx2/otx2_ethdev.c
+++ b/drivers/net/octeontx2/otx2_ethdev.c
@@ -3,7 +3,6 @@
  */
 
 #include <inttypes.h>
-#include <math.h>
 
 #include <rte_ethdev_pci.h>
 #include <rte_io.h>
@@ -521,6 +520,20 @@ otx2_nix_rx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t rq,
 
 	eth_dev->data->rx_queues[rq] = rxq;
 	eth_dev->data->rx_queue_state[rq] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+	/* Calculating delta and freq mult between PTP HI clock and tsc.
+	 * These are needed in deriving raw clock value from tsc counter.
+	 * read_clock eth op returns raw clock value.
+	 */
+	if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) ||
+	    otx2_ethdev_is_ptp_en(dev)) {
+		rc = otx2_nix_raw_clock_tsc_conv(dev);
+		if (rc) {
+			otx2_err("Failed to calculate delta and freq mult");
+			goto fail;
+		}
+	}
+
 	return 0;
 
 free_rxq:
@@ -1649,6 +1662,7 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
 	.vlan_pvid_set		  = otx2_nix_vlan_pvid_set,
 	.rx_queue_intr_enable	  = otx2_nix_rx_queue_intr_enable,
 	.rx_queue_intr_disable	  = otx2_nix_rx_queue_intr_disable,
+	.read_clock		  = otx2_nix_read_clock,
 };
 
 static inline int
diff --git a/drivers/net/octeontx2/otx2_ethdev.h b/drivers/net/octeontx2/otx2_ethdev.h
index 863d4877f..720386fd1 100644
--- a/drivers/net/octeontx2/otx2_ethdev.h
+++ b/drivers/net/octeontx2/otx2_ethdev.h
@@ -5,6 +5,7 @@
 #ifndef __OTX2_ETHDEV_H__
 #define __OTX2_ETHDEV_H__
 
+#include <math.h>
 #include <stdint.h>
 
 #include <rte_common.h>
@@ -300,6 +301,8 @@ struct otx2_eth_dev {
 	struct rte_timecounter  systime_tc;
 	struct rte_timecounter  rx_tstamp_tc;
 	struct rte_timecounter  tx_tstamp_tc;
+	double clk_freq_mult;
+	uint64_t clk_delta;
 } __rte_cache_aligned;
 
 struct otx2_eth_txq {
@@ -527,5 +530,7 @@ int otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
 int otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev,
 				struct timespec *ts);
 int otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en);
+int otx2_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *time);
+int otx2_nix_raw_clock_tsc_conv(struct otx2_eth_dev *dev);
 
 #endif /* __OTX2_ETHDEV_H__ */
diff --git a/drivers/net/octeontx2/otx2_ptp.c b/drivers/net/octeontx2/otx2_ptp.c
index 0186c629a..52e5456b5 100644
--- a/drivers/net/octeontx2/otx2_ptp.c
+++ b/drivers/net/octeontx2/otx2_ptp.c
@@ -8,6 +8,81 @@
 
 #define PTP_FREQ_ADJUST (1 << 9)
 
+static int
+nix_read_raw_clock(struct otx2_eth_dev *dev, uint64_t *clock, uint64_t *tsc,
+		   uint8_t is_pmu)
+{
+	struct otx2_mbox *mbox = dev->mbox;
+	struct ptp_req *req;
+	struct ptp_rsp *rsp;
+	int rc;
+
+	req = otx2_mbox_alloc_msg_ptp_op(mbox);
+	req->op = PTP_OP_GET_CLOCK;
+	req->is_pmu = is_pmu;
+	rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (rc)
+		goto fail;
+
+	if (clock)
+		*clock = rsp->clk;
+	if (tsc)
+		*tsc = rsp->tsc;
+
+fail:
+	return rc;
+}
+
+/* This function calculates two parameters "clk_freq_mult" and
+ * "clk_delta" which is useful in deriving PTP HI clock from
+ * timestamp counter (tsc) value.
+ */
+int
+otx2_nix_raw_clock_tsc_conv(struct otx2_eth_dev *dev)
+{
+	uint64_t ticks_base = 0, ticks = 0, tsc = 0, t_freq;
+	int rc, val;
+
+	/* Calculating the frequency at which PTP HI clock is running */
+	rc = nix_read_raw_clock(dev, &ticks_base, &tsc, false);
+	if (rc) {
+		otx2_err("Failed to read the raw clock value: %d", rc);
+		goto fail;
+	}
+
+	rte_delay_ms(100);
+
+	rc = nix_read_raw_clock(dev, &ticks, &tsc, false);
+	if (rc) {
+		otx2_err("Failed to read the raw clock value: %d", rc);
+		goto fail;
+	}
+
+	t_freq = (ticks - ticks_base) * 10;
+
+	/* Calculating the freq multiplier viz the ratio between the
+	 * frequency at which PTP HI clock works and tsc clock runs
+	 */
+	dev->clk_freq_mult =
+		(double)pow(10, floor(log10(t_freq))) / rte_get_timer_hz();
+
+	val = false;
+#ifdef RTE_ARM_EAL_RDTSC_USE_PMU
+	val = true;
+#endif
+	rc = nix_read_raw_clock(dev, &ticks, &tsc, val);
+	if (rc) {
+		otx2_err("Failed to read the raw clock value: %d", rc);
+		goto fail;
+	}
+
+	/* Calculating delta between PTP HI clock and tsc */
+	dev->clk_delta = ((uint64_t)(ticks / dev->clk_freq_mult) - tsc);
+
+fail:
+	return rc;
+}
+
 static void
 nix_start_timecounters(struct rte_eth_dev *eth_dev)
 {
@@ -224,6 +299,13 @@ otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
 		rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
 		if (rc)
 			return rc;
+		/* Since the frequency of PTP comp register is tuned, delta and
+		 * freq mult calculation for deriving PTP_HI from timestamp
+		 * counter should be done again.
+		 */
+		rc = otx2_nix_raw_clock_tsc_conv(dev);
+		if (rc)
+			otx2_err("Failed to calculate delta and freq mult");
 	}
 	dev->systime_tc.nsec += delta;
 	dev->rx_tstamp_tc.nsec += delta;
@@ -271,3 +353,21 @@ otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
 
 	return 0;
 }
+
+
+int
+otx2_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
+{
+	struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+
+	/* This API returns the raw PTP HI clock value. Since LFs doesn't
+	 * have direct access to PTP registers and it requires mbox msg
+	 * to AF for this value. In fastpath reading this value for every
+	 * packet (which involes mbox call) becomes very expensive, hence
+	 * we should be able to derive PTP HI clock value from tsc by
+	 * using freq_mult and clk_delta calculated during configure stage.
+	 */
+	*clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;
+
+	return 0;
+}
-- 
2.18.0


  reply	other threads:[~2019-07-28  9:09 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-27 14:57 [dpdk-dev] [PATCH 1/2] net/octeontx2: fix ptp performance issue Harman Kalra
2019-07-27 14:57 ` [dpdk-dev] [PATCH 2/2] net/octeontx2: support read clock API Harman Kalra
2019-07-27 15:48   ` Jerin Jacob Kollanukkaran
2019-07-27 20:41     ` [dpdk-dev] [PATCH v2 1/2] net/octeontx2: fix ptp performance issue Harman Kalra
2019-07-27 20:41       ` [dpdk-dev] [PATCH v2 2/2] net/octeontx2: support read clock API Harman Kalra
2019-07-28  7:43         ` Jerin Jacob Kollanukkaran
2019-07-28  9:09           ` [dpdk-dev] [PATCH v3 1/2] net/octeontx2: fix ptp performance issue Harman Kalra
2019-07-28  9:09             ` Harman Kalra [this message]
2019-07-28 16:52             ` Jerin Jacob Kollanukkaran

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=1564304876-13274-2-git-send-email-hkalra@marvell.com \
    --to=hkalra@marvell.com \
    --cc=dev@dpdk.org \
    --cc=jerinj@marvell.com \
    --cc=kirankumark@marvell.com \
    --cc=ndabilpuram@marvell.com \
    --cc=vattunuru@marvell.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;
as well as URLs for NNTP newsgroup(s).