On 12/1/20 6:53 PM, Tyrel Datwyler wrote: > +static void ibmvfc_handle_scrq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) > +{ > + struct ibmvfc_event *evt = (struct ibmvfc_event *)be64_to_cpu(crq->ioba); > + unsigned long flags; > + > + switch (crq->valid) { > + case IBMVFC_CRQ_CMD_RSP: > + break; > + case IBMVFC_CRQ_XPORT_EVENT: > + return; > + default: > + dev_err(vhost->dev, "Got and invalid message type 0x%02x\n", crq->valid); > + return; > + } > + > + /* The only kind of payload CRQs we should get are responses to > + * things we send. Make sure this response is to something we > + * actually sent > + */ > + if (unlikely(!ibmvfc_valid_event(&vhost->pool, evt))) { > + dev_err(vhost->dev, "Returned correlation_token 0x%08llx is invalid!\n", > + crq->ioba); > + return; > + } > + > + if (unlikely(atomic_read(&evt->free))) { > + dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n", > + crq->ioba); > + return; > + } > + > + spin_lock_irqsave(vhost->host->host_lock, flags); > + del_timer(&evt->timer); > + list_del(&evt->queue); > + ibmvfc_trc_end(evt); Another thought here... If you are going through ibmvfc_purge_requests at the same time as this code, you could check the free bit above, then have ibmvfc_purge_requests put the event on the free queue and call scsi_done, then you come down and get the host lock here, remove the command from the free list, and call the done function again, which could result in a double completion to the scsi layer. I think you need to grab the host lock before you check the free bit to avoid this race. > + spin_unlock_irqrestore(vhost->host->host_lock, flags); > + evt->done(evt); > +} > + -- Brian King Power Linux I/O IBM Linux Technology Center