Re: [ovs-dev] [PATCH 04/13] netdev-dpdk: Use RCU for egress QoS.

2016-10-12 Thread Daniele Di Proietto





On 12/10/2016 13:04, "Ben Pfaff"  wrote:

>On Tue, Oct 04, 2016 at 06:22:15PM -0700, Daniele Di Proietto wrote:
>> I think it's clearer to use RCU than to check for a pointer twice in the
>> fast path (before and after taking the spinlock). Now the spinlock is
>> integrated into 'qos_conf'.
>> 
>> 'qos_conf' objects cannot be modified, so, instead of having
>> 'qos_set()', we now have 'qos_is_equal()', which tells us if an object
>> must be destroyed and recreated.
>> 
>> With this patch we also avoid passing the netdev parameter to qos ops,
>> since it was unused most of the times.
>> 
>> Lastly, some duplication is removed.
>> 
>> CC: Ian Stokes 
>> Signed-off-by: Daniele Di Proietto 
>
>The use of rte_strerror(-error) in netdev_dpdk_set_qos() looks a little
>confusing to me.  Is ->qos_construct() supposed to return a negative
>number for errors?  But that doesn't seem to mesh with the assignment
>"error = EOPNOTSUPP;" earlier in netdev_dpdk_set_qos().  But maybe I'm
>not familiar enough with how DPDK reports errors.

You're right, there is a problem.  qos_construct() only returns positive
error codes, because it takes care of inverting the return value of
qos_construct().  I removed the minus sign


>
>Acked-by: Ben Pfaff 

and applied this to master, thanks
___
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev


Re: [ovs-dev] [PATCH 04/13] netdev-dpdk: Use RCU for egress QoS.

2016-10-12 Thread Ben Pfaff
On Tue, Oct 04, 2016 at 06:22:15PM -0700, Daniele Di Proietto wrote:
> I think it's clearer to use RCU than to check for a pointer twice in the
> fast path (before and after taking the spinlock). Now the spinlock is
> integrated into 'qos_conf'.
> 
> 'qos_conf' objects cannot be modified, so, instead of having
> 'qos_set()', we now have 'qos_is_equal()', which tells us if an object
> must be destroyed and recreated.
> 
> With this patch we also avoid passing the netdev parameter to qos ops,
> since it was unused most of the times.
> 
> Lastly, some duplication is removed.
> 
> CC: Ian Stokes 
> Signed-off-by: Daniele Di Proietto 

The use of rte_strerror(-error) in netdev_dpdk_set_qos() looks a little
confusing to me.  Is ->qos_construct() supposed to return a negative
number for errors?  But that doesn't seem to mesh with the assignment
"error = EOPNOTSUPP;" earlier in netdev_dpdk_set_qos().  But maybe I'm
not familiar enough with how DPDK reports errors.

Acked-by: Ben Pfaff 
___
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev


[ovs-dev] [PATCH 04/13] netdev-dpdk: Use RCU for egress QoS.

2016-10-04 Thread Daniele Di Proietto
I think it's clearer to use RCU than to check for a pointer twice in the
fast path (before and after taking the spinlock). Now the spinlock is
integrated into 'qos_conf'.

'qos_conf' objects cannot be modified, so, instead of having
'qos_set()', we now have 'qos_is_equal()', which tells us if an object
must be destroyed and recreated.

With this patch we also avoid passing the netdev parameter to qos ops,
since it was unused most of the times.

Lastly, some duplication is removed.

CC: Ian Stokes 
Signed-off-by: Daniele Di Proietto 
---
 lib/netdev-dpdk.c | 229 ++
 1 file changed, 92 insertions(+), 137 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index f4ee5de..f3f0b27 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -193,6 +193,7 @@ static int rte_eal_init_ret = ENODEV;
  */
 struct qos_conf {
 const struct dpdk_qos_ops *ops;
+rte_spinlock_t lock;
 };
 
 /* A particular implementation of dpdk QoS operations.
@@ -206,48 +207,45 @@ struct dpdk_qos_ops {
 /* Name of the QoS type */
 const char *qos_name;
 
-/* Called to construct the QoS implementation on 'netdev'. The
- * implementation should make the appropriate calls to configure QoS
- * according to 'details'. The implementation may assume that any current
- * QoS configuration already installed should be destroyed before
- * constructing the new configuration.
+/* Called to construct a qos_conf object. The implementation should make
+ * the appropriate calls to configure QoS 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 sets 'netdev->qos_conf'
- * to an initialized 'struct qos_conf'.
+ * This function must return 0 if and only if it sets '*conf' to an
+ * initialized 'struct qos_conf'.
  *
  * For all QoS implementations it should always be non-null.
  */
-int (*qos_construct)(struct netdev *netdev, const struct smap *details);
+int (*qos_construct)(const struct smap *details, struct qos_conf **conf);
 
 /* Destroys the data structures allocated by the implementation as part of
- * 'qos_conf.
+ * 'qos_conf'.
  *
  * For all QoS implementations it should always be non-null.
  */
-void (*qos_destruct)(struct netdev *netdev, struct qos_conf *conf);
+void (*qos_destruct)(struct qos_conf *conf);
 
-/* Retrieves details of 'netdev->qos_conf' configuration into 'details'.
+/* Retrieves details of 'conf' 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_get)(const struct netdev *netdev, struct smap *details);
+int (*qos_get)(const struct qos_conf *conf, struct smap *details);
 
-/* Reconfigures 'netdev->qos_conf' according to 'details', performing any
- * required calls to complete the reconfiguration.
+/* Returns true if 'conf' is already configured 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 may be null if 'qos_conf' is not configurable.
+ * For all QoS implementations it should always be non-null.
  */
-int (*qos_set)(struct netdev *netdev, const struct smap *details);
+bool (*qos_is_equal)(const struct qos_conf *conf,
+ const struct smap *details);
 
 /* Modify an array of rte_mbufs. The modification is specific to
  * each qos implementation.
@@ -262,8 +260,8 @@ struct dpdk_qos_ops {
  *
  * For all QoS implementations it should always be non-null.
  */
-int (*qos_run)(struct netdev *netdev, struct rte_mbuf **pkts,
-   int pkt_cnt);
+int (*qos_run)(struct qos_conf *qos_conf, struct rte_mbuf **pkts,
+   int pkt_cnt);
 };
 
 /* dpdk_qos_ops for each type of user space QoS implementation */
@@ -372,8 +370,7 @@ struct netdev_dpdk {
 struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex);
 
 /* QoS configuration and lock for the device */
-struct qos_conf *qos_conf;
-rte_spinlock_t qos_lock;
+OVSRCU_TYPE(struct qos_conf *) qos_conf;
 
 /* The following properties cannot be changed when a device is running,
  * so we remember the request and update them next time
@@ -855,11 +852,8 @@ netdev_dpdk_init(struct netdev *netdev, unsigned int 
port_no,
 goto unlock;
 }
 
-/* Initialise QoS configuration to NULL