From patchwork Wed Dec 19 13:49:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Barbette X-Patchwork-Id: 49120 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 EE1B71B951; Wed, 19 Dec 2018 14:50:06 +0100 (CET) Received: from smtp-3.sys.kth.se (smtp-3.sys.kth.se [130.237.48.192]) by dpdk.org (Postfix) with ESMTP id 6DFED1B93A for ; Wed, 19 Dec 2018 14:50:04 +0100 (CET) Received: from smtp-3.sys.kth.se (localhost.localdomain [127.0.0.1]) by smtp-3.sys.kth.se (Postfix) with ESMTP id 2CF2758C1; Wed, 19 Dec 2018 14:50:04 +0100 (CET) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-3.sys.kth.se ([127.0.0.1]) by smtp-3.sys.kth.se (smtp-3.sys.kth.se [127.0.0.1]) (amavisd-new, port 10024) with LMTP id AY7fq_HMKz1E; Wed, 19 Dec 2018 14:50:03 +0100 (CET) X-KTH-Auth: barbette [192.16.125.168] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kth.se; s=default; t=1545227403; bh=6xJxUOJCnbRj+KlLitFqxP5bcjKDlUKvhA2xodgZ54w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ob7iTiLGOOCAH96VcOSWtSsBhAbKVObcPufSylKc7niVPl/MA38ZHopO7e6tJWXXN Td/+C9E/FZ2Gjyz6mfTazAh+0aLV33H3ExUj88V2C48KmWOL2SfRiozC3i6j6j8XN9 nLj6BwTgl8L9HJokW4X5pn0uVo/1hxu3NDo4O+3k= X-KTH-mail-from: barbette@kth.se Received: from nslrack08.ssvl.kth.se (nslrack08.ssvl.kth.se [192.16.125.168]) by smtp-3.sys.kth.se (Postfix) with ESMTPSA id 711F65807; Wed, 19 Dec 2018 14:50:01 +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, 19 Dec 2018 14:49:32 +0100 Message-Id: <20181219134934.24693-2-barbette@kth.se> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181219134934.24693-1-barbette@kth.se> References: <20181219134934.24693-1-barbette@kth.se> Subject: [dpdk-dev] [PATCH 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 Acked-by: Shahaf Shuler --- 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 d3f904839..45484a30f 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 9d5107dce..97f92d11a 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -4124,6 +4124,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 1960f3a2d..5a831db29 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 3dbc6695e..4ceefa913 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -605,6 +605,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;