[dpdk-dev,3/3] net/mlx5: add hardware timestamp

Message ID 1503409570-9946-3-git-send-email-rasland@mellanox.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Raslan Darawsheh Aug. 22, 2017, 1:46 p.m. UTC
Expose a new capapilty of Rx hw timestamp and
added new device args to enable it hw_timestamp.
It will add the raw hw timestamp into the packets.

Its expected that it will lower down the performance since using it
will disable the cqe comprission, and will add extra checkes in
the vec rx path.

Signed-off-by: Raslan Darawsheh <rasland@mellanox.com>
---
 drivers/net/mlx5/mlx5.c              | 23 +++++++++++++++++++++++
 drivers/net/mlx5/mlx5.h              |  1 +
 drivers/net/mlx5/mlx5_ethdev.c       |  3 ++-
 drivers/net/mlx5/mlx5_rxq.c          |  3 +++
 drivers/net/mlx5/mlx5_rxtx.c         |  5 +++++
 drivers/net/mlx5/mlx5_rxtx.h         |  1 +
 drivers/net/mlx5/mlx5_rxtx_vec_sse.c | 14 ++++++++++++++
 7 files changed, 49 insertions(+), 1 deletion(-)
  

Comments

Nélio Laranjeiro Aug. 23, 2017, 3:02 p.m. UTC | #1
On Tue, Aug 22, 2017 at 04:46:10PM +0300, Raslan Darawsheh wrote:
> Expose a new capapilty of Rx hw timestamp and
> added new device args to enable it hw_timestamp.
> It will add the raw hw timestamp into the packets.
> 
> Its expected that it will lower down the performance since using it
> will disable the cqe comprission, and will add extra checkes in
> the vec rx path.
> 
> Signed-off-by: Raslan Darawsheh <rasland@mellanox.com>

The new parameter should be documented in the NIC documentation.

Thanks,
  

Patch

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b7e5046..4b3a3ab 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -94,6 +94,9 @@ 
 /* Device parameter to enable hardware TSO offload. */
 #define MLX5_TSO "tso"
 
+/* Device parameter to enable hardware timestamp offload. */
+#define MLX5_RX_TIMESTAMP "rx_timestamp"
+
 /* Device parameter to enable hardware Tx vector. */
 #define MLX5_TX_VEC_EN "tx_vec_en"
 
@@ -113,6 +116,7 @@  struct mlx5_args {
 	int tso;
 	int tx_vec_en;
 	int rx_vec_en;
+	int hw_timestamp;
 };
 /**
  * Retrieve integer value from environment variable.
@@ -336,6 +340,8 @@  mlx5_args_check(const char *key, const char *val, void *opaque)
 		args->tx_vec_en = !!tmp;
 	} else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
 		args->rx_vec_en = !!tmp;
+	} else if (strcmp(MLX5_RX_TIMESTAMP, key) == 0) {
+		args->hw_timestamp = !!tmp;
 	} else {
 		WARN("%s: unknown parameter", key);
 		return -EINVAL;
@@ -367,6 +373,7 @@  mlx5_args(struct mlx5_args *args, struct rte_devargs *devargs)
 		MLX5_TSO,
 		MLX5_TX_VEC_EN,
 		MLX5_RX_VEC_EN,
+		MLX5_RX_TIMESTAMP,
 		NULL,
 	};
 	struct rte_kvargs *kvlist;
@@ -426,6 +433,8 @@  mlx5_args_assign(struct priv *priv, struct mlx5_args *args)
 		priv->tx_vec_en = args->tx_vec_en;
 	if (args->rx_vec_en != MLX5_ARG_UNSET)
 		priv->rx_vec_en = args->rx_vec_en;
+	if (args->hw_timestamp != MLX5_ARG_UNSET)
+		priv->hw_timestamp = args->hw_timestamp;
 }
 
 /**
@@ -573,6 +582,7 @@  mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			.tso = MLX5_ARG_UNSET,
 			.tx_vec_en = MLX5_ARG_UNSET,
 			.rx_vec_en = MLX5_ARG_UNSET,
+			.hw_timestamp = MLX5_ARG_UNSET,
 		};
 
 		exp_device_attr.comp_mask =
@@ -581,6 +591,7 @@  mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			IBV_EXP_DEVICE_ATTR_VLAN_OFFLOADS |
 			IBV_EXP_DEVICE_ATTR_RX_PAD_END_ALIGN |
 			IBV_EXP_DEVICE_ATTR_TSO_CAPS |
+			IBV_EXP_DEVICE_ATTR_WITH_TIMESTAMP_MASK |
 			0;
 
 		DEBUG("using port %u (%08" PRIx32 ")", port, test);
@@ -662,6 +673,18 @@  mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 					 IBV_EXP_DEVICE_VXLAN_SUPPORT);
 		DEBUG("L2 tunnel checksum offloads are %ssupported",
 		      (priv->hw_csum_l2tun ? "" : "not "));
+		if (priv->hw_timestamp) {
+			priv->hw_timestamp =
+				(exp_device_attr.comp_mask |
+				 IBV_EXP_DEVICE_ATTR_WITH_TIMESTAMP_MASK);
+			DEBUG("Timestamping offload is %ssupported",
+			      (priv->hw_timestamp ? "" : "not "));
+			priv->cqe_comp = (priv->hw_timestamp ?
+					  0 : priv->cqe_comp);
+			DEBUG("%s",
+			      (priv->hw_timestamp ?
+			      "cqe compression is disabled" : ""));
+		}
 
 		priv->ind_table_max_size = exp_device_attr.rx_hash_caps.max_rwq_indirection_table_size;
 		/* Remove this check once DPDK supports larger/variable
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 43c5384..4d19351 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -120,6 +120,7 @@  struct priv {
 	unsigned int allmulti_req:1; /* All multicast mode requested. */
 	unsigned int hw_csum:1; /* Checksum offload is supported. */
 	unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */
+	unsigned int hw_timestamp:1; /* rx timestamp offload is supported. */
 	unsigned int hw_vlan_strip:1; /* VLAN stripping is supported. */
 	unsigned int hw_fcs_strip:1; /* FCS stripping is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index b0eb3cd..1942de7 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -686,7 +686,8 @@  mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		  DEV_RX_OFFLOAD_UDP_CKSUM |
 		  DEV_RX_OFFLOAD_TCP_CKSUM) :
 		 0) |
-		(priv->hw_vlan_strip ? DEV_RX_OFFLOAD_VLAN_STRIP : 0);
+		(priv->hw_vlan_strip ? DEV_RX_OFFLOAD_VLAN_STRIP : 0) |
+		(priv->hw_timestamp ? DEV_RX_OFFLOAD_TIMESTAMP : 0);
 	if (!priv->mps)
 		info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT;
 	if (priv->hw_csum)
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 74387a7..c8ccde2 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -929,6 +929,7 @@  rxq_ctrl_setup(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl,
 	if (priv->hw_csum_l2tun)
 		tmpl.rxq.csum_l2tun =
 			!!dev->data->dev_conf.rxmode.hw_ip_checksum;
+	tmpl.rxq.timestamp = priv->hw_timestamp;
 	/* Use the entire RX mempool as the memory region. */
 	tmpl.mr = mlx5_mp2mr(priv->pd, mp);
 	if (tmpl.mr == NULL) {
@@ -950,6 +951,8 @@  rxq_ctrl_setup(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl,
 	attr.cq = (struct ibv_exp_cq_init_attr){
 		.comp_mask = 0,
 	};
+	if (priv->hw_timestamp)
+		attr.cq.flags |= IBV_EXP_CQ_TIMESTAMP;
 	if (priv->cqe_comp) {
 		attr.cq.comp_mask |= IBV_EXP_CQ_INIT_ATTR_FLAGS;
 		attr.cq.flags |= IBV_EXP_CQ_COMPRESSED_CQE;
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index b07bcd1..47344f2 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -1865,6 +1865,11 @@  mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					PKT_RX_VLAN_STRIPPED;
 				pkt->vlan_tci = ntohs(cqe->vlan_info);
 			}
+			if (rxq->timestamp) {
+				pkt->timestamp =
+					rte_be_to_cpu_64(cqe->timestamp);
+				pkt->ol_flags |= PKT_RX_TIMESTAMP;
+			}
 			if (rxq->crc_present)
 				len -= ETHER_CRC_LEN;
 			PKT_LEN(pkt) = len;
diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
index 7de1d10..20c0f87 100644
--- a/drivers/net/mlx5/mlx5_rxtx.h
+++ b/drivers/net/mlx5/mlx5_rxtx.h
@@ -107,6 +107,7 @@  struct rxq_zip {
 struct rxq {
 	unsigned int csum:1; /* Enable checksum offloading. */
 	unsigned int csum_l2tun:1; /* Same for L2 tunnels. */
+	unsigned int timestamp:1; /* Enable timestamp offloading. */
 	unsigned int vlan_strip:1; /* Enable VLAN stripping. */
 	unsigned int crc_present:1; /* CRC must be subtracted. */
 	unsigned int sges_n:2; /* Log 2 of SGEs (max buffers per packet). */
diff --git a/drivers/net/mlx5/mlx5_rxtx_vec_sse.c b/drivers/net/mlx5/mlx5_rxtx_vec_sse.c
index 8560f74..9f1fd87 100644
--- a/drivers/net/mlx5/mlx5_rxtx_vec_sse.c
+++ b/drivers/net/mlx5/mlx5_rxtx_vec_sse.c
@@ -1214,6 +1214,20 @@  rxq_burst_v(struct rxq *rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		rxq->pending_err |= !!_mm_cvtsi128_si64(opcode);
 		/* D.5 fill in mbuf - rearm_data and packet_type. */
 		rxq_cq_to_ptype_oflags_v(rxq, cqes, opcode, &pkts[pos]);
+		if (rxq->timestamp) {
+			pkts[pos]->timestamp =
+				rte_be_to_cpu_64(cq[pos].timestamp);
+			pkts[pos + 1]->timestamp =
+				rte_be_to_cpu_64(cq[pos + 1].timestamp);
+			pkts[pos + 2]->timestamp =
+				rte_be_to_cpu_64(cq[pos + 2].timestamp);
+			pkts[pos + 3]->timestamp =
+				rte_be_to_cpu_64(cq[pos + 3].timestamp);
+			pkts[pos]->ol_flags |= PKT_RX_TIMESTAMP;
+			pkts[pos + 1]->ol_flags |= PKT_RX_TIMESTAMP;
+			pkts[pos + 2]->ol_flags |= PKT_RX_TIMESTAMP;
+			pkts[pos + 3]->ol_flags |= PKT_RX_TIMESTAMP;
+		}
 #ifdef MLX5_PMD_SOFT_COUNTERS
 		/* Add up received bytes count. */
 		byte_cnt = _mm_shuffle_epi8(op_own, len_shuf_mask);