Re: [ovs-dev] [PATCH v5 1/2] netdev-dpdk: Add support for multi-queue QoS to the DPDK datapath

2020-01-15 Thread Ilya Maximets
On 14.01.2020 17:12, Eelco Chaudron wrote:
> This patch adds support for multi-queue QoS to the DPDK datapath.

Small nit:  Please, don't use term 'DPDK datapath' in the future.
There is no such thing in OVS.

Best regards, Ilya Maximets.
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v5 1/2] netdev-dpdk: Add support for multi-queue QoS to the DPDK datapath

2020-01-15 Thread Eelco Chaudron




On 15 Jan 2020, at 12:20, Stokes, Ian wrote:


On 1/14/2020 4:12 PM, Eelco Chaudron wrote:
This patch adds support for multi-queue QoS to the DPDK datapath. 
Most of

the code is based on an earlier patch from a patchset sent out by
zhaozhanxu. The patch was titled "[ovs-dev, v2, 1/4] netdev-dpdk.c: 
Support

the multi-queue QoS configuration for dpdk datapath"

Co-authored-by: zhaozhanxu 
Signed-off-by: Eelco Chaudron 


Thansk Eelco.

Overall LGTM, there should be a sign-off for zhaozhanxu also as he is 
a co-athour, I can add this on commit however.


Thanks, please add the sign-off, as it was on his original patch set. I 
did try to contact him earlier, but never got a response.




___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v5 1/2] netdev-dpdk: Add support for multi-queue QoS to the DPDK datapath

2020-01-15 Thread Stokes, Ian




On 1/14/2020 4:12 PM, Eelco Chaudron wrote:

This patch adds support for multi-queue QoS to the DPDK datapath. Most of
the code is based on an earlier patch from a patchset sent out by
zhaozhanxu. The patch was titled "[ovs-dev, v2, 1/4] netdev-dpdk.c: Support
the multi-queue QoS configuration for dpdk datapath"

Co-authored-by: zhaozhanxu 
Signed-off-by: Eelco Chaudron 


Thansk Eelco.

Overall LGTM, there should be a sign-off for zhaozhanxu also as he is a 
co-athour, I can add this on commit however.


Regards
Ian

---
  lib/netdev-dpdk.c |  219 -
  1 file changed, 213 insertions(+), 6 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 8198a0b..128963f 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -219,6 +219,13 @@ struct qos_conf {
  rte_spinlock_t lock;
  };
  
+/* QoS queue information used by the netdev queue dump functions. */

+struct netdev_dpdk_queue_state {
+uint32_t *queues;
+size_t cur_queue;
+size_t n_queues;
+};
+
  /* A particular implementation of dpdk QoS operations.
   *
   * The functions below return 0 if successful or a positive errno value on
@@ -285,6 +292,41 @@ struct dpdk_qos_ops {
   */
  int (*qos_run)(struct qos_conf *qos_conf, struct rte_mbuf **pkts,
 int pkt_cnt, bool should_steal);
+
+/* Called to construct a QoS Queue. The implementation should make
+ * the appropriate calls to configure QoS Queue according to 'details'.
+ *
+ * The contents of 'details' should be documented as valid for 'ovs_name'
+ * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
+ * (which is built as ovs-vswitchd.conf.db(8)).
+ *
+ * This function must return 0 if and only if it constructs
+ * QoS queue successfully.
+ */
+int (*qos_queue_construct)(const struct smap *details,
+   uint32_t queue_id, struct qos_conf *conf);
+
+/* Destroys the QoS Queue. */
+void (*qos_queue_destruct)(struct qos_conf *conf, uint32_t queue_id);
+
+/* Retrieves details of QoS Queue configuration into 'details'.
+ *
+ * The contents of 'details' should be documented as valid for 'ovs_name'
+ * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
+ * (which is built as ovs-vswitchd.conf.db(8)).
+ */
+int (*qos_queue_get)(struct smap *details, uint32_t queue_id,
+ const struct qos_conf *conf);
+
+/* Retrieves statistics of QoS Queue configuration into 'stats'. */
+int (*qos_queue_get_stats)(const struct qos_conf *conf, uint32_t queue_id,
+   struct netdev_queue_stats *stats);
+
+/* Setup the 'netdev_dpdk_queue_state' structure used by the dpdk queue
+ * dump functions.
+ */
+int (*qos_queue_dump_state_init)(const struct qos_conf *conf,
+ struct netdev_dpdk_queue_state *state);
  };
  
  /* dpdk_qos_ops for each type of user space QoS implementation */

@@ -4191,6 +4233,164 @@ netdev_dpdk_set_qos(struct netdev *netdev, const char 
*type,
  return error;
  }
  
+static int

+netdev_dpdk_get_queue(const struct netdev *netdev, uint32_t queue_id,
+  struct smap *details)
+{
+struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+struct qos_conf *qos_conf;
+int error = 0;
+
+ovs_mutex_lock(&dev->mutex);
+
+qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf);
+if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_get) {
+error = EOPNOTSUPP;
+} else {
+error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf);
+}
+
+ovs_mutex_unlock(&dev->mutex);
+
+return error;
+}
+
+static int
+netdev_dpdk_set_queue(struct netdev *netdev, uint32_t queue_id,
+  const struct smap *details)
+{
+struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+struct qos_conf *qos_conf;
+int error = 0;
+
+ovs_mutex_lock(&dev->mutex);
+
+qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf);
+if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_construct) {
+error = EOPNOTSUPP;
+} else {
+error = qos_conf->ops->qos_queue_construct(details, queue_id,
+   qos_conf);
+}
+
+if (error && error != EOPNOTSUPP) {
+VLOG_ERR("Failed to set QoS queue %d on port %s: %s",
+ queue_id, netdev_get_name(netdev), rte_strerror(error));
+}
+
+ovs_mutex_unlock(&dev->mutex);
+
+return error;
+}
+
+static int
+netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id)
+{
+struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+struct qos_conf *qos_conf;
+int error = 0;
+
+ovs_mutex_lock(&dev->mutex);
+
+qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf);
+if (qos_conf && qos_

[ovs-dev] [PATCH v5 1/2] netdev-dpdk: Add support for multi-queue QoS to the DPDK datapath

2020-01-14 Thread Eelco Chaudron
This patch adds support for multi-queue QoS to the DPDK datapath. Most of
the code is based on an earlier patch from a patchset sent out by
zhaozhanxu. The patch was titled "[ovs-dev, v2, 1/4] netdev-dpdk.c: Support
the multi-queue QoS configuration for dpdk datapath"

Co-authored-by: zhaozhanxu 
Signed-off-by: Eelco Chaudron 
---
 lib/netdev-dpdk.c |  219 -
 1 file changed, 213 insertions(+), 6 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 8198a0b..128963f 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -219,6 +219,13 @@ struct qos_conf {
 rte_spinlock_t lock;
 };
 
+/* QoS queue information used by the netdev queue dump functions. */
+struct netdev_dpdk_queue_state {
+uint32_t *queues;
+size_t cur_queue;
+size_t n_queues;
+};
+
 /* A particular implementation of dpdk QoS operations.
  *
  * The functions below return 0 if successful or a positive errno value on
@@ -285,6 +292,41 @@ struct dpdk_qos_ops {
  */
 int (*qos_run)(struct qos_conf *qos_conf, struct rte_mbuf **pkts,
int pkt_cnt, bool should_steal);
+
+/* Called to construct a QoS Queue. The implementation should make
+ * the appropriate calls to configure QoS Queue according to 'details'.
+ *
+ * The contents of 'details' should be documented as valid for 'ovs_name'
+ * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
+ * (which is built as ovs-vswitchd.conf.db(8)).
+ *
+ * This function must return 0 if and only if it constructs
+ * QoS queue successfully.
+ */
+int (*qos_queue_construct)(const struct smap *details,
+   uint32_t queue_id, struct qos_conf *conf);
+
+/* Destroys the QoS Queue. */
+void (*qos_queue_destruct)(struct qos_conf *conf, uint32_t queue_id);
+
+/* Retrieves details of QoS Queue configuration into 'details'.
+ *
+ * The contents of 'details' should be documented as valid for 'ovs_name'
+ * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
+ * (which is built as ovs-vswitchd.conf.db(8)).
+ */
+int (*qos_queue_get)(struct smap *details, uint32_t queue_id,
+ const struct qos_conf *conf);
+
+/* Retrieves statistics of QoS Queue configuration into 'stats'. */
+int (*qos_queue_get_stats)(const struct qos_conf *conf, uint32_t queue_id,
+   struct netdev_queue_stats *stats);
+
+/* Setup the 'netdev_dpdk_queue_state' structure used by the dpdk queue
+ * dump functions.
+ */
+int (*qos_queue_dump_state_init)(const struct qos_conf *conf,
+ struct netdev_dpdk_queue_state *state);
 };
 
 /* dpdk_qos_ops for each type of user space QoS implementation */
@@ -4191,6 +4233,164 @@ netdev_dpdk_set_qos(struct netdev *netdev, const char 
*type,
 return error;
 }
 
+static int
+netdev_dpdk_get_queue(const struct netdev *netdev, uint32_t queue_id,
+  struct smap *details)
+{
+struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+struct qos_conf *qos_conf;
+int error = 0;
+
+ovs_mutex_lock(&dev->mutex);
+
+qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf);
+if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_get) {
+error = EOPNOTSUPP;
+} else {
+error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf);
+}
+
+ovs_mutex_unlock(&dev->mutex);
+
+return error;
+}
+
+static int
+netdev_dpdk_set_queue(struct netdev *netdev, uint32_t queue_id,
+  const struct smap *details)
+{
+struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+struct qos_conf *qos_conf;
+int error = 0;
+
+ovs_mutex_lock(&dev->mutex);
+
+qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf);
+if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_construct) {
+error = EOPNOTSUPP;
+} else {
+error = qos_conf->ops->qos_queue_construct(details, queue_id,
+   qos_conf);
+}
+
+if (error && error != EOPNOTSUPP) {
+VLOG_ERR("Failed to set QoS queue %d on port %s: %s",
+ queue_id, netdev_get_name(netdev), rte_strerror(error));
+}
+
+ovs_mutex_unlock(&dev->mutex);
+
+return error;
+}
+
+static int
+netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id)
+{
+struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+struct qos_conf *qos_conf;
+int error = 0;
+
+ovs_mutex_lock(&dev->mutex);
+
+qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf);
+if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_destruct) {
+qos_conf->ops->qos_queue_destruct(qos_conf, queue_id);
+} else {
+error =  EOPNOTSUPP;
+}
+
+ovs_mutex_unlock(&dev->mutex);
+
+return er