diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-12-25 11:31:42 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-12-25 11:31:42 +0000 |
commit | 2af882cf362e2c94b359bdcc131860a50d263710 (patch) | |
tree | b0b9bd05053f20f9492b5379e4f91eea8a56b393 /sys/dev/pci/drm | |
parent | 1037e00d7dfda3b214c26ef184a3d1f5d5be8ce7 (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.c | 27 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_gem_shrinker.c | 10 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/linux/mm.h | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/linux/mutex.h | 18 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/linux/shrinker.h | 25 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/linux/swap.h | 6 |
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 |