Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i40evf: set flags before sending message

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>

authored by

Mitch Williams and committed by
Jeff Kirsher
fc86a970 0b9754e9

+16 -17
+16 -17
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
··· 248 248 vqpi++; 249 249 } 250 250 251 + adapter->aq_pending |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES; 252 + adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_QUEUES; 251 253 i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES, 252 254 (u8 *)vqci, len); 253 255 kfree(vqci); 254 - adapter->aq_pending |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES; 255 - adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_QUEUES; 256 256 } 257 257 258 258 /** ··· 275 275 vqs.vsi_id = adapter->vsi_res->vsi_id; 276 276 vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1; 277 277 vqs.rx_queues = vqs.tx_queues; 278 - i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ENABLE_QUEUES, 279 - (u8 *)&vqs, sizeof(vqs)); 280 278 adapter->aq_pending |= I40EVF_FLAG_AQ_ENABLE_QUEUES; 281 279 adapter->aq_required &= ~I40EVF_FLAG_AQ_ENABLE_QUEUES; 280 + i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ENABLE_QUEUES, 281 + (u8 *)&vqs, sizeof(vqs)); 282 282 } 283 283 284 284 /** ··· 301 301 vqs.vsi_id = adapter->vsi_res->vsi_id; 302 302 vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1; 303 303 vqs.rx_queues = vqs.tx_queues; 304 - i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DISABLE_QUEUES, 305 - (u8 *)&vqs, sizeof(vqs)); 306 304 adapter->aq_pending |= I40EVF_FLAG_AQ_DISABLE_QUEUES; 307 305 adapter->aq_required &= ~I40EVF_FLAG_AQ_DISABLE_QUEUES; 306 + i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DISABLE_QUEUES, 307 + (u8 *)&vqs, sizeof(vqs)); 308 308 } 309 309 310 310 /** ··· 352 352 vimi->vecmap[v_idx].txq_map = 0; 353 353 vimi->vecmap[v_idx].rxq_map = 0; 354 354 355 + adapter->aq_pending |= I40EVF_FLAG_AQ_MAP_VECTORS; 356 + adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS; 355 357 i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP, 356 358 (u8 *)vimi, len); 357 359 kfree(vimi); 358 - adapter->aq_pending |= I40EVF_FLAG_AQ_MAP_VECTORS; 359 - adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS; 360 360 } 361 361 362 362 /** ··· 413 413 f->add = false; 414 414 } 415 415 } 416 + adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_MAC_FILTER; 417 + adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER; 416 418 i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS, 417 419 (u8 *)veal, len); 418 420 kfree(veal); 419 - adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_MAC_FILTER; 420 - adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER; 421 - 422 421 } 423 422 424 423 /** ··· 474 475 kfree(f); 475 476 } 476 477 } 478 + adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_MAC_FILTER; 479 + adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER; 477 480 i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS, 478 481 (u8 *)veal, len); 479 482 kfree(veal); 480 - adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_MAC_FILTER; 481 - adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER; 482 483 } 483 484 484 485 /** ··· 535 536 f->add = false; 536 537 } 537 538 } 538 - i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len); 539 - kfree(vvfl); 540 539 adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER; 541 540 adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER; 541 + i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len); 542 + kfree(vvfl); 542 543 } 543 544 544 545 /** ··· 596 597 kfree(f); 597 598 } 598 599 } 599 - i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len); 600 - kfree(vvfl); 601 600 adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER; 602 601 adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER; 602 + i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len); 603 + kfree(vvfl); 603 604 } 604 605 605 606 /**