diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-17 21:29:06 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-22 10:26:13 -0400 |
| commit | 90b1253e4139776e8257914ae9e2292d0de2fecc (patch) | |
| tree | 47ed9f35d8f58d42f6e3c8614d355b1edc86f51b | |
| parent | 6d2cd3ce815b302e885b44ca1bdbe3c7db321c7a (diff) | |
vfio: get rid of vfio_device_put()/vfio_group_get_device* races
we really need to make sure that dropping the last reference happens
under the group->device_lock; otherwise a loop (under device_lock)
might find vfio_device instance that is being freed right now, has
already dropped the last reference and waits on device_lock to exclude
the sucker from the list.
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | drivers/vfio/vfio.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 92b85676e6be..887ae43276bb 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c | |||
| @@ -396,7 +396,6 @@ static void vfio_device_release(struct kref *kref) | |||
| 396 | struct vfio_device, kref); | 396 | struct vfio_device, kref); |
| 397 | struct vfio_group *group = device->group; | 397 | struct vfio_group *group = device->group; |
| 398 | 398 | ||
| 399 | mutex_lock(&group->device_lock); | ||
| 400 | list_del(&device->group_next); | 399 | list_del(&device->group_next); |
| 401 | mutex_unlock(&group->device_lock); | 400 | mutex_unlock(&group->device_lock); |
| 402 | 401 | ||
| @@ -412,7 +411,7 @@ static void vfio_device_release(struct kref *kref) | |||
| 412 | static void vfio_device_put(struct vfio_device *device) | 411 | static void vfio_device_put(struct vfio_device *device) |
| 413 | { | 412 | { |
| 414 | struct vfio_group *group = device->group; | 413 | struct vfio_group *group = device->group; |
| 415 | kref_put(&device->kref, vfio_device_release); | 414 | kref_put_mutex(&device->kref, vfio_device_release, &group->device_lock); |
| 416 | vfio_group_put(group); | 415 | vfio_group_put(group); |
| 417 | } | 416 | } |
| 418 | 417 | ||
