[PATCH v1 18/18] vfio/ccw: Manage ccw/mdev reference counts

Eric Farman
2022-06-02T17:20:16Z

Take a reference to the vfio device when looking at the
corresponding vfio_ccw_private struct, and put it back
once we are finished.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Eric Farman <farman@linux.ibm.com>
---
drivers/s390/cio/vfio_ccw_drv.c | 9 ++++++++-
drivers/s390/cio/vfio_ccw_private.h | 2 ++
2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index c8cbbad6e1c5..2e55fa45f76c 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -71,6 +71,7 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch)
ret = cio_disable_subchannel(sch);
} while (ret == -EBUSY);

+ vfio_device_put(&private->vdev);
return ret;
}

@@ -131,6 +132,7 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)

inc_irq_stat(IRQIO_CIO);
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
+ vfio_device_put(&private->vdev);
}

struct vfio_ccw_private *vfio_ccw_alloc_private(struct mdev_device *mdev,
@@ -252,6 +254,7 @@ static void vfio_ccw_sch_shutdown(struct subchannel *sch)

vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
+ vfio_device_put(&private->vdev);
}

/**
@@ -287,6 +290,7 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process)

out_unlock:
spin_unlock_irqrestore(sch->lock, flags);
+ vfio_device_put(&private->vdev);

return rc;
}
@@ -334,8 +338,10 @@ static int vfio_ccw_chp_event(struct subchannel *sch,
sch->schid.ssid, sch->schid.sch_no,
mask, event);

- if (cio_update_schib(sch))
+ if (cio_update_schib(sch)) {
+ vfio_device_put(&private->vdev);
return -ENODEV;
+ }

switch (event) {
case CHP_VARY_OFF:
@@ -365,6 +371,7 @@ static int vfio_ccw_chp_event(struct subchannel *sch,
break;
}

+ vfio_device_put(&private->vdev);
return 0;
}

diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index 3833204bd388..be238cf277ff 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -135,6 +135,8 @@ static inline struct vfio_ccw_private *vfio_ccw_get_private(struct subchannel *s
return NULL;

private = dev_get_drvdata(&sch->dev);
+ if (private && !vfio_device_try_get(&private->vdev))
+ private = NULL;

return private;
}
--
2.32.0