s390/ap: re-enable interrupt for AP queues
authorHarald Freudenberger <freude@linux.ibm.com>
Mon, 23 Oct 2023 13:42:21 +0000 (15:42 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Sun, 5 Nov 2023 21:34:57 +0000 (22:34 +0100)
This patch introduces some code lines which check
for interrupt support enabled on an AP queue after
a reply has been received. This invocation has been
chosen as there is a good chance to have the queue
empty at that time. As the enablement of the irq
imples a state machine change the queue should not
have any pending requests or unreceived replies.

Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/crypto/ap_queue.c

index f1abd21661dc393755134bd2c133ea9fe9301f4f..3934a0cc13e7629735f5e8d200b98f4a5451e5f5 100644 (file)
@@ -200,13 +200,13 @@ static enum ap_sm_wait ap_sm_read(struct ap_queue *aq)
                        return AP_SM_WAIT_AGAIN;
                }
                aq->sm_state = AP_SM_STATE_IDLE;
-               return AP_SM_WAIT_NONE;
+               break;
        case AP_RESPONSE_NO_PENDING_REPLY:
                if (aq->queue_count > 0)
                        return status.irq_enabled ?
                                AP_SM_WAIT_INTERRUPT : AP_SM_WAIT_HIGH_TIMEOUT;
                aq->sm_state = AP_SM_STATE_IDLE;
-               return AP_SM_WAIT_NONE;
+               break;
        default:
                aq->dev_state = AP_DEV_STATE_ERROR;
                aq->last_err_rc = status.response_code;
@@ -215,6 +215,16 @@ static enum ap_sm_wait ap_sm_read(struct ap_queue *aq)
                            AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
                return AP_SM_WAIT_NONE;
        }
+       /* Check and maybe enable irq support (again) on this queue */
+       if (!status.irq_enabled && status.queue_empty) {
+               void *lsi_ptr = ap_airq_ptr();
+
+               if (lsi_ptr && ap_queue_enable_irq(aq, lsi_ptr) == 0) {
+                       aq->sm_state = AP_SM_STATE_SETIRQ_WAIT;
+                       return AP_SM_WAIT_AGAIN;
+               }
+       }
+       return AP_SM_WAIT_NONE;
 }
 
 /**