summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2019-12-25 11:31:42 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2019-12-25 11:31:42 +0000
commit2af882cf362e2c94b359bdcc131860a50d263710 (patch)
treeb0b9bd05053f20f9492b5379e4f91eea8a56b393 /sys/dev/pci/drm
parent1037e00d7dfda3b214c26ef184a3d1f5d5be8ce7 (diff)
Hook up the shrinker for inteldrm(4). This is a "light" version that only
drops graphics buffers that are cached and not in active use. Help from beck@ for pointing out how to hook this up to our pagedaemon. ok jsg@
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r--sys/dev/pci/drm/drm_linux.c27
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.h2
-rw-r--r--sys/dev/pci/drm/i915/i915_gem_shrinker.c10
-rw-r--r--sys/dev/pci/drm/include/linux/mm.h1
-rw-r--r--sys/dev/pci/drm/include/linux/mutex.h18
-rw-r--r--sys/dev/pci/drm/include/linux/shrinker.h25
-rw-r--r--sys/dev/pci/drm/include/linux/swap.h6
7 files changed, 77 insertions, 12 deletions
diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c
index ffd8ded926d..1fb37929613 100644
--- a/sys/dev/pci/drm/drm_linux.c
+++ b/sys/dev/pci/drm/drm_linux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_linux.c,v 1.51 2019/11/30 11:19:17 visa Exp $ */
+/* $OpenBSD: drm_linux.c,v 1.52 2019/12/25 11:31:41 kettenis Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -1867,3 +1867,28 @@ pci_resize_resource(struct pci_dev *pdev, int bar, int nsize)
return 0;
}
+
+TAILQ_HEAD(, shrinker) shrinkers = TAILQ_HEAD_INITIALIZER(shrinkers);
+
+int
+register_shrinker(struct shrinker *shrinker)
+{
+ TAILQ_INSERT_TAIL(&shrinkers, shrinker, next);
+ return 0;
+}
+
+void
+drmbackoff(long npages)
+{
+ struct shrink_control sc;
+ struct shrinker *shrinker;
+ u_long ret;
+
+ shrinker = TAILQ_FIRST(&shrinkers);
+ while (shrinker && npages > 0) {
+ sc.nr_to_scan = npages;
+ ret = shrinker->scan_objects(shrinker, &sc);
+ npages -= ret;
+ shrinker = TAILQ_NEXT(shrinker, next);
+ }
+}
diff --git a/sys/dev/pci/drm/i915/i915_drv.h b/sys/dev/pci/drm/i915/i915_drv.h
index d690cc87b87..0a40b9aac72 100644
--- a/sys/dev/pci/drm/i915/i915_drv.h
+++ b/sys/dev/pci/drm/i915/i915_drv.h
@@ -1072,9 +1072,7 @@ struct i915_gem_mm {
struct notifier_block oom_notifier;
struct notifier_block vmap_notifier;
-#ifdef notyet
struct shrinker shrinker;
-#endif
/** LRU list of objects with fence regs on them. */
struct list_head fence_list;
diff --git a/sys/dev/pci/drm/i915/i915_gem_shrinker.c b/sys/dev/pci/drm/i915/i915_gem_shrinker.c
index 4fd8979b7cb..8bac088399d 100644
--- a/sys/dev/pci/drm/i915/i915_gem_shrinker.c
+++ b/sys/dev/pci/drm/i915/i915_gem_shrinker.c
@@ -36,7 +36,6 @@
#include "i915_drv.h"
#include "i915_trace.h"
-#ifdef notyet
static bool shrinker_lock(struct drm_i915_private *i915, bool *unlock)
{
switch (mutex_trylock_recursive(&i915->drm.struct_mutex)) {
@@ -115,7 +114,6 @@ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj)
__i915_gem_object_put_pages(obj, I915_MM_SHRINKER);
return !i915_gem_object_has_pages(obj);
}
-#endif
/**
* i915_gem_shrink - Shrink buffer object caches
@@ -148,9 +146,6 @@ i915_gem_shrink(struct drm_i915_private *i915,
unsigned long *nr_scanned,
unsigned flags)
{
- STUB();
- return -ENOSYS;
-#ifdef notyet
const struct {
struct list_head *list;
unsigned int bit;
@@ -280,7 +275,6 @@ i915_gem_shrink(struct drm_i915_private *i915,
if (nr_scanned)
*nr_scanned += scanned;
return count;
-#endif
}
/**
@@ -311,7 +305,6 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915)
return freed;
}
-#ifdef notyet
static unsigned long
i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
{
@@ -393,6 +386,7 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
return sc->nr_scanned ? freed : SHRINK_STOP;
}
+#ifdef notyet
static bool
shrinker_lock_uninterruptible(struct drm_i915_private *i915, bool *unlock,
int timeout_ms)
@@ -513,13 +507,13 @@ out:
*/
void i915_gem_shrinker_register(struct drm_i915_private *i915)
{
-#ifdef notyet
i915->mm.shrinker.scan_objects = i915_gem_shrinker_scan;
i915->mm.shrinker.count_objects = i915_gem_shrinker_count;
i915->mm.shrinker.seeks = DEFAULT_SEEKS;
i915->mm.shrinker.batch = 4096;
WARN_ON(register_shrinker(&i915->mm.shrinker));
+#ifdef notyet
i915->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom;
WARN_ON(register_oom_notifier(&i915->mm.oom_notifier));
diff --git a/sys/dev/pci/drm/include/linux/mm.h b/sys/dev/pci/drm/include/linux/mm.h
index da4080289ba..3d38297afbd 100644
--- a/sys/dev/pci/drm/include/linux/mm.h
+++ b/sys/dev/pci/drm/include/linux/mm.h
@@ -11,6 +11,7 @@
#include <machine/cpu.h>
#include <uvm/uvm_extern.h>
#include <linux/fs.h>
+#include <linux/shrinker.h>
#include <asm/pgtable.h>
#define unmap_mapping_range(mapping, holebegin, holeend, even_cows)
diff --git a/sys/dev/pci/drm/include/linux/mutex.h b/sys/dev/pci/drm/include/linux/mutex.h
index ec0abdbbe69..a1436f82228 100644
--- a/sys/dev/pci/drm/include/linux/mutex.h
+++ b/sys/dev/pci/drm/include/linux/mutex.h
@@ -16,7 +16,23 @@
#define mutex_lock_nested(rwl, sub) rw_enter_write(rwl)
#define mutex_trylock(rwl) (rw_enter(rwl, RW_WRITE | RW_NOSLEEP) == 0)
#define mutex_unlock(rwl) rw_exit_write(rwl)
-#define mutex_is_locked(rwl) (rw_status(rwl) == RW_WRITE)
+#define mutex_is_locked(rwl) (rw_status(rwl) != 0)
#define mutex_destroy(rwl)
+enum mutex_trylock_recursive_result {
+ MUTEX_TRYLOCK_FAILED,
+ MUTEX_TRYLOCK_SUCCESS,
+ MUTEX_TRYLOCK_RECURSIVE
+};
+
+static inline enum mutex_trylock_recursive_result
+mutex_trylock_recursive(struct rwlock *rwl)
+{
+ if (rw_status(rwl) == RW_WRITE)
+ return MUTEX_TRYLOCK_RECURSIVE;
+ if (mutex_trylock(rwl))
+ return MUTEX_TRYLOCK_SUCCESS;
+ return MUTEX_TRYLOCK_FAILED;
+}
+
#endif
diff --git a/sys/dev/pci/drm/include/linux/shrinker.h b/sys/dev/pci/drm/include/linux/shrinker.h
new file mode 100644
index 00000000000..12d36810d46
--- /dev/null
+++ b/sys/dev/pci/drm/include/linux/shrinker.h
@@ -0,0 +1,25 @@
+/* Public domain. */
+
+#ifndef _LINUX_SHRINKER_H
+#define _LINUX_SHRINKER_H
+
+struct shrink_control {
+ u_long nr_to_scan;
+ u_long nr_scanned;
+};
+
+struct shrinker {
+ u_long (*count_objects)(struct shrinker *, struct shrink_control *);
+ u_long (*scan_objects)(struct shrinker *, struct shrink_control *);
+ long batch;
+ int seeks;
+ TAILQ_ENTRY(shrinker) next;
+};
+
+#define SHRINK_STOP ~0UL
+
+#define DEFAULT_SEEKS 2
+
+int register_shrinker(struct shrinker *);
+
+#endif
diff --git a/sys/dev/pci/drm/include/linux/swap.h b/sys/dev/pci/drm/include/linux/swap.h
index 98827081640..ce2f8ad9378 100644
--- a/sys/dev/pci/drm/include/linux/swap.h
+++ b/sys/dev/pci/drm/include/linux/swap.h
@@ -11,4 +11,10 @@ get_nr_swap_pages(void)
return uvmexp.swpages - uvmexp.swpginuse;
}
+/*
+ * XXX For now, we don't want the shrinker to be too aggressive, so
+ * pretend we're not called from the pagedaemon even if we are.
+ */
+#define current_is_kswapd() 0
+
#endif