@@ -521,6 +521,12 @@ static int i915_gem_aperture_info(struct seq_file *m, void *data)
arg.fence_available_size);
seq_printf(m, "Single largest fence available: %llu bytes\n",
arg.fence_largest_size);
+ seq_printf(m, "Total size of the stolen region: %llu bytes\n",
+ arg.stolen_total_size);
+ seq_printf(m, "Available size of the stolen region: %llu bytes\n",
+ arg.stolen_available_size);
+ seq_printf(m, "Single largest area in the stolen region: %llu bytes\n",
+ arg.stolen_largest_size);
return 0;
}
@@ -2950,6 +2950,9 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
u32 stolen_offset,
u32 gtt_offset,
u32 size);
+void i915_gem_stolen_size_info(struct drm_mm *mm, uint64_t *stolen_total,
+ uint64_t *stolen_free,
+ uint64_t *stolen_largest);
/* i915_gem_shrinker.c */
unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv,
@@ -203,6 +203,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct list_head map_list;
const u32 map_limit = dev_priv->gtt.mappable_end;
size_t pinned, map_space, map_largest, fence_space, fence_largest;
+ uint64_t stolen_total, stolen_available, stolen_largest;
u32 last, size;
INIT_LIST_HEAD(&map_list);
@@ -260,6 +261,9 @@ skip_first:
fence_largest = size;
fence_space += size;
}
+
+ i915_gem_stolen_size_info(&dev_priv->mm.stolen, &stolen_total,
+ &stolen_available, &stolen_largest);
mutex_unlock(&dev->struct_mutex);
args->aper_size = dev_priv->gtt.base.total;
@@ -269,6 +273,9 @@ skip_first:
args->map_total_size = dev_priv->gtt.mappable_end;
args->fence_available_size = fence_space;
args->fence_largest_size = fence_largest;
+ args->stolen_total_size = stolen_total;
+ args->stolen_available_size = stolen_available;
+ args->stolen_largest_size = stolen_largest;
return 0;
}
@@ -650,3 +650,38 @@ err_out:
drm_gem_object_unreference(&obj->base);
return NULL;
}
+
+void i915_gem_stolen_size_info(struct drm_mm *mm, uint64_t *stolen_total,
+ uint64_t *stolen_free,
+ uint64_t *stolen_largest)
+{
+ struct drm_mm_node *entry;
+ struct drm_mm_node *head_node = &mm->head_node;
+ uint64_t hole_size, hole_start, hole_end, largest_hole = 0;
+ uint64_t total_used = 0, total_free = 0;
+
+ if (head_node->hole_follows) {
+ hole_start = drm_mm_hole_node_start(head_node);
+ hole_end = drm_mm_hole_node_end(head_node);
+ hole_size = hole_end - hole_start;
+ total_free += hole_size;
+ if (largest_hole < hole_size)
+ largest_hole = hole_size;
+ }
+
+ drm_mm_for_each_node(entry, mm) {
+ total_used += entry->size;
+ if (entry->hole_follows) {
+ hole_start = drm_mm_hole_node_start(entry);
+ hole_end = drm_mm_hole_node_end(entry);
+ hole_size = hole_end - hole_start;
+ total_free += hole_size;
+ if (largest_hole < hole_size)
+ largest_hole = hole_size;
+ }
+ }
+
+ *stolen_total = total_free + total_used;
+ *stolen_free = total_free;
+ *stolen_largest = largest_hole;
+}
@@ -957,6 +957,21 @@ struct drm_i915_gem_get_aperture {
* Single largest fenceable region, in bytes.
*/
__u64 fence_largest_size;
+
+ /**
+ * Total space in the stolen region, in bytes
+ */
+ __u64 stolen_total_size;
+
+ /**
+ * Available space in the stolen region, in bytes
+ */
+ __u64 stolen_available_size;
+
+ /**
+ * Single largest block in stolen region, in bytes
+ */
+ __u64 stolen_largest_size;
};
struct drm_i915_get_pipe_from_crtc_id {