Skip to content

Commit 857b6c6

Browse files
Jiri Bencanguy11
authored andcommitted
i40e: fix endless loop under rtnl
The loop in i40e_get_capabilities can never end. The problem is that although i40e_aq_discover_capabilities returns with an error if there's a firmware problem, the returned error is not checked. There is a check for pf->hw.aq.asq_last_status but that value is set to I40E_AQ_RC_OK on most firmware problems. When i40e_aq_discover_capabilities encounters a firmware problem, it will encounter the same problem on its next invocation. As the result, the loop becomes endless. We hit this with I40E_ERR_ADMIN_QUEUE_TIMEOUT but looking at the code, it can happen with a range of other firmware errors. I don't know what the correct behavior should be: whether the firmware should be retried a few times, or whether pf->hw.aq.asq_last_status should be always set to the encountered firmware error (but then it would be pointless and can be just replaced by the i40e_aq_discover_capabilities return value). However, the current behavior with an endless loop under the rtnl mutex(!) is unacceptable and Intel has not submitted a fix, although we explained the bug to them 7 months ago. This may not be the best possible fix but it's better than hanging the whole system on a firmware bug. Fixes: 56a62fc ("i40e: init code and hardware support") Tested-by: Stefan Assmann <[email protected]> Signed-off-by: Jiri Benc <[email protected]> Reviewed-by: Jesse Brandeburg <[email protected]> Tested-by: Dave Switzer <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent a50a059 commit 857b6c6

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10113,7 +10113,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf,
1011310113
if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) {
1011410114
/* retry with a larger buffer */
1011510115
buf_len = data_size;
10116-
} else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) {
10116+
} else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) {
1011710117
dev_info(&pf->pdev->dev,
1011810118
"capability discovery failed, err %s aq_err %s\n",
1011910119
i40e_stat_str(&pf->hw, err),

0 commit comments

Comments
 (0)