mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-11-01 09:13:37 +00:00
drm/ttm: Handle cgroup based eviction in TTM
cgroup resource allocation has to be handled in TTM, so -EAGAIN from cgroups can be converted into -ENOSPC, and the limitcg can be properly evicted in ttm code. When hitting a resource limit through -EAGAIN, the cgroup for which the limit is hit is also returned. This allows eviction to delete only from cgroups which are a subgroup of the current cgroup. The returned CSS is used to determine if eviction is valuable for a given resource, and allows TTM to only target specific resources to lower memory usage. Co-developed-by: Friedrich Vock <friedrich.vock@gmx.de> Signed-off-by: Friedrich Vock <friedrich.vock@gmx.de> Co-developed-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Maarten Lankhorst <dev@lankhorst.se> Acked-by: Tejun Heo <tj@kernel.org> Link: https://lore.kernel.org/r/20241204134410.1161769-4-dev@lankhorst.se Signed-off-by: Maxime Ripard <mripard@kernel.org>
This commit is contained in:
parent
7b0af165e2
commit
2b624a2c18
6 changed files with 89 additions and 22 deletions
|
|
@ -258,13 +258,13 @@ static void ttm_bo_unreserve_basic(struct kunit *test)
|
||||||
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
||||||
bo->priority = bo_prio;
|
bo->priority = bo_prio;
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &res1);
|
err = ttm_resource_alloc(bo, place, &res1, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
|
|
||||||
bo->resource = res1;
|
bo->resource = res1;
|
||||||
|
|
||||||
/* Add a dummy resource to populate LRU */
|
/* Add a dummy resource to populate LRU */
|
||||||
ttm_resource_alloc(bo, place, &res2);
|
ttm_resource_alloc(bo, place, &res2, NULL);
|
||||||
|
|
||||||
dma_resv_lock(bo->base.resv, NULL);
|
dma_resv_lock(bo->base.resv, NULL);
|
||||||
ttm_bo_unreserve(bo);
|
ttm_bo_unreserve(bo);
|
||||||
|
|
@ -300,12 +300,12 @@ static void ttm_bo_unreserve_pinned(struct kunit *test)
|
||||||
dma_resv_lock(bo->base.resv, NULL);
|
dma_resv_lock(bo->base.resv, NULL);
|
||||||
ttm_bo_pin(bo);
|
ttm_bo_pin(bo);
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &res1);
|
err = ttm_resource_alloc(bo, place, &res1, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
bo->resource = res1;
|
bo->resource = res1;
|
||||||
|
|
||||||
/* Add a dummy resource to the pinned list */
|
/* Add a dummy resource to the pinned list */
|
||||||
err = ttm_resource_alloc(bo, place, &res2);
|
err = ttm_resource_alloc(bo, place, &res2, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
KUNIT_ASSERT_EQ(test,
|
KUNIT_ASSERT_EQ(test,
|
||||||
list_is_last(&res2->lru.link, &priv->ttm_dev->unevictable), 1);
|
list_is_last(&res2->lru.link, &priv->ttm_dev->unevictable), 1);
|
||||||
|
|
@ -355,7 +355,7 @@ static void ttm_bo_unreserve_bulk(struct kunit *test)
|
||||||
ttm_bo_set_bulk_move(bo1, &lru_bulk_move);
|
ttm_bo_set_bulk_move(bo1, &lru_bulk_move);
|
||||||
dma_resv_unlock(bo1->base.resv);
|
dma_resv_unlock(bo1->base.resv);
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo1, place, &res1);
|
err = ttm_resource_alloc(bo1, place, &res1, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
bo1->resource = res1;
|
bo1->resource = res1;
|
||||||
|
|
||||||
|
|
@ -363,7 +363,7 @@ static void ttm_bo_unreserve_bulk(struct kunit *test)
|
||||||
ttm_bo_set_bulk_move(bo2, &lru_bulk_move);
|
ttm_bo_set_bulk_move(bo2, &lru_bulk_move);
|
||||||
dma_resv_unlock(bo2->base.resv);
|
dma_resv_unlock(bo2->base.resv);
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo2, place, &res2);
|
err = ttm_resource_alloc(bo2, place, &res2, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
bo2->resource = res2;
|
bo2->resource = res2;
|
||||||
|
|
||||||
|
|
@ -401,7 +401,7 @@ static void ttm_bo_put_basic(struct kunit *test)
|
||||||
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
||||||
bo->type = ttm_bo_type_device;
|
bo->type = ttm_bo_type_device;
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &res);
|
err = ttm_resource_alloc(bo, place, &res, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
bo->resource = res;
|
bo->resource = res;
|
||||||
|
|
||||||
|
|
@ -518,7 +518,7 @@ static void ttm_bo_pin_unpin_resource(struct kunit *test)
|
||||||
|
|
||||||
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &res);
|
err = ttm_resource_alloc(bo, place, &res, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
bo->resource = res;
|
bo->resource = res;
|
||||||
|
|
||||||
|
|
@ -569,7 +569,7 @@ static void ttm_bo_multiple_pin_one_unpin(struct kunit *test)
|
||||||
|
|
||||||
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &res);
|
err = ttm_resource_alloc(bo, place, &res, NULL);
|
||||||
KUNIT_ASSERT_EQ(test, err, 0);
|
KUNIT_ASSERT_EQ(test, err, 0);
|
||||||
bo->resource = res;
|
bo->resource = res;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -542,7 +542,7 @@ static void ttm_bo_validate_no_placement_signaled(struct kunit *test)
|
||||||
bo->ttm = old_tt;
|
bo->ttm = old_tt;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &bo->resource);
|
err = ttm_resource_alloc(bo, place, &bo->resource, NULL);
|
||||||
KUNIT_EXPECT_EQ(test, err, 0);
|
KUNIT_EXPECT_EQ(test, err, 0);
|
||||||
KUNIT_ASSERT_EQ(test, man->usage, size);
|
KUNIT_ASSERT_EQ(test, man->usage, size);
|
||||||
|
|
||||||
|
|
@ -603,7 +603,7 @@ static void ttm_bo_validate_no_placement_not_signaled(struct kunit *test)
|
||||||
bo = ttm_bo_kunit_init(test, test->priv, size, NULL);
|
bo = ttm_bo_kunit_init(test, test->priv, size, NULL);
|
||||||
bo->type = params->bo_type;
|
bo->type = params->bo_type;
|
||||||
|
|
||||||
err = ttm_resource_alloc(bo, place, &bo->resource);
|
err = ttm_resource_alloc(bo, place, &bo->resource, NULL);
|
||||||
KUNIT_EXPECT_EQ(test, err, 0);
|
KUNIT_EXPECT_EQ(test, err, 0);
|
||||||
|
|
||||||
placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL);
|
placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL);
|
||||||
|
|
|
||||||
|
|
@ -302,7 +302,7 @@ static void ttm_sys_man_free_basic(struct kunit *test)
|
||||||
res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
|
res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, res);
|
KUNIT_ASSERT_NOT_NULL(test, res);
|
||||||
|
|
||||||
ttm_resource_alloc(bo, place, &res);
|
ttm_resource_alloc(bo, place, &res, NULL);
|
||||||
|
|
||||||
man = ttm_manager_type(priv->devs->ttm_dev, mem_type);
|
man = ttm_manager_type(priv->devs->ttm_dev, mem_type);
|
||||||
man->func->free(man, res);
|
man->func->free(man, res);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
|
#include <linux/cgroup_dmem.h>
|
||||||
#include <linux/dma-resv.h>
|
#include <linux/dma-resv.h>
|
||||||
|
|
||||||
#include "ttm_module.h"
|
#include "ttm_module.h"
|
||||||
|
|
@ -499,6 +500,13 @@ struct ttm_bo_evict_walk {
|
||||||
struct ttm_resource **res;
|
struct ttm_resource **res;
|
||||||
/** @evicted: Number of successful evictions. */
|
/** @evicted: Number of successful evictions. */
|
||||||
unsigned long evicted;
|
unsigned long evicted;
|
||||||
|
|
||||||
|
/** @limit_pool: Which pool limit we should test against */
|
||||||
|
struct dmem_cgroup_pool_state *limit_pool;
|
||||||
|
/** @try_low: Whether we should attempt to evict BO's with low watermark threshold */
|
||||||
|
bool try_low;
|
||||||
|
/** @hit_low: If we cannot evict a bo when @try_low is false (first pass) */
|
||||||
|
bool hit_low;
|
||||||
};
|
};
|
||||||
|
|
||||||
static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
||||||
|
|
@ -507,6 +515,10 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *
|
||||||
container_of(walk, typeof(*evict_walk), walk);
|
container_of(walk, typeof(*evict_walk), walk);
|
||||||
s64 lret;
|
s64 lret;
|
||||||
|
|
||||||
|
if (!dmem_cgroup_state_evict_valuable(evict_walk->limit_pool, bo->resource->css,
|
||||||
|
evict_walk->try_low, &evict_walk->hit_low))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (bo->pin_count || !bo->bdev->funcs->eviction_valuable(bo, evict_walk->place))
|
if (bo->pin_count || !bo->bdev->funcs->eviction_valuable(bo, evict_walk->place))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -524,7 +536,7 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *
|
||||||
evict_walk->evicted++;
|
evict_walk->evicted++;
|
||||||
if (evict_walk->res)
|
if (evict_walk->res)
|
||||||
lret = ttm_resource_alloc(evict_walk->evictor, evict_walk->place,
|
lret = ttm_resource_alloc(evict_walk->evictor, evict_walk->place,
|
||||||
evict_walk->res);
|
evict_walk->res, NULL);
|
||||||
if (lret == 0)
|
if (lret == 0)
|
||||||
return 1;
|
return 1;
|
||||||
out:
|
out:
|
||||||
|
|
@ -545,7 +557,8 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
|
||||||
struct ttm_buffer_object *evictor,
|
struct ttm_buffer_object *evictor,
|
||||||
struct ttm_operation_ctx *ctx,
|
struct ttm_operation_ctx *ctx,
|
||||||
struct ww_acquire_ctx *ticket,
|
struct ww_acquire_ctx *ticket,
|
||||||
struct ttm_resource **res)
|
struct ttm_resource **res,
|
||||||
|
struct dmem_cgroup_pool_state *limit_pool)
|
||||||
{
|
{
|
||||||
struct ttm_bo_evict_walk evict_walk = {
|
struct ttm_bo_evict_walk evict_walk = {
|
||||||
.walk = {
|
.walk = {
|
||||||
|
|
@ -556,22 +569,39 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
|
||||||
.place = place,
|
.place = place,
|
||||||
.evictor = evictor,
|
.evictor = evictor,
|
||||||
.res = res,
|
.res = res,
|
||||||
|
.limit_pool = limit_pool,
|
||||||
};
|
};
|
||||||
s64 lret;
|
s64 lret;
|
||||||
|
|
||||||
evict_walk.walk.trylock_only = true;
|
evict_walk.walk.trylock_only = true;
|
||||||
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
||||||
|
|
||||||
|
/* One more attempt if we hit low limit? */
|
||||||
|
if (!lret && evict_walk.hit_low) {
|
||||||
|
evict_walk.try_low = true;
|
||||||
|
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
||||||
|
}
|
||||||
if (lret || !ticket)
|
if (lret || !ticket)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* Reset low limit */
|
||||||
|
evict_walk.try_low = evict_walk.hit_low = false;
|
||||||
/* If ticket-locking, repeat while making progress. */
|
/* If ticket-locking, repeat while making progress. */
|
||||||
evict_walk.walk.trylock_only = false;
|
evict_walk.walk.trylock_only = false;
|
||||||
|
|
||||||
|
retry:
|
||||||
do {
|
do {
|
||||||
/* The walk may clear the evict_walk.walk.ticket field */
|
/* The walk may clear the evict_walk.walk.ticket field */
|
||||||
evict_walk.walk.ticket = ticket;
|
evict_walk.walk.ticket = ticket;
|
||||||
evict_walk.evicted = 0;
|
evict_walk.evicted = 0;
|
||||||
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
||||||
} while (!lret && evict_walk.evicted);
|
} while (!lret && evict_walk.evicted);
|
||||||
|
|
||||||
|
/* We hit the low limit? Try once more */
|
||||||
|
if (!lret && evict_walk.hit_low && !evict_walk.try_low) {
|
||||||
|
evict_walk.try_low = true;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
if (lret < 0)
|
if (lret < 0)
|
||||||
return lret;
|
return lret;
|
||||||
|
|
@ -689,6 +719,7 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
|
||||||
|
|
||||||
for (i = 0; i < placement->num_placement; ++i) {
|
for (i = 0; i < placement->num_placement; ++i) {
|
||||||
const struct ttm_place *place = &placement->placement[i];
|
const struct ttm_place *place = &placement->placement[i];
|
||||||
|
struct dmem_cgroup_pool_state *limit_pool = NULL;
|
||||||
struct ttm_resource_manager *man;
|
struct ttm_resource_manager *man;
|
||||||
bool may_evict;
|
bool may_evict;
|
||||||
|
|
||||||
|
|
@ -701,15 +732,20 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
may_evict = (force_space && place->mem_type != TTM_PL_SYSTEM);
|
may_evict = (force_space && place->mem_type != TTM_PL_SYSTEM);
|
||||||
ret = ttm_resource_alloc(bo, place, res);
|
ret = ttm_resource_alloc(bo, place, res, force_space ? &limit_pool : NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret != -ENOSPC)
|
if (ret != -ENOSPC && ret != -EAGAIN) {
|
||||||
|
dmem_cgroup_pool_state_put(limit_pool);
|
||||||
return ret;
|
return ret;
|
||||||
if (!may_evict)
|
}
|
||||||
|
if (!may_evict) {
|
||||||
|
dmem_cgroup_pool_state_put(limit_pool);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ttm_bo_evict_alloc(bdev, man, place, bo, ctx,
|
ret = ttm_bo_evict_alloc(bdev, man, place, bo, ctx,
|
||||||
ticket, res);
|
ticket, res, limit_pool);
|
||||||
|
dmem_cgroup_pool_state_put(limit_pool);
|
||||||
if (ret == -EBUSY)
|
if (ret == -EBUSY)
|
||||||
continue;
|
continue;
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
@ -1056,6 +1092,8 @@ struct ttm_bo_swapout_walk {
|
||||||
struct ttm_lru_walk walk;
|
struct ttm_lru_walk walk;
|
||||||
/** @gfp_flags: The gfp flags to use for ttm_tt_swapout() */
|
/** @gfp_flags: The gfp flags to use for ttm_tt_swapout() */
|
||||||
gfp_t gfp_flags;
|
gfp_t gfp_flags;
|
||||||
|
|
||||||
|
bool hit_low, evict_low;
|
||||||
};
|
};
|
||||||
|
|
||||||
static s64
|
static s64
|
||||||
|
|
@ -1106,7 +1144,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
||||||
|
|
||||||
memset(&hop, 0, sizeof(hop));
|
memset(&hop, 0, sizeof(hop));
|
||||||
place.mem_type = TTM_PL_SYSTEM;
|
place.mem_type = TTM_PL_SYSTEM;
|
||||||
ret = ttm_resource_alloc(bo, &place, &evict_mem);
|
ret = ttm_resource_alloc(bo, &place, &evict_mem, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/io-mapping.h>
|
#include <linux/io-mapping.h>
|
||||||
#include <linux/iosys-map.h>
|
#include <linux/iosys-map.h>
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/cgroup_dmem.h>
|
||||||
|
|
||||||
#include <drm/ttm/ttm_bo.h>
|
#include <drm/ttm/ttm_bo.h>
|
||||||
#include <drm/ttm/ttm_placement.h>
|
#include <drm/ttm/ttm_placement.h>
|
||||||
|
|
@ -350,15 +351,28 @@ EXPORT_SYMBOL(ttm_resource_fini);
|
||||||
|
|
||||||
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
||||||
const struct ttm_place *place,
|
const struct ttm_place *place,
|
||||||
struct ttm_resource **res_ptr)
|
struct ttm_resource **res_ptr,
|
||||||
|
struct dmem_cgroup_pool_state **ret_limit_pool)
|
||||||
{
|
{
|
||||||
struct ttm_resource_manager *man =
|
struct ttm_resource_manager *man =
|
||||||
ttm_manager_type(bo->bdev, place->mem_type);
|
ttm_manager_type(bo->bdev, place->mem_type);
|
||||||
|
struct dmem_cgroup_pool_state *pool = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (man->cg) {
|
||||||
|
ret = dmem_cgroup_try_charge(man->cg, bo->base.size, &pool, ret_limit_pool);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = man->func->alloc(man, bo, place, res_ptr);
|
ret = man->func->alloc(man, bo, place, res_ptr);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
if (pool)
|
||||||
|
dmem_cgroup_uncharge(pool, bo->base.size);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*res_ptr)->css = pool;
|
||||||
|
|
||||||
spin_lock(&bo->bdev->lru_lock);
|
spin_lock(&bo->bdev->lru_lock);
|
||||||
ttm_resource_add_bulk_move(*res_ptr, bo);
|
ttm_resource_add_bulk_move(*res_ptr, bo);
|
||||||
|
|
@ -370,6 +384,7 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_resource_alloc);
|
||||||
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
|
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
|
||||||
{
|
{
|
||||||
struct ttm_resource_manager *man;
|
struct ttm_resource_manager *man;
|
||||||
|
struct dmem_cgroup_pool_state *pool;
|
||||||
|
|
||||||
if (!*res)
|
if (!*res)
|
||||||
return;
|
return;
|
||||||
|
|
@ -377,9 +392,13 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
|
||||||
spin_lock(&bo->bdev->lru_lock);
|
spin_lock(&bo->bdev->lru_lock);
|
||||||
ttm_resource_del_bulk_move(*res, bo);
|
ttm_resource_del_bulk_move(*res, bo);
|
||||||
spin_unlock(&bo->bdev->lru_lock);
|
spin_unlock(&bo->bdev->lru_lock);
|
||||||
|
|
||||||
|
pool = (*res)->css;
|
||||||
man = ttm_manager_type(bo->bdev, (*res)->mem_type);
|
man = ttm_manager_type(bo->bdev, (*res)->mem_type);
|
||||||
man->func->free(man, *res);
|
man->func->free(man, *res);
|
||||||
*res = NULL;
|
*res = NULL;
|
||||||
|
if (man->cg)
|
||||||
|
dmem_cgroup_uncharge(pool, bo->base.size);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ttm_resource_free);
|
EXPORT_SYMBOL(ttm_resource_free);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#define TTM_MAX_BO_PRIORITY 4U
|
#define TTM_MAX_BO_PRIORITY 4U
|
||||||
#define TTM_NUM_MEM_TYPES 8
|
#define TTM_NUM_MEM_TYPES 8
|
||||||
|
|
||||||
|
struct dmem_cgroup_device;
|
||||||
struct ttm_device;
|
struct ttm_device;
|
||||||
struct ttm_resource_manager;
|
struct ttm_resource_manager;
|
||||||
struct ttm_resource;
|
struct ttm_resource;
|
||||||
|
|
@ -211,6 +212,11 @@ struct ttm_resource_manager {
|
||||||
* bdev->lru_lock.
|
* bdev->lru_lock.
|
||||||
*/
|
*/
|
||||||
uint64_t usage;
|
uint64_t usage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @cg: &dmem_cgroup_region used for memory accounting, if not NULL.
|
||||||
|
*/
|
||||||
|
struct dmem_cgroup_region *cg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -239,6 +245,7 @@ struct ttm_bus_placement {
|
||||||
* @placement: Placement flags.
|
* @placement: Placement flags.
|
||||||
* @bus: Placement on io bus accessible to the CPU
|
* @bus: Placement on io bus accessible to the CPU
|
||||||
* @bo: weak reference to the BO, protected by ttm_device::lru_lock
|
* @bo: weak reference to the BO, protected by ttm_device::lru_lock
|
||||||
|
* @css: cgroup state this resource is charged to
|
||||||
*
|
*
|
||||||
* Structure indicating the placement and space resources used by a
|
* Structure indicating the placement and space resources used by a
|
||||||
* buffer object.
|
* buffer object.
|
||||||
|
|
@ -251,6 +258,8 @@ struct ttm_resource {
|
||||||
struct ttm_bus_placement bus;
|
struct ttm_bus_placement bus;
|
||||||
struct ttm_buffer_object *bo;
|
struct ttm_buffer_object *bo;
|
||||||
|
|
||||||
|
struct dmem_cgroup_pool_state *css;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @lru: Least recently used list, see &ttm_resource_manager.lru
|
* @lru: Least recently used list, see &ttm_resource_manager.lru
|
||||||
*/
|
*/
|
||||||
|
|
@ -432,7 +441,8 @@ void ttm_resource_fini(struct ttm_resource_manager *man,
|
||||||
|
|
||||||
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
||||||
const struct ttm_place *place,
|
const struct ttm_place *place,
|
||||||
struct ttm_resource **res);
|
struct ttm_resource **res,
|
||||||
|
struct dmem_cgroup_pool_state **ret_limit_pool);
|
||||||
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
|
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
|
||||||
bool ttm_resource_intersects(struct ttm_device *bdev,
|
bool ttm_resource_intersects(struct ttm_device *bdev,
|
||||||
struct ttm_resource *res,
|
struct ttm_resource *res,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue