dp_netdev_free() must free 'dp->upcall_rwlock', but when upcalls are disabled (if the datapath is being freed upcalls should be disabled) 'dp->upcall_rwlock' is taken and freeing it causes an assertion to fail.
This commit takes makes sure that the upcalls are disabled and releases 'dp->upcall_rwlock' before freeing it. A simple testcase is added to detect the failure. Signed-off-by: Daniele Di Proietto <ddiproie...@vmware.com> --- lib/dpif-netdev.c | 17 ++++++++++++++++- tests/dpif-netdev.at | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2476435..7978959 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -592,6 +592,18 @@ dpif_netdev_open(const struct dpif_class *class, const char *name, return error; } +static void +dp_netdev_destroy_upcall_lock(struct dp_netdev *dp) + OVS_NO_THREAD_SAFETY_ANALYSIS +{ + /* Check that upcalls are disabled, i.e. that the rwlock is taken */ + ovs_assert(fat_rwlock_tryrdlock(&dp->upcall_rwlock)); + + /* Before freeing a lock we should release it */ + fat_rwlock_unlock(&dp->upcall_rwlock); + fat_rwlock_destroy(&dp->upcall_rwlock); +} + /* Requires dp_netdev_mutex so that we can't get a new reference to 'dp' * through the 'dp_netdevs' shash while freeing 'dp'. */ static void @@ -625,7 +637,10 @@ dp_netdev_free(struct dp_netdev *dp) ovs_mutex_destroy(&dp->flow_mutex); seq_destroy(dp->port_seq); cmap_destroy(&dp->ports); - fat_rwlock_destroy(&dp->upcall_rwlock); + + /* Upcalls must be disabled at this point */ + dp_netdev_destroy_upcall_lock(dp); + latch_destroy(&dp->exit_latch); emc_cache_uninit(&dp->flow_cache); diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index c50b1a8..69d561b 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at @@ -122,3 +122,11 @@ skb_priority(0),skb_mark(0/0),recirc_id(0),dp_hash(0/0),in_port(1),eth(src=50:54 OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([dpif-netdev - Datapath removal]) +OVS_VSWITCHD_START() +AT_CHECK([ovs-appctl dpctl/add-dp dummy@br0]) +AT_CHECK([ovs-appctl dpctl/del-dp dummy@br0]) + +OVS_VSWITCHD_STOP +AT_CLEANUP -- 2.1.0.rc1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev