Commit 440fd528 authored by Thierry Reding's avatar Thierry Reding Committed by Dave Airlie

drm/mm: Support 4 GiB and larger ranges

The current implementation is limited by the number of addresses that
fit into an unsigned long. This causes problems on 32-bit Tegra where
unsigned long is 32-bit but drm_mm is used to manage an IOVA space of
4 GiB. Given the 32-bit limitation, the range is limited to 4 GiB - 1
(or 4 GiB - 4 KiB for page granularity).

This commit changes the start and size of the range to be an unsigned
64-bit integer, thus allowing much larger ranges to be supported.

[airlied: fix i915 warnings and coloring callback]
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

fixupo
parent ed9ed50c
This diff is collapsed.
...@@ -152,12 +152,12 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) ...@@ -152,12 +152,12 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
seq_puts(m, " (pp"); seq_puts(m, " (pp");
else else
seq_puts(m, " (g"); seq_puts(m, " (g");
seq_printf(m, "gtt offset: %08lx, size: %08lx, type: %u)", seq_printf(m, "gtt offset: %08llx, size: %08llx, type: %u)",
vma->node.start, vma->node.size, vma->node.start, vma->node.size,
vma->ggtt_view.type); vma->ggtt_view.type);
} }
if (obj->stolen) if (obj->stolen)
seq_printf(m, " (stolen: %08lx)", obj->stolen->start); seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
if (obj->pin_mappable || obj->fault_mappable) { if (obj->pin_mappable || obj->fault_mappable) {
char s[3], *t = s; char s[3], *t = s;
if (obj->pin_mappable) if (obj->pin_mappable)
......
...@@ -1145,7 +1145,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -1145,7 +1145,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true); ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n", DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n",
ppgtt->node.size >> 20, ppgtt->node.size >> 20,
ppgtt->node.start / PAGE_SIZE); ppgtt->node.start / PAGE_SIZE);
...@@ -1713,8 +1713,8 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) ...@@ -1713,8 +1713,8 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj)
static void i915_gtt_color_adjust(struct drm_mm_node *node, static void i915_gtt_color_adjust(struct drm_mm_node *node,
unsigned long color, unsigned long color,
unsigned long *start, u64 *start,
unsigned long *end) u64 *end)
{ {
if (node->color != color) if (node->color != color)
*start += 4096; *start += 4096;
......
...@@ -68,8 +68,8 @@ struct drm_mm_node { ...@@ -68,8 +68,8 @@ struct drm_mm_node {
unsigned scanned_preceeds_hole : 1; unsigned scanned_preceeds_hole : 1;
unsigned allocated : 1; unsigned allocated : 1;
unsigned long color; unsigned long color;
unsigned long start; u64 start;
unsigned long size; u64 size;
struct drm_mm *mm; struct drm_mm *mm;
}; };
...@@ -82,16 +82,16 @@ struct drm_mm { ...@@ -82,16 +82,16 @@ struct drm_mm {
unsigned int scan_check_range : 1; unsigned int scan_check_range : 1;
unsigned scan_alignment; unsigned scan_alignment;
unsigned long scan_color; unsigned long scan_color;
unsigned long scan_size; u64 scan_size;
unsigned long scan_hit_start; u64 scan_hit_start;
unsigned long scan_hit_end; u64 scan_hit_end;
unsigned scanned_blocks; unsigned scanned_blocks;
unsigned long scan_start; u64 scan_start;
unsigned long scan_end; u64 scan_end;
struct drm_mm_node *prev_scanned_node; struct drm_mm_node *prev_scanned_node;
void (*color_adjust)(struct drm_mm_node *node, unsigned long color, void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
unsigned long *start, unsigned long *end); u64 *start, u64 *end);
}; };
/** /**
...@@ -124,7 +124,7 @@ static inline bool drm_mm_initialized(struct drm_mm *mm) ...@@ -124,7 +124,7 @@ static inline bool drm_mm_initialized(struct drm_mm *mm)
return mm->hole_stack.next; return mm->hole_stack.next;
} }
static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node) static inline u64 __drm_mm_hole_node_start(struct drm_mm_node *hole_node)
{ {
return hole_node->start + hole_node->size; return hole_node->start + hole_node->size;
} }
...@@ -140,13 +140,13 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no ...@@ -140,13 +140,13 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no
* Returns: * Returns:
* Start of the subsequent hole. * Start of the subsequent hole.
*/ */
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) static inline u64 drm_mm_hole_node_start(struct drm_mm_node *hole_node)
{ {
BUG_ON(!hole_node->hole_follows); BUG_ON(!hole_node->hole_follows);
return __drm_mm_hole_node_start(hole_node); return __drm_mm_hole_node_start(hole_node);
} }
static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node) static inline u64 __drm_mm_hole_node_end(struct drm_mm_node *hole_node)
{ {
return list_entry(hole_node->node_list.next, return list_entry(hole_node->node_list.next,
struct drm_mm_node, node_list)->start; struct drm_mm_node, node_list)->start;
...@@ -163,7 +163,7 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node ...@@ -163,7 +163,7 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node
* Returns: * Returns:
* End of the subsequent hole. * End of the subsequent hole.
*/ */
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) static inline u64 drm_mm_hole_node_end(struct drm_mm_node *hole_node)
{ {
return __drm_mm_hole_node_end(hole_node); return __drm_mm_hole_node_end(hole_node);
} }
...@@ -222,7 +222,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node); ...@@ -222,7 +222,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
int drm_mm_insert_node_generic(struct drm_mm *mm, int drm_mm_insert_node_generic(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, u64 size,
unsigned alignment, unsigned alignment,
unsigned long color, unsigned long color,
enum drm_mm_search_flags sflags, enum drm_mm_search_flags sflags,
...@@ -245,7 +245,7 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, ...@@ -245,7 +245,7 @@ int drm_mm_insert_node_generic(struct drm_mm *mm,
*/ */
static inline int drm_mm_insert_node(struct drm_mm *mm, static inline int drm_mm_insert_node(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, u64 size,
unsigned alignment, unsigned alignment,
enum drm_mm_search_flags flags) enum drm_mm_search_flags flags)
{ {
...@@ -255,11 +255,11 @@ static inline int drm_mm_insert_node(struct drm_mm *mm, ...@@ -255,11 +255,11 @@ static inline int drm_mm_insert_node(struct drm_mm *mm,
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, u64 size,
unsigned alignment, unsigned alignment,
unsigned long color, unsigned long color,
unsigned long start, u64 start,
unsigned long end, u64 end,
enum drm_mm_search_flags sflags, enum drm_mm_search_flags sflags,
enum drm_mm_allocator_flags aflags); enum drm_mm_allocator_flags aflags);
/** /**
...@@ -282,10 +282,10 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, ...@@ -282,10 +282,10 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
*/ */
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, u64 size,
unsigned alignment, unsigned alignment,
unsigned long start, u64 start,
unsigned long end, u64 end,
enum drm_mm_search_flags flags) enum drm_mm_search_flags flags)
{ {
return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
...@@ -296,21 +296,21 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, ...@@ -296,21 +296,21 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
void drm_mm_remove_node(struct drm_mm_node *node); void drm_mm_remove_node(struct drm_mm_node *node);
void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
void drm_mm_init(struct drm_mm *mm, void drm_mm_init(struct drm_mm *mm,
unsigned long start, u64 start,
unsigned long size); u64 size);
void drm_mm_takedown(struct drm_mm *mm); void drm_mm_takedown(struct drm_mm *mm);
bool drm_mm_clean(struct drm_mm *mm); bool drm_mm_clean(struct drm_mm *mm);
void drm_mm_init_scan(struct drm_mm *mm, void drm_mm_init_scan(struct drm_mm *mm,
unsigned long size, u64 size,
unsigned alignment, unsigned alignment,
unsigned long color); unsigned long color);
void drm_mm_init_scan_with_range(struct drm_mm *mm, void drm_mm_init_scan_with_range(struct drm_mm *mm,
unsigned long size, u64 size,
unsigned alignment, unsigned alignment,
unsigned long color, unsigned long color,
unsigned long start, u64 start,
unsigned long end); u64 end);
bool drm_mm_scan_add_block(struct drm_mm_node *node); bool drm_mm_scan_add_block(struct drm_mm_node *node);
bool drm_mm_scan_remove_block(struct drm_mm_node *node); bool drm_mm_scan_remove_block(struct drm_mm_node *node);
......
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