aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2015-09-28 20:31:26 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-28 23:57:14 -0400
commit43ae93a93e8c95c5e6389dc8e11704712b1ab2e9 (patch)
treee89c6388d42dbad5d1ac9b1ee65c0377190de01b
parentc4bbac3913c0d649898a0d767728a585869a7d7d (diff)
i40e/i40evf: check for stopped admin queue
It's possible that while we are waiting for the spinlock, another entity (that owns the spinlock) has shut down the admin queue. If we then attempt to use the queue, we will panic. Add a check for this condition on the receive side. This matches an existing check on the send queue side. Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c9
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.c9
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 3e0d20037675..62488a67149d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -946,6 +946,13 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
946 /* take the lock before we start messing with the ring */ 946 /* take the lock before we start messing with the ring */
947 mutex_lock(&hw->aq.arq_mutex); 947 mutex_lock(&hw->aq.arq_mutex);
948 948
949 if (hw->aq.arq.count == 0) {
950 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
951 "AQRX: Admin queue not initialized.\n");
952 ret_code = I40E_ERR_QUEUE_EMPTY;
953 goto clean_arq_element_err;
954 }
955
949 /* set next_to_use to head */ 956 /* set next_to_use to head */
950 ntu = (rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK); 957 ntu = (rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK);
951 if (ntu == ntc) { 958 if (ntu == ntc) {
@@ -1007,6 +1014,8 @@ clean_arq_element_out:
1007 /* Set pending if needed, unlock and return */ 1014 /* Set pending if needed, unlock and return */
1008 if (pending != NULL) 1015 if (pending != NULL)
1009 *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc); 1016 *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
1017
1018clean_arq_element_err:
1010 mutex_unlock(&hw->aq.arq_mutex); 1019 mutex_unlock(&hw->aq.arq_mutex);
1011 1020
1012 if (i40e_is_nvm_update_op(&e->desc)) { 1021 if (i40e_is_nvm_update_op(&e->desc)) {
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
index f08450b90774..929d47152bf2 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -887,6 +887,13 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
887 /* take the lock before we start messing with the ring */ 887 /* take the lock before we start messing with the ring */
888 mutex_lock(&hw->aq.arq_mutex); 888 mutex_lock(&hw->aq.arq_mutex);
889 889
890 if (hw->aq.arq.count == 0) {
891 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
892 "AQRX: Admin queue not initialized.\n");
893 ret_code = I40E_ERR_QUEUE_EMPTY;
894 goto clean_arq_element_err;
895 }
896
890 /* set next_to_use to head */ 897 /* set next_to_use to head */
891 ntu = (rd32(hw, hw->aq.arq.head) & I40E_VF_ARQH1_ARQH_MASK); 898 ntu = (rd32(hw, hw->aq.arq.head) & I40E_VF_ARQH1_ARQH_MASK);
892 if (ntu == ntc) { 899 if (ntu == ntc) {
@@ -948,6 +955,8 @@ clean_arq_element_out:
948 /* Set pending if needed, unlock and return */ 955 /* Set pending if needed, unlock and return */
949 if (pending != NULL) 956 if (pending != NULL)
950 *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc); 957 *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
958
959clean_arq_element_err:
951 mutex_unlock(&hw->aq.arq_mutex); 960 mutex_unlock(&hw->aq.arq_mutex);
952 961
953 return ret_code; 962 return ret_code;