Skip to content

Commit 63f17ef

Browse files
committed
drm/msm: Support evicting GEM objects to swap
Now that tracking is wired up for potentially evictable GEM objects, wire up shrinker and the remaining GEM bits for unpinning backing pages of inactive objects. Disabled by default for now, with an 'enable_eviction' module param to enable so that we can get some more testing on the range of generations (and iommu pairings) supported. Signed-off-by: Rob Clark <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rob Clark <[email protected]>
1 parent 81d4d59 commit 63f17ef

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

drivers/gpu/drm/msm/msm_gem.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,29 @@ void msm_gem_purge(struct drm_gem_object *obj)
759759
0, (loff_t)-1);
760760
}
761761

762+
/**
763+
* Unpin the backing pages and make them available to be swapped out.
764+
*/
765+
void msm_gem_evict(struct drm_gem_object *obj)
766+
{
767+
struct drm_device *dev = obj->dev;
768+
struct msm_gem_object *msm_obj = to_msm_bo(obj);
769+
770+
GEM_WARN_ON(!msm_gem_is_locked(obj));
771+
GEM_WARN_ON(is_unevictable(msm_obj));
772+
GEM_WARN_ON(!msm_obj->evictable);
773+
GEM_WARN_ON(msm_obj->active_count);
774+
775+
/* Get rid of any iommu mapping(s): */
776+
put_iova_spaces(obj, false);
777+
778+
drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
779+
780+
put_pages(obj);
781+
782+
update_inactive(msm_obj);
783+
}
784+
762785
void msm_gem_vunmap(struct drm_gem_object *obj)
763786
{
764787
struct msm_gem_object *msm_obj = to_msm_bo(obj);

drivers/gpu/drm/msm/msm_gem_shrinker.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,29 @@
99
#include "msm_gpu.h"
1010
#include "msm_gpu_trace.h"
1111

12+
/* Default disabled for now until it has some more testing on the different
13+
* iommu combinations that can be paired with the driver:
14+
*/
15+
bool enable_eviction = false;
16+
MODULE_PARM_DESC(enable_eviction, "Enable swappable GEM buffers");
17+
module_param(enable_eviction, bool, 0600);
18+
19+
static bool can_swap(void)
20+
{
21+
return enable_eviction && get_nr_swap_pages() > 0;
22+
}
23+
1224
static unsigned long
1325
msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
1426
{
1527
struct msm_drm_private *priv =
1628
container_of(shrinker, struct msm_drm_private, shrinker);
17-
return priv->shrinkable_count;
29+
unsigned count = priv->shrinkable_count;
30+
31+
if (can_swap())
32+
count += priv->evictable_count;
33+
34+
return count;
1835
}
1936

2037
static bool
@@ -32,6 +49,17 @@ purge(struct msm_gem_object *msm_obj)
3249
return true;
3350
}
3451

52+
static bool
53+
evict(struct msm_gem_object *msm_obj)
54+
{
55+
if (is_unevictable(msm_obj))
56+
return false;
57+
58+
msm_gem_evict(&msm_obj->base);
59+
60+
return true;
61+
}
62+
3563
static unsigned long
3664
scan(struct msm_drm_private *priv, unsigned nr_to_scan, struct list_head *list,
3765
bool (*shrink)(struct msm_gem_object *msm_obj))
@@ -104,6 +132,16 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
104132
if (freed > 0)
105133
trace_msm_gem_purge(freed << PAGE_SHIFT);
106134

135+
if (can_swap() && freed < sc->nr_to_scan) {
136+
int evicted = scan(priv, sc->nr_to_scan - freed,
137+
&priv->inactive_willneed, evict);
138+
139+
if (evicted > 0)
140+
trace_msm_gem_evict(evicted << PAGE_SHIFT);
141+
142+
freed += evicted;
143+
}
144+
107145
return (freed > 0) ? freed : SHRINK_STOP;
108146
}
109147

drivers/gpu/drm/msm/msm_gpu_trace.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,19 @@ TRACE_EVENT(msm_gem_purge,
128128
);
129129

130130

131+
TRACE_EVENT(msm_gem_evict,
132+
TP_PROTO(u32 bytes),
133+
TP_ARGS(bytes),
134+
TP_STRUCT__entry(
135+
__field(u32, bytes)
136+
),
137+
TP_fast_assign(
138+
__entry->bytes = bytes;
139+
),
140+
TP_printk("Evicting %u bytes", __entry->bytes)
141+
);
142+
143+
131144
TRACE_EVENT(msm_gem_purge_vmaps,
132145
TP_PROTO(u32 unmapped),
133146
TP_ARGS(unmapped),

0 commit comments

Comments
 (0)