Commit 92d0d515d ("dpif-netlink: Probe for broken Linux meter
implementations.") introduced a deadlock on the 'once' structure
declared in probe_broken_meters() with the following callstack:
probe_broken_meters()
probe_broken_meters__()
dpif_netlink_meter_set()
probe_broken_meters()
This commit introduce a modified version of dpif_netlink_meter_set()
that sets a meter without calling the probe.
Reported-by: Numan Siddique <[email protected]>
Signed-off-by: Justin Pettit <[email protected]>
---
lib/dpif-netlink.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index e2810a83a656..e6d5a6ec5757 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -3223,13 +3223,9 @@ dpif_netlink_meter_get_features(const struct dpif *dpif_,
}
static int
-dpif_netlink_meter_set(struct dpif *dpif_, ofproto_meter_id meter_id,
- struct ofputil_meter_config *config)
+dpif_netlink_meter_set__(struct dpif *dpif_, ofproto_meter_id meter_id,
+ struct ofputil_meter_config *config)
{
- if (probe_broken_meters(dpif_)) {
- return ENOMEM;
- }
-
struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
struct ofpbuf buf, *msg;
uint64_t stub[1024 / 8];
@@ -3303,6 +3299,17 @@ dpif_netlink_meter_set(struct dpif *dpif_,
ofproto_meter_id meter_id,
return 0;
}
+static int
+dpif_netlink_meter_set(struct dpif *dpif_, ofproto_meter_id meter_id,
+ struct ofputil_meter_config *config)
+{
+ if (probe_broken_meters(dpif_)) {
+ return ENOMEM;
+ }
+
+ return dpif_netlink_meter_set__(dpif_, meter_id, config);
+}
+
/* Retrieve statistics and/or delete meter 'meter_id'. Statistics are
* stored in 'stats', if it is not null. If 'command' is
* OVS_METER_CMD_DEL, the meter is deleted and statistics are optionally
@@ -3416,9 +3423,10 @@ probe_broken_meters__(struct dpif *dpif)
struct ofputil_meter_config config2 = { 2, OFPMF13_KBPS, 1, &band};
/* Try adding two meters and make sure that they both come back with
- * the proper meter id. */
- dpif_netlink_meter_set(dpif, id1, &config1);
- dpif_netlink_meter_set(dpif, id2, &config2);
+ * the proper meter id. Use the "__" version so that we don't cause
+ * a recurve deadlock. */
+ dpif_netlink_meter_set__(dpif, id1, &config1);
+ dpif_netlink_meter_set__(dpif, id2, &config2);
if (dpif_netlink_meter_get(dpif, id1, NULL, 0)
|| dpif_netlink_meter_get(dpif, id2, NULL, 0)) {
--
2.17.1
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev