From patchwork Wed Mar 27 06:19:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Barbette X-Patchwork-Id: 51760 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 402395B36; Wed, 27 Mar 2019 07:20:04 +0100 (CET) Received: from smtp-4.sys.kth.se (smtp-4.sys.kth.se [130.237.48.193]) by dpdk.org (Postfix) with ESMTP id BBDF25A4A for ; Wed, 27 Mar 2019 07:19:57 +0100 (CET) Received: from smtp-4.sys.kth.se (localhost.localdomain [127.0.0.1]) by smtp-4.sys.kth.se (Postfix) with ESMTP id 6EF7D6711; Wed, 27 Mar 2019 07:19:57 +0100 (CET) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-4.sys.kth.se ([127.0.0.1]) by smtp-4.sys.kth.se (smtp-4.sys.kth.se [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 8ASRg1b63KM2; Wed, 27 Mar 2019 07:19:56 +0100 (CET) X-KTH-Auth: barbette [130.237.20.142] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kth.se; s=default; t=1553667596; bh=a/3CfXhwL/UnW6TclYwp2akO7vGndJjzdWriY4fqx3M=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=GaZpUbC76CvOTnfURTTv45SGo/GbrcH44tSS6rU0V70/8tMtCnzdw2GCNcp7WNPiY ldSEIgZ8nluqwvfuf9gLOqU+JnidABxVVrmydnhISvWPLd/qxubNNzubcE00II8EvC V+Df2fLNOS4u/Fsoj/anFjbnjv5yVWhglABoM2SI= X-KTH-mail-from: barbette@kth.se Received: from tom-kth-workstation.it.kth.se (s2587.it.kth.se [130.237.20.142]) by smtp-4.sys.kth.se (Postfix) with ESMTPSA id 5570D6712; Wed, 27 Mar 2019 07:19:56 +0100 (CET) From: Tom Barbette To: dev@dpdk.org Cc: bruce.richardson@intel.com, john.mcnamara@intel.com, Thomas Monjalon , Ferruh Yigit , Andrew Rybchenko , Shahaf Shuler , Yongseok Koh , Tom Barbette Date: Wed, 27 Mar 2019 07:19:33 +0100 Message-Id: <20190327061935.19572-2-barbette@kth.se> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190327061935.19572-1-barbette@kth.se> References: <20190327061935.19572-1-barbette@kth.se> Subject: [dpdk-dev] [PATCH v2 1/3] rte_ethdev: Add API function to read dev clock X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add rte_eth_read_clock to read the raw clock of a devide. The main use is to get the device clock conversion co-efficients to be able to translate the raw clock of the timestamp field of the pkt mbuf to a local synced time value. This function was missing to allow users to convert the RX timestamp field to real time without the complexity of the rte_timesync* facility. One can derivate the clock frequency by calling twice read_clock and then keep a common time base. Signed-off-by: Tom Barbette --- doc/guides/nics/features.rst | 1 + lib/librte_ethdev/rte_ethdev.c | 13 +++++++ lib/librte_ethdev/rte_ethdev.h | 44 ++++++++++++++++++++++++ lib/librte_ethdev/rte_ethdev_core.h | 6 ++++ lib/librte_ethdev/rte_ethdev_version.map | 1 + lib/librte_mbuf/rte_mbuf.h | 2 ++ 6 files changed, 67 insertions(+) diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst index c5bf32222..1e6adfb0b 100644 --- a/doc/guides/nics/features.rst +++ b/doc/guides/nics/features.rst @@ -602,6 +602,7 @@ Supports Timestamp. * **[provides] mbuf**: ``mbuf.ol_flags:PKT_RX_TIMESTAMP``. * **[provides] mbuf**: ``mbuf.timestamp``. * **[provides] rte_eth_dev_info**: ``rx_offload_capa,rx_queue_offload_capa: DEV_RX_OFFLOAD_TIMESTAMP``. +* **[implements] eth_dev_ops**: ``read_clock``. .. _nic_features_macsec_offload: diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 85c179496..7de0f35b5 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -4127,6 +4127,19 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp) timestamp)); } +int +rte_eth_read_clock(uint16_t port_id, uint64_t *timestamp) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP); + return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, + timestamp)); +} + int rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) { diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index a3c864a13..e254da8b1 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -3642,6 +3642,50 @@ int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time); */ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Read the current clock counter of an Ethernet device + * + * This returns the current raw clock value of an Ethernet device. + * The value returned here is from the same clock than the one + * filling timestamp field of RX packets. Therefore it can be used + * to compute a precise conversion of the device clock to the real time. + * + * E.g, a simple heuristic to derivate the frequency would be: + * uint64_t start, end; + * rte_eth_read_clock(port, start); + * rte_delay_ms(100); + * rte_eth_read_clock(port, end); + * double freq = (end - start) * 10; + * + * Compute a common reference with: + * uint64_t base_time_sec = current_time(); + * uint64_t base_clock; + * rte_eth_read_clock(port, base_clock); + * + * Then, convert the raw mbuf timestamp with: + * base_time_sec + (double)(mbuf->timestamp - base_clock) / freq; + * + * This simple example will not provide a very good accuracy. One must + * at least measure multiple times the frequency and do a regression. + * To avoid deviation from the system time, the common reference can + * be repeated from time to time. The integer division can also be + * converted by a multiplication and a shift for better performance. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param time + * Pointer to the uint64_t that holds the raw clock value. + * + * @return + * - 0: Success. + * - -ENODEV: The port ID is invalid. + * - -ENOTSUP: The function is not supported by the Ethernet driver. + */ +int __rte_experimental rte_eth_read_clock(uint16_t port_id, uint64_t *time); + /** * Config l2 tunnel ether type of an Ethernet device for filtering specific * tunnel packets by ether type. diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h index 8f03f83f6..86806b3eb 100644 --- a/lib/librte_ethdev/rte_ethdev_core.h +++ b/lib/librte_ethdev/rte_ethdev_core.h @@ -322,6 +322,10 @@ typedef int (*eth_timesync_write_time)(struct rte_eth_dev *dev, const struct timespec *timestamp); /**< @internal Function used to get time from the device clock */ +typedef int (*eth_read_clock)(struct rte_eth_dev *dev, + uint64_t *timestamp); +/**< @internal Function used to get the current value of the device clock. */ + typedef int (*eth_get_reg_t)(struct rte_eth_dev *dev, struct rte_dev_reg_info *info); /**< @internal Retrieve registers */ @@ -496,6 +500,8 @@ struct eth_dev_ops { eth_timesync_read_time timesync_read_time; /** Get the device clock time. */ eth_timesync_write_time timesync_write_time; /** Set the device clock time. */ + eth_read_clock read_clock; + eth_xstats_get_by_id_t xstats_get_by_id; /**< Get extended device statistic values by ID. */ eth_xstats_get_names_by_id_t xstats_get_names_by_id; diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index 92ac3de25..12d6c3c1d 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -249,6 +249,7 @@ EXPERIMENTAL { rte_eth_switch_domain_free; rte_flow_conv; rte_flow_expand_rss; + rte_eth_read_clock; rte_mtr_capabilities_get; rte_mtr_create; rte_mtr_destroy; diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index d961ccaf6..dd55b942c 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -619,6 +619,8 @@ struct rte_mbuf { /** Valid if PKT_RX_TIMESTAMP is set. The unit and time reference * are not normalized but are always the same for a given port. + * Some devices allow to query rte_eth_read_clock that will return the + * current device timestamp. */ uint64_t timestamp;