Commit ca262a99 authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie

drm/ttm: Rework validation & memory space allocation (V3)

This change allow driver to pass sorted memory placement,
from most prefered placement to least prefered placement.
In order to avoid long function prototype a structure is
used to gather memory placement informations such as range
restriction (if you need a buffer to be in given range).
Range restriction is determined by fpfn & lpfn which are
the first page and last page number btw which allocation
can happen. If those fields are set to 0 ttm will assume
buffer can be put anywhere in the address space (thus it
avoids putting a burden on the driver to always properly
set those fields).

This patch also factor few functions like evicting first
entry of lru list or getting a memory space. This avoid
code duplication.

V2: Change API to use placement flags and array instead
    of packing placement order into a quadword.
V3: Make sure we set the appropriate mem.placement flag
    when validating or allocation memory space.

[Pending Thomas Hellstrom further review but okay
from preliminary review so far].
Signed-off-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent a2e68e92
This diff is collapsed.
...@@ -44,6 +44,29 @@ struct ttm_bo_device; ...@@ -44,6 +44,29 @@ struct ttm_bo_device;
struct drm_mm_node; struct drm_mm_node;
/**
* struct ttm_placement
*
* @fpfn: first valid page frame number to put the object
* @lpfn: last valid page frame number to put the object
* @num_placement: number of prefered placements
* @placement: prefered placements
* @num_busy_placement: number of prefered placements when need to evict buffer
* @busy_placement: prefered placements when need to evict buffer
*
* Structure indicating the placement you request for an object.
*/
struct ttm_placement {
unsigned fpfn;
unsigned lpfn;
unsigned num_placement;
const uint32_t *placement;
unsigned num_busy_placement;
const uint32_t *busy_placement;
};
/** /**
* struct ttm_mem_reg * struct ttm_mem_reg
* *
...@@ -109,10 +132,6 @@ struct ttm_tt; ...@@ -109,10 +132,6 @@ struct ttm_tt;
* the object is destroyed. * the object is destroyed.
* @event_queue: Queue for processes waiting on buffer object status change. * @event_queue: Queue for processes waiting on buffer object status change.
* @lock: spinlock protecting mostly synchronization members. * @lock: spinlock protecting mostly synchronization members.
* @proposed_placement: Proposed placement for the buffer. Changed only by the
* creator prior to validation as opposed to bo->mem.proposed_flags which is
* changed by the implementation prior to a buffer move if it wants to outsmart
* the buffer creator / user. This latter happens, for example, at eviction.
* @mem: structure describing current placement. * @mem: structure describing current placement.
* @persistant_swap_storage: Usually the swap storage is deleted for buffers * @persistant_swap_storage: Usually the swap storage is deleted for buffers
* pinned in physical memory. If this behaviour is not desired, this member * pinned in physical memory. If this behaviour is not desired, this member
...@@ -177,7 +196,6 @@ struct ttm_buffer_object { ...@@ -177,7 +196,6 @@ struct ttm_buffer_object {
* Members protected by the bo::reserved lock. * Members protected by the bo::reserved lock.
*/ */
uint32_t proposed_placement;
struct ttm_mem_reg mem; struct ttm_mem_reg mem;
struct file *persistant_swap_storage; struct file *persistant_swap_storage;
struct ttm_tt *ttm; struct ttm_tt *ttm;
...@@ -293,21 +311,22 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, ...@@ -293,21 +311,22 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
* ttm_buffer_object_validate * ttm_buffer_object_validate
* *
* @bo: The buffer object. * @bo: The buffer object.
* @proposed_placement: Proposed_placement for the buffer object. * @placement: Proposed placement for the buffer object.
* @interruptible: Sleep interruptible if sleeping. * @interruptible: Sleep interruptible if sleeping.
* @no_wait: Return immediately if the buffer is busy. * @no_wait: Return immediately if the buffer is busy.
* *
* Changes placement and caching policy of the buffer object * Changes placement and caching policy of the buffer object
* according to bo::proposed_flags. * according proposed placement.
* Returns * Returns
* -EINVAL on invalid proposed_flags. * -EINVAL on invalid proposed placement.
* -ENOMEM on out-of-memory condition. * -ENOMEM on out-of-memory condition.
* -EBUSY if no_wait is true and buffer busy. * -EBUSY if no_wait is true and buffer busy.
* -ERESTART if interrupted by a signal. * -ERESTART if interrupted by a signal.
*/ */
extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo, extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
uint32_t proposed_placement, struct ttm_placement *placement,
bool interruptible, bool no_wait); bool interruptible, bool no_wait);
/** /**
* ttm_bo_unref * ttm_bo_unref
* *
...@@ -445,7 +464,6 @@ extern int ttm_bo_check_placement(struct ttm_buffer_object *bo, ...@@ -445,7 +464,6 @@ extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
* *
* @bdev: Pointer to a ttm_bo_device struct. * @bdev: Pointer to a ttm_bo_device struct.
* @mem_type: The memory type. * @mem_type: The memory type.
* @p_offset: offset for managed area in pages.
* @p_size: size managed area in pages. * @p_size: size managed area in pages.
* *
* Initialize a manager for a given memory type. * Initialize a manager for a given memory type.
...@@ -458,7 +476,7 @@ extern int ttm_bo_check_placement(struct ttm_buffer_object *bo, ...@@ -458,7 +476,7 @@ extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
*/ */
extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
unsigned long p_offset, unsigned long p_size); unsigned long p_size);
/** /**
* ttm_bo_clean_mm * ttm_bo_clean_mm
* *
......
...@@ -242,12 +242,6 @@ struct ttm_mem_type_manager { ...@@ -242,12 +242,6 @@ struct ttm_mem_type_manager {
/** /**
* struct ttm_bo_driver * struct ttm_bo_driver
* *
* @mem_type_prio: Priority array of memory types to place a buffer object in
* if it fits without evicting buffers from any of these memory types.
* @mem_busy_prio: Priority array of memory types to place a buffer object in
* if it needs to evict buffers to make room.
* @num_mem_type_prio: Number of elements in the @mem_type_prio array.
* @num_mem_busy_prio: Number of elements in the @num_mem_busy_prio array.
* @create_ttm_backend_entry: Callback to create a struct ttm_backend. * @create_ttm_backend_entry: Callback to create a struct ttm_backend.
* @invalidate_caches: Callback to invalidate read caches when a buffer object * @invalidate_caches: Callback to invalidate read caches when a buffer object
* has been evicted. * has been evicted.
...@@ -265,11 +259,6 @@ struct ttm_mem_type_manager { ...@@ -265,11 +259,6 @@ struct ttm_mem_type_manager {
*/ */
struct ttm_bo_driver { struct ttm_bo_driver {
const uint32_t *mem_type_prio;
const uint32_t *mem_busy_prio;
uint32_t num_mem_type_prio;
uint32_t num_mem_busy_prio;
/** /**
* struct ttm_bo_driver member create_ttm_backend_entry * struct ttm_bo_driver member create_ttm_backend_entry
* *
...@@ -306,7 +295,8 @@ struct ttm_bo_driver { ...@@ -306,7 +295,8 @@ struct ttm_bo_driver {
* finished, they'll end up in bo->mem.flags * finished, they'll end up in bo->mem.flags
*/ */
uint32_t(*evict_flags) (struct ttm_buffer_object *bo); void(*evict_flags) (struct ttm_buffer_object *bo,
struct ttm_placement *placement);
/** /**
* struct ttm_bo_driver member move: * struct ttm_bo_driver member move:
* *
...@@ -651,9 +641,9 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, ...@@ -651,9 +641,9 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev,
* -ERESTART: An interruptible sleep was interrupted by a signal. * -ERESTART: An interruptible sleep was interrupted by a signal.
*/ */
extern int ttm_bo_mem_space(struct ttm_buffer_object *bo, extern int ttm_bo_mem_space(struct ttm_buffer_object *bo,
uint32_t proposed_placement, struct ttm_placement *placement,
struct ttm_mem_reg *mem, struct ttm_mem_reg *mem,
bool interruptible, bool no_wait); bool interruptible, bool no_wait);
/** /**
* ttm_bo_wait_for_cpu * ttm_bo_wait_for_cpu
* *
......
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