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: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
96503f592f
commit
129b78bfca
|
@ -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 @@ retry:
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
* 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,
|
||||||
|
|
||||||
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,
|
||||||
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 {
|
||||||
*
|
*
|
||||||
* @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 {
|
||||||
|
|
||||||
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,
|
||||||
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 {
|
||||||
#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 {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue