Hey Ben, Could you help review this? also,
Since, there can be some scenarios about netdev deletion we do not know, Thanks, Alex Wang, On Thu, May 15, 2014 at 3:01 AM, Ryan Wilson <wr...@nicira.com> wrote: > When the user changes port type (i.e. changing p0 from type 'internal' to > 'gre'), the netdev must first be deleted, then re-created with the new > type. > Deleting the netdev requires there exist no more references to the netdev. > However, the xlate cache holds references to netdevs and the cache is only > invalidated by revalidator threads. Thus, if cache is not invalidated > prior to > the netdev being re-created, the netdev will not be able to be re-created > and > the configuration change will fail. > > This patch always removes the netdev from the global netdev shash when the > user changes port type. This ensures that the new netdev can always be > created > while handler and revalidator threads can retain references to the old > netdev > until they are finished. > --- > lib/netdev.c | 26 +++++++++++++++++++++++++- > lib/netdev.h | 1 + > vswitchd/bridge.c | 2 +- > 3 files changed, 27 insertions(+), 2 deletions(-) > > diff --git a/lib/netdev.c b/lib/netdev.c > index 5bf2220..af42c9a 100644 > --- a/lib/netdev.c > +++ b/lib/netdev.c > @@ -489,7 +489,9 @@ netdev_unref(struct netdev *dev) > > dev->netdev_class->destruct(dev); > > - shash_delete(&netdev_shash, dev->node); > + if (dev->node) { > + shash_delete(&netdev_shash, dev->node); > + } > free(dev->name); > dev->netdev_class->dealloc(dev); > ovs_mutex_unlock(&netdev_mutex); > @@ -515,6 +517,28 @@ netdev_close(struct netdev *netdev) > } > } > > +/* Removes 'netdev' from global hash table and destroys 'netdev' if > possible. > + * > + * This allows handler and revalidator threads to still retain references > + * to this netdev while the main thread changes interface configuration. > + * > + * This function should only be called by the main thread when closing > + * netdevs during user configuration changes. Otherwise, netdev_close > should be > + * used to close netdevs. */ > +void > +netdev_remove(struct netdev *netdev) > +{ > + if (netdev) { > + ovs_mutex_lock(&netdev_mutex); > + if (netdev->node) { > + shash_delete(&netdev_shash, netdev->node); > + netdev->node = NULL; > + netdev_change_seq_changed(netdev); > + } > + netdev_unref(netdev); > + } > +} > + > /* Parses 'netdev_name_', which is of the form [type@]name into its > component > * pieces. 'name' and 'type' must be freed by the caller. */ > void > diff --git a/lib/netdev.h b/lib/netdev.h > index 7cb3c80..9b35972 100644 > --- a/lib/netdev.h > +++ b/lib/netdev.h > @@ -141,6 +141,7 @@ bool netdev_is_pmd(const struct netdev *netdev); > int netdev_open(const char *name, const char *type, struct netdev > **netdevp); > > struct netdev *netdev_ref(const struct netdev *); > +void netdev_remove(struct netdev *); > void netdev_close(struct netdev *); > > void netdev_parse_name(const char *netdev_name, char **name, char **type); > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c > index 43c109c..7189340 100644 > --- a/vswitchd/bridge.c > +++ b/vswitchd/bridge.c > @@ -3471,7 +3471,7 @@ iface_destroy__(struct iface *iface) > list_remove(&iface->port_elem); > hmap_remove(&br->iface_by_name, &iface->name_node); > > - netdev_close(iface->netdev); > + netdev_remove(iface->netdev); > > free(iface->name); > free(iface); > -- > 1.7.9.5 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev >
_______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev