i40evf: set flags before sending message
authorMitch Williams <mitch.a.williams@intel.com>
Wed, 4 Jun 2014 20:41:38 +0000 (20:41 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 1 Jul 2014 06:46:11 +0000 (23:46 -0700)
In some circumstances, the firmware could beat us to the punch, and the
reply from the PF would come back before we were able to properly modify
the aq_pending and aq_required flags. This would mess up the flags and
put the driver in an indeterminate state, much like Schrödinger's cat.
However, unlike the cat, the driver is definitely dead.

To fix this, simply set the flags before sending the request to the AQ.
This way, it won't matter if the interrupt comes back too soon.

Change-ID: I9784655e475675ebcb3140cc7f36f4a96aaadce5
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index 0ed2ad7e4eee2feb3fe6241b94c7a853158d067d..66d12f5b4ca83d0de07c7b8fbc567ccaa6def1dd 100644 (file)
@@ -248,11 +248,11 @@ void i40evf_configure_queues(struct i40evf_adapter *adapter)
                vqpi++;
        }
 
+       adapter->aq_pending |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
+       adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
        i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES,
                           (u8 *)vqci, len);
        kfree(vqci);
-       adapter->aq_pending |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
-       adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
 }
 
 /**
@@ -275,10 +275,10 @@ void i40evf_enable_queues(struct i40evf_adapter *adapter)
        vqs.vsi_id = adapter->vsi_res->vsi_id;
        vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1;
        vqs.rx_queues = vqs.tx_queues;
-       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
-                          (u8 *)&vqs, sizeof(vqs));
        adapter->aq_pending |= I40EVF_FLAG_AQ_ENABLE_QUEUES;
        adapter->aq_required &= ~I40EVF_FLAG_AQ_ENABLE_QUEUES;
+       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
+                          (u8 *)&vqs, sizeof(vqs));
 }
 
 /**
@@ -301,10 +301,10 @@ void i40evf_disable_queues(struct i40evf_adapter *adapter)
        vqs.vsi_id = adapter->vsi_res->vsi_id;
        vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1;
        vqs.rx_queues = vqs.tx_queues;
-       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DISABLE_QUEUES,
-                          (u8 *)&vqs, sizeof(vqs));
        adapter->aq_pending |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
        adapter->aq_required &= ~I40EVF_FLAG_AQ_DISABLE_QUEUES;
+       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DISABLE_QUEUES,
+                          (u8 *)&vqs, sizeof(vqs));
 }
 
 /**
@@ -352,11 +352,11 @@ void i40evf_map_queues(struct i40evf_adapter *adapter)
        vimi->vecmap[v_idx].txq_map = 0;
        vimi->vecmap[v_idx].rxq_map = 0;
 
+       adapter->aq_pending |= I40EVF_FLAG_AQ_MAP_VECTORS;
+       adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS;
        i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP,
                           (u8 *)vimi, len);
        kfree(vimi);
-       adapter->aq_pending |= I40EVF_FLAG_AQ_MAP_VECTORS;
-       adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS;
 }
 
 /**
@@ -413,12 +413,11 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
                        f->add = false;
                }
        }
+       adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
+       adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
        i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
                           (u8 *)veal, len);
        kfree(veal);
-       adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
-       adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
-
 }
 
 /**
@@ -475,11 +474,11 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
                        kfree(f);
                }
        }
+       adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
+       adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
        i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
                           (u8 *)veal, len);
        kfree(veal);
-       adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
-       adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
 }
 
 /**
@@ -536,10 +535,10 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
                        f->add = false;
                }
        }
-       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
-       kfree(vvfl);
        adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
        adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
+       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
+       kfree(vvfl);
 }
 
 /**
@@ -597,10 +596,10 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
                        kfree(f);
                }
        }
-       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
-       kfree(vvfl);
        adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
        adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
+       i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
+       kfree(vvfl);
 }
 
 /**