diff options
author | Dave Airlie <airlied@redhat.com> | 2013-08-06 15:49:21 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-09-03 15:11:29 +1000 |
commit | 77fccfe7b9c313b159f27b0fd6bba575aa0e117a (patch) | |
tree | b7c420a5e9b1521be5dfb0e0925ad13a9a6a503e | |
parent | 8f6206598f2304911bf27e922841a25b796ab967 (diff) |
virgl: unreference buffers aand free outside spinlock
when we remove buffers add them to a list, then free them outside the lock
-rw-r--r-- | drivers/gpu/drm/virgl/virgl_3d.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/virgl/virgl_drv.h | 1 |
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/gpu/drm/virgl/virgl_3d.c b/drivers/gpu/drm/virgl/virgl_3d.c index 342c2f4c2274..5c7923a5a8ee 100644 --- a/drivers/gpu/drm/virgl/virgl_3d.c +++ b/drivers/gpu/drm/virgl/virgl_3d.c @@ -334,13 +334,13 @@ struct virgl_command *virgl_alloc_cmd_buf(struct virgl_device *qdev, return (struct virgl_command *)vbuf->buf; } -static int reclaim_vbufs(struct virtqueue *vq) +static int reclaim_vbufs(struct virtqueue *vq, struct list_head *reclaim_list) { struct virgl_vbuffer *vbuf; unsigned int len; int freed = 0; while ((vbuf = virtqueue_get_buf(vq, &len))) { - free_vbuf(vbuf); + list_add(&vbuf->destroy_list, reclaim_list); freed++; } return freed; @@ -351,15 +351,24 @@ void virgl_dequeue_work_func(struct work_struct *work) struct virgl_device *qdev = container_of(work, struct virgl_device, dequeue_work); int ret; + struct list_head reclaim_list; + struct virgl_vbuffer *entry, *tmp; + + INIT_LIST_HEAD(&reclaim_list); spin_lock(&qdev->cmdq_lock); do { virtqueue_disable_cb(qdev->cmdq); - ret = reclaim_vbufs(qdev->cmdq); + ret = reclaim_vbufs(qdev->cmdq, &reclaim_list); if (ret == 0) printk("cleaned 0 buffers wierd\n"); qdev->num_freed += ret; } while (!virtqueue_enable_cb(qdev->cmdq)); spin_unlock(&qdev->cmdq_lock); + + list_for_each_entry_safe(entry, tmp, &reclaim_list, destroy_list) { + list_del(&entry->destroy_list); + free_vbuf(entry); + } wake_up(&qdev->cmd_ack_queue); } diff --git a/drivers/gpu/drm/virgl/virgl_drv.h b/drivers/gpu/drm/virgl/virgl_drv.h index 90e0fa82c481..1e96c4373f13 100644 --- a/drivers/gpu/drm/virgl/virgl_drv.h +++ b/drivers/gpu/drm/virgl/virgl_drv.h @@ -127,6 +127,7 @@ struct virgl_vbuffer { char *buf; size_t size; + struct list_head destroy_list; size_t bo_max_len; size_t bo_start_offset; size_t bo_user_offset; |