DF-4507 / fix.diff
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 1111111..2222222 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -158,6 +158,9 @@ struct image_params; struct proc; +/* Low memory events */ +typedef void (*vm_lowmem_fn)(void *, int); + /* Shutdown events */ typedef void (*shutdown_fn) (void *, int); @@ -170,6 +173,7 @@ typedef void (*shutdown_fn) (void *, int); typedef void (*execlist_fn)(void *, struct image_params *); typedef void (*exit_list_fn)(void *, struct proc *); +EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_fn); /* low on memory */ EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 1111111..2222222 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1792,6 +1792,13 @@ */ if (swap_pager_almost_full && pass > 0 && isep == 0 && (vm_paging_min_dnc(recycle_count) || avail_shortage > 0)) { + + /* + * System is critically short of memory. Give caches + * (e.g. the TTM page pools) a chance to release pages + * before we start killing processes. + */ + EVENTHANDLER_INVOKE(vm_lowmem, 0); + kprintf("Warning: system low on memory+swap " "shortage %ld for %d ticks!\n", avail_shortage, ticks - swap_fail_ticks); diff --git a/sys/dev/drm/ttm/ttm_page_alloc.c b/sys/dev/drm/ttm/ttm_page_alloc.c index 1111111..2222222 100644 --- a/sys/dev/drm/ttm/ttm_page_alloc.c +++ b/sys/dev/drm/ttm/ttm_page_alloc.c @@ -382,7 +382,18 @@ * * XXX: (dchinner) Deadlock warning! * * This code is crying out for a shrinker per pool.... */ +/* + * vm_lowmem adapter: eventhandlers are invoked as func(arg, flags) and + * cannot be passed directly as a shrinker callback. Build a local + * shrink_control instead of casting the event argument to a pointer + * (which would dereference the integer flags argument). + */ +static void +ttm_pool_lowmem(void *arg, int flags) +{ + struct shrink_control sc; + + sc.gfp_mask = M_WAITOK; + sc.nr_to_scan = ~0UL; + ttm_pool_shrink_scan((struct shrinker *)arg, &sc); +} + static unsigned long ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { @@ -439,11 +450,9 @@ static void ttm_pool_mm_shrink_init(struct ttm_pool_manager *manager) { - manager->mm_shrink.count_objects = ttm_pool_shrink_count; - manager->mm_shrink.scan_objects = ttm_pool_shrink_scan; - manager->mm_shrink.seeks = 1; - manager->lowmem_handler = EVENTHANDLER_REGISTER(vm_lowmem, - ttm_pool_shrink_scan, manager, EVENTHANDLER_PRI_ANY); + manager->lowmem_handler = EVENTHANDLER_REGISTER(vm_lowmem, + ttm_pool_lowmem, manager, EVENTHANDLER_PRI_ANY); } |