vfio: Add and use device request op for vfio bus drivers
When a request is made to unbind a device from a vfio bus driver, we need to wait for the device to become unused, ie. for userspace to release the device. However, we have a long standing TODO in the code to do something proactive to make that happen. To enable this, we add a request callback on the vfio bus driver struct, which is intended to signal the user through the vfio device interface to release the device. Instead of passively waiting for the device to become unused, we can now pester the user to give it up. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
Родитель
4a68810dbb
Коммит
13060b64b8
|
@ -710,6 +710,7 @@ void *vfio_del_group_dev(struct device *dev)
|
|||
struct vfio_group *group = device->group;
|
||||
void *device_data = device->device_data;
|
||||
struct vfio_unbound_dev *unbound;
|
||||
unsigned int i = 0;
|
||||
|
||||
/*
|
||||
* The group exists so long as we have a device reference. Get
|
||||
|
@ -737,8 +738,27 @@ void *vfio_del_group_dev(struct device *dev)
|
|||
|
||||
vfio_device_put(device);
|
||||
|
||||
/* TODO send a signal to encourage this to be released */
|
||||
wait_event(vfio.release_q, !vfio_dev_present(group, dev));
|
||||
/*
|
||||
* If the device is still present in the group after the above
|
||||
* 'put', then it is in use and we need to request it from the
|
||||
* bus driver. The driver may in turn need to request the
|
||||
* device from the user. We send the request on an arbitrary
|
||||
* interval with counter to allow the driver to take escalating
|
||||
* measures to release the device if it has the ability to do so.
|
||||
*/
|
||||
do {
|
||||
device = vfio_group_get_device(group, dev);
|
||||
if (!device)
|
||||
break;
|
||||
|
||||
if (device->ops->request)
|
||||
device->ops->request(device_data, i++);
|
||||
|
||||
vfio_device_put(device);
|
||||
|
||||
} while (wait_event_interruptible_timeout(vfio.release_q,
|
||||
!vfio_dev_present(group, dev),
|
||||
HZ * 10) <= 0);
|
||||
|
||||
vfio_group_put(group);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_*
|
||||
* operations documented below
|
||||
* @mmap: Perform mmap(2) on a region of the device file descriptor
|
||||
* @request: Request for the bus driver to release the device
|
||||
*/
|
||||
struct vfio_device_ops {
|
||||
char *name;
|
||||
|
@ -38,6 +39,7 @@ struct vfio_device_ops {
|
|||
long (*ioctl)(void *device_data, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int (*mmap)(void *device_data, struct vm_area_struct *vma);
|
||||
void (*request)(void *device_data, unsigned int count);
|
||||
};
|
||||
|
||||
extern int vfio_add_group_dev(struct device *dev,
|
||||
|
|
Загрузка…
Ссылка в новой задаче