summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-09-03 16:46:47 +1000
committerDave Airlie <airlied@redhat.com>2013-09-03 17:14:24 +1000
commitafdfc14806b3507cdeee899f3c1a93bb77ec03ba (patch)
treee249ad9e4eb221de4379be501b9b9a475879758d
parent62d0946cfc646a472c90ff601256e740f59082b8 (diff)
step one for rebase to 3.11
virtio changes reservation changes
-rw-r--r--drivers/gpu/drm/virgl/virgl_3d.c63
-rw-r--r--drivers/gpu/drm/virgl/virgl_drv.h2
-rw-r--r--drivers/gpu/drm/virgl/virgl_ioctl.c5
-rw-r--r--drivers/gpu/drm/virgl/virgl_object.h5
4 files changed, 43 insertions, 32 deletions
diff --git a/drivers/gpu/drm/virgl/virgl_3d.c b/drivers/gpu/drm/virgl/virgl_3d.c
index 43b973b59d1f..936a84742449 100644
--- a/drivers/gpu/drm/virgl/virgl_3d.c
+++ b/drivers/gpu/drm/virgl/virgl_3d.c
@@ -5,6 +5,8 @@
#include "virgl_drv.h"
#include "virgl_object.h"
#include "ttm/ttm_execbuf_util.h"
+
+static void virt_map_sgt(struct scatterlist *sg, struct virgl_vbuffer *buf);
/* virtio config->get_features() implementation */
static u32 vp_get_features(struct virtio_device *vdev)
{
@@ -267,8 +269,6 @@ struct virgl_vbuffer *allocate_vbuf(struct virgl_device *qdev,
if (!bo->is_res_bound)
sgpages = bo->tbo.num_pages;
- sgpages++;
-
vbuf = kmalloc(sizeof(*vbuf) + sizeof(struct scatterlist) * sgpages + size, GFP_KERNEL);
if (!vbuf)
goto fail;
@@ -282,6 +282,7 @@ struct virgl_vbuffer *allocate_vbuf(struct virgl_device *qdev,
struct scatterlist *sg;
unsigned int i;
uint32_t offset = 0;
+
vbuf->bo = virgl_bo_ref(bo);
vbuf->bo_max_len = max_bo_len;
/* TODO work out offset */
@@ -309,6 +310,8 @@ struct virgl_vbuffer *allocate_vbuf(struct virgl_device *qdev,
vbuf->bo_start_offset = offset;
} else
vbuf->bo_start_offset = 0;
+
+ virt_map_sgt(&vbuf->sg[0], vbuf);
} else {
vbuf->bo = NULL;
vbuf->bo_max_len = 0;
@@ -376,17 +379,21 @@ void virgl_dequeue_work_func(struct work_struct *work)
wake_up(&qdev->cmd_ack_queue);
}
-static void virt_map_sgt(struct scatterlist *sg, struct virgl_vbuffer *buf,
- unsigned int *p_idx)
+static void virt_map_sgt(struct scatterlist *sg, struct virgl_vbuffer *buf)
{
struct scatterlist *sg_elem;
int i;
- int idx = *p_idx;
+ int idx = 0;
uint32_t offset = buf->bo->sgt->sgl->offset;
+ bool just_count = true;
+
+restart:
for_each_sg(buf->bo->sgt->sgl, sg_elem, buf->bo->sgt->nents, i) {
if (offset + sg_elem->length <= buf->bo_start_offset)
goto skip;
- sg[idx++] = *sg_elem;
+ if (just_count == false)
+ sg_set_page(&sg[idx], sg_page(sg_elem), sg_elem->length, sg_elem->offset);
+ idx++;
if (buf->bo_max_len)
if (offset + sg_elem->length > buf->bo_start_offset + buf->bo_user_offset + buf->bo_max_len)
break;
@@ -394,33 +401,39 @@ static void virt_map_sgt(struct scatterlist *sg, struct virgl_vbuffer *buf,
offset += sg_elem->length;
}
- *p_idx = idx;
+ if (just_count == true) {
+ sg_init_table(sg, idx);
+ idx = 0;
+ just_count = false;
+ offset = buf->bo->sgt->sgl->offset;
+ goto restart;
+ }
+ printk(KERN_ERR "remapped sgt %d vs %d\n", buf->bo->sgt->nents, idx);
}
int virgl_queue_cmd_buf(struct virgl_device *qdev,
struct virgl_vbuffer *buf)
{
struct virtqueue *vq = qdev->cmdq;
- struct scatterlist *sg = buf->sg;
int ret;
int idx = 0, outcnt = 0, incnt = 0, old_idx;
+ struct scatterlist *sgs[2], vcmd, vbuf;
+
+ sg_init_one(&vcmd, buf->buf, buf->size);
+ sgs[0] = &vcmd;
+ outcnt = 1;
- /* always put the command into in */
- sg_set_buf(&sg[idx++], buf->buf, buf->size);
- if (buf->inout == true)
- outcnt = idx;
if (buf->bo) {
- old_idx = idx;
- virt_map_sgt(sg, buf, &idx);
+ sgs[1] = &buf->sg[0];
+ if (buf->inout == true)
+ incnt = 1;
+ else
+ outcnt = 2;
}
- if (buf->inout == true)
- incnt = idx - outcnt;
- else
- outcnt = idx;
spin_lock(&qdev->cmdq_lock);
retry:
- ret = virtqueue_add_buf(vq, sg, outcnt, incnt, buf, GFP_ATOMIC);
+ ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, buf, GFP_ATOMIC);
if (ret == -ENOSPC) {
virtqueue_kick(vq);
spin_unlock(&qdev->cmdq_lock);
@@ -541,14 +554,15 @@ fail:
return ret;
}
-int virgl_bo_list_validate(struct list_head *head)
+int virgl_bo_list_validate(struct ww_acquire_ctx *ticket,
+ struct list_head *head)
{
struct ttm_validate_buffer *buf;
struct ttm_buffer_object *bo;
struct virgl_bo *qobj;
int ret;
- ret = ttm_eu_reserve_buffers(head);
+ ret = ttm_eu_reserve_buffers(ticket, head);
if (ret != 0)
return ret;
@@ -595,6 +609,7 @@ int virgl_execbuffer(struct drm_device *dev,
struct ttm_validate_buffer *buflist = NULL;
struct ttm_validate_buffer cmdbuffer;
int i;
+ struct ww_acquire_ctx ticket;
//printk("user cmd size %d\n", user_cmd.command_size);
memset(&cmdbuffer, 0, sizeof(struct ttm_validate_buffer));
@@ -644,7 +659,7 @@ int virgl_execbuffer(struct drm_device *dev,
cmdbuffer.bo = &qobj->tbo;
list_add(&cmdbuffer.head, &validate_list);
- ret = virgl_bo_list_validate(&validate_list);
+ ret = virgl_bo_list_validate(&ticket, &validate_list);
if (ret)
goto out_free;
@@ -677,7 +692,7 @@ int virgl_execbuffer(struct drm_device *dev,
virgl_queue_cmd_buf(qdev, vbuf);
}
- ttm_eu_fence_buffer_objects(&validate_list, fence);
+ ttm_eu_fence_buffer_objects(&ticket, &validate_list, fence);
/* fence the command bo */
virgl_unref_list(&validate_list);
@@ -686,7 +701,7 @@ int virgl_execbuffer(struct drm_device *dev,
out_kunmap:
virgl_bo_kunmap(qobj);
out_unresv:
- ttm_eu_backoff_reservation(&validate_list);
+ ttm_eu_backoff_reservation(&ticket, &validate_list);
out_free:
virgl_unref_list(&validate_list);
drm_free_large(buflist);
diff --git a/drivers/gpu/drm/virgl/virgl_drv.h b/drivers/gpu/drm/virgl/virgl_drv.h
index 6e7e5c55956f..cb674b887598 100644
--- a/drivers/gpu/drm/virgl/virgl_drv.h
+++ b/drivers/gpu/drm/virgl/virgl_drv.h
@@ -402,6 +402,6 @@ void virgl_disable_vblank(struct drm_device *dev, int crtc);
int virgl_get_caps(struct virgl_device *vdev);
-int virgl_bo_list_validate(struct list_head *head);
+int virgl_bo_list_validate(struct ww_acquire_ctx *ticket, struct list_head *head);
void virgl_unref_list(struct list_head *head);
#endif
diff --git a/drivers/gpu/drm/virgl/virgl_ioctl.c b/drivers/gpu/drm/virgl/virgl_ioctl.c
index 8932883bbca6..7178ab1517dd 100644
--- a/drivers/gpu/drm/virgl/virgl_ioctl.c
+++ b/drivers/gpu/drm/virgl/virgl_ioctl.c
@@ -111,6 +111,7 @@ static int virgl_resource_create_ioctl(struct drm_device *dev, void *data,
struct list_head validate_list;
struct ttm_validate_buffer mainbuf, page_info_buf;
struct virgl_fence *fence;
+ struct ww_acquire_ctx ticket;
INIT_LIST_HEAD(&validate_list);
memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer));
@@ -154,7 +155,7 @@ static int virgl_resource_create_ioctl(struct drm_device *dev, void *data,
list_add(&page_info_buf.head, &validate_list);
}
- ret = virgl_bo_list_validate(&validate_list);
+ ret = virgl_bo_list_validate(&ticket, &validate_list);
if (ret) {
printk("failed to validate\n");
goto fail_unref;
@@ -192,7 +193,7 @@ static int virgl_resource_create_ioctl(struct drm_device *dev, void *data,
virgl_queue_cmd_buf(qdev, vbuf);
- ttm_eu_fence_buffer_objects(&validate_list, fence);
+ ttm_eu_fence_buffer_objects(&ticket, &validate_list, fence);
qobj->res_handle = res_id;
qobj->stride = rc->stride;
diff --git a/drivers/gpu/drm/virgl/virgl_object.h b/drivers/gpu/drm/virgl/virgl_object.h
index 17b31b8581a3..67950ffd1750 100644
--- a/drivers/gpu/drm/virgl/virgl_object.h
+++ b/drivers/gpu/drm/virgl/virgl_object.h
@@ -57,11 +57,6 @@ static inline unsigned long virgl_bo_size(struct virgl_bo *bo)
return bo->tbo.num_pages << PAGE_SHIFT;
}
-static inline bool virgl_bo_is_reserved(struct virgl_bo *bo)
-{
- return !!atomic_read(&bo->tbo.reserved);
-}
-
static inline u64 virgl_bo_mmap_offset(struct virgl_bo *bo)
{
return bo->tbo.addr_space_offset;