Commit 129b78bf authored by Dave Airlie's avatar Dave Airlie

ttm: add prime sharing support to TTM (v2)

This adds the ability for ttm common code to take an SG table
and use it as the backing for a slave TTM object.

The drivers can then populate their GTT tables using the SG object.

v2: make sure to setup VM for sg bos as well.
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 96503f59
...@@ -121,7 +121,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align, ...@@ -121,7 +121,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
ttm_bo_type_device, &nvbo->placement, ttm_bo_type_device, &nvbo->placement,
align >> PAGE_SHIFT, 0, false, NULL, acc_size, align >> PAGE_SHIFT, 0, false, NULL, acc_size, NULL,
nouveau_bo_del_ttm); nouveau_bo_del_ttm);
if (ret) { if (ret) {
/* ttm will call nouveau_bo_del_ttm if it fails.. */ /* ttm will call nouveau_bo_del_ttm if it fails.. */
......
...@@ -155,7 +155,7 @@ int radeon_bo_create(struct radeon_device *rdev, ...@@ -155,7 +155,7 @@ int radeon_bo_create(struct radeon_device *rdev,
mutex_lock(&rdev->vram_mutex); mutex_lock(&rdev->vram_mutex);
r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
&bo->placement, page_align, 0, !kernel, NULL, &bo->placement, page_align, 0, !kernel, NULL,
acc_size, &radeon_ttm_bo_destroy); acc_size, NULL, &radeon_ttm_bo_destroy);
mutex_unlock(&rdev->vram_mutex); mutex_unlock(&rdev->vram_mutex);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
if (r != -ERESTARTSYS) { if (r != -ERESTARTSYS) {
......
...@@ -343,6 +343,16 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) ...@@ -343,6 +343,16 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
if (unlikely(bo->ttm == NULL)) if (unlikely(bo->ttm == NULL))
ret = -ENOMEM; ret = -ENOMEM;
break; break;
case ttm_bo_type_sg:
bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
page_flags | TTM_PAGE_FLAG_SG,
glob->dummy_read_page);
if (unlikely(bo->ttm == NULL)) {
ret = -ENOMEM;
break;
}
bo->ttm->sg = bo->sg;
break;
default: default:
pr_err("Illegal buffer object type\n"); pr_err("Illegal buffer object type\n");
ret = -EINVAL; ret = -EINVAL;
...@@ -1169,6 +1179,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, ...@@ -1169,6 +1179,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
bool interruptible, bool interruptible,
struct file *persistent_swap_storage, struct file *persistent_swap_storage,
size_t acc_size, size_t acc_size,
struct sg_table *sg,
void (*destroy) (struct ttm_buffer_object *)) void (*destroy) (struct ttm_buffer_object *))
{ {
int ret = 0; int ret = 0;
...@@ -1223,6 +1234,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, ...@@ -1223,6 +1234,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
bo->seq_valid = false; bo->seq_valid = false;
bo->persistent_swap_storage = persistent_swap_storage; bo->persistent_swap_storage = persistent_swap_storage;
bo->acc_size = acc_size; bo->acc_size = acc_size;
bo->sg = sg;
atomic_inc(&bo->glob->bo_count); atomic_inc(&bo->glob->bo_count);
ret = ttm_bo_check_placement(bo, placement); ret = ttm_bo_check_placement(bo, placement);
...@@ -1233,7 +1245,8 @@ int ttm_bo_init(struct ttm_bo_device *bdev, ...@@ -1233,7 +1245,8 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
* For ttm_bo_type_device buffers, allocate * For ttm_bo_type_device buffers, allocate
* address space from the device. * address space from the device.
*/ */
if (bo->type == ttm_bo_type_device) { if (bo->type == ttm_bo_type_device ||
bo->type == ttm_bo_type_sg) {
ret = ttm_bo_setup_vm(bo); ret = ttm_bo_setup_vm(bo);
if (ret) if (ret)
goto out_err; goto out_err;
...@@ -1312,7 +1325,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev, ...@@ -1312,7 +1325,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev,
ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
buffer_start, interruptible, buffer_start, interruptible,
persistent_swap_storage, acc_size, NULL); persistent_swap_storage, acc_size, NULL, NULL);
if (likely(ret == 0)) if (likely(ret == 0))
*p_bo = bo; *p_bo = bo;
......
...@@ -1567,7 +1567,7 @@ int vmw_dmabuf_init(struct vmw_private *dev_priv, ...@@ -1567,7 +1567,7 @@ int vmw_dmabuf_init(struct vmw_private *dev_priv,
ret = ttm_bo_init(bdev, &vmw_bo->base, size, ret = ttm_bo_init(bdev, &vmw_bo->base, size,
ttm_bo_type_device, placement, ttm_bo_type_device, placement,
0, 0, interruptible, 0, 0, interruptible,
NULL, acc_size, bo_free); NULL, acc_size, NULL, bo_free);
return ret; return ret;
} }
......
...@@ -124,11 +124,15 @@ struct ttm_mem_reg { ...@@ -124,11 +124,15 @@ struct ttm_mem_reg {
* *
* @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers, * @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers,
* but they cannot be accessed from user-space. For kernel-only use. * but they cannot be accessed from user-space. For kernel-only use.
*
* @ttm_bo_type_sg: Buffer made from dmabuf sg table shared with another
* driver.
*/ */
enum ttm_bo_type { enum ttm_bo_type {
ttm_bo_type_device, ttm_bo_type_device,
ttm_bo_type_kernel ttm_bo_type_kernel,
ttm_bo_type_sg
}; };
struct ttm_tt; struct ttm_tt;
...@@ -271,6 +275,8 @@ struct ttm_buffer_object { ...@@ -271,6 +275,8 @@ struct ttm_buffer_object {
unsigned long offset; unsigned long offset;
uint32_t cur_placement; uint32_t cur_placement;
struct sg_table *sg;
}; };
/** /**
...@@ -503,6 +509,7 @@ extern int ttm_bo_init(struct ttm_bo_device *bdev, ...@@ -503,6 +509,7 @@ extern int ttm_bo_init(struct ttm_bo_device *bdev,
bool interrubtible, bool interrubtible,
struct file *persistent_swap_storage, struct file *persistent_swap_storage,
size_t acc_size, size_t acc_size,
struct sg_table *sg,
void (*destroy) (struct ttm_buffer_object *)); void (*destroy) (struct ttm_buffer_object *));
/** /**
......
...@@ -81,6 +81,7 @@ struct ttm_backend_func { ...@@ -81,6 +81,7 @@ struct ttm_backend_func {
#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5) #define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5)
#define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) #define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6)
#define TTM_PAGE_FLAG_DMA32 (1 << 7) #define TTM_PAGE_FLAG_DMA32 (1 << 7)
#define TTM_PAGE_FLAG_SG (1 << 8)
enum ttm_caching_state { enum ttm_caching_state {
tt_uncached, tt_uncached,
...@@ -116,6 +117,7 @@ struct ttm_tt { ...@@ -116,6 +117,7 @@ struct ttm_tt {
struct page **pages; struct page **pages;
uint32_t page_flags; uint32_t page_flags;
unsigned long num_pages; unsigned long num_pages;
struct sg_table *sg; /* for SG objects via dma-buf */
struct ttm_bo_global *glob; struct ttm_bo_global *glob;
struct ttm_backend *be; struct ttm_backend *be;
struct file *swap_storage; struct file *swap_storage;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment