mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
vfio-ccw: Wire in the request callback
The device is being unplugged, so pass the request to userspace to ask for a graceful cleanup. This should free up the thread that would otherwise loop waiting for the device to be fully released. Signed-off-by: Eric Farman <farman@linux.ibm.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
committed by
Alex Williamson
parent
a15ac665b9
commit
bccce80bbd
@@ -394,6 +394,7 @@ static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
|
|||||||
switch (info->index) {
|
switch (info->index) {
|
||||||
case VFIO_CCW_IO_IRQ_INDEX:
|
case VFIO_CCW_IO_IRQ_INDEX:
|
||||||
case VFIO_CCW_CRW_IRQ_INDEX:
|
case VFIO_CCW_CRW_IRQ_INDEX:
|
||||||
|
case VFIO_CCW_REQ_IRQ_INDEX:
|
||||||
info->count = 1;
|
info->count = 1;
|
||||||
info->flags = VFIO_IRQ_INFO_EVENTFD;
|
info->flags = VFIO_IRQ_INFO_EVENTFD;
|
||||||
break;
|
break;
|
||||||
@@ -424,6 +425,9 @@ static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
|
|||||||
case VFIO_CCW_CRW_IRQ_INDEX:
|
case VFIO_CCW_CRW_IRQ_INDEX:
|
||||||
ctx = &private->crw_trigger;
|
ctx = &private->crw_trigger;
|
||||||
break;
|
break;
|
||||||
|
case VFIO_CCW_REQ_IRQ_INDEX:
|
||||||
|
ctx = &private->req_trigger;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -607,6 +611,27 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Request removal of the device*/
|
||||||
|
static void vfio_ccw_mdev_request(struct mdev_device *mdev, unsigned int count)
|
||||||
|
{
|
||||||
|
struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev));
|
||||||
|
|
||||||
|
if (!private)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (private->req_trigger) {
|
||||||
|
if (!(count % 10))
|
||||||
|
dev_notice_ratelimited(mdev_dev(private->mdev),
|
||||||
|
"Relaying device request to user (#%u)\n",
|
||||||
|
count);
|
||||||
|
|
||||||
|
eventfd_signal(private->req_trigger, 1);
|
||||||
|
} else if (count == 0) {
|
||||||
|
dev_notice(mdev_dev(private->mdev),
|
||||||
|
"No device request channel registered, blocked until released by user\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
|
static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.supported_type_groups = mdev_type_groups,
|
.supported_type_groups = mdev_type_groups,
|
||||||
@@ -617,6 +642,7 @@ static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
|
|||||||
.read = vfio_ccw_mdev_read,
|
.read = vfio_ccw_mdev_read,
|
||||||
.write = vfio_ccw_mdev_write,
|
.write = vfio_ccw_mdev_write,
|
||||||
.ioctl = vfio_ccw_mdev_ioctl,
|
.ioctl = vfio_ccw_mdev_ioctl,
|
||||||
|
.request = vfio_ccw_mdev_request,
|
||||||
};
|
};
|
||||||
|
|
||||||
int vfio_ccw_mdev_reg(struct subchannel *sch)
|
int vfio_ccw_mdev_reg(struct subchannel *sch)
|
||||||
|
@@ -84,7 +84,10 @@ struct vfio_ccw_crw {
|
|||||||
* @irb: irb info received from interrupt
|
* @irb: irb info received from interrupt
|
||||||
* @scsw: scsw info
|
* @scsw: scsw info
|
||||||
* @io_trigger: eventfd ctx for signaling userspace I/O results
|
* @io_trigger: eventfd ctx for signaling userspace I/O results
|
||||||
|
* @crw_trigger: eventfd ctx for signaling userspace CRW information
|
||||||
|
* @req_trigger: eventfd ctx for signaling userspace to return device
|
||||||
* @io_work: work for deferral process of I/O handling
|
* @io_work: work for deferral process of I/O handling
|
||||||
|
* @crw_work: work for deferral process of CRW handling
|
||||||
*/
|
*/
|
||||||
struct vfio_ccw_private {
|
struct vfio_ccw_private {
|
||||||
struct subchannel *sch;
|
struct subchannel *sch;
|
||||||
@@ -108,6 +111,7 @@ struct vfio_ccw_private {
|
|||||||
|
|
||||||
struct eventfd_ctx *io_trigger;
|
struct eventfd_ctx *io_trigger;
|
||||||
struct eventfd_ctx *crw_trigger;
|
struct eventfd_ctx *crw_trigger;
|
||||||
|
struct eventfd_ctx *req_trigger;
|
||||||
struct work_struct io_work;
|
struct work_struct io_work;
|
||||||
struct work_struct crw_work;
|
struct work_struct crw_work;
|
||||||
} __aligned(8);
|
} __aligned(8);
|
||||||
|
@@ -820,6 +820,7 @@ enum {
|
|||||||
enum {
|
enum {
|
||||||
VFIO_CCW_IO_IRQ_INDEX,
|
VFIO_CCW_IO_IRQ_INDEX,
|
||||||
VFIO_CCW_CRW_IRQ_INDEX,
|
VFIO_CCW_CRW_IRQ_INDEX,
|
||||||
|
VFIO_CCW_REQ_IRQ_INDEX,
|
||||||
VFIO_CCW_NUM_IRQS
|
VFIO_CCW_NUM_IRQS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user