aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_mm.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index d0a8e8482fe0..276a7a27c166 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -47,6 +47,45 @@
47#include <linux/seq_file.h> 47#include <linux/seq_file.h>
48#include <linux/export.h> 48#include <linux/export.h>
49 49
50/**
51 * DOC: Overview
52 *
53 * drm_mm provides a simple range allocator. The drivers are free to use the
54 * resource allocator from the linux core if it suits them, the upside of drm_mm
55 * is that it's in the DRM core. Which means that it's easier to extend for
56 * some of the crazier special purpose needs of gpus.
57 *
58 * The main data struct is &drm_mm, allocations are tracked in &drm_mm_node.
59 * Drivers are free to embed either of them into their own suitable
60 * datastructures. drm_mm itself will not do any allocations of its own, so if
61 * drivers choose not to embed nodes they need to still allocate them
62 * themselves.
63 *
64 * The range allocator also supports reservation of preallocated blocks. This is
65 * useful for taking over initial mode setting configurations from the firmware,
66 * where an object needs to be created which exactly matches the firmware's
67 * scanout target. As long as the range is still free it can be inserted anytime
68 * after the allocator is initialized, which helps with avoiding looped
69 * depencies in the driver load sequence.
70 *
71 * drm_mm maintains a stack of most recently freed holes, which of all
72 * simplistic datastructures seems to be a fairly decent approach to clustering
73 * allocations and avoiding too much fragmentation. This means free space
74 * searches are O(num_holes). Given that all the fancy features drm_mm supports
75 * something better would be fairly complex and since gfx thrashing is a fairly
76 * steep cliff not a real concern. Removing a node again is O(1).
77 *
78 * drm_mm supports a few features: Alignment and range restrictions can be
79 * supplied. Further more every &drm_mm_node has a color value (which is just an
80 * opaqua unsigned long) which in conjunction with a driver callback can be used
81 * to implement sophisticated placement restrictions. The i915 DRM driver uses
82 * this to implement guard pages between incompatible caching domains in the
83 * graphics TT.
84 *
85 * Finally iteration helpers to walk all nodes and all holes are provided as are
86 * some basic allocator dumpers for debugging.
87 */
88
50static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, 89static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
51 unsigned long size, 90 unsigned long size,
52 unsigned alignment, 91 unsigned alignment,
@@ -400,6 +439,34 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
400EXPORT_SYMBOL(drm_mm_replace_node); 439EXPORT_SYMBOL(drm_mm_replace_node);
401 440
402/** 441/**
442 * DOC: lru scan roaster
443 *
444 * Very often GPUs need to have continuous allocations for a given object. When
445 * evicting objects to make space for a new one it is therefore not most
446 * efficient when we simply start to select all objects from the tail of an LRU
447 * until there's a suitable hole: Especially for big objects or nodes that
448 * otherwise have special allocation constraints there's a good chance we evict
449 * lots of (smaller) objects unecessarily.
450 *
451 * The DRM range allocator supports this use-case through the scanning
452 * interfaces. First a scan operation needs to be initialized with
453 * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The the driver adds
454 * objects to the roaster (probably by walking an LRU list, but this can be
455 * freely implemented) until a suitable hole is found or there's no further
456 * evitable object.
457 *
458 * The the driver must walk through all objects again in exactly the reverse
459 * order to restore the allocator state. Note that while the allocator is used
460 * in the scan mode no other operation is allowed.
461 *
462 * Finally the driver evicts all objects selected in the scan. Adding and
463 * removing an object is O(1), and since freeing a node is also O(1) the overall
464 * complexity is O(scanned_objects). So like the free stack which needs to be
465 * walked before a scan operation even begins this is linear in the number of
466 * objects. It doesn't seem to hurt badly.
467 */
468
469/**
403 * Initializa lru scanning. 470 * Initializa lru scanning.
404 * 471 *
405 * This simply sets up the scanning routines with the parameters for the desired 472 * This simply sets up the scanning routines with the parameters for the desired