Commit ca9cf68d authored by Nicolai Hähnle's avatar Nicolai Hähnle Committed by Alex Deucher

drm/ttm: add ttm_bo_init_reserved

This variant of ttm_bo_init returns the validated buffer object with
the reservation lock held when resv == NULL. This is convenient for
callers that want to use the BO immediately, e.g. for initializing its
contents.
Signed-off-by: default avatarNicolai Hähnle <nicolai.haehnle@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 882e8cfc
...@@ -1093,18 +1093,18 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1093,18 +1093,18 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
} }
EXPORT_SYMBOL(ttm_bo_validate); EXPORT_SYMBOL(ttm_bo_validate);
int ttm_bo_init(struct ttm_bo_device *bdev, int ttm_bo_init_reserved(struct ttm_bo_device *bdev,
struct ttm_buffer_object *bo, struct ttm_buffer_object *bo,
unsigned long size, unsigned long size,
enum ttm_bo_type type, enum ttm_bo_type type,
struct ttm_placement *placement, struct ttm_placement *placement,
uint32_t page_alignment, uint32_t page_alignment,
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, struct sg_table *sg,
struct reservation_object *resv, struct reservation_object *resv,
void (*destroy) (struct ttm_buffer_object *)) void (*destroy) (struct ttm_buffer_object *))
{ {
int ret = 0; int ret = 0;
unsigned long num_pages; unsigned long num_pages;
...@@ -1188,10 +1188,10 @@ int ttm_bo_init(struct ttm_bo_device *bdev, ...@@ -1188,10 +1188,10 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
if (likely(!ret)) if (likely(!ret))
ret = ttm_bo_validate(bo, placement, interruptible, false); ret = ttm_bo_validate(bo, placement, interruptible, false);
if (!resv)
ttm_bo_unreserve(bo);
if (unlikely(ret)) { if (unlikely(ret)) {
if (!resv)
ttm_bo_unreserve(bo);
ttm_bo_unref(&bo); ttm_bo_unref(&bo);
return ret; return ret;
} }
...@@ -1204,6 +1204,35 @@ int ttm_bo_init(struct ttm_bo_device *bdev, ...@@ -1204,6 +1204,35 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
return ret; return ret;
} }
EXPORT_SYMBOL(ttm_bo_init_reserved);
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,
bool interruptible,
struct file *persistent_swap_storage,
size_t acc_size,
struct sg_table *sg,
struct reservation_object *resv,
void (*destroy) (struct ttm_buffer_object *))
{
int ret;
ret = ttm_bo_init_reserved(bdev, bo, size, type, placement,
page_alignment, interruptible,
persistent_swap_storage, acc_size,
sg, resv, destroy);
if (ret)
return ret;
if (!resv)
ttm_bo_unreserve(bo);
return 0;
}
EXPORT_SYMBOL(ttm_bo_init); EXPORT_SYMBOL(ttm_bo_init);
size_t ttm_bo_acc_size(struct ttm_bo_device *bdev, size_t ttm_bo_acc_size(struct ttm_bo_device *bdev,
......
...@@ -439,6 +439,60 @@ size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, ...@@ -439,6 +439,60 @@ size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev,
unsigned long bo_size, unsigned long bo_size,
unsigned struct_size); unsigned struct_size);
/**
* ttm_bo_init_reserved
*
* @bdev: Pointer to a ttm_bo_device struct.
* @bo: Pointer to a ttm_buffer_object to be initialized.
* @size: Requested size of buffer object.
* @type: Requested type of buffer object.
* @flags: Initial placement flags.
* @page_alignment: Data alignment in pages.
* @interruptible: If needing to sleep to wait for GPU resources,
* sleep interruptible.
* @persistent_swap_storage: Usually the swap storage is deleted for buffers
* pinned in physical memory. If this behaviour is not desired, this member
* holds a pointer to a persistent shmem object. Typically, this would
* point to the shmem object backing a GEM object if TTM is used to back a
* GEM user interface.
* @acc_size: Accounted size for this object.
* @resv: Pointer to a reservation_object, or NULL to let ttm allocate one.
* @destroy: Destroy function. Use NULL for kfree().
*
* This function initializes a pre-allocated struct ttm_buffer_object.
* As this object may be part of a larger structure, this function,
* together with the @destroy function,
* enables driver-specific objects derived from a ttm_buffer_object.
*
* On successful return, the caller owns an object kref to @bo. The kref and
* list_kref are usually set to 1, but note that in some situations, other
* tasks may already be holding references to @bo as well.
* Furthermore, if resv == NULL, the buffer's reservation lock will be held,
* and it is the caller's responsibility to call ttm_bo_unreserve.
*
* If a failure occurs, the function will call the @destroy function, or
* kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is
* illegal and will likely cause memory corruption.
*
* Returns
* -ENOMEM: Out of memory.
* -EINVAL: Invalid placement flags.
* -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
*/
extern int ttm_bo_init_reserved(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,
bool interrubtible,
struct file *persistent_swap_storage,
size_t acc_size,
struct sg_table *sg,
struct reservation_object *resv,
void (*destroy) (struct ttm_buffer_object *));
/** /**
* ttm_bo_init * ttm_bo_init
* *
......
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