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