diff mbox series

[ovs-dev,RFC] bridge: Allow manual notifications about interfaces' updates.

Message ID 20191101123158.28847-1-i.maximets@ovn.org
State Superseded
Headers show
Series [ovs-dev,RFC] bridge: Allow manual notifications about interfaces' updates. | expand

Commit Message

Ilya Maximets Nov. 1, 2019, 12:31 p.m. UTC
Sometimes interface updates could happen in a way ifnotifier is not
able to catch.  For example some heavy operations (device reset) in
netdev-dpdk could require re-applying of the bridge configuration.

For this purpose new function 'bridge_report_if_update' introduced.
It could be called directly by the code that aware about changes.

Since the calls could go from the different thread contexts we need
to protect the sequence number itself from updates before allocation
and after destruction.  Using the same seq mutex for this purpose to
not introduce another one.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---

Sending this as RFC that might be useful in context of the following patch:
https://mail.openvswitch.org/pipermail/ovs-dev/2019-October/364155.html

It will allow us to not introduce heavy dpdk notifier just to update
one sequence number on RTE_ETH_EVENT_INTR_RESET events. We could also
use it to report other changes from DPDK, e.g. LSC interrupts.

 vswitchd/bridge.c | 26 +++++++++++++++++++++++++-
 vswitchd/bridge.h |  2 ++
 2 files changed, 27 insertions(+), 1 deletion(-)

Comments

Eelco Chaudron Nov. 4, 2019, 11:04 a.m. UTC | #1
On 1 Nov 2019, at 13:31, Ilya Maximets wrote:

> Sometimes interface updates could happen in a way ifnotifier is not
> able to catch.  For example some heavy operations (device reset) in
> netdev-dpdk could require re-applying of the bridge configuration.
>
> For this purpose new function 'bridge_report_if_update' introduced.
> It could be called directly by the code that aware about changes.
>
> Since the calls could go from the different thread contexts we need
> to protect the sequence number itself from updates before allocation
> and after destruction.  Using the same seq mutex for this purpose to
> not introduce another one.
>
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
> ---
>
> Sending this as RFC that might be useful in context of the following 
> patch:
> https://mail.openvswitch.org/pipermail/ovs-dev/2019-October/364155.html
>
> It will allow us to not introduce heavy dpdk notifier just to update
> one sequence number on RTE_ETH_EVENT_INTR_RESET events. We could also
> use it to report other changes from DPDK, e.g. LSC interrupts.
>
>  vswitchd/bridge.c | 26 +++++++++++++++++++++++++-
>  vswitchd/bridge.h |  2 ++
>  2 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index 9095ebf5d..68239783f 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -252,6 +252,7 @@ static long long int aa_refresh_timer = LLONG_MIN;
>  static struct if_notifier *ifnotifier;
>  static struct seq *ifaces_changed;
>  static uint64_t last_ifaces_changed;
> +static bool ifaces_updates_enabled = false;
>
>  /* Default/min/max packet-in queue sizes towards the controllers. */
>  #define BRIDGE_CONTROLLER_PACKET_QUEUE_DEFAULT_SIZE 100
> @@ -403,7 +404,19 @@ bridge_init_ofproto(const struct 
> ovsrec_open_vswitch *cfg)
>  static void
>  if_change_cb(void *aux OVS_UNUSED)
>  {
> -    seq_change(ifaces_changed);
> +    seq_lock();
> +    if (ifaces_updates_enabled) {
> +        seq_change_protected(ifaces_changed);
> +    }
> +    seq_unlock();
> +}
> +
> +static void
> +if_updates_enable(bool enable)
> +{
> +    seq_lock();
> +    ifaces_updates_enabled = enable;
> +    seq_unlock();
>  }
>
>  static bool
> @@ -422,6 +435,15 @@ if_notifier_changed(struct if_notifier *notifier 
> OVS_UNUSED)
>  
>  /* Public functions. */
>
> +/* Raports that some interfaces were changed from the outside of OVS.
> + * Could be used for catching events that could not be tracked by
> + * if_notifier, e.g. port updates in netdev-dpdk. */

How would I call this directly from the netdev-dpdk code? The later is 
in /lib which should this not be isolated from /vswitchd, i.e. /vswitchd 
can call into /lib function but not the other way around?

> +void
> +bridge_report_if_update(void)
> +{
> +    if_change_cb(NULL);
> +}
> +
>  /* Initializes the bridge module, configuring it to obtain its 
> configuration
>   * from an OVSDB server accessed over 'remote', which should be a 
> string in a
>   * form acceptable to ovsdb_idl_create(). */
> @@ -529,11 +551,13 @@ bridge_init(const char *remote)
>      ifaces_changed = seq_create();
>      last_ifaces_changed = seq_read(ifaces_changed);
>      ifnotifier = if_notifier_create(if_change_cb, NULL);
> +    if_updates_enable(true);
>  }
>
>  void
>  bridge_exit(bool delete_datapath)
>  {
> +    if_updates_enable(false);
>      if_notifier_destroy(ifnotifier);
>      seq_destroy(ifaces_changed);
>
> diff --git a/vswitchd/bridge.h b/vswitchd/bridge.h
> index 8b2fce451..69a3db2bc 100644
> --- a/vswitchd/bridge.h
> +++ b/vswitchd/bridge.h
> @@ -28,4 +28,6 @@ void bridge_wait(void);
>
>  void bridge_get_memory_usage(struct simap *usage);
>
> +void bridge_report_if_update(void);
> +
>  #endif /* bridge.h */
> -- 
> 2.17.1
Ilya Maximets Nov. 4, 2019, 1:20 p.m. UTC | #2
On 04.11.2019 12:04, Eelco Chaudron wrote:
> 
> 
> On 1 Nov 2019, at 13:31, Ilya Maximets wrote:
> 
>> Sometimes interface updates could happen in a way ifnotifier is not
>> able to catch.  For example some heavy operations (device reset) in
>> netdev-dpdk could require re-applying of the bridge configuration.
>>
>> For this purpose new function 'bridge_report_if_update' introduced.
>> It could be called directly by the code that aware about changes.
>>
>> Since the calls could go from the different thread contexts we need
>> to protect the sequence number itself from updates before allocation
>> and after destruction.  Using the same seq mutex for this purpose to
>> not introduce another one.
>>
>> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
>> ---
>>
>> Sending this as RFC that might be useful in context of the following patch:
>> https://mail.openvswitch.org/pipermail/ovs-dev/2019-October/364155.html
>>
>> It will allow us to not introduce heavy dpdk notifier just to update
>> one sequence number on RTE_ETH_EVENT_INTR_RESET events. We could also
>> use it to report other changes from DPDK, e.g. LSC interrupts.
>>
>>  vswitchd/bridge.c | 26 +++++++++++++++++++++++++-
>>  vswitchd/bridge.h |  2 ++
>>  2 files changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
>> index 9095ebf5d..68239783f 100644
>> --- a/vswitchd/bridge.c
>> +++ b/vswitchd/bridge.c
>> @@ -252,6 +252,7 @@ static long long int aa_refresh_timer = LLONG_MIN;
>>  static struct if_notifier *ifnotifier;
>>  static struct seq *ifaces_changed;
>>  static uint64_t last_ifaces_changed;
>> +static bool ifaces_updates_enabled = false;
>>
>>  /* Default/min/max packet-in queue sizes towards the controllers. */
>>  #define BRIDGE_CONTROLLER_PACKET_QUEUE_DEFAULT_SIZE 100
>> @@ -403,7 +404,19 @@ bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
>>  static void
>>  if_change_cb(void *aux OVS_UNUSED)
>>  {
>> -    seq_change(ifaces_changed);
>> +    seq_lock();
>> +    if (ifaces_updates_enabled) {
>> +        seq_change_protected(ifaces_changed);
>> +    }
>> +    seq_unlock();
>> +}
>> +
>> +static void
>> +if_updates_enable(bool enable)
>> +{
>> +    seq_lock();
>> +    ifaces_updates_enabled = enable;
>> +    seq_unlock();
>>  }
>>
>>  static bool
>> @@ -422,6 +435,15 @@ if_notifier_changed(struct if_notifier *notifier OVS_UNUSED)
>>  
>>  /* Public functions. */
>>
>> +/* Raports that some interfaces were changed from the outside of OVS.
>> + * Could be used for catching events that could not be tracked by
>> + * if_notifier, e.g. port updates in netdev-dpdk. */
> 
> How would I call this directly from the netdev-dpdk code? The later is in /lib which should this not be isolated from /vswitchd, i.e. /vswitchd can call into /lib function but not the other way around?

Yes, you're right.  I'll move the code to 'lib'.

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 9095ebf5d..68239783f 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -252,6 +252,7 @@  static long long int aa_refresh_timer = LLONG_MIN;
 static struct if_notifier *ifnotifier;
 static struct seq *ifaces_changed;
 static uint64_t last_ifaces_changed;
+static bool ifaces_updates_enabled = false;
 
 /* Default/min/max packet-in queue sizes towards the controllers. */
 #define BRIDGE_CONTROLLER_PACKET_QUEUE_DEFAULT_SIZE 100
@@ -403,7 +404,19 @@  bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
 static void
 if_change_cb(void *aux OVS_UNUSED)
 {
-    seq_change(ifaces_changed);
+    seq_lock();
+    if (ifaces_updates_enabled) {
+        seq_change_protected(ifaces_changed);
+    }
+    seq_unlock();
+}
+
+static void
+if_updates_enable(bool enable)
+{
+    seq_lock();
+    ifaces_updates_enabled = enable;
+    seq_unlock();
 }
 
 static bool
@@ -422,6 +435,15 @@  if_notifier_changed(struct if_notifier *notifier OVS_UNUSED)
 
 /* Public functions. */
 
+/* Raports that some interfaces were changed from the outside of OVS.
+ * Could be used for catching events that could not be tracked by
+ * if_notifier, e.g. port updates in netdev-dpdk. */
+void
+bridge_report_if_update(void)
+{
+    if_change_cb(NULL);
+}
+
 /* Initializes the bridge module, configuring it to obtain its configuration
  * from an OVSDB server accessed over 'remote', which should be a string in a
  * form acceptable to ovsdb_idl_create(). */
@@ -529,11 +551,13 @@  bridge_init(const char *remote)
     ifaces_changed = seq_create();
     last_ifaces_changed = seq_read(ifaces_changed);
     ifnotifier = if_notifier_create(if_change_cb, NULL);
+    if_updates_enable(true);
 }
 
 void
 bridge_exit(bool delete_datapath)
 {
+    if_updates_enable(false);
     if_notifier_destroy(ifnotifier);
     seq_destroy(ifaces_changed);
 
diff --git a/vswitchd/bridge.h b/vswitchd/bridge.h
index 8b2fce451..69a3db2bc 100644
--- a/vswitchd/bridge.h
+++ b/vswitchd/bridge.h
@@ -28,4 +28,6 @@  void bridge_wait(void);
 
 void bridge_get_memory_usage(struct simap *usage);
 
+void bridge_report_if_update(void);
+
 #endif /* bridge.h */