ACK/cmnt[Bionic/Cosmic/Disco]: [SRU][Cosmic][Disco][PATCH 1/1] s390/zcrypt: reinit ap queue state machine during device probe
Kleber Souza
kleber.souza at canonical.com
Mon Dec 17 13:24:45 UTC 2018
On 12/14/18 5:32 PM, Joseph Salisbury wrote:
> From: Harald Freudenberger <freude at linux.ibm.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1805414
>
> Until the vfio-ap driver came into live there was a well known
> agreement about the way how ap devices are initialized and their
> states when the driver's probe function is called.
>
> However, the vfio device driver when receiving an ap queue device does
> additional resets thereby removing the registration for interrupts for
> the ap device done by the ap bus core code. So when later the vfio
> driver releases the device and one of the default zcrypt drivers takes
> care of the device the interrupt registration needs to get
> renewed. The current code does no renew and result is that requests
> send into such a queue will never see a reply processed - the
> application hangs.
>
> This patch adds a function which resets the aq queue state machine for
> the ap queue device and triggers the walk through the initial states
> (which are reset and registration for interrupts). This function is
> now called before the driver's probe function is invoked.
>
> When the association between driver and device is released, the
> driver's remove function is called. The current implementation calls a
> ap queue function ap_queue_remove(). This invokation has been moved to
> the ap bus function to make the probe / remove pair for ap bus and
> drivers more symmetric.
>
> Fixes: 7e0bdbe5c21c ("s390/zcrypt: AP bus support for alternate driver(s)")
> Cc: stable at vger.kernel.org # 4.19+
> Signed-off-by: Harald Freudenberger <freude at linux.ibm.com>
> Reviewd-by: Tony Krowiak <akrowiak at linux.ibm.com>
> Reviewd-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
> Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
> (cherry picked from commit 104f708fd1241b22f808bdf066ab67dc5a051de5)
> Signed-off-by: Joseph Salisbury <joseph.salisbury at canonical.com>
Clean cherry-pick, limited to s390x. ACK'ing also for Bionic:
Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> ---
> drivers/s390/crypto/ap_bus.c | 8 ++++----
> drivers/s390/crypto/ap_bus.h | 1 +
> drivers/s390/crypto/ap_queue.c | 15 +++++++++++++++
> drivers/s390/crypto/zcrypt_cex2a.c | 1 -
> drivers/s390/crypto/zcrypt_cex4.c | 1 -
> drivers/s390/crypto/zcrypt_pcixcc.c | 1 -
> 6 files changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
> index 4521b21..84595b2 100644
> --- a/drivers/s390/crypto/ap_bus.c
> +++ b/drivers/s390/crypto/ap_bus.c
> @@ -795,6 +795,8 @@ static int ap_device_probe(struct device *dev)
> drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
> if (!!devres != !!drvres)
> return -ENODEV;
> + /* (re-)init queue's state machine */
> + ap_queue_reinit_state(to_ap_queue(dev));
> }
>
> /* Add queue/card to list of active queues/cards */
> @@ -827,6 +829,8 @@ static int ap_device_remove(struct device *dev)
> struct ap_device *ap_dev = to_ap_dev(dev);
> struct ap_driver *ap_drv = ap_dev->drv;
>
> + if (is_queue_dev(dev))
> + ap_queue_remove(to_ap_queue(dev));
> if (ap_drv->remove)
> ap_drv->remove(ap_dev);
>
> @@ -1484,10 +1488,6 @@ static void ap_scan_bus(struct work_struct *unused)
> aq->ap_dev.device.parent = &ac->ap_dev.device;
> dev_set_name(&aq->ap_dev.device,
> "%02x.%04x", id, dom);
> - /* Start with a device reset */
> - spin_lock_bh(&aq->lock);
> - ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
> - spin_unlock_bh(&aq->lock);
> /* Register device */
> rc = device_register(&aq->ap_dev.device);
> if (rc) {
> diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
> index 7c3c077..5ea5eaf 100644
> --- a/drivers/s390/crypto/ap_bus.h
> +++ b/drivers/s390/crypto/ap_bus.h
> @@ -252,6 +252,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type);
> void ap_queue_remove(struct ap_queue *aq);
> void ap_queue_suspend(struct ap_device *ap_dev);
> void ap_queue_resume(struct ap_device *ap_dev);
> +void ap_queue_reinit_state(struct ap_queue *aq);
>
> struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
> int comp_device_type, unsigned int functions);
> diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
> index c3e9e9f..7450b3b 100644
> --- a/drivers/s390/crypto/ap_queue.c
> +++ b/drivers/s390/crypto/ap_queue.c
> @@ -738,5 +738,20 @@ void ap_queue_remove(struct ap_queue *aq)
> {
> ap_flush_queue(aq);
> del_timer_sync(&aq->timeout);
> +
> + /* reset with zero, also clears irq registration */
> + spin_lock_bh(&aq->lock);
> + ap_zapq(aq->qid);
> + aq->state = AP_STATE_BORKED;
> + spin_unlock_bh(&aq->lock);
> }
> EXPORT_SYMBOL(ap_queue_remove);
> +
> +void ap_queue_reinit_state(struct ap_queue *aq)
> +{
> + spin_lock_bh(&aq->lock);
> + aq->state = AP_STATE_RESET_START;
> + ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
> + spin_unlock_bh(&aq->lock);
> +}
> +EXPORT_SYMBOL(ap_queue_reinit_state);
> diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
> index f4ae5fa..ff17a00 100644
> --- a/drivers/s390/crypto/zcrypt_cex2a.c
> +++ b/drivers/s390/crypto/zcrypt_cex2a.c
> @@ -198,7 +198,6 @@ static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
> struct ap_queue *aq = to_ap_queue(&ap_dev->device);
> struct zcrypt_queue *zq = aq->private;
>
> - ap_queue_remove(aq);
> if (zq)
> zcrypt_queue_unregister(zq);
> }
> diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
> index 35d58db..2a42e59 100644
> --- a/drivers/s390/crypto/zcrypt_cex4.c
> +++ b/drivers/s390/crypto/zcrypt_cex4.c
> @@ -273,7 +273,6 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
> struct ap_queue *aq = to_ap_queue(&ap_dev->device);
> struct zcrypt_queue *zq = aq->private;
>
> - ap_queue_remove(aq);
> if (zq)
> zcrypt_queue_unregister(zq);
> }
> diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
> index 94d9f72..baa683c 100644
> --- a/drivers/s390/crypto/zcrypt_pcixcc.c
> +++ b/drivers/s390/crypto/zcrypt_pcixcc.c
> @@ -276,7 +276,6 @@ static void zcrypt_pcixcc_queue_remove(struct ap_device *ap_dev)
> struct ap_queue *aq = to_ap_queue(&ap_dev->device);
> struct zcrypt_queue *zq = aq->private;
>
> - ap_queue_remove(aq);
> if (zq)
> zcrypt_queue_unregister(zq);
> }
More information about the kernel-team
mailing list