diff mbox series

[06/13] ibmvfc: add handlers to drain and complete Sub-CRQ responses

Message ID 20201126014824.123831-7-tyreld@linux.ibm.com
State Superseded
Headers show
Series ibmvfc: initial MQ development | expand

Commit Message

Tyrel Datwyler Nov. 26, 2020, 1:48 a.m. UTC
The logic for iterating over the Sub-CRQ responses is similiar to that
of the primary CRQ. Add the necessary handlers for processing those
responses.

Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
---
 drivers/scsi/ibmvscsi/ibmvfc.c | 72 ++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

Comments

Brian King Nov. 27, 2020, 5:47 p.m. UTC | #1
On 11/25/20 7:48 PM, Tyrel Datwyler wrote:
> The logic for iterating over the Sub-CRQ responses is similiar to that

> of the primary CRQ. Add the necessary handlers for processing those

> responses.

> 

> Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>

> ---

>  drivers/scsi/ibmvscsi/ibmvfc.c | 72 ++++++++++++++++++++++++++++++++++

>  1 file changed, 72 insertions(+)

> 

> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c

> index 6eaedda4917a..a8730522920e 100644

> --- a/drivers/scsi/ibmvscsi/ibmvfc.c

> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c

> @@ -3371,6 +3371,78 @@ static int ibmvfc_toggle_scrq_irq(struct ibmvfc_sub_queue *scrq, int enable)

>  	return rc;

>  }

>  

> +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);

> +

> +	switch (crq->valid) {

> +	case IBMVFC_CRQ_CMD_RSP:

> +		break;

> +	default:

> +		dev_err(vhost->dev, "Got and invalid message type 0x%02x\n", crq->valid);


Is this correct? Can't we get transport events here as well?

> +		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;

> +	}

> +

> +	del_timer(&evt->timer);

> +	list_del(&evt->queue);

> +	ibmvfc_trc_end(evt);

> +	evt->done(evt);

> +}

> +




-- 
Brian King
Power Linux I/O
IBM Linux Technology Center
Tyrel Datwyler Nov. 30, 2020, 5:27 p.m. UTC | #2
On 11/27/20 9:47 AM, Brian King wrote:
> On 11/25/20 7:48 PM, Tyrel Datwyler wrote:

>> The logic for iterating over the Sub-CRQ responses is similiar to that

>> of the primary CRQ. Add the necessary handlers for processing those

>> responses.

>>

>> Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>

>> ---

>>  drivers/scsi/ibmvscsi/ibmvfc.c | 72 ++++++++++++++++++++++++++++++++++

>>  1 file changed, 72 insertions(+)

>>

>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c

>> index 6eaedda4917a..a8730522920e 100644

>> --- a/drivers/scsi/ibmvscsi/ibmvfc.c

>> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c

>> @@ -3371,6 +3371,78 @@ static int ibmvfc_toggle_scrq_irq(struct ibmvfc_sub_queue *scrq, int enable)

>>  	return rc;

>>  }

>>  

>> +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);

>> +

>> +	switch (crq->valid) {

>> +	case IBMVFC_CRQ_CMD_RSP:

>> +		break;

>> +	default:

>> +		dev_err(vhost->dev, "Got and invalid message type 0x%02x\n", crq->valid);

> 

> Is this correct? Can't we get transport events here as well?


Yes we can. We still handle them in the primary CRQ so at least for the time
being we can ignore them, but yeah we shouldn't log scary messages about them.

-Tyrel

> 

>> +		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;

>> +	}

>> +

>> +	del_timer(&evt->timer);

>> +	list_del(&evt->queue);

>> +	ibmvfc_trc_end(evt);

>> +	evt->done(evt);

>> +}

>> +

> 

> 

>
diff mbox series

Patch

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 6eaedda4917a..a8730522920e 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -3371,6 +3371,78 @@  static int ibmvfc_toggle_scrq_irq(struct ibmvfc_sub_queue *scrq, int enable)
 	return rc;
 }
 
+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);
+
+	switch (crq->valid) {
+	case IBMVFC_CRQ_CMD_RSP:
+		break;
+	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;
+	}
+
+	del_timer(&evt->timer);
+	list_del(&evt->queue);
+	ibmvfc_trc_end(evt);
+	evt->done(evt);
+}
+
+static struct ibmvfc_crq *ibmvfc_next_scrq(struct ibmvfc_sub_queue *scrq)
+{
+	struct ibmvfc_crq *crq;
+
+	crq = &scrq->msgs[scrq->cur].crq;
+	if (crq->valid & 0x80) {
+		if (++scrq->cur == scrq->size)
+			scrq->cur = 0;
+		rmb();
+	} else
+		crq = NULL;
+
+	return crq;
+}
+
+static void ibmvfc_drain_sub_crq(struct ibmvfc_sub_queue *scrq)
+{
+	struct ibmvfc_crq *crq;
+	int done = 0;
+
+	while (!done) {
+		while ((crq = ibmvfc_next_scrq(scrq)) != NULL) {
+			ibmvfc_handle_scrq(crq, scrq->vhost);
+			crq->valid = 0;
+			wmb();
+		}
+
+		ibmvfc_toggle_scrq_irq(scrq, 1);
+		if ((crq = ibmvfc_next_scrq(scrq)) != NULL) {
+			ibmvfc_toggle_scrq_irq(scrq, 0);
+			ibmvfc_handle_scrq(crq, scrq->vhost);
+			crq->valid = 0;
+			wmb();
+		} else
+			done = 1;
+	}
+}
+
 /**
  * ibmvfc_init_tgt - Set the next init job step for the target
  * @tgt:		ibmvfc target struct