Re: [PATCH v7 3/4] s390: ap: implement PAPQ AQIC interception in kernel

From: Pierre Morel
Date: Thu May 02 2019 - 03:58:12 EST


On 30/04/2019 16:09, Pierre Morel wrote:
On 30/04/2019 15:26, Halil Pasic wrote:
On Fri, 26 Apr 2019 15:01:27 +0200
Pierre Morel <pmorel@xxxxxxxxxxxxx> wrote:

+/**
+ * vfio_ap_clrirq: Disable Interruption for a APQN
+ *
+ * @dev: the device associated with the ap_queue
+ * @q:ÂÂ the vfio_ap_queue holding AQIC parameters
+ *
+ * Issue the host side PQAP/AQIC
+ * On success: unpin the NIB saved in *q and unregister from GIB
+ * interface
+ *
+ * Return the ap_queue_status returned by the ap_aqic()
+ */
+static struct ap_queue_status vfio_ap_clrirq(struct vfio_ap_queue *q)
+{
+ÂÂÂ struct ap_qirq_ctrl aqic_gisa = {};
+ÂÂÂ struct ap_queue_status status;
+ÂÂÂ int checks = 10;
+
+ÂÂÂ status = ap_aqic(q->apqn, aqic_gisa, NULL);
+ÂÂÂ if (!status.response_code) {
+ÂÂÂÂÂÂÂ while (status.irq_enabled && checks--) {
+ÂÂÂÂÂÂÂÂÂÂÂ msleep(20);

Hm, that seems like a lot of time to me. And I suppose we are holding the
kvm lock: e.g. no other instruction can be interpreted by kvm in the
meantime.

+ÂÂÂÂÂÂÂÂÂÂÂ status = ap_tapq(q->apqn, NULL);
+ÂÂÂÂÂÂÂ }
+ÂÂÂÂÂÂÂ if (checks >= 0)
+ÂÂÂÂÂÂÂÂÂÂÂ vfio_ap_free_irq_data(q);

Actually we don't have to wait for the async part to do it's magic
(indicated by the status.irq_enabled --> !status.irq_enabled transition)
in the instruction handler. We have to wait so we can unpin the NIB but
that could be done async (e.g. workqueue).

BTW do you have any measurements here? How many msleep(20) do we
experience for one clear on average?

No idea but it is probably linked to the queue state and usage history.
I can use a lower sleep time and increment the retry count.


If linux is not using clear (you told so offline, and I also remember
something similar), we can probably get away with something like this,
and do it properly (from performance standpoint) later.

In the Linux AP code it is only used once, in the explicit
ap_queue_enable_interruption() function.

My answer is not clear: ap_aqic() is used only once, during the bus probe, in the all code to enable interrupt and is never used to disable interrupt.

Interrupt disabling is only done by using ap_zapq() or ap_rapq() which can not be intercepted.



Yes, thanks, I will keep it as is, may be just play with msleep()time and retry count.

Regards,
Pierre


Regards,
Halil

+ÂÂÂÂÂÂÂ else
+ÂÂÂÂÂÂÂÂÂÂÂ WARN_ONCE("%s: failed disabling IRQ", __func__);
+ÂÂÂ }
+
+ÂÂÂ return status;
+}





--
Pierre Morel
Linux/KVM/QEMU in BÃblingen - Germany