2022-05-18 04:58:04

by Jason Wang

[permalink] [raw]
Subject: [PATCH V5 6/9] virtio-ccw: implement synchronize_cbs()

This patch tries to implement the synchronize_cbs() for ccw. For the
vring_interrupt() that is called via virtio_airq_handler(), the
synchronization is simply done via the airq_info's lock. For the
vring_interrupt() that is called via virtio_ccw_int_handler(), a per
device rwlock is introduced ans used in the synchronization method.

Cc: Thomas Gleixner <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: "Paul E. McKenney" <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Halil Pasic <[email protected]>
Cc: Cornelia Huck <[email protected]>
Cc: Vineeth Vijayan <[email protected]>
Cc: Peter Oberparleiter <[email protected]>
Cc: [email protected]
Signed-off-by: Jason Wang <[email protected]>
---
drivers/s390/virtio/virtio_ccw.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index d35e7a3f7067..22d36594bcdd 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -62,6 +62,7 @@ struct virtio_ccw_device {
unsigned int revision; /* Transport revision */
wait_queue_head_t wait_q;
spinlock_t lock;
+ rwlock_t irq_lock;
struct mutex io_lock; /* Serializes I/O requests */
struct list_head virtqueues;
bool is_thinint;
@@ -984,6 +985,27 @@ static const char *virtio_ccw_bus_name(struct virtio_device *vdev)
return dev_name(&vcdev->cdev->dev);
}

+static void virtio_ccw_synchronize_cbs(struct virtio_device *vdev)
+{
+ struct virtio_ccw_device *vcdev = to_vc_device(vdev);
+ struct airq_info *info = vcdev->airq_info;
+
+ if (info) {
+ /*
+ * Synchronize with the vring_interrupt() with airq indicator
+ */
+ write_lock_irq(&info->lock);
+ write_unlock_irq(&info->lock);
+ } else {
+ /*
+ * Synchronize with the vring_interrupt() called by
+ * virtio_ccw_int_handler().
+ */
+ write_lock_irq(&vcdev->irq_lock);
+ write_unlock_irq(&vcdev->irq_lock);
+ }
+}
+
static const struct virtio_config_ops virtio_ccw_config_ops = {
.get_features = virtio_ccw_get_features,
.finalize_features = virtio_ccw_finalize_features,
@@ -995,6 +1017,7 @@ static const struct virtio_config_ops virtio_ccw_config_ops = {
.find_vqs = virtio_ccw_find_vqs,
.del_vqs = virtio_ccw_del_vqs,
.bus_name = virtio_ccw_bus_name,
+ .synchronize_cbs = virtio_ccw_synchronize_cbs,
};


@@ -1106,6 +1129,8 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
vcdev->err = -EIO;
}
virtio_ccw_check_activity(vcdev, activity);
+ /* Local interrupt should be disabled at this time */
+ read_lock(&vcdev->irq_lock);
for_each_set_bit(i, indicators(vcdev),
sizeof(*indicators(vcdev)) * BITS_PER_BYTE) {
/* The bit clear must happen before the vring kick. */
@@ -1114,6 +1139,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
vq = virtio_ccw_vq_by_ind(vcdev, i);
vring_interrupt(0, vq);
}
+ read_unlock(&vcdev->irq_lock);
if (test_bit(0, indicators2(vcdev))) {
virtio_config_changed(&vcdev->vdev);
clear_bit(0, indicators2(vcdev));
@@ -1284,6 +1310,7 @@ static int virtio_ccw_online(struct ccw_device *cdev)
init_waitqueue_head(&vcdev->wait_q);
INIT_LIST_HEAD(&vcdev->virtqueues);
spin_lock_init(&vcdev->lock);
+ rwlock_init(&vcdev->irq_lock);
mutex_init(&vcdev->io_lock);

spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
--
2.25.1



2022-05-18 09:44:12

by Cornelia Huck

[permalink] [raw]
Subject: Re: [PATCH V5 6/9] virtio-ccw: implement synchronize_cbs()

On Wed, May 18 2022, Jason Wang <[email protected]> wrote:

> This patch tries to implement the synchronize_cbs() for ccw. For the
> vring_interrupt() that is called via virtio_airq_handler(), the
> synchronization is simply done via the airq_info's lock. For the
> vring_interrupt() that is called via virtio_ccw_int_handler(), a per
> device rwlock is introduced ans used in the synchronization method.

s/ans/and/

>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: "Paul E. McKenney" <[email protected]>
> Cc: Marc Zyngier <[email protected]>
> Cc: Halil Pasic <[email protected]>
> Cc: Cornelia Huck <[email protected]>
> Cc: Vineeth Vijayan <[email protected]>
> Cc: Peter Oberparleiter <[email protected]>
> Cc: [email protected]
> Signed-off-by: Jason Wang <[email protected]>
> ---
> drivers/s390/virtio/virtio_ccw.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
> index d35e7a3f7067..22d36594bcdd 100644
> --- a/drivers/s390/virtio/virtio_ccw.c
> +++ b/drivers/s390/virtio/virtio_ccw.c
> @@ -62,6 +62,7 @@ struct virtio_ccw_device {
> unsigned int revision; /* Transport revision */
> wait_queue_head_t wait_q;
> spinlock_t lock;
> + rwlock_t irq_lock;
> struct mutex io_lock; /* Serializes I/O requests */
> struct list_head virtqueues;
> bool is_thinint;
> @@ -984,6 +985,27 @@ static const char *virtio_ccw_bus_name(struct virtio_device *vdev)
> return dev_name(&vcdev->cdev->dev);
> }
>
> +static void virtio_ccw_synchronize_cbs(struct virtio_device *vdev)
> +{
> + struct virtio_ccw_device *vcdev = to_vc_device(vdev);
> + struct airq_info *info = vcdev->airq_info;
> +
> + if (info) {
> + /*
> + * Synchronize with the vring_interrupt() with airq indicator

Maybe

/*
* This device uses adapter interrupts: synchronize with
* vring_interrupt() called by virtio_airq_handler() via the indicator
* area lock.
*/

> + */
> + write_lock_irq(&info->lock);
> + write_unlock_irq(&info->lock);
> + } else {
> + /*
> + * Synchronize with the vring_interrupt() called by
> + * virtio_ccw_int_handler().

/*
* This device uses classic interrupts: synchronize with
* vring_interrupt() called by virtio_ccw_int_handler() via the
* per-device irq_lock.
*/

> + */
> + write_lock_irq(&vcdev->irq_lock);
> + write_unlock_irq(&vcdev->irq_lock);
> + }
> +}
> +
> static const struct virtio_config_ops virtio_ccw_config_ops = {
> .get_features = virtio_ccw_get_features,
> .finalize_features = virtio_ccw_finalize_features,
> @@ -995,6 +1017,7 @@ static const struct virtio_config_ops virtio_ccw_config_ops = {
> .find_vqs = virtio_ccw_find_vqs,
> .del_vqs = virtio_ccw_del_vqs,
> .bus_name = virtio_ccw_bus_name,
> + .synchronize_cbs = virtio_ccw_synchronize_cbs,
> };
>
>
> @@ -1106,6 +1129,8 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
> vcdev->err = -EIO;
> }
> virtio_ccw_check_activity(vcdev, activity);
> + /* Local interrupt should be disabled at this time */

/* Interrupts are disabled here. */

?

Interrupts enabled here would surely be a bug.

> + read_lock(&vcdev->irq_lock);
> for_each_set_bit(i, indicators(vcdev),
> sizeof(*indicators(vcdev)) * BITS_PER_BYTE) {
> /* The bit clear must happen before the vring kick. */


2022-05-19 14:23:29

by Jason Wang

[permalink] [raw]
Subject: Re: [PATCH V5 6/9] virtio-ccw: implement synchronize_cbs()

On Wed, May 18, 2022 at 5:32 PM Cornelia Huck <[email protected]> wrote:
>
> On Wed, May 18 2022, Jason Wang <[email protected]> wrote:
>
> > This patch tries to implement the synchronize_cbs() for ccw. For the
> > vring_interrupt() that is called via virtio_airq_handler(), the
> > synchronization is simply done via the airq_info's lock. For the
> > vring_interrupt() that is called via virtio_ccw_int_handler(), a per
> > device rwlock is introduced ans used in the synchronization method.
>
> s/ans/and/
>

Will fix.

> >
> > Cc: Thomas Gleixner <[email protected]>
> > Cc: Peter Zijlstra <[email protected]>
> > Cc: "Paul E. McKenney" <[email protected]>
> > Cc: Marc Zyngier <[email protected]>
> > Cc: Halil Pasic <[email protected]>
> > Cc: Cornelia Huck <[email protected]>
> > Cc: Vineeth Vijayan <[email protected]>
> > Cc: Peter Oberparleiter <[email protected]>
> > Cc: [email protected]
> > Signed-off-by: Jason Wang <[email protected]>
> > ---
> > drivers/s390/virtio/virtio_ccw.c | 27 +++++++++++++++++++++++++++
> > 1 file changed, 27 insertions(+)
> >
> > diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
> > index d35e7a3f7067..22d36594bcdd 100644
> > --- a/drivers/s390/virtio/virtio_ccw.c
> > +++ b/drivers/s390/virtio/virtio_ccw.c
> > @@ -62,6 +62,7 @@ struct virtio_ccw_device {
> > unsigned int revision; /* Transport revision */
> > wait_queue_head_t wait_q;
> > spinlock_t lock;
> > + rwlock_t irq_lock;
> > struct mutex io_lock; /* Serializes I/O requests */
> > struct list_head virtqueues;
> > bool is_thinint;
> > @@ -984,6 +985,27 @@ static const char *virtio_ccw_bus_name(struct virtio_device *vdev)
> > return dev_name(&vcdev->cdev->dev);
> > }
> >
> > +static void virtio_ccw_synchronize_cbs(struct virtio_device *vdev)
> > +{
> > + struct virtio_ccw_device *vcdev = to_vc_device(vdev);
> > + struct airq_info *info = vcdev->airq_info;
> > +
> > + if (info) {
> > + /*
> > + * Synchronize with the vring_interrupt() with airq indicator
>
> Maybe
>
> /*
> * This device uses adapter interrupts: synchronize with
> * vring_interrupt() called by virtio_airq_handler() via the indicator
> * area lock.
> */
>

Fine.

> > + */
> > + write_lock_irq(&info->lock);
> > + write_unlock_irq(&info->lock);
> > + } else {
> > + /*
> > + * Synchronize with the vring_interrupt() called by
> > + * virtio_ccw_int_handler().
>
> /*
> * This device uses classic interrupts: synchronize with
> * vring_interrupt() called by virtio_ccw_int_handler() via the
> * per-device irq_lock.
> */
>

Looks fine.

> > + */
> > + write_lock_irq(&vcdev->irq_lock);
> > + write_unlock_irq(&vcdev->irq_lock);
> > + }
> > +}
> > +
> > static const struct virtio_config_ops virtio_ccw_config_ops = {
> > .get_features = virtio_ccw_get_features,
> > .finalize_features = virtio_ccw_finalize_features,
> > @@ -995,6 +1017,7 @@ static const struct virtio_config_ops virtio_ccw_config_ops = {
> > .find_vqs = virtio_ccw_find_vqs,
> > .del_vqs = virtio_ccw_del_vqs,
> > .bus_name = virtio_ccw_bus_name,
> > + .synchronize_cbs = virtio_ccw_synchronize_cbs,
> > };
> >
> >
> > @@ -1106,6 +1129,8 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
> > vcdev->err = -EIO;
> > }
> > virtio_ccw_check_activity(vcdev, activity);
> > + /* Local interrupt should be disabled at this time */
>
> /* Interrupts are disabled here. */
>
> ?
>
> Interrupts enabled here would surely be a bug.

Right.

Thanks

>
> > + read_lock(&vcdev->irq_lock);
> > for_each_set_bit(i, indicators(vcdev),
> > sizeof(*indicators(vcdev)) * BITS_PER_BYTE) {
> > /* The bit clear must happen before the vring kick. */
>


2022-05-25 11:30:44

by Halil Pasic

[permalink] [raw]
Subject: Re: [PATCH V5 6/9] virtio-ccw: implement synchronize_cbs()

On Wed, 18 May 2022 11:59:48 +0800
Jason Wang <[email protected]> wrote:

> This patch tries to implement the synchronize_cbs() for ccw. For the
> vring_interrupt() that is called via virtio_airq_handler(), the
> synchronization is simply done via the airq_info's lock. For the
> vring_interrupt() that is called via virtio_ccw_int_handler(), a per
> device rwlock is introduced ans used in the synchronization method.
>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: "Paul E. McKenney" <[email protected]>
> Cc: Marc Zyngier <[email protected]>
> Cc: Halil Pasic <[email protected]>
> Cc: Cornelia Huck <[email protected]>
> Cc: Vineeth Vijayan <[email protected]>
> Cc: Peter Oberparleiter <[email protected]>
> Cc: [email protected]
> Signed-off-by: Jason Wang <[email protected]>

Reviewed-by: Halil Pasic <[email protected]>