From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vasily Philipov Subject: [PATCH v8 2/4] net/mlx4: implement isolated mode from flow API Date: Wed, 5 Jul 2017 11:14:09 +0300 Message-ID: <2d1e72d0efa775a05318c6489416bf7329e36b4a.1499242343.git.vasilyf@mellanox.com> References: <225679c202aa0bae5c61882aef6c8117a9074029.1499242343.git.vasilyf@mellanox.com> Cc: Vasily Philipov , Adrien Mazarguil , Nelio Laranjeiro To: dev@dpdk.org Return-path: Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id EAA143772 for ; Wed, 5 Jul 2017 10:14:20 +0200 (CEST) In-Reply-To: <225679c202aa0bae5c61882aef6c8117a9074029.1499242343.git.vasilyf@mellanox.com> In-Reply-To: <0dca86aa1372d6ff09d0aff01d522c580e0e24ab.1495717153.git.vasilyf@mellanox.com> References: <0dca86aa1372d6ff09d0aff01d522c580e0e24ab.1495717153.git.vasilyf@mellanox.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The user must request isolated mode before device configuration. Signed-off-by: Vasily Philipov --- drivers/net/mlx4/mlx4.c | 57 +++++++++++++++++++++++++++++++++++--------- drivers/net/mlx4/mlx4.h | 1 + drivers/net/mlx4/mlx4_flow.c | 37 ++++++++++++++++++++++++++++ drivers/net/mlx4/mlx4_flow.h | 5 ++++ 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index 16cafae..fdd9cce 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -588,7 +588,7 @@ void priv_unlock(struct priv *priv) } if (rxqs_n == priv->rxqs_n) return 0; - if (!rte_is_power_of_2(rxqs_n)) { + if (!rte_is_power_of_2(rxqs_n) && !priv->isolated) { unsigned n_active; n_active = rte_align32pow2(rxqs_n + 1) >> 1; @@ -2518,6 +2518,7 @@ struct txq_mp2mr_mbuf_check_data { { unsigned int i; + assert(!priv->isolated); assert(mac_index < elemof(priv->mac)); if (!BITFIELD_ISSET(priv->mac_configured, mac_index)) return; @@ -2767,12 +2768,13 @@ struct txq_mp2mr_mbuf_check_data { rxq->if_cq, ¶ms)); } - if (rxq->qp != NULL) { + if (rxq->qp != NULL && !rxq->priv->isolated) { rxq_promiscuous_disable(rxq); rxq_allmulticast_disable(rxq); rxq_mac_addrs_del(rxq); - claim_zero(ibv_destroy_qp(rxq->qp)); } + if (rxq->qp != NULL) + claim_zero(ibv_destroy_qp(rxq->qp)); if (rxq->cq != NULL) claim_zero(ibv_destroy_cq(rxq->cq)); if (rxq->channel != NULL) @@ -3472,7 +3474,7 @@ struct txq_mp2mr_mbuf_check_data { return 0; } /* Remove attached flows if RSS is disabled (no parent queue). */ - if (!priv->rss) { + if (!priv->rss && !priv->isolated) { rxq_allmulticast_disable(&tmpl); rxq_promiscuous_disable(&tmpl); rxq_mac_addrs_del(&tmpl); @@ -3517,7 +3519,7 @@ struct txq_mp2mr_mbuf_check_data { return err; }; /* Reconfigure flows. Do not care for errors. */ - if (!priv->rss) { + if (!priv->rss && !priv->isolated) { rxq_mac_addrs_add(&tmpl); if (priv->promisc) rxq_promiscuous_enable(&tmpl); @@ -3773,7 +3775,7 @@ struct txq_mp2mr_mbuf_check_data { (void *)dev, strerror(ret)); goto error; } - if ((parent) || (!priv->rss)) { + if (!priv->isolated && (parent || !priv->rss)) { /* Configure MAC and broadcast addresses. */ ret = rxq_mac_addrs_add(&tmpl); if (ret) { @@ -4002,7 +4004,10 @@ struct txq_mp2mr_mbuf_check_data { } DEBUG("%p: attaching configured flows to all RX queues", (void *)dev); priv->started = 1; - if (priv->rss) { + if (priv->isolated) { + rxq = NULL; + r = 1; + } else if (priv->rss) { rxq = &priv->rxq_parent; r = 1; } else { @@ -4090,7 +4095,10 @@ struct txq_mp2mr_mbuf_check_data { } DEBUG("%p: detaching flows from all RX queues", (void *)dev); priv->started = 0; - if (priv->rss) { + if (priv->isolated) { + rxq = NULL; + r = 1; + } else if (priv->rss) { rxq = &priv->rxq_parent; r = 1; } else { @@ -4522,6 +4530,8 @@ struct txq_mp2mr_mbuf_check_data { if (mlx4_is_secondary()) return; priv_lock(priv); + if (priv->isolated) + goto end; DEBUG("%p: removing MAC address from index %" PRIu32, (void *)dev, index); /* Last array entry is reserved for broadcast. */ @@ -4555,6 +4565,12 @@ struct txq_mp2mr_mbuf_check_data { return -ENOTSUP; (void)vmdq; priv_lock(priv); + if (priv->isolated) { + DEBUG("%p: cannot add MAC address, " + "device is in isolated mode", (void *)dev); + re = EPERM; + goto end; + } DEBUG("%p: adding MAC address at index %" PRIu32, (void *)dev, index); /* Last array entry is reserved for broadcast. */ @@ -4602,6 +4618,12 @@ struct txq_mp2mr_mbuf_check_data { if (mlx4_is_secondary()) return; priv_lock(priv); + if (priv->isolated) { + DEBUG("%p: cannot enable promiscuous, " + "device is in isolated mode", (void *)dev); + priv_unlock(priv); + return; + } if (priv->promisc) { priv_unlock(priv); return; @@ -4650,7 +4672,7 @@ struct txq_mp2mr_mbuf_check_data { if (mlx4_is_secondary()) return; priv_lock(priv); - if (!priv->promisc) { + if (!priv->promisc || priv->isolated) { priv_unlock(priv); return; } @@ -4682,6 +4704,12 @@ struct txq_mp2mr_mbuf_check_data { if (mlx4_is_secondary()) return; priv_lock(priv); + if (priv->isolated) { + DEBUG("%p: cannot enable allmulticast, " + "device is in isolated mode", (void *)dev); + priv_unlock(priv); + return; + } if (priv->allmulti) { priv_unlock(priv); return; @@ -4730,7 +4758,7 @@ struct txq_mp2mr_mbuf_check_data { if (mlx4_is_secondary()) return; priv_lock(priv); - if (!priv->allmulti) { + if (!priv->allmulti || priv->isolated) { priv_unlock(priv); return; } @@ -4873,7 +4901,7 @@ struct txq_mp2mr_mbuf_check_data { } /* Reenable non-RSS queue attributes. No need to check * for errors at this stage. */ - if (!priv->rss) { + if (!priv->rss && !priv->isolated) { rxq_mac_addrs_add(rxq); if (priv->promisc) rxq_promiscuous_enable(rxq); @@ -5108,6 +5136,12 @@ struct txq_mp2mr_mbuf_check_data { if (mlx4_is_secondary()) return -E_RTE_SECONDARY; priv_lock(priv); + if (priv->isolated) { + DEBUG("%p: cannot set vlan filter, " + "device is in isolated mode", (void *)dev); + priv_unlock(priv); + return -EINVAL; + } ret = vlan_filter_set(dev, vlan_id, on); priv_unlock(priv); assert(ret >= 0); @@ -5120,6 +5154,7 @@ struct txq_mp2mr_mbuf_check_data { .destroy = mlx4_flow_destroy, .flush = mlx4_flow_flush, .query = NULL, + .isolate = mlx4_flow_isolate, }; /** diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index c46fc23..1119525 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -335,6 +335,7 @@ struct priv { unsigned int rss:1; /* RSS is enabled. */ unsigned int vf:1; /* This is a VF device. */ unsigned int pending_alarm:1; /* An alarm is pending. */ + unsigned int isolated:1; /* Toggle isolated mode. */ #ifdef INLINE_RECV unsigned int inl_recv_size; /* Inline recv size */ #endif diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c index edfac03..5ad50bd 100644 --- a/drivers/net/mlx4/mlx4_flow.c +++ b/drivers/net/mlx4/mlx4_flow.c @@ -957,6 +957,43 @@ struct rte_flow * } /** + * @see rte_flow_isolate() + * + * Must be done before calling dev_configure(). + * + * @param dev + * Pointer to the ethernet device structure. + * @param enable + * Nonzero to enter isolated mode, attempt to leave it otherwise. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 on success, a negative value on error. + */ +int +mlx4_flow_isolate(struct rte_eth_dev *dev, + int enable, + struct rte_flow_error *error) +{ + struct priv *priv = dev->data->dev_private; + + priv_lock(priv); + if (priv->rxqs) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "isolated mode must be set" + " before configuring the device"); + priv_unlock(priv); + return -rte_errno; + } + priv->isolated = !!enable; + priv_unlock(priv); + return 0; +} + +/** * Destroy a flow. * * @param priv diff --git a/drivers/net/mlx4/mlx4_flow.h b/drivers/net/mlx4/mlx4_flow.h index 12a293e..4d007da 100644 --- a/drivers/net/mlx4/mlx4_flow.h +++ b/drivers/net/mlx4/mlx4_flow.h @@ -90,6 +90,11 @@ struct mlx4_flow { unsigned int offset; /**< Offset in bytes in the ibv_attr buffer. */ }; +int +mlx4_flow_isolate(struct rte_eth_dev *dev, + int enable, + struct rte_flow_error *error); + struct mlx4_flow_action { uint32_t drop:1; /**< Target is a drop queue. */ uint32_t queue:1; /**< Target is a receive queue. */ -- 1.8.3.1