Skip to content

Commit

Permalink
drm/ttm: Convert ttm_buffer_object_init to use ttm_placement
Browse files Browse the repository at this point in the history
Convert ttm_buffer_object_init to use struct ttm_placement and
rename to ttm_bo_init for consistency with function naming. This
allow to give more complex placement at buffer creation. For
instance you ask to allocate bo into vram first but if there is
not enough vram you can give system as a second possible
placement. It also allow to create buffer in a specific range.

Also rename ttm_buffer_object_validate to ttm_bo_validate.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Jerome Glisse authored and airlied committed Dec 11, 2009
1 parent 4361e52 commit 09855ac
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 106 deletions.
130 changes: 57 additions & 73 deletions drivers/gpu/drm/ttm/ttm_bo.c
Expand Up @@ -1002,9 +1002,9 @@ static int ttm_bo_mem_compat(struct ttm_placement *placement,
return -1;
}

int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
bool interruptible, bool no_wait)
int ttm_bo_validate(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
bool interruptible, bool no_wait)
{
int ret;

Expand Down Expand Up @@ -1040,55 +1040,57 @@ int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
}
return 0;
}
EXPORT_SYMBOL(ttm_buffer_object_validate);
EXPORT_SYMBOL(ttm_bo_validate);

int
ttm_bo_check_placement(struct ttm_buffer_object *bo,
uint32_t set_flags, uint32_t clr_flags)
int ttm_bo_check_placement(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
uint32_t new_mask = set_flags | clr_flags;

if ((bo->type == ttm_bo_type_user) &&
(clr_flags & TTM_PL_FLAG_CACHED)) {
printk(KERN_ERR TTM_PFX
"User buffers require cache-coherent memory.\n");
return -EINVAL;
}
int i;

if (!capable(CAP_SYS_ADMIN)) {
if (new_mask & TTM_PL_FLAG_NO_EVICT) {
printk(KERN_ERR TTM_PFX "Need to be root to modify"
" NO_EVICT status.\n");
if (placement->fpfn || placement->lpfn) {
if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) {
printk(KERN_ERR TTM_PFX "Page number range to small "
"Need %lu pages, range is [%u, %u]\n",
bo->mem.num_pages, placement->fpfn,
placement->lpfn);
return -EINVAL;
}

if ((clr_flags & bo->mem.placement & TTM_PL_MASK_MEMTYPE) &&
(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
printk(KERN_ERR TTM_PFX
"Incompatible memory specification"
" for NO_EVICT buffer.\n");
return -EINVAL;
}
for (i = 0; i < placement->num_placement; i++) {
if (!capable(CAP_SYS_ADMIN)) {
if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
printk(KERN_ERR TTM_PFX "Need to be root to "
"modify NO_EVICT status.\n");
return -EINVAL;
}
}
}
for (i = 0; i < placement->num_busy_placement; i++) {
if (!capable(CAP_SYS_ADMIN)) {
if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) {
printk(KERN_ERR TTM_PFX "Need to be root to "
"modify NO_EVICT status.\n");
return -EINVAL;
}
}
}
return 0;
}

int ttm_buffer_object_init(struct ttm_bo_device *bdev,
struct ttm_buffer_object *bo,
unsigned long size,
enum ttm_bo_type type,
uint32_t flags,
uint32_t page_alignment,
unsigned long buffer_start,
bool interruptible,
struct file *persistant_swap_storage,
size_t acc_size,
void (*destroy) (struct ttm_buffer_object *))
int ttm_bo_init(struct ttm_bo_device *bdev,
struct ttm_buffer_object *bo,
unsigned long size,
enum ttm_bo_type type,
struct ttm_placement *placement,
uint32_t page_alignment,
unsigned long buffer_start,
bool interruptible,
struct file *persistant_swap_storage,
size_t acc_size,
void (*destroy) (struct ttm_buffer_object *))
{
int i, c, ret = 0;
int ret = 0;
unsigned long num_pages;
uint32_t placements[8];
struct ttm_placement placement;

size += buffer_start & ~PAGE_MASK;
num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
Expand Down Expand Up @@ -1123,38 +1125,21 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,
bo->acc_size = acc_size;
atomic_inc(&bo->glob->bo_count);

ret = ttm_bo_check_placement(bo, flags, 0ULL);
ret = ttm_bo_check_placement(bo, placement);
if (unlikely(ret != 0))
goto out_err;

/*
* If no caching attributes are set, accept any form of caching.
*/

if ((flags & TTM_PL_MASK_CACHING) == 0)
flags |= TTM_PL_MASK_CACHING;

/*
* For ttm_bo_type_device buffers, allocate
* address space from the device.
*/

if (bo->type == ttm_bo_type_device) {
ret = ttm_bo_setup_vm(bo);
if (ret)
goto out_err;
}

placement.fpfn = 0;
placement.lpfn = 0;
for (i = 0, c = 0; i <= TTM_PL_PRIV5; i++)
if (flags & (1 << i))
placements[c++] = (flags & ~TTM_PL_MASK_MEM) | (1 << i);
placement.placement = placements;
placement.num_placement = c;
placement.busy_placement = placements;
placement.num_busy_placement = c;
ret = ttm_buffer_object_validate(bo, &placement, interruptible, false);
ret = ttm_bo_validate(bo, placement, interruptible, false);
if (ret)
goto out_err;

Expand All @@ -1167,7 +1152,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,

return ret;
}
EXPORT_SYMBOL(ttm_buffer_object_init);
EXPORT_SYMBOL(ttm_bo_init);

static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
unsigned long num_pages)
Expand All @@ -1178,15 +1163,15 @@ static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
return glob->ttm_bo_size + 2 * page_array_size;
}

int ttm_buffer_object_create(struct ttm_bo_device *bdev,
unsigned long size,
enum ttm_bo_type type,
uint32_t flags,
uint32_t page_alignment,
unsigned long buffer_start,
bool interruptible,
struct file *persistant_swap_storage,
struct ttm_buffer_object **p_bo)
int ttm_bo_create(struct ttm_bo_device *bdev,
unsigned long size,
enum ttm_bo_type type,
struct ttm_placement *placement,
uint32_t page_alignment,
unsigned long buffer_start,
bool interruptible,
struct file *persistant_swap_storage,
struct ttm_buffer_object **p_bo)
{
struct ttm_buffer_object *bo;
struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
Expand All @@ -1205,10 +1190,9 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev,
return -ENOMEM;
}

ret = ttm_buffer_object_init(bdev, bo, size, type, flags,
page_alignment, buffer_start,
interruptible,
persistant_swap_storage, acc_size, NULL);
ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
buffer_start, interruptible,
persistant_swap_storage, acc_size, NULL);
if (likely(ret == 0))
*p_bo = bo;

Expand Down
63 changes: 30 additions & 33 deletions include/drm/ttm/ttm_bo_api.h
Expand Up @@ -308,7 +308,7 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
bool interruptible, bool no_wait);
/**
* ttm_buffer_object_validate
* ttm_bo_validate
*
* @bo: The buffer object.
* @placement: Proposed placement for the buffer object.
Expand All @@ -323,9 +323,9 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
* -EBUSY if no_wait is true and buffer busy.
* -ERESTARTSYS if interrupted by a signal.
*/
extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
bool interruptible, bool no_wait);
extern int ttm_bo_validate(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
bool interruptible, bool no_wait);

/**
* ttm_bo_unref
Expand Down Expand Up @@ -362,7 +362,7 @@ ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait);
extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);

/**
* ttm_buffer_object_init
* ttm_bo_init
*
* @bdev: Pointer to a ttm_bo_device struct.
* @bo: Pointer to a ttm_buffer_object to be initialized.
Expand Down Expand Up @@ -393,17 +393,17 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
* -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
*/

extern int ttm_buffer_object_init(struct ttm_bo_device *bdev,
struct ttm_buffer_object *bo,
unsigned long size,
enum ttm_bo_type type,
uint32_t flags,
uint32_t page_alignment,
unsigned long buffer_start,
bool interrubtible,
struct file *persistant_swap_storage,
size_t acc_size,
void (*destroy) (struct ttm_buffer_object *));
extern int ttm_bo_init(struct ttm_bo_device *bdev,
struct ttm_buffer_object *bo,
unsigned long size,
enum ttm_bo_type type,
struct ttm_placement *placement,
uint32_t page_alignment,
unsigned long buffer_start,
bool interrubtible,
struct file *persistant_swap_storage,
size_t acc_size,
void (*destroy) (struct ttm_buffer_object *));
/**
* ttm_bo_synccpu_object_init
*
Expand All @@ -424,40 +424,37 @@ extern int ttm_buffer_object_init(struct ttm_bo_device *bdev,
* GEM user interface.
* @p_bo: On successful completion *p_bo points to the created object.
*
* This function allocates a ttm_buffer_object, and then calls
* ttm_buffer_object_init on that object.
* The destroy function is set to kfree().
* This function allocates a ttm_buffer_object, and then calls ttm_bo_init
* on that object. The destroy function is set to kfree().
* Returns
* -ENOMEM: Out of memory.
* -EINVAL: Invalid placement flags.
* -ERESTARTSYS: Interrupted by signal while waiting for resources.
*/

extern int ttm_buffer_object_create(struct ttm_bo_device *bdev,
unsigned long size,
enum ttm_bo_type type,
uint32_t flags,
uint32_t page_alignment,
unsigned long buffer_start,
bool interruptible,
struct file *persistant_swap_storage,
struct ttm_buffer_object **p_bo);
extern int ttm_bo_create(struct ttm_bo_device *bdev,
unsigned long size,
enum ttm_bo_type type,
struct ttm_placement *placement,
uint32_t page_alignment,
unsigned long buffer_start,
bool interruptible,
struct file *persistant_swap_storage,
struct ttm_buffer_object **p_bo);

/**
* ttm_bo_check_placement
*
* @bo: the buffer object.
* @set_flags: placement flags to set.
* @clr_flags: placement flags to clear.
* @bo: the buffer object.
* @placement: placements
*
* Performs minimal validity checking on an intended change of
* placement flags.
* Returns
* -EINVAL: Intended change is invalid or not allowed.
*/

extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
uint32_t set_flags, uint32_t clr_flags);
struct ttm_placement *placement);

/**
* ttm_bo_init_mm
Expand Down

0 comments on commit 09855ac

Please sign in to comment.