mirror of https://gitee.com/openkylin/linux.git
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:
parent
a15ac665b9
commit
bccce80bbd
|
@ -394,6 +394,7 @@ static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
|
|||
switch (info->index) {
|
||||
case VFIO_CCW_IO_IRQ_INDEX:
|
||||
case VFIO_CCW_CRW_IRQ_INDEX:
|
||||
case VFIO_CCW_REQ_IRQ_INDEX:
|
||||
info->count = 1;
|
||||
info->flags = VFIO_IRQ_INFO_EVENTFD;
|
||||
break;
|
||||
|
@ -424,6 +425,9 @@ static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
|
|||
case VFIO_CCW_CRW_IRQ_INDEX:
|
||||
ctx = &private->crw_trigger;
|
||||
break;
|
||||
case VFIO_CCW_REQ_IRQ_INDEX:
|
||||
ctx = &private->req_trigger;
|
||||
break;
|
||||
default:
|
||||
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 = {
|
||||
.owner = THIS_MODULE,
|
||||
.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,
|
||||
.write = vfio_ccw_mdev_write,
|
||||
.ioctl = vfio_ccw_mdev_ioctl,
|
||||
.request = vfio_ccw_mdev_request,
|
||||
};
|
||||
|
||||
int vfio_ccw_mdev_reg(struct subchannel *sch)
|
||||
|
|
|
@ -84,7 +84,10 @@ struct vfio_ccw_crw {
|
|||
* @irb: irb info received from interrupt
|
||||
* @scsw: scsw info
|
||||
* @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
|
||||
* @crw_work: work for deferral process of CRW handling
|
||||
*/
|
||||
struct vfio_ccw_private {
|
||||
struct subchannel *sch;
|
||||
|
@ -108,6 +111,7 @@ struct vfio_ccw_private {
|
|||
|
||||
struct eventfd_ctx *io_trigger;
|
||||
struct eventfd_ctx *crw_trigger;
|
||||
struct eventfd_ctx *req_trigger;
|
||||
struct work_struct io_work;
|
||||
struct work_struct crw_work;
|
||||
} __aligned(8);
|
||||
|
|
|
@ -820,6 +820,7 @@ enum {
|
|||
enum {
|
||||
VFIO_CCW_IO_IRQ_INDEX,
|
||||
VFIO_CCW_CRW_IRQ_INDEX,
|
||||
VFIO_CCW_REQ_IRQ_INDEX,
|
||||
VFIO_CCW_NUM_IRQS
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue