summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/interface.c
diff options
context:
space:
mode:
authorGeorgi Savov <gsavov@cisco.com>2016-02-25 12:56:03 -0500
committerGerrit Code Review <gerrit@fd.io>2016-03-01 01:22:42 +0000
commit3a03598aab24500568ecd1e80b1b0d6bb66eb59d (patch)
treeb5cce4c0379b79612a765dbd189c0bed4e9f1e4d /vnet/vnet/interface.c
parent679ea7951514736e8c8318b434ad7162b27eea84 (diff)
Fix for TX and RX descriptor queue lockup
On admin up/down changes the TX and RX queues were getting locked up for VNET_DPDK_PMD_VMXNET3 interfaces. The fix is to ensure the interface is in admin down before touching the hardware. Change-Id: Ia264d95355a860607bff7ada00d2be48f91e6dd9 Signed-off-by: Todd Foggoa (tfoggoa) <tfoggoa@cisco.com>
Diffstat (limited to 'vnet/vnet/interface.c')
-rw-r--r--vnet/vnet/interface.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/vnet/vnet/interface.c b/vnet/vnet/interface.c
index ffe0b672acd..6c8823f14bc 100644
--- a/vnet/vnet/interface.c
+++ b/vnet/vnet/interface.c
@@ -325,6 +325,7 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, u32 flag
u32 mask;
clib_error_t * error = 0;
u32 is_create = (helper_flags & VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE) != 0;
+ u32 old_flags;
mask = VNET_SW_INTERFACE_FLAG_ADMIN_UP | VNET_SW_INTERFACE_FLAG_PUNT;
flags &= mask;
@@ -397,13 +398,32 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, u32 flag
vnet_hw_interface_class_t * hw_class = vnet_get_hw_interface_class (vnm, hi->hw_class_index);
vnet_device_class_t * dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
- if (dev_class->admin_up_down_function
- && (error = dev_class->admin_up_down_function (vnm, si->hw_if_index, flags)))
- goto done;
-
- if (hw_class->admin_up_down_function
- && (error = hw_class->admin_up_down_function (vnm, si->hw_if_index, flags)))
- goto done;
+ /* save the si admin up flag */
+ old_flags = si->flags;
+
+ /* update si admin up flag in advance if we are going admin down */
+ if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
+ si->flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP;
+
+ if (dev_class->admin_up_down_function
+ && (error = dev_class->admin_up_down_function(vnm,
+ si->hw_if_index,
+ flags)))
+ {
+ /* restore si admin up flag to it's original state on errors */
+ si->flags = old_flags;
+ goto done;
+ }
+
+ if (hw_class->admin_up_down_function
+ && (error = hw_class->admin_up_down_function(vnm,
+ si->hw_if_index,
+ flags)))
+ {
+ /* restore si admin up flag to it's original state on errors */
+ si->flags = old_flags;
+ goto done;
+ }
/* Admin down implies link down. */
if (! (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)