ibmvnic: Introduce active CRQ state
Introduce an "active" state for a IBM vNIC Command-Response Queue. A CRQ is considered active once it has initialized or linked with its partner by sending an initialization request and getting a successful response back from the management partition. Until this has happened, do not allow CRQ commands to be sent other than the initialization request. This change will avoid a protocol error in case of a device transport event occurring during a initialization. When the driver receives a transport event notification indicating that the backing hardware has changed and needs reinitialization, any further commands other than the initialization handshake with the VIOS management partition will result in an invalid state error. Instead of sending a command that will be returned with an error, print a warning and return an error that will be handled by the caller. Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c3f2241547
commit
5153698e55
2 changed files with 11 additions and 0 deletions
|
@ -3147,6 +3147,12 @@ static int ibmvnic_send_crq(struct ibmvnic_adapter *adapter,
|
|||
(unsigned long int)cpu_to_be64(u64_crq[0]),
|
||||
(unsigned long int)cpu_to_be64(u64_crq[1]));
|
||||
|
||||
if (!adapter->crq.active &&
|
||||
crq->generic.first != IBMVNIC_CRQ_INIT_CMD) {
|
||||
dev_warn(dev, "Invalid request detected while CRQ is inactive, possible device state change during reset\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make sure the hypervisor sees the complete request */
|
||||
mb();
|
||||
|
||||
|
@ -4225,6 +4231,7 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
|||
break;
|
||||
case IBMVNIC_CRQ_INIT_COMPLETE:
|
||||
dev_info(dev, "Partner initialization complete\n");
|
||||
adapter->crq.active = true;
|
||||
send_version_xchg(adapter);
|
||||
break;
|
||||
default:
|
||||
|
@ -4233,6 +4240,7 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
|||
return;
|
||||
case IBMVNIC_CRQ_XPORT_EVENT:
|
||||
netif_carrier_off(netdev);
|
||||
adapter->crq.active = false;
|
||||
if (gen_crq->cmd == IBMVNIC_PARTITION_MIGRATED) {
|
||||
dev_info(dev, "Migrated, re-enabling adapter\n");
|
||||
ibmvnic_reset(adapter, VNIC_RESET_MOBILITY);
|
||||
|
@ -4420,6 +4428,7 @@ static int ibmvnic_reset_crq(struct ibmvnic_adapter *adapter)
|
|||
/* Clean out the queue */
|
||||
memset(crq->msgs, 0, PAGE_SIZE);
|
||||
crq->cur = 0;
|
||||
crq->active = false;
|
||||
|
||||
/* And re-open it again */
|
||||
rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
|
||||
|
@ -4454,6 +4463,7 @@ static void release_crq_queue(struct ibmvnic_adapter *adapter)
|
|||
DMA_BIDIRECTIONAL);
|
||||
free_page((unsigned long)crq->msgs);
|
||||
crq->msgs = NULL;
|
||||
crq->active = false;
|
||||
}
|
||||
|
||||
static int init_crq_queue(struct ibmvnic_adapter *adapter)
|
||||
|
|
|
@ -865,6 +865,7 @@ struct ibmvnic_crq_queue {
|
|||
int size, cur;
|
||||
dma_addr_t msg_token;
|
||||
spinlock_t lock;
|
||||
bool active;
|
||||
};
|
||||
|
||||
union sub_crq {
|
||||
|
|
Loading…
Reference in a new issue