[Intel-gfx] [PATCH 1/3] drm: Add colouring to the range allocator
Daniel Vetter
daniel at ffwll.ch
Tue Jul 10 11:21:57 CEST 2012
On Mon, Jul 09, 2012 at 12:34:37PM +0100, Chris Wilson wrote:
> In order to support snoopable memory on non-LLC architectures (so that
> we can bind vgem objects into the i915 GATT for example), we have to
> avoid the prefetcher on the GPU from crossing memory domains and so
> prevent allocation of a snoopable PTE immediately following an uncached
> PTE. To do that, we need to extend the range allocator with support for
> tracking and segregating different node colours.
>
> This will be used by i915 to segregate memory domains within the GTT.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Dave Airlie <airlied at redhat.com
> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Cc: Ben Skeggs <bskeggs at redhat.com>
> Cc: Jerome Glisse <jglisse at redhat.com>
> Cc: Alex Deucher <alexander.deucher at amd.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
Two little bikesheds:
- Do we really need 64bits of colour? Especially since we have quite a few
bits of space left ...
- I think we could add a new insert_color helper that always takes a range
(we can select the right rang in the driver). That way this patch
wouldn't need to touch the drivers, and we could take the opportunity to
embed the gtt_space mm_node into our gem object ...
Besides that this looks good and I like it, but I think I've mentioned
that way back when this patch first popped up ;-)
-Daniel
>
> Conflicts:
>
> drivers/gpu/drm/i915/i915_gem_stolen.c
> ---
> drivers/gpu/drm/drm_gem.c | 2 +-
> drivers/gpu/drm/drm_mm.c | 151 +++++++++++++++++-----------
> drivers/gpu/drm/i915/i915_gem.c | 6 +-
> drivers/gpu/drm/i915/i915_gem_evict.c | 9 +-
> drivers/gpu/drm/i915/i915_gem_stolen.c | 5 +-
> drivers/gpu/drm/nouveau/nouveau_notifier.c | 4 +-
> drivers/gpu/drm/nouveau/nouveau_object.c | 2 +-
> drivers/gpu/drm/nouveau/nv04_instmem.c | 2 +-
> drivers/gpu/drm/nouveau/nv20_fb.c | 2 +-
> drivers/gpu/drm/nouveau/nv50_vram.c | 2 +-
> drivers/gpu/drm/ttm/ttm_bo.c | 2 +-
> drivers/gpu/drm/ttm/ttm_bo_manager.c | 4 +-
> include/drm/drm_mm.h | 38 +++++--
> 13 files changed, 143 insertions(+), 86 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index d58e69d..961ccd8 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -354,7 +354,7 @@ drm_gem_create_mmap_offset(struct drm_gem_object *obj)
>
> /* Get a DRM GEM mmap offset allocated... */
> list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
> - obj->size / PAGE_SIZE, 0, 0);
> + obj->size / PAGE_SIZE, 0, 0, false);
>
> if (!list->file_offset_node) {
> DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
> diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
> index 961fb54..0311dba 100644
> --- a/drivers/gpu/drm/drm_mm.c
> +++ b/drivers/gpu/drm/drm_mm.c
> @@ -118,45 +118,53 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
>
> static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
> struct drm_mm_node *node,
> - unsigned long size, unsigned alignment)
> + unsigned long size, unsigned alignment,
> + unsigned long color)
> {
> struct drm_mm *mm = hole_node->mm;
> - unsigned long tmp = 0, wasted = 0;
> unsigned long hole_start = drm_mm_hole_node_start(hole_node);
> unsigned long hole_end = drm_mm_hole_node_end(hole_node);
> + unsigned long adj_start = hole_start;
> + unsigned long adj_end = hole_end;
>
> BUG_ON(!hole_node->hole_follows || node->allocated);
>
> - if (alignment)
> - tmp = hole_start % alignment;
> + if (mm->color_adjust)
> + mm->color_adjust(hole_node, color, &adj_start, &adj_end);
>
> - if (!tmp) {
> + if (alignment) {
> + unsigned tmp = adj_start % alignment;
> + if (tmp)
> + adj_start += alignment - tmp;
> + }
> +
> + if (adj_start == hole_start) {
> hole_node->hole_follows = 0;
> - list_del_init(&hole_node->hole_stack);
> - } else
> - wasted = alignment - tmp;
> + list_del(&hole_node->hole_stack);
> + }
>
> - node->start = hole_start + wasted;
> + node->start = adj_start;
> node->size = size;
> node->mm = mm;
> + node->color = color;
> node->allocated = 1;
>
> INIT_LIST_HEAD(&node->hole_stack);
> list_add(&node->node_list, &hole_node->node_list);
>
> - BUG_ON(node->start + node->size > hole_end);
> + BUG_ON(node->start + node->size > adj_end);
>
> + node->hole_follows = 0;
> if (node->start + node->size < hole_end) {
> list_add(&node->hole_stack, &mm->hole_stack);
> node->hole_follows = 1;
> - } else {
> - node->hole_follows = 0;
> }
> }
>
> struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> int atomic)
> {
> struct drm_mm_node *node;
> @@ -165,7 +173,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
> if (unlikely(node == NULL))
> return NULL;
>
> - drm_mm_insert_helper(hole_node, node, size, alignment);
> + drm_mm_insert_helper(hole_node, node, size, alignment, color);
>
> return node;
> }
> @@ -181,11 +189,11 @@ int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
> {
> struct drm_mm_node *hole_node;
>
> - hole_node = drm_mm_search_free(mm, size, alignment, 0);
> + hole_node = drm_mm_search_free(mm, size, alignment, 0, false);
> if (!hole_node)
> return -ENOSPC;
>
> - drm_mm_insert_helper(hole_node, node, size, alignment);
> + drm_mm_insert_helper(hole_node, node, size, alignment, 0);
>
> return 0;
> }
> @@ -194,50 +202,57 @@ EXPORT_SYMBOL(drm_mm_insert_node);
> static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
> struct drm_mm_node *node,
> unsigned long size, unsigned alignment,
> + unsigned long color,
> unsigned long start, unsigned long end)
> {
> struct drm_mm *mm = hole_node->mm;
> - unsigned long tmp = 0, wasted = 0;
> unsigned long hole_start = drm_mm_hole_node_start(hole_node);
> unsigned long hole_end = drm_mm_hole_node_end(hole_node);
> + unsigned long adj_start = hole_start;
> + unsigned long adj_end = hole_end;
>
> BUG_ON(!hole_node->hole_follows || node->allocated);
>
> - if (hole_start < start)
> - wasted += start - hole_start;
> - if (alignment)
> - tmp = (hole_start + wasted) % alignment;
> + if (mm->color_adjust)
> + mm->color_adjust(hole_node, color, &adj_start, &adj_end);
>
> - if (tmp)
> - wasted += alignment - tmp;
> + if (adj_start < start)
> + adj_start = start;
>
> - if (!wasted) {
> + if (alignment) {
> + unsigned tmp = adj_start % alignment;
> + if (tmp)
> + adj_start += alignment - tmp;
> + }
> +
> + if (adj_start == hole_start) {
> hole_node->hole_follows = 0;
> - list_del_init(&hole_node->hole_stack);
> + list_del(&hole_node->hole_stack);
> }
>
> - node->start = hole_start + wasted;
> + node->start = adj_start;
> node->size = size;
> node->mm = mm;
> + node->color = color;
> node->allocated = 1;
>
> INIT_LIST_HEAD(&node->hole_stack);
> list_add(&node->node_list, &hole_node->node_list);
>
> - BUG_ON(node->start + node->size > hole_end);
> + BUG_ON(node->start + node->size > adj_end);
> BUG_ON(node->start + node->size > end);
>
> + node->hole_follows = 0;
> if (node->start + node->size < hole_end) {
> list_add(&node->hole_stack, &mm->hole_stack);
> node->hole_follows = 1;
> - } else {
> - node->hole_follows = 0;
> }
> }
>
> struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end,
> int atomic)
> @@ -248,7 +263,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node
> if (unlikely(node == NULL))
> return NULL;
>
> - drm_mm_insert_helper_range(hole_node, node, size, alignment,
> + drm_mm_insert_helper_range(hole_node, node, size, alignment, color,
> start, end);
>
> return node;
> @@ -266,12 +281,12 @@ int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node,
> {
> struct drm_mm_node *hole_node;
>
> - hole_node = drm_mm_search_free_in_range(mm, size, alignment,
> - start, end, 0);
> + hole_node = drm_mm_search_free_in_range(mm, size, alignment, 0,
> + start, end, false);
> if (!hole_node)
> return -ENOSPC;
>
> - drm_mm_insert_helper_range(hole_node, node, size, alignment,
> + drm_mm_insert_helper_range(hole_node, node, size, alignment, 0,
> start, end);
>
> return 0;
> @@ -336,27 +351,23 @@ EXPORT_SYMBOL(drm_mm_put_block);
> static int check_free_hole(unsigned long start, unsigned long end,
> unsigned long size, unsigned alignment)
> {
> - unsigned wasted = 0;
> -
> if (end - start < size)
> return 0;
>
> if (alignment) {
> unsigned tmp = start % alignment;
> if (tmp)
> - wasted = alignment - tmp;
> - }
> -
> - if (end >= start + size + wasted) {
> - return 1;
> + start += alignment - tmp;
> }
>
> - return 0;
> + return end >= start + size;
> }
>
> struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
> unsigned long size,
> - unsigned alignment, int best_match)
> + unsigned alignment,
> + unsigned long color,
> + bool best_match)
> {
> struct drm_mm_node *entry;
> struct drm_mm_node *best;
> @@ -368,10 +379,17 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
> best_size = ~0UL;
>
> list_for_each_entry(entry, &mm->hole_stack, hole_stack) {
> + unsigned long adj_start = drm_mm_hole_node_start(entry);
> + unsigned long adj_end = drm_mm_hole_node_end(entry);
> +
> + if (mm->color_adjust) {
> + mm->color_adjust(entry, color, &adj_start, &adj_end);
> + if (adj_end <= adj_start)
> + continue;
> + }
> +
> BUG_ON(!entry->hole_follows);
> - if (!check_free_hole(drm_mm_hole_node_start(entry),
> - drm_mm_hole_node_end(entry),
> - size, alignment))
> + if (!check_free_hole(adj_start, adj_end, size, alignment))
> continue;
>
> if (!best_match)
> @@ -390,9 +408,10 @@ EXPORT_SYMBOL(drm_mm_search_free);
> struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end,
> - int best_match)
> + bool best_match)
> {
> struct drm_mm_node *entry;
> struct drm_mm_node *best;
> @@ -410,6 +429,13 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
> end : drm_mm_hole_node_end(entry);
>
> BUG_ON(!entry->hole_follows);
> +
> + if (mm->color_adjust) {
> + mm->color_adjust(entry, color, &adj_start, &adj_end);
> + if (adj_end <= adj_start)
> + continue;
> + }
> +
> if (!check_free_hole(adj_start, adj_end, size, alignment))
> continue;
>
> @@ -437,6 +463,7 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
> new->mm = old->mm;
> new->start = old->start;
> new->size = old->size;
> + new->color = old->color;
>
> old->allocated = 0;
> new->allocated = 1;
> @@ -452,9 +479,12 @@ EXPORT_SYMBOL(drm_mm_replace_node);
> * Warning: As long as the scan list is non-empty, no other operations than
> * adding/removing nodes to/from the scan list are allowed.
> */
> -void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
> - unsigned alignment)
> +void drm_mm_init_scan(struct drm_mm *mm,
> + unsigned long size,
> + unsigned alignment,
> + unsigned long color)
> {
> + mm->scan_color = color;
> mm->scan_alignment = alignment;
> mm->scan_size = size;
> mm->scanned_blocks = 0;
> @@ -474,11 +504,14 @@ EXPORT_SYMBOL(drm_mm_init_scan);
> * Warning: As long as the scan list is non-empty, no other operations than
> * adding/removing nodes to/from the scan list are allowed.
> */
> -void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
> +void drm_mm_init_scan_with_range(struct drm_mm *mm,
> + unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end)
> {
> + mm->scan_color = color;
> mm->scan_alignment = alignment;
> mm->scan_size = size;
> mm->scanned_blocks = 0;
> @@ -522,17 +555,21 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
>
> hole_start = drm_mm_hole_node_start(prev_node);
> hole_end = drm_mm_hole_node_end(prev_node);
> +
> + adj_start = hole_start;
> + adj_end = hole_end;
> +
> + if (mm->color_adjust)
> + mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end);
> +
> if (mm->scan_check_range) {
> - adj_start = hole_start < mm->scan_start ?
> - mm->scan_start : hole_start;
> - adj_end = hole_end > mm->scan_end ?
> - mm->scan_end : hole_end;
> - } else {
> - adj_start = hole_start;
> - adj_end = hole_end;
> + if (adj_start < mm->scan_start)
> + adj_start = mm->scan_start;
> + if (adj_end > mm->scan_end)
> + adj_end = mm->scan_end;
> }
>
> - if (check_free_hole(adj_start , adj_end,
> + if (check_free_hole(adj_start, adj_end,
> mm->scan_size, mm->scan_alignment)) {
> mm->scan_hit_start = hole_start;
> mm->scan_hit_size = hole_end;
> @@ -616,6 +653,8 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
> mm->head_node.size = start - mm->head_node.start;
> list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack);
>
> + mm->color_adjust = NULL;
> +
> return 0;
> }
> EXPORT_SYMBOL(drm_mm_init);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index db438f0..cad56dd 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2756,18 +2756,18 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
> free_space =
> drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
> size, alignment, 0,
> - dev_priv->mm.gtt_mappable_end,
> + 0, dev_priv->mm.gtt_mappable_end,
> 0);
> else
> free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
> - size, alignment, 0);
> + size, alignment, 0, 0);
>
> if (free_space != NULL) {
> if (map_and_fenceable)
> obj->gtt_space =
> drm_mm_get_block_range_generic(free_space,
> size, alignment, 0,
> - dev_priv->mm.gtt_mappable_end,
> + 0, dev_priv->mm.gtt_mappable_end,
> 0);
> else
> obj->gtt_space =
> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
> index ae7c24e..eba0308 100644
> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> @@ -78,11 +78,12 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
>
> INIT_LIST_HEAD(&unwind_list);
> if (mappable)
> - drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size,
> - alignment, 0,
> - dev_priv->mm.gtt_mappable_end);
> + drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space,
> + min_size, alignment, 0,
> + 0, dev_priv->mm.gtt_mappable_end);
> else
> - drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment);
> + drm_mm_init_scan(&dev_priv->mm.gtt_space,
> + min_size, alignment, 0);
>
> /* First see if there is a large enough contiguous idle region... */
> list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) {
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index ada2e90..dba13cf 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -111,7 +111,8 @@ static void i915_setup_compression(struct drm_device *dev, int size)
> /* Just in case the BIOS is doing something questionable. */
> intel_disable_fbc(dev);
>
> - compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0);
> + compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
> + size, 4096, 0, 0);
> if (compressed_fb)
> compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
> if (!compressed_fb)
> @@ -123,7 +124,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
>
> if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) {
> compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen,
> - 4096, 4096, 0);
> + 4096, 4096, 0, 0);
> if (compressed_llb)
> compressed_llb = drm_mm_get_block(compressed_llb,
> 4096, 4096);
> diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
> index 2ef883c..65c64b1 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
> @@ -118,10 +118,10 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
> uint64_t offset;
> int target, ret;
>
> - mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0,
> + mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0, 0,
> start, end, 0);
> if (mem)
> - mem = drm_mm_get_block_range(mem, size, 0, start, end);
> + mem = drm_mm_get_block_range(mem, size, 0, 0, start, end);
> if (!mem) {
> NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
> return -ENOMEM;
> diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
> index b190cc0..15d5d97 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_object.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_object.c
> @@ -163,7 +163,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
> spin_unlock(&dev_priv->ramin_lock);
>
> if (!(flags & NVOBJ_FLAG_VM) && chan) {
> - ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0);
> + ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0, 0);
> if (ramin)
> ramin = drm_mm_get_block(ramin, size, align);
> if (!ramin) {
> diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c
> index ef7a934..ce57bcd 100644
> --- a/drivers/gpu/drm/nouveau/nv04_instmem.c
> +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c
> @@ -149,7 +149,7 @@ nv04_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
> return -ENOMEM;
>
> spin_lock(&dev_priv->ramin_lock);
> - ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0);
> + ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0, 0);
> if (ramin == NULL) {
> spin_unlock(&dev_priv->ramin_lock);
> return -ENOMEM;
> diff --git a/drivers/gpu/drm/nouveau/nv20_fb.c b/drivers/gpu/drm/nouveau/nv20_fb.c
> index 19bd640..754f47f 100644
> --- a/drivers/gpu/drm/nouveau/nv20_fb.c
> +++ b/drivers/gpu/drm/nouveau/nv20_fb.c
> @@ -16,7 +16,7 @@ nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size)
> return NULL;
>
> spin_lock(&dev_priv->tile.lock);
> - mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0);
> + mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0, 0);
> if (mem)
> mem = drm_mm_get_block_atomic(mem, size, 0);
> spin_unlock(&dev_priv->tile.lock);
> diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c
> index 9ed9ae39..6c8ea3f 100644
> --- a/drivers/gpu/drm/nouveau/nv50_vram.c
> +++ b/drivers/gpu/drm/nouveau/nv50_vram.c
> @@ -105,7 +105,7 @@ nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc,
> struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
> int n = (size >> 4) * comp;
>
> - mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0);
> + mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0, 0);
> if (mem->tag)
> mem->tag = drm_mm_get_block(mem->tag, n, 0);
> }
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index 36f4b28..76ee39f 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -1686,7 +1686,7 @@ retry_pre_get:
>
> write_lock(&bdev->vm_lock);
> bo->vm_node = drm_mm_search_free(&bdev->addr_space_mm,
> - bo->mem.num_pages, 0, 0);
> + bo->mem.num_pages, 0, 0, 0);
>
> if (unlikely(bo->vm_node == NULL)) {
> ret = -ENOMEM;
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
> index 038e947..b426b29 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
> @@ -68,14 +68,14 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
>
> spin_lock(&rman->lock);
> node = drm_mm_search_free_in_range(mm,
> - mem->num_pages, mem->page_alignment,
> + mem->num_pages, mem->page_alignment, 0,
> placement->fpfn, lpfn, 1);
> if (unlikely(node == NULL)) {
> spin_unlock(&rman->lock);
> return 0;
> }
> node = drm_mm_get_block_atomic_range(node, mem->num_pages,
> - mem->page_alignment,
> + mem->page_alignment, 0,
> placement->fpfn,
> lpfn);
> spin_unlock(&rman->lock);
> diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
> index 564b14a..04a9554 100644
> --- a/include/drm/drm_mm.h
> +++ b/include/drm/drm_mm.h
> @@ -50,6 +50,7 @@ struct drm_mm_node {
> unsigned scanned_next_free : 1;
> unsigned scanned_preceeds_hole : 1;
> unsigned allocated : 1;
> + unsigned long color;
> unsigned long start;
> unsigned long size;
> struct drm_mm *mm;
> @@ -66,6 +67,7 @@ struct drm_mm {
> spinlock_t unused_lock;
> unsigned int scan_check_range : 1;
> unsigned scan_alignment;
> + unsigned long scan_color;
> unsigned long scan_size;
> unsigned long scan_hit_start;
> unsigned scan_hit_size;
> @@ -73,6 +75,9 @@ struct drm_mm {
> unsigned long scan_start;
> unsigned long scan_end;
> struct drm_mm_node *prev_scanned_node;
> +
> + void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
> + unsigned long *start, unsigned long *end);
> };
>
> static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
> @@ -100,11 +105,13 @@ static inline bool drm_mm_initialized(struct drm_mm *mm)
> extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> int atomic);
> extern struct drm_mm_node *drm_mm_get_block_range_generic(
> struct drm_mm_node *node,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end,
> int atomic);
> @@ -112,32 +119,34 @@ static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
> unsigned long size,
> unsigned alignment)
> {
> - return drm_mm_get_block_generic(parent, size, alignment, 0);
> + return drm_mm_get_block_generic(parent, size, alignment, 0, 0);
> }
> static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
> unsigned long size,
> unsigned alignment)
> {
> - return drm_mm_get_block_generic(parent, size, alignment, 1);
> + return drm_mm_get_block_generic(parent, size, alignment, 0, 1);
> }
> static inline struct drm_mm_node *drm_mm_get_block_range(
> struct drm_mm_node *parent,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end)
> {
> - return drm_mm_get_block_range_generic(parent, size, alignment,
> - start, end, 0);
> + return drm_mm_get_block_range_generic(parent, size, alignment, color,
> + start, end, 0);
> }
> static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
> struct drm_mm_node *parent,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end)
> {
> - return drm_mm_get_block_range_generic(parent, size, alignment,
> + return drm_mm_get_block_range_generic(parent, size, alignment, color,
> start, end, 1);
> }
> extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
> @@ -152,15 +161,18 @@ extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new
> extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
> unsigned long size,
> unsigned alignment,
> - int best_match);
> + unsigned long color,
> + bool best_match);
> extern struct drm_mm_node *drm_mm_search_free_in_range(
> const struct drm_mm *mm,
> unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end,
> - int best_match);
> -extern int drm_mm_init(struct drm_mm *mm, unsigned long start,
> + bool best_match);
> +extern int drm_mm_init(struct drm_mm *mm,
> + unsigned long start,
> unsigned long size);
> extern void drm_mm_takedown(struct drm_mm *mm);
> extern int drm_mm_clean(struct drm_mm *mm);
> @@ -171,10 +183,14 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
> return block->mm;
> }
>
> -void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
> - unsigned alignment);
> -void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
> +void drm_mm_init_scan(struct drm_mm *mm,
> + unsigned long size,
> + unsigned alignment,
> + unsigned long color);
> +void drm_mm_init_scan_with_range(struct drm_mm *mm,
> + unsigned long size,
> unsigned alignment,
> + unsigned long color,
> unsigned long start,
> unsigned long end);
> int drm_mm_scan_add_block(struct drm_mm_node *node);
> --
> 1.7.10
>
--
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48
More information about the Intel-gfx
mailing list