[ovs-dev] [PATCH 2.5] ifnotifier: do not wake up when there is no db connection
Thadeu Lima de Souza Cascardo
cascardo at redhat.com
Mon Nov 21 19:02:10 UTC 2016
When bridge uses the interface notifier, it wakes up until a reconfiguration
takes place. However, if there is no connection or a lock contention to the
database, the check for reconfiguration will not take place.
This uses a seq and only seq_wait when checking for the interfaces change.
This is easily reproduced by starting ovs-vswitchd without starting
ovsdb-server, and then creating a new system interface, like using
'ip link add type veth'. ovs-vswitchd will then consume 100% CPU.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at redhat.com>
---
Backport to OVS 2.5.
---
vswitchd/bridge.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 4ff77c1..591ecd2 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -223,7 +223,8 @@ static long long int aa_refresh_timer = LLONG_MIN;
* will be reconfigured.
*/
static struct if_notifier *ifnotifier;
-static bool ifaces_changed = false;
+static struct seq *ifaces_changed;
+static uint64_t last_ifaces_changed;
static void add_del_bridges(const struct ovsrec_open_vswitch *);
static void bridge_run__(void);
@@ -386,7 +387,21 @@ bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
static void
if_change_cb(void *aux OVS_UNUSED)
{
- ifaces_changed = true;
+ seq_change(ifaces_changed);
+}
+
+static bool
+if_notifier_changed(struct if_notifier *notifier OVS_UNUSED)
+{
+ uint64_t new_seq;
+ bool changed = false;
+ new_seq = seq_read(ifaces_changed);
+ if (new_seq != last_ifaces_changed) {
+ changed = true;
+ last_ifaces_changed = new_seq;
+ }
+ seq_wait(ifaces_changed, last_ifaces_changed);
+ return changed;
}
/* Public functions. */
@@ -491,6 +506,8 @@ bridge_init(const char *remote)
stp_init();
lldp_init();
rstp_init();
+ ifaces_changed = seq_create();
+ last_ifaces_changed = seq_read(ifaces_changed);
ifnotifier = if_notifier_create(if_change_cb, NULL);
}
@@ -500,6 +517,7 @@ bridge_exit(void)
struct bridge *br, *next_br;
if_notifier_destroy(ifnotifier);
+ seq_destroy(ifaces_changed);
HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) {
bridge_destroy(br, false);
}
@@ -2969,12 +2987,10 @@ bridge_run(void)
}
}
- if (ovsdb_idl_get_seqno(idl) != idl_seqno || vlan_splinters_changed
- || ifaces_changed) {
+ if (ovsdb_idl_get_seqno(idl) != idl_seqno || vlan_splinters_changed ||
+ if_notifier_changed(ifnotifier)) {
struct ovsdb_idl_txn *txn;
- ifaces_changed = false;
-
idl_seqno = ovsdb_idl_get_seqno(idl);
txn = ovsdb_idl_txn_create(idl);
bridge_reconfigure(cfg ? cfg : &null_cfg);
@@ -3032,9 +3048,6 @@ bridge_wait(void)
}
if_notifier_wait();
- if (ifaces_changed) {
- poll_immediate_wake();
- }
sset_init(&types);
ofproto_enumerate_types(&types);
--
2.7.4
More information about the dev
mailing list