| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/23 02:59 | flow | patch-triage |
3mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch implements proactive reclaim and high watermark threshold handling for the dmem cgroup controller and DRM TTM. All runtime code paths introduced or modified (including proactive eviction in ttm_bo.c, dmem charge tracking, high limit checks, and the dmem.high cgroup control interface) strictly require registered dmem memory regions and a configured TTM manager cgroup (man-\u003ecg). The only drivers in the kernel that register dmem regions and set man-\u003ecg are amdgpu and Intel xe, both of which require physical GPU ASICs that are not emulated in standard virtualized environments (QEMU/syzkaller). Without registered regions, cgroup operations on dmem.high fail immediately with -EINVAL or return 0, leaving all modified logic structurally unreachable.",
"WorthFuzzing": false
} |
| 1/1 | 2026/09/23 02:59 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 8d7a6557f245829a62c6bab85d3edfd95d8a40c5\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Sep 23 02:59:23 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c\nindex f3103307b5df9..7a03f6a04f4e8 100644\n--- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c\n+++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c\n@@ -258,13 +258,13 @@ static void ttm_bo_unreserve_basic(struct kunit *test)\n \tbo = ttm_bo_kunit_init(test, test-\u003epriv, BO_SIZE, NULL);\n \tbo-\u003epriority = bo_prio;\n \n-\terr = ttm_resource_alloc(bo, place, \u0026res1, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026res1, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \n \tbo-\u003eresource = res1;\n \n \t/* Add a dummy resource to populate LRU */\n-\tttm_resource_alloc(bo, place, \u0026res2, NULL);\n+\tttm_resource_alloc(bo, place, \u0026res2, NULL, NULL);\n \n \tdma_resv_lock(bo-\u003ebase.resv, NULL);\n \tttm_bo_unreserve(bo);\n@@ -300,12 +300,12 @@ static void ttm_bo_unreserve_pinned(struct kunit *test)\n \tdma_resv_lock(bo-\u003ebase.resv, NULL);\n \tttm_bo_pin(bo);\n \n-\terr = ttm_resource_alloc(bo, place, \u0026res1, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026res1, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tbo-\u003eresource = res1;\n \n \t/* Add a dummy resource to the pinned list */\n-\terr = ttm_resource_alloc(bo, place, \u0026res2, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026res2, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tKUNIT_ASSERT_EQ(test,\n \t\t\tlist_is_last(\u0026res2-\u003elru.link, \u0026priv-\u003ettm_dev-\u003eunevictable), 1);\n@@ -355,7 +355,7 @@ static void ttm_bo_unreserve_bulk(struct kunit *test)\n \tttm_bo_set_bulk_move(bo1, \u0026lru_bulk_move);\n \tdma_resv_unlock(bo1-\u003ebase.resv);\n \n-\terr = ttm_resource_alloc(bo1, place, \u0026res1, NULL);\n+\terr = ttm_resource_alloc(bo1, place, \u0026res1, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tbo1-\u003eresource = res1;\n \n@@ -363,7 +363,7 @@ static void ttm_bo_unreserve_bulk(struct kunit *test)\n \tttm_bo_set_bulk_move(bo2, \u0026lru_bulk_move);\n \tdma_resv_unlock(bo2-\u003ebase.resv);\n \n-\terr = ttm_resource_alloc(bo2, place, \u0026res2, NULL);\n+\terr = ttm_resource_alloc(bo2, place, \u0026res2, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tbo2-\u003eresource = res2;\n \n@@ -401,7 +401,7 @@ static void ttm_bo_fini_basic(struct kunit *test)\n \tbo = ttm_bo_kunit_init(test, test-\u003epriv, BO_SIZE, NULL);\n \tbo-\u003etype = ttm_bo_type_device;\n \n-\terr = ttm_resource_alloc(bo, place, \u0026res, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026res, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tbo-\u003eresource = res;\n \n@@ -518,7 +518,7 @@ static void ttm_bo_pin_unpin_resource(struct kunit *test)\n \n \tbo = ttm_bo_kunit_init(test, test-\u003epriv, BO_SIZE, NULL);\n \n-\terr = ttm_resource_alloc(bo, place, \u0026res, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026res, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tbo-\u003eresource = res;\n \n@@ -569,7 +569,7 @@ static void ttm_bo_multiple_pin_one_unpin(struct kunit *test)\n \n \tbo = ttm_bo_kunit_init(test, test-\u003epriv, BO_SIZE, NULL);\n \n-\terr = ttm_resource_alloc(bo, place, \u0026res, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026res, NULL, NULL);\n \tKUNIT_ASSERT_EQ(test, err, 0);\n \tbo-\u003eresource = res;\n \ndiff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c\nindex 2db221f6fc3a1..cd40f5b2ab4f1 100644\n--- a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c\n+++ b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c\n@@ -547,7 +547,7 @@ static void ttm_bo_validate_no_placement_signaled(struct kunit *test)\n \n \tttm_bo_reserve(bo, false, false, NULL);\n \n-\terr = ttm_resource_alloc(bo, place, \u0026bo-\u003eresource, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026bo-\u003eresource, NULL, NULL);\n \tKUNIT_EXPECT_EQ(test, err, 0);\n \tKUNIT_ASSERT_EQ(test, man-\u003eusage, size);\n \n@@ -604,7 +604,7 @@ static void ttm_bo_validate_no_placement_not_signaled(struct kunit *test)\n \tbo = ttm_bo_kunit_init(test, test-\u003epriv, size, NULL);\n \tbo-\u003etype = params-\u003ebo_type;\n \n-\terr = ttm_resource_alloc(bo, place, \u0026bo-\u003eresource, NULL);\n+\terr = ttm_resource_alloc(bo, place, \u0026bo-\u003eresource, NULL, NULL);\n \tKUNIT_EXPECT_EQ(test, err, 0);\n \n \tplacement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL);\ndiff --git a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c\nindex c0e4e35e04426..41fe4d89cd714 100644\n--- a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c\n+++ b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c\n@@ -303,7 +303,7 @@ static void ttm_sys_man_free_basic(struct kunit *test)\n \tres = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);\n \tKUNIT_ASSERT_NOT_NULL(test, res);\n \n-\tttm_resource_alloc(bo, place, \u0026res, NULL);\n+\tttm_resource_alloc(bo, place, \u0026res, NULL, NULL);\n \n \tman = ttm_manager_type(priv-\u003edevs-\u003ettm_dev, mem_type);\n \tman-\u003efunc-\u003efree(man, res);\ndiff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c\nindex bcd76f6bb7f02..91f9889b3d079 100644\n--- a/drivers/gpu/drm/ttm/ttm_bo.c\n+++ b/drivers/gpu/drm/ttm/ttm_bo.c\n@@ -505,6 +505,8 @@ struct ttm_bo_evict_walk {\n \n \t/** @limit_pool: Which pool limit we should test against */\n \tstruct dmem_cgroup_pool_state *limit_pool;\n+\t/** @try_high: Whether to only evict BO's above the high watermark (first pass) */\n+\tbool try_high;\n \t/** @try_low: Whether we should attempt to evict BO's with low watermark threshold */\n \tbool try_low;\n \t/** @hit_low: If we cannot evict a bo when @try_low is false (first pass) */\n@@ -518,7 +520,8 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *\n \ts64 lret;\n \n \tif (!dmem_cgroup_state_evict_valuable(evict_walk-\u003elimit_pool, bo-\u003eresource-\u003ecss,\n-\t\t\t\t\t evict_walk-\u003etry_low, \u0026evict_walk-\u003ehit_low))\n+\t\t\t\t\t evict_walk-\u003etry_high, evict_walk-\u003etry_low,\n+\t\t\t\t\t \u0026evict_walk-\u003ehit_low))\n \t\treturn 0;\n \n \tif (bo-\u003epin_count || !bo-\u003ebdev-\u003efuncs-\u003eeviction_valuable(bo, evict_walk-\u003eplace))\n@@ -538,7 +541,7 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *\n \tevict_walk-\u003eevicted++;\n \tif (evict_walk-\u003eres)\n \t\tlret = ttm_resource_alloc(evict_walk-\u003eevictor, evict_walk-\u003eplace,\n-\t\t\t\t\t evict_walk-\u003eres, NULL);\n+\t\t\t\t\t evict_walk-\u003eres, NULL, NULL);\n \tif (lret == 0)\n \t\treturn 1;\n out:\n@@ -553,6 +556,42 @@ static const struct ttm_lru_walk_ops ttm_evict_walk_ops = {\n \t.process_bo = ttm_bo_evict_cb,\n };\n \n+/*\n+ * Proactive reclaim: evict one BO from a cgroup that exceeds its dmem.high\n+ * soft limit. Called after a successful charge that pushed usage over the\n+ * high threshold. Best-effort; allocation already succeeded (soft limit).\n+ *\n+ * Returns the ttm_lru_walk_for_evict() result so callers using a ww_mutex\n+ * ticket can detect -EDEADLK and run the required backoff instead of it\n+ * being silently swallowed.\n+ */\n+static s64 ttm_bo_proactive_evict_high(struct ttm_device *bdev,\n+\t\t\t\t struct ttm_resource_manager *man,\n+\t\t\t\t const struct ttm_place *place,\n+\t\t\t\t struct ttm_buffer_object *evictor,\n+\t\t\t\t struct ttm_operation_ctx *ctx,\n+\t\t\t\t struct ww_acquire_ctx *ticket,\n+\t\t\t\t struct dmem_cgroup_pool_state *over_high_pool)\n+{\n+\tstruct ttm_bo_evict_walk evict_walk = {\n+\t\t.walk = {\n+\t\t\t.ops = \u0026ttm_evict_walk_ops,\n+\t\t\t.arg = {\n+\t\t\t\t.ctx = ctx,\n+\t\t\t\t.ticket = ticket,\n+\t\t\t\t.trylock_only = !ticket,\n+\t\t\t}\n+\t\t},\n+\t\t.place = place,\n+\t\t.evictor = evictor,\n+\t\t.res = NULL,\n+\t\t.limit_pool = over_high_pool,\n+\t\t.try_high = true,\n+\t};\n+\n+\treturn ttm_lru_walk_for_evict(\u0026evict_walk.walk, bdev, man, 1);\n+}\n+\n static int ttm_bo_evict_alloc(struct ttm_device *bdev,\n \t\t\t struct ttm_resource_manager *man,\n \t\t\t const struct ttm_place *place,\n@@ -579,29 +618,24 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,\n \n \tevict_walk.walk.arg.trylock_only = true;\n \tlret = ttm_lru_walk_for_evict(\u0026evict_walk.walk, bdev, man, 1);\n-\n-\t/* One more attempt if we hit low limit? */\n \tif (!lret \u0026\u0026 evict_walk.hit_low) {\n \t\tevict_walk.try_low = true;\n \t\tlret = ttm_lru_walk_for_evict(\u0026evict_walk.walk, bdev, man, 1);\n \t}\n+\n \tif (lret || !ticket)\n \t\tgoto out;\n \n-\t/* Reset low limit */\n \tevict_walk.try_low = evict_walk.hit_low = false;\n-\t/* If ticket-locking, repeat while making progress. */\n \tevict_walk.walk.arg.trylock_only = false;\n \n retry:\n \tdo {\n-\t\t/* The walk may clear the evict_walk.walk.ticket field */\n \t\tevict_walk.walk.arg.ticket = ticket;\n \t\tevict_walk.evicted = 0;\n \t\tlret = ttm_lru_walk_for_evict(\u0026evict_walk.walk, bdev, man, 1);\n \t} while (!lret \u0026\u0026 evict_walk.evicted);\n \n-\t/* We hit the low limit? Try once more */\n \tif (!lret \u0026\u0026 evict_walk.hit_low \u0026\u0026 !evict_walk.try_low) {\n \t\tevict_walk.try_low = true;\n \t\tgoto retry;\n@@ -737,7 +771,26 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,\n \t\t\tcontinue;\n \n \t\tmay_evict = (force_space \u0026\u0026 place-\u003emem_type != TTM_PL_SYSTEM);\n-\t\tret = ttm_resource_alloc(bo, place, res, force_space ? \u0026limit_pool : NULL);\n+\t\t{\n+\t\t\tstruct dmem_cgroup_pool_state *over_high_pool = NULL;\n+\n+\t\t\tret = ttm_resource_alloc(bo, place, res,\n+\t\t\t\t\t\t force_space ? \u0026limit_pool : NULL,\n+\t\t\t\t\t\t \u0026over_high_pool);\n+\t\t\tif (!ret \u0026\u0026 over_high_pool) {\n+\t\t\t\ts64 evict_ret;\n+\n+\t\t\t\tevict_ret = ttm_bo_proactive_evict_high(bdev, man, place,\n+\t\t\t\t\t\t\t\t\tbo, ctx, ticket,\n+\t\t\t\t\t\t\t\t\tover_high_pool);\n+\t\t\t\tif (evict_ret \u003c 0) {\n+\t\t\t\t\tdmem_cgroup_pool_state_put(over_high_pool);\n+\t\t\t\t\tttm_resource_free(bo, res);\n+\t\t\t\t\treturn evict_ret;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tdmem_cgroup_pool_state_put(over_high_pool);\n+\t\t}\n \t\tif (ret) {\n \t\t\tif (ret != -ENOSPC) {\n \t\t\t\tdmem_cgroup_pool_state_put(limit_pool);\n@@ -1152,7 +1205,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)\n \n \t\tmemset(\u0026hop, 0, sizeof(hop));\n \t\tplace.mem_type = TTM_PL_SYSTEM;\n-\t\tret = ttm_resource_alloc(bo, \u0026place, \u0026evict_mem, NULL);\n+\t\tret = ttm_resource_alloc(bo, \u0026place, \u0026evict_mem, NULL, NULL);\n \t\tif (ret)\n \t\t\tgoto out;\n \ndiff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c\nindex 154d6739256f8..aca133a331063 100644\n--- a/drivers/gpu/drm/ttm/ttm_resource.c\n+++ b/drivers/gpu/drm/ttm/ttm_resource.c\n@@ -389,7 +389,8 @@ EXPORT_SYMBOL(ttm_resource_fini);\n int ttm_resource_alloc(struct ttm_buffer_object *bo,\n \t\t const struct ttm_place *place,\n \t\t struct ttm_resource **res_ptr,\n-\t\t struct dmem_cgroup_pool_state **ret_limit_pool)\n+\t\t struct dmem_cgroup_pool_state **ret_limit_pool,\n+\t\t struct dmem_cgroup_pool_state **ret_over_high_pool)\n {\n \tstruct ttm_resource_manager *man =\n \t\tttm_manager_type(bo-\u003ebdev, place-\u003emem_type);\n@@ -397,7 +398,8 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,\n \tint ret;\n \n \tif (man-\u003ecg) {\n-\t\tret = dmem_cgroup_try_charge(man-\u003ecg, bo-\u003ebase.size, \u0026pool, ret_limit_pool);\n+\t\tret = dmem_cgroup_try_charge(man-\u003ecg, bo-\u003ebase.size, \u0026pool,\n+\t\t\t\t\t ret_limit_pool, ret_over_high_pool);\n \t\tif (ret) {\n \t\t\tif (ret == -EAGAIN)\n \t\t\t\tret = -ENOSPC;\n@@ -409,6 +411,10 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,\n \tif (ret) {\n \t\tif (pool)\n \t\t\tdmem_cgroup_uncharge(pool, bo-\u003ebase.size);\n+\t\tif (ret_over_high_pool) {\n+\t\t\tdmem_cgroup_pool_state_put(*ret_over_high_pool);\n+\t\t\t*ret_over_high_pool = NULL;\n+\t\t}\n \t\treturn ret;\n \t}\n \ndiff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h\nindex a5d386583fb6e..88fb402acfdc6 100644\n--- a/include/drm/ttm/ttm_resource.h\n+++ b/include/drm/ttm/ttm_resource.h\n@@ -461,7 +461,8 @@ void ttm_resource_fini(struct ttm_resource_manager *man,\n int ttm_resource_alloc(struct ttm_buffer_object *bo,\n \t\t const struct ttm_place *place,\n \t\t struct ttm_resource **res,\n-\t\t struct dmem_cgroup_pool_state **ret_limit_pool);\n+\t\t struct dmem_cgroup_pool_state **ret_limit_pool,\n+\t\t struct dmem_cgroup_pool_state **ret_over_high_pool);\n void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);\n bool ttm_resource_intersects(struct ttm_device *bdev,\n \t\t\t struct ttm_resource *res,\ndiff --git a/include/linux/cgroup_dmem.h b/include/linux/cgroup_dmem.h\nindex dd4869f1d736e..1808bfbbc9a31 100644\n--- a/include/linux/cgroup_dmem.h\n+++ b/include/linux/cgroup_dmem.h\n@@ -19,11 +19,12 @@ struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *nam\n void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region);\n int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,\n \t\t\t struct dmem_cgroup_pool_state **ret_pool,\n-\t\t\t struct dmem_cgroup_pool_state **ret_limit_pool);\n+\t\t\t struct dmem_cgroup_pool_state **ret_limit_pool,\n+\t\t\t struct dmem_cgroup_pool_state **ret_over_high_pool);\n void dmem_cgroup_uncharge(struct dmem_cgroup_pool_state *pool, u64 size);\n bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,\n \t\t\t\t struct dmem_cgroup_pool_state *test_pool,\n-\t\t\t\t bool ignore_low, bool *ret_hit_low);\n+\t\t\t\t bool try_high, bool ignore_low, bool *ret_hit_low);\n \n void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool);\n #else\n@@ -38,13 +39,17 @@ static inline void dmem_cgroup_unregister_region(struct dmem_cgroup_region *regi\n \n static inline int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,\n \t\t\t\t\t struct dmem_cgroup_pool_state **ret_pool,\n-\t\t\t\t\t struct dmem_cgroup_pool_state **ret_limit_pool)\n+\t\t\t\t\t struct dmem_cgroup_pool_state **ret_limit_pool,\n+\t\t\t\t\t struct dmem_cgroup_pool_state **ret_over_high_pool)\n {\n \t*ret_pool = NULL;\n \n \tif (ret_limit_pool)\n \t\t*ret_limit_pool = NULL;\n \n+\tif (ret_over_high_pool)\n+\t\t*ret_over_high_pool = NULL;\n+\n \treturn 0;\n }\n \n@@ -54,8 +59,10 @@ static inline void dmem_cgroup_uncharge(struct dmem_cgroup_pool_state *pool, u64\n static inline\n bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,\n \t\t\t\t struct dmem_cgroup_pool_state *test_pool,\n-\t\t\t\t bool ignore_low, bool *ret_hit_low)\n+\t\t\t\t bool try_high, bool ignore_low, bool *ret_hit_low)\n {\n+\tif (try_high)\n+\t\treturn false;\n \treturn true;\n }\n \ndiff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c\nindex 4753a67d0f0f2..e314943290612 100644\n--- a/kernel/cgroup/dmem.c\n+++ b/kernel/cgroup/dmem.c\n@@ -156,6 +156,12 @@ set_resource_low(struct dmem_cgroup_pool_state *pool, u64 val)\n \tpage_counter_set_low(\u0026pool-\u003ecnt, val);\n }\n \n+static void\n+set_resource_high(struct dmem_cgroup_pool_state *pool, u64 val)\n+{\n+\tpage_counter_set_high(\u0026pool-\u003ecnt, val);\n+}\n+\n static void\n set_resource_max(struct dmem_cgroup_pool_state *pool, u64 val)\n {\n@@ -167,6 +173,11 @@ static u64 get_resource_low(struct dmem_cgroup_pool_state *pool)\n \treturn pool ? READ_ONCE(pool-\u003ecnt.low) : 0;\n }\n \n+static u64 get_resource_high(struct dmem_cgroup_pool_state *pool)\n+{\n+\treturn pool ? READ_ONCE(pool-\u003ecnt.high) : PAGE_COUNTER_MAX;\n+}\n+\n static u64 get_resource_min(struct dmem_cgroup_pool_state *pool)\n {\n \treturn pool ? READ_ONCE(pool-\u003ecnt.min) : 0;\n@@ -186,6 +197,7 @@ static void reset_all_resource_limits(struct dmem_cgroup_pool_state *rpool)\n {\n \tset_resource_min(rpool, 0);\n \tset_resource_low(rpool, 0);\n+\tset_resource_high(rpool, PAGE_COUNTER_MAX);\n \tset_resource_max(rpool, PAGE_COUNTER_MAX);\n }\n \n@@ -289,10 +301,13 @@ dmem_cgroup_calculate_protection(struct dmem_cgroup_pool_state *limit_pool,\n * dmem_cgroup_state_evict_valuable() - Check if we should evict from test_pool\n * @limit_pool: The pool for which we hit limits\n * @test_pool: The pool for which to test\n+ * @try_high: Only evict BOs whose usage exceeds the high limit (first pass)\n * @ignore_low: Whether we have to respect low watermarks.\n * @ret_hit_low: Pointer to whether it makes sense to consider low watermark.\n *\n * This function returns true if we can evict from @test_pool, false if not.\n+ * When @try_high is set, only pools with usage above their high limit are\n+ * evictable, enabling prioritized eviction of over-limit cgroups.\n * When returning false and @ignore_low is false, @ret_hit_low may\n * be set to true to indicate this function can be retried with @ignore_low\n * set to true.\n@@ -301,15 +316,26 @@ dmem_cgroup_calculate_protection(struct dmem_cgroup_pool_state *limit_pool,\n */\n bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,\n \t\t\t\t struct dmem_cgroup_pool_state *test_pool,\n-\t\t\t\t bool ignore_low, bool *ret_hit_low)\n+\t\t\t\t bool try_high, bool ignore_low, bool *ret_hit_low)\n {\n \tstruct dmem_cgroup_pool_state *pool = test_pool;\n \tstruct page_counter *ctest;\n \tu64 used, min, low;\n \n-\t/* Can always evict from current pool, despite limits */\n-\tif (limit_pool == test_pool)\n+\t/*\n+\t * When the limit-hitting cgroup's own BOs are being considered\n+\t * in try_high mode, only evict them if their pool exceeds its\n+\t * own dmem.high limit. For non-try_high mode, maintain the\n+\t * existing behavior: always evict from the limit-hitting pool.\n+\t */\n+\tif (limit_pool == test_pool) {\n+\t\tif (try_high \u0026\u0026 test_pool) {\n+\t\t\tctest = \u0026test_pool-\u003ecnt;\n+\t\t\tused = page_counter_read(ctest);\n+\t\t\treturn used \u003e READ_ONCE(ctest-\u003ehigh);\n+\t\t}\n \t\treturn true;\n+\t}\n \n \tif (limit_pool) {\n \t\tif (!parent_dmemcs(limit_pool-\u003ecs))\n@@ -330,10 +356,38 @@ bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,\n \t}\n \n \tctest = \u0026test_pool-\u003ecnt;\n+\tused = page_counter_read(ctest);\n+\n+\tif (try_high) {\n+\t\tstruct page_counter *c;\n+\n+\t\t/*\n+\t\t * Walk the page_counter parent chain to check whether any\n+\t\t * ancestor cgroup exceeds its dmem.high limit. This prevents\n+\t\t * child cgroups from evading the penalty when a parent cgroup\n+\t\t * is over its high limit.\n+\t\t */\n+\t\tif (used \u003c= READ_ONCE(ctest-\u003ehigh)) {\n+\t\t\tfor (c = ctest-\u003eparent; c; c = c-\u003eparent) {\n+\t\t\t\tif (page_counter_read(c) \u003e READ_ONCE(c-\u003ehigh))\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (!c)\n+\t\t\t\treturn false;\n+\t\t}\n+\n+\t\t/*\n+\t\t * Respect dmem.min protection: do not evict BOs below the\n+\t\t * effective minimum even during the high-priority pass.\n+\t\t */\n+\t\tdmem_cgroup_calculate_protection(limit_pool, test_pool);\n+\t\tmin = READ_ONCE(ctest-\u003eemin);\n+\n+\t\treturn used \u003e min;\n+\t}\n \n \tdmem_cgroup_calculate_protection(limit_pool, test_pool);\n \n-\tused = page_counter_read(ctest);\n \tmin = READ_ONCE(ctest-\u003eemin);\n \n \tif (used \u003c= min)\n@@ -634,8 +688,9 @@ EXPORT_SYMBOL_GPL(dmem_cgroup_uncharge);\n * dmem_cgroup_try_charge() - Try charging a new allocation to a region.\n * @region: dmem region to charge\n * @size: Size (in bytes) to charge.\n- * @ret_pool: On succesfull allocation, the pool that is charged.\n+ * @ret_pool: On successful allocation, the pool that is charged.\n * @ret_limit_pool: On a failed allocation, the limiting pool.\n+ * @ret_over_high_pool: On successful allocation, set if usage exceeds dmem.high.\n *\n * This function charges the @region region for a size of @size bytes.\n *\n@@ -647,11 +702,17 @@ EXPORT_SYMBOL_GPL(dmem_cgroup_uncharge);\n * eviction as argument to dmem_cgroup_evict_valuable(). This reference must be freed\n * with @dmem_cgroup_pool_state_put().\n *\n+ * When the function succeeds and @ret_over_high_pool is non-null, it will be\n+ * set if the charged pool's usage now exceeds its dmem.high soft limit. The\n+ * caller should trigger proactive eviction to bring usage back under the limit.\n+ * This reference must be freed with @dmem_cgroup_pool_state_put().\n+ *\n * Return: 0 on success, -EAGAIN on hitting a limit, or a negative errno on failure.\n */\n int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,\n \t\t\t struct dmem_cgroup_pool_state **ret_pool,\n-\t\t\t struct dmem_cgroup_pool_state **ret_limit_pool)\n+\t\t\t struct dmem_cgroup_pool_state **ret_limit_pool,\n+\t\t\t struct dmem_cgroup_pool_state **ret_over_high_pool)\n {\n \tstruct dmemcg_state *cg;\n \tstruct dmem_cgroup_pool_state *pool;\n@@ -661,6 +722,8 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,\n \t*ret_pool = NULL;\n \tif (ret_limit_pool)\n \t\t*ret_limit_pool = NULL;\n+\tif (ret_over_high_pool)\n+\t\t*ret_over_high_pool = NULL;\n \n \t/*\n \t * hold on to css, as cgroup can be removed but resource\n@@ -685,6 +748,31 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,\n \t\tgoto err;\n \t}\n \n+\t/*\n+\t * Charge succeeded. Check if usage now exceeds the soft high limit on\n+\t * this pool or on any ancestor, so the caller can trigger proactive\n+\t * reclaim to bring the hierarchy back under its dmem.high threshold.\n+\t * Walking the page_counter parent chain (as dmem_cgroup_state_evict_valuable()\n+\t * does) keeps a descendant from dodging a limit that an ancestor is\n+\t * actually violating.\n+\t */\n+\tif (ret_over_high_pool) {\n+\t\tstruct page_counter *c;\n+\n+\t\tfor (c = \u0026pool-\u003ecnt; c; c = c-\u003eparent) {\n+\t\t\tstruct dmem_cgroup_pool_state *over_pool;\n+\n+\t\t\tif (page_counter_read(c) \u003c= READ_ONCE(c-\u003ehigh))\n+\t\t\t\tcontinue;\n+\n+\t\t\tover_pool = container_of(c, struct dmem_cgroup_pool_state, cnt);\n+\t\t\t*ret_over_high_pool = over_pool;\n+\t\t\tcss_get(\u0026over_pool-\u003ecs-\u003ecss);\n+\t\t\tdmemcg_pool_get(over_pool);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \t/* On success, reference from get_current_dmemcs is transferred to *ret_pool */\n \t*ret_pool = pool;\n \treturn 0;\n@@ -835,6 +923,17 @@ static ssize_t dmem_cgroup_region_low_write(struct kernfs_open_file *of,\n \treturn dmemcg_limit_write(of, buf, nbytes, off, set_resource_low);\n }\n \n+static int dmem_cgroup_region_high_show(struct seq_file *sf, void *v)\n+{\n+\treturn dmemcg_limit_show(sf, v, get_resource_high);\n+}\n+\n+static ssize_t dmem_cgroup_region_high_write(struct kernfs_open_file *of,\n+\t\t\t\t\t char *buf, size_t nbytes, loff_t off)\n+{\n+\treturn dmemcg_limit_write(of, buf, nbytes, off, set_resource_high);\n+}\n+\n static int dmem_cgroup_region_max_show(struct seq_file *sf, void *v)\n {\n \treturn dmemcg_limit_show(sf, v, get_resource_max);\n@@ -868,6 +967,12 @@ static struct cftype files[] = {\n \t\t.seq_show = dmem_cgroup_region_low_show,\n \t\t.flags = CFTYPE_NOT_ON_ROOT,\n \t},\n+\t{\n+\t\t.name = \"high\",\n+\t\t.write = dmem_cgroup_region_high_write,\n+\t\t.seq_show = dmem_cgroup_region_high_show,\n+\t\t.flags = CFTYPE_NOT_ON_ROOT,\n+\t},\n \t{\n \t\t.name = \"max\",\n \t\t.write = dmem_cgroup_region_max_write,\n"
} |
| 2/1 | 2026/09/23 02:59 | agent | patch-evaluator |
3mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch implements proactive reclaim and high watermark threshold handling for the dmem cgroup controller and DRM TTM. All runtime code paths introduced or modified (including proactive eviction in ttm_bo.c, dmem charge tracking, high limit checks, and the dmem.high cgroup control interface) strictly require registered dmem memory regions and a configured TTM manager cgroup (man-\u003ecg). The only drivers in the kernel that register dmem regions and set man-\u003ecg are amdgpu and Intel xe, both of which require physical GPU ASICs that are not emulated in standard virtualized environments (QEMU/syzkaller). Without registered regions, cgroup operations on dmem.high fail immediately with -EINVAL or return 0, leaving all modified logic structurally unreachable.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 8d7a6557f245829a62c6bab85d3edfd95d8a40c5
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Sep 23 02:59:23 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c
index f3103307b5df9..7a03f6a04f4e8 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c
+++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c
@@ -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->priority = bo_prio;
- err = ttm_resource_alloc(bo, place, &res1, NULL);
+ err = ttm_resource_alloc(bo, place, &res1, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
bo->resource = res1;
/* Add a dummy resource to populate LRU */
- ttm_resource_alloc(bo, place, &res2, NULL);
+ ttm_resource_alloc(bo, place, &res2, NULL, NULL);
dma_resv_lock(bo->base.resv, NULL);
ttm_bo_unreserve(bo);
@@ -300,12 +300,12 @@ static void ttm_bo_unreserve_pinned(struct kunit *test)
dma_resv_lock(bo->base.resv, NULL);
ttm_bo_pin(bo);
- err = ttm_resource_alloc(bo, place, &res1, NULL);
+ err = ttm_resource_alloc(bo, place, &res1, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
bo->resource = res1;
/* Add a dummy resource to the pinned list */
- err = ttm_resource_alloc(bo, place, &res2, NULL);
+ err = ttm_resource_alloc(bo, place, &res2, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
KUNIT_ASSERT_EQ(test,
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);
dma_resv_unlock(bo1->base.resv);
- err = ttm_resource_alloc(bo1, place, &res1, NULL);
+ err = ttm_resource_alloc(bo1, place, &res1, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
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);
dma_resv_unlock(bo2->base.resv);
- err = ttm_resource_alloc(bo2, place, &res2, NULL);
+ err = ttm_resource_alloc(bo2, place, &res2, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
bo2->resource = res2;
@@ -401,7 +401,7 @@ static void ttm_bo_fini_basic(struct kunit *test)
bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
bo->type = ttm_bo_type_device;
- err = ttm_resource_alloc(bo, place, &res, NULL);
+ err = ttm_resource_alloc(bo, place, &res, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
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);
- err = ttm_resource_alloc(bo, place, &res, NULL);
+ err = ttm_resource_alloc(bo, place, &res, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
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);
- err = ttm_resource_alloc(bo, place, &res, NULL);
+ err = ttm_resource_alloc(bo, place, &res, NULL, NULL);
KUNIT_ASSERT_EQ(test, err, 0);
bo->resource = res;
diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
index 2db221f6fc3a1..cd40f5b2ab4f1 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
+++ b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
@@ -547,7 +547,7 @@ static void ttm_bo_validate_no_placement_signaled(struct kunit *test)
ttm_bo_reserve(bo, false, false, NULL);
- err = ttm_resource_alloc(bo, place, &bo->resource, NULL);
+ err = ttm_resource_alloc(bo, place, &bo->resource, NULL, NULL);
KUNIT_EXPECT_EQ(test, err, 0);
KUNIT_ASSERT_EQ(test, man->usage, size);
@@ -604,7 +604,7 @@ static void ttm_bo_validate_no_placement_not_signaled(struct kunit *test)
bo = ttm_bo_kunit_init(test, test->priv, size, NULL);
bo->type = params->bo_type;
- err = ttm_resource_alloc(bo, place, &bo->resource, NULL);
+ err = ttm_resource_alloc(bo, place, &bo->resource, NULL, NULL);
KUNIT_EXPECT_EQ(test, err, 0);
placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL);
diff --git a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c
index c0e4e35e04426..41fe4d89cd714 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c
+++ b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c
@@ -303,7 +303,7 @@ static void ttm_sys_man_free_basic(struct kunit *test)
res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, res);
- ttm_resource_alloc(bo, place, &res, NULL);
+ ttm_resource_alloc(bo, place, &res, NULL, NULL);
man = ttm_manager_type(priv->devs->ttm_dev, mem_type);
man->func->free(man, res);
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index bcd76f6bb7f02..91f9889b3d079 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -505,6 +505,8 @@ struct ttm_bo_evict_walk {
/** @limit_pool: Which pool limit we should test against */
struct dmem_cgroup_pool_state *limit_pool;
+ /** @try_high: Whether to only evict BO's above the high watermark (first pass) */
+ bool try_high;
/** @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) */
@@ -518,7 +520,8 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *
s64 lret;
if (!dmem_cgroup_state_evict_valuable(evict_walk->limit_pool, bo->resource->css,
- evict_walk->try_low, &evict_walk->hit_low))
+ evict_walk->try_high, evict_walk->try_low,
+ &evict_walk->hit_low))
return 0;
if (bo->pin_count || !bo->bdev->funcs->eviction_valuable(bo, evict_walk->place))
@@ -538,7 +541,7 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *
evict_walk->evicted++;
if (evict_walk->res)
lret = ttm_resource_alloc(evict_walk->evictor, evict_walk->place,
- evict_walk->res, NULL);
+ evict_walk->res, NULL, NULL);
if (lret == 0)
return 1;
out:
@@ -553,6 +556,42 @@ static const struct ttm_lru_walk_ops ttm_evict_walk_ops = {
.process_bo = ttm_bo_evict_cb,
};
+/*
+ * Proactive reclaim: evict one BO from a cgroup that exceeds its dmem.high
+ * soft limit. Called after a successful charge that pushed usage over the
+ * high threshold. Best-effort; allocation already succeeded (soft limit).
+ *
+ * Returns the ttm_lru_walk_for_evict() result so callers using a ww_mutex
+ * ticket can detect -EDEADLK and run the required backoff instead of it
+ * being silently swallowed.
+ */
+static s64 ttm_bo_proactive_evict_high(struct ttm_device *bdev,
+ struct ttm_resource_manager *man,
+ const struct ttm_place *place,
+ struct ttm_buffer_object *evictor,
+ struct ttm_operation_ctx *ctx,
+ struct ww_acquire_ctx *ticket,
+ struct dmem_cgroup_pool_state *over_high_pool)
+{
+ struct ttm_bo_evict_walk evict_walk = {
+ .walk = {
+ .ops = &ttm_evict_walk_ops,
+ .arg = {
+ .ctx = ctx,
+ .ticket = ticket,
+ .trylock_only = !ticket,
+ }
+ },
+ .place = place,
+ .evictor = evictor,
+ .res = NULL,
+ .limit_pool = over_high_pool,
+ .try_high = true,
+ };
+
+ return ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
+}
+
static int ttm_bo_evict_alloc(struct ttm_device *bdev,
struct ttm_resource_manager *man,
const struct ttm_place *place,
@@ -579,29 +618,24 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
evict_walk.walk.arg.trylock_only = true;
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)
goto out;
- /* Reset low limit */
evict_walk.try_low = evict_walk.hit_low = false;
- /* If ticket-locking, repeat while making progress. */
evict_walk.walk.arg.trylock_only = false;
retry:
do {
- /* The walk may clear the evict_walk.walk.ticket field */
evict_walk.walk.arg.ticket = ticket;
evict_walk.evicted = 0;
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
} 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;
@@ -737,7 +771,26 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
continue;
may_evict = (force_space && place->mem_type != TTM_PL_SYSTEM);
- ret = ttm_resource_alloc(bo, place, res, force_space ? &limit_pool : NULL);
+ {
+ struct dmem_cgroup_pool_state *over_high_pool = NULL;
+
+ ret = ttm_resource_alloc(bo, place, res,
+ force_space ? &limit_pool : NULL,
+ &over_high_pool);
+ if (!ret && over_high_pool) {
+ s64 evict_ret;
+
+ evict_ret = ttm_bo_proactive_evict_high(bdev, man, place,
+ bo, ctx, ticket,
+ over_high_pool);
+ if (evict_ret < 0) {
+ dmem_cgroup_pool_state_put(over_high_pool);
+ ttm_resource_free(bo, res);
+ return evict_ret;
+ }
+ }
+ dmem_cgroup_pool_state_put(over_high_pool);
+ }
if (ret) {
if (ret != -ENOSPC) {
dmem_cgroup_pool_state_put(limit_pool);
@@ -1152,7 +1205,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
memset(&hop, 0, sizeof(hop));
place.mem_type = TTM_PL_SYSTEM;
- ret = ttm_resource_alloc(bo, &place, &evict_mem, NULL);
+ ret = ttm_resource_alloc(bo, &place, &evict_mem, NULL, NULL);
if (ret)
goto out;
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 154d6739256f8..aca133a331063 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -389,7 +389,8 @@ EXPORT_SYMBOL(ttm_resource_fini);
int ttm_resource_alloc(struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res_ptr,
- struct dmem_cgroup_pool_state **ret_limit_pool)
+ struct dmem_cgroup_pool_state **ret_limit_pool,
+ struct dmem_cgroup_pool_state **ret_over_high_pool)
{
struct ttm_resource_manager *man =
ttm_manager_type(bo->bdev, place->mem_type);
@@ -397,7 +398,8 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
int ret;
if (man->cg) {
- ret = dmem_cgroup_try_charge(man->cg, bo->base.size, &pool, ret_limit_pool);
+ ret = dmem_cgroup_try_charge(man->cg, bo->base.size, &pool,
+ ret_limit_pool, ret_over_high_pool);
if (ret) {
if (ret == -EAGAIN)
ret = -ENOSPC;
@@ -409,6 +411,10 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
if (ret) {
if (pool)
dmem_cgroup_uncharge(pool, bo->base.size);
+ if (ret_over_high_pool) {
+ dmem_cgroup_pool_state_put(*ret_over_high_pool);
+ *ret_over_high_pool = NULL;
+ }
return ret;
}
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index a5d386583fb6e..88fb402acfdc6 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -461,7 +461,8 @@ void ttm_resource_fini(struct ttm_resource_manager *man,
int ttm_resource_alloc(struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res,
- struct dmem_cgroup_pool_state **ret_limit_pool);
+ struct dmem_cgroup_pool_state **ret_limit_pool,
+ struct dmem_cgroup_pool_state **ret_over_high_pool);
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
bool ttm_resource_intersects(struct ttm_device *bdev,
struct ttm_resource *res,
diff --git a/include/linux/cgroup_dmem.h b/include/linux/cgroup_dmem.h
index dd4869f1d736e..1808bfbbc9a31 100644
--- a/include/linux/cgroup_dmem.h
+++ b/include/linux/cgroup_dmem.h
@@ -19,11 +19,12 @@ struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *nam
void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region);
int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
struct dmem_cgroup_pool_state **ret_pool,
- struct dmem_cgroup_pool_state **ret_limit_pool);
+ struct dmem_cgroup_pool_state **ret_limit_pool,
+ struct dmem_cgroup_pool_state **ret_over_high_pool);
void dmem_cgroup_uncharge(struct dmem_cgroup_pool_state *pool, u64 size);
bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,
struct dmem_cgroup_pool_state *test_pool,
- bool ignore_low, bool *ret_hit_low);
+ bool try_high, bool ignore_low, bool *ret_hit_low);
void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool);
#else
@@ -38,13 +39,17 @@ static inline void dmem_cgroup_unregister_region(struct dmem_cgroup_region *regi
static inline int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
struct dmem_cgroup_pool_state **ret_pool,
- struct dmem_cgroup_pool_state **ret_limit_pool)
+ struct dmem_cgroup_pool_state **ret_limit_pool,
+ struct dmem_cgroup_pool_state **ret_over_high_pool)
{
*ret_pool = NULL;
if (ret_limit_pool)
*ret_limit_pool = NULL;
+ if (ret_over_high_pool)
+ *ret_over_high_pool = NULL;
+
return 0;
}
@@ -54,8 +59,10 @@ static inline void dmem_cgroup_uncharge(struct dmem_cgroup_pool_state *pool, u64
static inline
bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,
struct dmem_cgroup_pool_state *test_pool,
- bool ignore_low, bool *ret_hit_low)
+ bool try_high, bool ignore_low, bool *ret_hit_low)
{
+ if (try_high)
+ return false;
return true;
}
diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
index 4753a67d0f0f2..e314943290612 100644
--- a/kernel/cgroup/dmem.c
+++ b/kernel/cgroup/dmem.c
@@ -156,6 +156,12 @@ set_resource_low(struct dmem_cgroup_pool_state *pool, u64 val)
page_counter_set_low(&pool->cnt, val);
}
+static void
+set_resource_high(struct dmem_cgroup_pool_state *pool, u64 val)
+{
+ page_counter_set_high(&pool->cnt, val);
+}
+
static void
set_resource_max(struct dmem_cgroup_pool_state *pool, u64 val)
{
@@ -167,6 +173,11 @@ static u64 get_resource_low(struct dmem_cgroup_pool_state *pool)
return pool ? READ_ONCE(pool->cnt.low) : 0;
}
+static u64 get_resource_high(struct dmem_cgroup_pool_state *pool)
+{
+ return pool ? READ_ONCE(pool->cnt.high) : PAGE_COUNTER_MAX;
+}
+
static u64 get_resource_min(struct dmem_cgroup_pool_state *pool)
{
return pool ? READ_ONCE(pool->cnt.min) : 0;
@@ -186,6 +197,7 @@ static void reset_all_resource_limits(struct dmem_cgroup_pool_state *rpool)
{
set_resource_min(rpool, 0);
set_resource_low(rpool, 0);
+ set_resource_high(rpool, PAGE_COUNTER_MAX);
set_resource_max(rpool, PAGE_COUNTER_MAX);
}
@@ -289,10 +301,13 @@ dmem_cgroup_calculate_protection(struct dmem_cgroup_pool_state *limit_pool,
* dmem_cgroup_state_evict_valuable() - Check if we should evict from test_pool
* @limit_pool: The pool for which we hit limits
* @test_pool: The pool for which to test
+ * @try_high: Only evict BOs whose usage exceeds the high limit (first pass)
* @ignore_low: Whether we have to respect low watermarks.
* @ret_hit_low: Pointer to whether it makes sense to consider low watermark.
*
* This function returns true if we can evict from @test_pool, false if not.
+ * When @try_high is set, only pools with usage above their high limit are
+ * evictable, enabling prioritized eviction of over-limit cgroups.
* When returning false and @ignore_low is false, @ret_hit_low may
* be set to true to indicate this function can be retried with @ignore_low
* set to true.
@@ -301,15 +316,26 @@ dmem_cgroup_calculate_protection(struct dmem_cgroup_pool_state *limit_pool,
*/
bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,
struct dmem_cgroup_pool_state *test_pool,
- bool ignore_low, bool *ret_hit_low)
+ bool try_high, bool ignore_low, bool *ret_hit_low)
{
struct dmem_cgroup_pool_state *pool = test_pool;
struct page_counter *ctest;
u64 used, min, low;
- /* Can always evict from current pool, despite limits */
- if (limit_pool == test_pool)
+ /*
+ * When the limit-hitting cgroup's own BOs are being considered
+ * in try_high mode, only evict them if their pool exceeds its
+ * own dmem.high limit. For non-try_high mode, maintain the
+ * existing behavior: always evict from the limit-hitting pool.
+ */
+ if (limit_pool == test_pool) {
+ if (try_high && test_pool) {
+ ctest = &test_pool->cnt;
+ used = page_counter_read(ctest);
+ return used > READ_ONCE(ctest->high);
+ }
return true;
+ }
if (limit_pool) {
if (!parent_dmemcs(limit_pool->cs))
@@ -330,10 +356,38 @@ bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool,
}
ctest = &test_pool->cnt;
+ used = page_counter_read(ctest);
+
+ if (try_high) {
+ struct page_counter *c;
+
+ /*
+ * Walk the page_counter parent chain to check whether any
+ * ancestor cgroup exceeds its dmem.high limit. This prevents
+ * child cgroups from evading the penalty when a parent cgroup
+ * is over its high limit.
+ */
+ if (used <= READ_ONCE(ctest->high)) {
+ for (c = ctest->parent; c; c = c->parent) {
+ if (page_counter_read(c) > READ_ONCE(c->high))
+ break;
+ }
+ if (!c)
+ return false;
+ }
+
+ /*
+ * Respect dmem.min protection: do not evict BOs below the
+ * effective minimum even during the high-priority pass.
+ */
+ dmem_cgroup_calculate_protection(limit_pool, test_pool);
+ min = READ_ONCE(ctest->emin);
+
+ return used > min;
+ }
dmem_cgroup_calculate_protection(limit_pool, test_pool);
- used = page_counter_read(ctest);
min = READ_ONCE(ctest->emin);
if (used <= min)
@@ -634,8 +688,9 @@ EXPORT_SYMBOL_GPL(dmem_cgroup_uncharge);
* dmem_cgroup_try_charge() - Try charging a new allocation to a region.
* @region: dmem region to charge
* @size: Size (in bytes) to charge.
- * @ret_pool: On succesfull allocation, the pool that is charged.
+ * @ret_pool: On successful allocation, the pool that is charged.
* @ret_limit_pool: On a failed allocation, the limiting pool.
+ * @ret_over_high_pool: On successful allocation, set if usage exceeds dmem.high.
*
* This function charges the @region region for a size of @size bytes.
*
@@ -647,11 +702,17 @@ EXPORT_SYMBOL_GPL(dmem_cgroup_uncharge);
* eviction as argument to dmem_cgroup_evict_valuable(). This reference must be freed
* with @dmem_cgroup_pool_state_put().
*
+ * When the function succeeds and @ret_over_high_pool is non-null, it will be
+ * set if the charged pool's usage now exceeds its dmem.high soft limit. The
+ * caller should trigger proactive eviction to bring usage back under the limit.
+ * This reference must be freed with @dmem_cgroup_pool_state_put().
+ *
* Return: 0 on success, -EAGAIN on hitting a limit, or a negative errno on failure.
*/
int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
struct dmem_cgroup_pool_state **ret_pool,
- struct dmem_cgroup_pool_state **ret_limit_pool)
+ struct dmem_cgroup_pool_state **ret_limit_pool,
+ struct dmem_cgroup_pool_state **ret_over_high_pool)
{
struct dmemcg_state *cg;
struct dmem_cgroup_pool_state *pool;
@@ -661,6 +722,8 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
*ret_pool = NULL;
if (ret_limit_pool)
*ret_limit_pool = NULL;
+ if (ret_over_high_pool)
+ *ret_over_high_pool = NULL;
/*
* hold on to css, as cgroup can be removed but resource
@@ -685,6 +748,31 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
goto err;
}
+ /*
+ * Charge succeeded. Check if usage now exceeds the soft high limit on
+ * this pool or on any ancestor, so the caller can trigger proactive
+ * reclaim to bring the hierarchy back under its dmem.high threshold.
+ * Walking the page_counter parent chain (as dmem_cgroup_state_evict_valuable()
+ * does) keeps a descendant from dodging a limit that an ancestor is
+ * actually violating.
+ */
+ if (ret_over_high_pool) {
+ struct page_counter *c;
+
+ for (c = &pool->cnt; c; c = c->parent) {
+ struct dmem_cgroup_pool_state *over_pool;
+
+ if (page_counter_read(c) <= READ_ONCE(c->high))
+ continue;
+
+ over_pool = container_of(c, struct dmem_cgroup_pool_state, cnt);
+ *ret_over_high_pool = over_pool;
+ css_get(&over_pool->cs->css);
+ dmemcg_pool_get(over_pool);
+ break;
+ }
+ }
+
/* On success, reference from get_current_dmemcs is transferred to *ret_pool */
*ret_pool = pool;
return 0;
@@ -835,6 +923,17 @@ static ssize_t dmem_cgroup_region_low_write(struct kernfs_open_file *of,
return dmemcg_limit_write(of, buf, nbytes, off, set_resource_low);
}
+static int dmem_cgroup_region_high_show(struct seq_file *sf, void *v)
+{
+ return dmemcg_limit_show(sf, v, get_resource_high);
+}
+
+static ssize_t dmem_cgroup_region_high_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ return dmemcg_limit_write(of, buf, nbytes, off, set_resource_high);
+}
+
static int dmem_cgroup_region_max_show(struct seq_file *sf, void *v)
{
return dmemcg_limit_show(sf, v, get_resource_max);
@@ -868,6 +967,12 @@ static struct cftype files[] = {
.seq_show = dmem_cgroup_region_low_show,
.flags = CFTYPE_NOT_ON_ROOT,
},
+ {
+ .name = "high",
+ .write = dmem_cgroup_region_high_write,
+ .seq_show = dmem_cgroup_region_high_show,
+ .flags = CFTYPE_NOT_ON_ROOT,
+ },
{
.name = "max",
.write = dmem_cgroup_region_max_write,
|
| 3/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11619 output: 29 thoughts: 63 Thoughts: Okay, let's dive into this patch. **Analyzing the DRM TTM and Cgroup Dmem Modification** Alright, so the patch is touching DRM's TTM and `kernel/cgroup/dmem.c`. My initial thought is, "Right, `dmem`. Let's refresh my memory on what exactly that is within the kernel context. What's it doing and, most importantly, how's it configured and employed?" I need a solid understanding of its purpose here. I'm going to quickly run some `grep` commands across the kernel source to get a good sense of `dmem.c` itself and where its configuration hooks reside in the Kconfig files. That'll provide a framework for fully understanding the implications of these changes. |
| 4/2 | 2026/09/23 02:59 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_CGROUP_DMEM|CGROUP_DMEM"
}Results: {
"Output": "arch/loongarch/configs/loongson32_defconfig=25=CONFIG_CGROUP_RDMA=y\narch/loongarch/configs/loongson32_defconfig:26:CONFIG_CGROUP_DMEM=y\narch/loongarch/configs/loongson32_defconfig-27-CONFIG_CGROUP_FREEZER=y\n--\narch/loongarch/configs/loongson64_defconfig=28=CONFIG_CGROUP_RDMA=y\narch/loongarch/configs/loongson64_defconfig:29:CONFIG_CGROUP_DMEM=y\narch/loongarch/configs/loongson64_defconfig-30-CONFIG_CGROUP_FREEZER=y\n--\ninclude/linux/cgroup_dmem.h-5-\ninclude/linux/cgroup_dmem.h:6:#ifndef _CGROUP_DMEM_H\ninclude/linux/cgroup_dmem.h:7:#define _CGROUP_DMEM_H\ninclude/linux/cgroup_dmem.h-8-\n--\ninclude/linux/cgroup_dmem.h=15=struct dmem_cgroup_region;\ninclude/linux/cgroup_dmem.h-16-\ninclude/linux/cgroup_dmem.h:17:#if IS_ENABLED(CONFIG_CGROUP_DMEM)\ninclude/linux/cgroup_dmem.h-18-struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *name_fmt, ...) __printf(2,3);\n--\ninclude/linux/cgroup_dmem.h=69=static inline void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool)\n--\ninclude/linux/cgroup_dmem.h-72-#endif\ninclude/linux/cgroup_dmem.h:73:#endif\t/* _CGROUP_DMEM_H */\n--\ninclude/linux/cgroup_subsys.h=65=SUBSYS(misc)\n--\ninclude/linux/cgroup_subsys.h-67-\ninclude/linux/cgroup_subsys.h:68:#if IS_ENABLED(CONFIG_CGROUP_DMEM)\ninclude/linux/cgroup_subsys.h-69-SUBSYS(dmem)\n--\ninclude/linux/page_counter.h=90=static inline void page_counter_reset_watermark(struct page_counter *counter)\n--\ninclude/linux/page_counter.h-101-\ninclude/linux/page_counter.h:102:#if IS_ENABLED(CONFIG_MEMCG) || IS_ENABLED(CONFIG_CGROUP_DMEM)\ninclude/linux/page_counter.h-103-void page_counter_calculate_protection(struct page_counter *root,\n--\ninit/Kconfig=1239=config CGROUP_RDMA\n--\ninit/Kconfig-1248-\ninit/Kconfig:1249:config CGROUP_DMEM\ninit/Kconfig-1250-\tbool \"Device memory controller (DMEM)\"\n--\nkernel/cgroup/Makefile=9=obj-$(CONFIG_CGROUP_MISC) += misc.o\nkernel/cgroup/Makefile:10:obj-$(CONFIG_CGROUP_DMEM) += dmem.o\nkernel/cgroup/Makefile-11-obj-$(CONFIG_CGROUP_DEBUG) += debug.o\n--\nmm/page_counter.c=272=int page_counter_memparse(const char *buf, const char *max,\n--\nmm/page_counter.c-292-\nmm/page_counter.c:293:#if IS_ENABLED(CONFIG_MEMCG) || IS_ENABLED(CONFIG_CGROUP_DMEM)\nmm/page_counter.c-294-/*\n--\nmm/page_counter.c=424=void page_counter_calculate_protection(struct page_counter *root,\n--\nmm/page_counter.c-464-}\nmm/page_counter.c:465:#endif /* CONFIG_MEMCG || CONFIG_CGROUP_DMEM */\n"
} |
| 5/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 12920 output: 33 thoughts: 30 Thoughts: Okay, let's dive into this. Here's how I'd approach that kernel configuration investigation: **Investigating CGROUP_DMEM Dependencies in Kconfig** Alright, I'm thinking, "Let's get down to the nitty-gritty. To fully understand the landscape surrounding `CGROUP_DMEM`, I need to see what other configurations or features it's tied to." My initial instinct is to go directly to the source - the `init/Kconfig` file, specifically around line 1249. That's usually where these things are defined, and I expect to see the dependencies clearly laid out there. Hopefully, the Kconfig entry is well-written and includes clear `depends on` statements. This should quickly reveal the prerequisite configurations and potentially illuminate the reasoning behind those dependencies. I'm hoping to get a clear picture of its role within the kernel's overall configuration ecosystem. I'm expecting to use this information to determine how this feature works with other features. |
| 6/2 | 2026/09/23 02:59 | tool | read-file |
0mArgs:{
"File": "init/Kconfig",
"FirstLine": 1245,
"LineCount": 20
}Results: {
"Contents": "1245:\t\t RDMA controller is designed to stop this from happening.\n1246:\t\t Attaching processes with active RDMA resources to the cgroup\n1247:\t\t hierarchy is allowed even if can cross the hierarchy's limit.\n1248:\t\n1249:\tconfig CGROUP_DMEM\n1250:\t\tbool \"Device memory controller (DMEM)\"\n1251:\t\tselect PAGE_COUNTER\n1252:\t\thelp\n1253:\t\t The DMEM controller allows compatible devices to restrict device\n1254:\t\t memory usage based on the cgroup hierarchy.\n1255:\t\n1256:\t\t As an example, it allows you to restrict VRAM usage for applications\n1257:\t\t in the DRM subsystem.\n1258:\t\n1259:\tconfig CGROUP_FREEZER\n1260:\t\tbool \"Freezer controller\"\n1261:\t\thelp\n1262:\t\t Provides a way to freeze and unfreeze all tasks in a\n1263:\t\t cgroup.\n1264:\t\n"
} |
| 7/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13482 output: 23 thoughts: 70 Thoughts: **Investigating Potential Compatibility Issues in Virtualized Environments** Okay, so I'm trying to figure out if there's a potential problem with how certain drivers or devices interact with virtualized environments like QEMU. My thinking is, let's focus on two key areas: the `dmem_cgroup_register_region` function and the TTM (Translation Table Manager) resource allocation functions, specifically `ttm_resource_alloc`. These are the most likely points of interaction that I should focus on. The question I'm trying to answer is: Can TTM and `dmem` specifically be reached and used as intended within a virtualized setting? If they're not fully compatible, or there are any unexpected behaviours, I need to understand them. To begin, I should just start by searching for instances of where the `dmem_cgroup_register_region` function is used. That'll provide a foundation for further exploration. |
| 8/2 | 2026/09/23 02:59 | tool | grepper |
0mArgs:{
"Expression": "dmem_cgroup_register_region"
}Results: {
"Output": "drivers/gpu/drm/drm_drv.c=964=struct dmem_cgroup_region *drmm_cgroup_register_region(struct drm_device *dev, const char *region_name, u64 size)\n--\ndrivers/gpu/drm/drm_drv.c-968-\ndrivers/gpu/drm/drm_drv.c:969:\tregion = dmem_cgroup_register_region(size, \"drm/%s/%s\", dev-\u003eunique, region_name);\ndrivers/gpu/drm/drm_drv.c-970-\tif (IS_ERR_OR_NULL(region))\n--\ninclude/linux/cgroup_dmem.h=15=struct dmem_cgroup_region;\n--\ninclude/linux/cgroup_dmem.h-17-#if IS_ENABLED(CONFIG_CGROUP_DMEM)\ninclude/linux/cgroup_dmem.h:18:struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *name_fmt, ...) __printf(2,3);\ninclude/linux/cgroup_dmem.h-19-void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region);\n--\ninclude/linux/cgroup_dmem.h=31=static inline __printf(2,3) struct dmem_cgroup_region *\ninclude/linux/cgroup_dmem.h:32:dmem_cgroup_register_region(u64 size, const char *name_fmt, ...)\ninclude/linux/cgroup_dmem.h-33-{\n--\nkernel/cgroup/dmem.c=21=struct dmem_cgroup_region {\n--\nkernel/cgroup/dmem.c-45-\nkernel/cgroup/dmem.c:46:\t/** @name: Name describing the node, set by dmem_cgroup_register_region */\nkernel/cgroup/dmem.c-47-\tchar *name;\n--\nkernel/cgroup/dmem.c=509=static void dmemcg_free_region(struct kref *ref)\n--\nkernel/cgroup/dmem.c-519- *\nkernel/cgroup/dmem.c:520: * This function undoes dmem_cgroup_register_region.\nkernel/cgroup/dmem.c-521- */\n--\nkernel/cgroup/dmem.c=550=EXPORT_SYMBOL_GPL(dmem_cgroup_unregister_region);\n--\nkernel/cgroup/dmem.c-552-/**\nkernel/cgroup/dmem.c:553: * dmem_cgroup_register_region() - Register a regions for dev cgroup.\nkernel/cgroup/dmem.c-554- * @size: Size of region to register, in bytes.\n--\nkernel/cgroup/dmem.c-562- */\nkernel/cgroup/dmem.c:563:struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *fmt, ...)\nkernel/cgroup/dmem.c-564-{\n--\nkernel/cgroup/dmem.c-594-}\nkernel/cgroup/dmem.c:595:EXPORT_SYMBOL_GPL(dmem_cgroup_register_region);\nkernel/cgroup/dmem.c-596-\n"
} |
| 9/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14631 output: 23 thoughts: 32 Thoughts: Here's a summary of my thought process: **Investigating the Registration of a DRM CGROUP Region** Okay, so I see `drmm_cgroup_register_region` is in play. My immediate concern is *where* this function is being called from. I need to understand its context. This is crucial for performance analysis, security auditing, and resource management within the DRM (Direct Rendering Manager) framework, especially if this is related to CGROUP functionality. The first step is to quickly identify all the call sites of `drmm_cgroup_register_region`. I will need to understand the relationship between CGROUPs and DRM memory management from a systems level. Identifying the callers will enable me to comprehend the initialization process and determine what modules and subsystems are interacting with this registration process. Knowing this, I can begin to assess if this is being handled correctly within the wider system. |
| 10/2 | 2026/09/23 02:59 | tool | grepper |
0mArgs:{
"Expression": "drmm_cgroup_register_region"
}Results: {
"Output": "drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c=915=int amdgpu_vram_mgr_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-920-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921:\tman-\u003ecg = drmm_cgroup_register_region(adev_to_drm(adev), \"vram\", adev-\u003egmc.real_vram_size);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-922-\tif (IS_ERR(man-\u003ecg))\n--\ndrivers/gpu/drm/drm_drv.c=950=static void drmm_cg_unregister_region(struct drm_device *dev, void *arg)\n--\ndrivers/gpu/drm/drm_drv.c-955-/**\ndrivers/gpu/drm/drm_drv.c:956: * drmm_cgroup_register_region - Register a region of a DRM device to cgroups\ndrivers/gpu/drm/drm_drv.c-957- * @dev: device for region\n--\ndrivers/gpu/drm/drm_drv.c-963- */\ndrivers/gpu/drm/drm_drv.c:964:struct dmem_cgroup_region *drmm_cgroup_register_region(struct drm_device *dev, const char *region_name, u64 size)\ndrivers/gpu/drm/drm_drv.c-965-{\n--\ndrivers/gpu/drm/drm_drv.c-978-}\ndrivers/gpu/drm/drm_drv.c:979:EXPORT_SYMBOL_GPL(drmm_cgroup_register_region);\ndrivers/gpu/drm/drm_drv.c-980-\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c=299=int __xe_ttm_vram_mgr_init(struct xe_device *xe, struct xe_ttm_vram_mgr *mgr,\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-307-\t\tconst char *name = mem_type == XE_PL_VRAM0 ? \"vram0\" : \"vram1\";\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308:\t\tman-\u003ecg = drmm_cgroup_register_region(\u0026xe-\u003edrm, name, size);\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-309-\t\tif (IS_ERR(man-\u003ecg))\n--\ninclude/drm/drm_drv.h=440=struct dmem_cgroup_region *\ninclude/drm/drm_drv.h:441:drmm_cgroup_register_region(struct drm_device *dev,\ninclude/drm/drm_drv.h-442-\t\t\t const char *region_name, u64 size);\n"
} |
| 11/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15642 output: 18 thoughts: 80 Thoughts: Okay, here's my thought process on this, distilled into a first-person summary, keeping in mind my expertise: **Checking for Unexpected Users of `dmem_cgroup_register_region`** Right, hold on a second. I need to be absolutely sure about how widely this `dmem_cgroup_register_region` function is being used. My immediate concern is that there could be some unexpected consumers. Before I proceed, let's take a comprehensive look, in particular, I should verify if any of the following devices - `virtio-gpu`, `vgem`, `vkms`, `qxl` or `bochs` -- or any other emulated or virtualized graphics devices are somehow leveraging the TTM (Translation Table Manager) infrastructure or, critically, directly calling `dmem_cgroup_register_region` or are indirectly interacting with this through the `man->cg` field which is passed to the function! I have a strong suspicion about this. I should also pay close attention to `man->cg`, to understand its usage in relation to this function call. |
| 12/2 | 2026/09/23 02:59 | tool | grepper |
0mArgs:{
"Expression": "-\u003ecg\\b"
}Results: {
"Output": "drivers/clk/clk-qoriq.c=850=static int mux_set_parent(struct clk_hw *hw, u8 idx)\n--\ndrivers/clk/clk-qoriq.c-858-\tclksel = hwc-\u003eparent_to_clksel[idx];\ndrivers/clk/clk-qoriq.c:859:\tcg_out(hwc-\u003ecg, (clksel \u003c\u003c CLKSEL_SHIFT) \u0026 CLKSEL_MASK, hwc-\u003ereg);\ndrivers/clk/clk-qoriq.c-860-\n--\ndrivers/clk/clk-qoriq.c=864=static u8 mux_get_parent(struct clk_hw *hw)\n--\ndrivers/clk/clk-qoriq.c-869-\ndrivers/clk/clk-qoriq.c:870:\tclksel = (cg_in(hwc-\u003ecg, hwc-\u003ereg) \u0026 CLKSEL_MASK) \u003e\u003e CLKSEL_SHIFT;\ndrivers/clk/clk-qoriq.c-871-\n--\ndrivers/clk/clk-qoriq.c=911=create_mux_common(struct clockgen *cg, struct mux_hwclock *hwc,\n--\ndrivers/clk/clk-qoriq.c-958-\thwc-\u003ehw.init = \u0026init;\ndrivers/clk/clk-qoriq.c:959:\thwc-\u003ecg = cg;\ndrivers/clk/clk-qoriq.c-960-\n--\ndrivers/clk/tegra/clk-dfll.c=880=static void dfll_set_frequency_request(struct tegra_dfll *td,\n--\ndrivers/clk/tegra/clk-dfll.c-886-\ndrivers/clk/tegra/clk-dfll.c:887:\tforce_val = (req-\u003elut_index - td-\u003elut_safe) * coef / td-\u003ecg;\ndrivers/clk/tegra/clk-dfll.c-888-\tforce_val = clamp(force_val, FORCE_MIN, FORCE_MAX);\n--\ndrivers/clk/tegra/clk-dfll.c=1396=static void dfll_set_default_params(struct tegra_dfll *td)\n--\ndrivers/clk/tegra/clk-dfll.c-1406-\t\t(td-\u003eci \u003c\u003c DFLL_PARAMS_CI_PARAM_SHIFT) |\ndrivers/clk/tegra/clk-dfll.c:1407:\t\t(td-\u003ecg \u003c\u003c DFLL_PARAMS_CG_PARAM_SHIFT) |\ndrivers/clk/tegra/clk-dfll.c-1408-\t\t(td-\u003ecg_scale ? DFLL_PARAMS_CG_SCALE : 0);\n--\ndrivers/clk/tegra/clk-dfll.c=1904=static int dfll_fetch_common_params(struct tegra_dfll *td)\n--\ndrivers/clk/tegra/clk-dfll.c-1912-\tok \u0026= read_dt_param(td, \"nvidia,ci\", \u0026td-\u003eci);\ndrivers/clk/tegra/clk-dfll.c:1913:\tok \u0026= read_dt_param(td, \"nvidia,cg\", \u0026td-\u003ecg);\ndrivers/clk/tegra/clk-dfll.c-1914-\ttd-\u003ecg_scale = of_property_read_bool(td-\u003edev-\u003eof_node,\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c=915=int amdgpu_vram_mgr_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-920-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921:\tman-\u003ecg = drmm_cgroup_register_region(adev_to_drm(adev), \"vram\", adev-\u003egmc.real_vram_size);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:922:\tif (IS_ERR(man-\u003ecg))\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:923:\t\treturn PTR_ERR(man-\u003ecg);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-924-\tttm_resource_manager_init(man, \u0026adev-\u003emman.bdev,\n--\ndrivers/gpu/drm/ttm/ttm_resource.c=389=int ttm_resource_alloc(struct ttm_buffer_object *bo,\n--\ndrivers/gpu/drm/ttm/ttm_resource.c-399-\ndrivers/gpu/drm/ttm/ttm_resource.c:400:\tif (man-\u003ecg) {\ndrivers/gpu/drm/ttm/ttm_resource.c:401:\t\tret = dmem_cgroup_try_charge(man-\u003ecg, bo-\u003ebase.size, \u0026pool,\ndrivers/gpu/drm/ttm/ttm_resource.c-402-\t\t\t\t\t ret_limit_pool, ret_over_high_pool);\n--\ndrivers/gpu/drm/ttm/ttm_resource.c=430=void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)\n--\ndrivers/gpu/drm/ttm/ttm_resource.c-445-\t*res = NULL;\ndrivers/gpu/drm/ttm/ttm_resource.c:446:\tif (man-\u003ecg)\ndrivers/gpu/drm/ttm/ttm_resource.c-447-\t\tdmem_cgroup_uncharge(pool, bo-\u003ebase.size);\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c=299=int __xe_ttm_vram_mgr_init(struct xe_device *xe, struct xe_ttm_vram_mgr *mgr,\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-307-\t\tconst char *name = mem_type == XE_PL_VRAM0 ? \"vram0\" : \"vram1\";\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308:\t\tman-\u003ecg = drmm_cgroup_register_region(\u0026xe-\u003edrm, name, size);\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:309:\t\tif (IS_ERR(man-\u003ecg))\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:310:\t\t\treturn PTR_ERR(man-\u003ecg);\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-311-\t}\n--\ndrivers/infiniband/core/cgroup.c=37=int ib_rdmacg_try_charge(struct ib_rdmacg_object *cg_obj,\n--\ndrivers/infiniband/core/cgroup.c-40-{\ndrivers/infiniband/core/cgroup.c:41:\treturn rdmacg_try_charge(\u0026cg_obj-\u003ecg, \u0026device-\u003ecg_device,\ndrivers/infiniband/core/cgroup.c-42-\t\t\t\t resource_index);\n--\ndrivers/infiniband/core/cgroup.c=46=void ib_rdmacg_uncharge(struct ib_rdmacg_object *cg_obj,\n--\ndrivers/infiniband/core/cgroup.c-49-{\ndrivers/infiniband/core/cgroup.c:50:\trdmacg_uncharge(cg_obj-\u003ecg, \u0026device-\u003ecg_device,\ndrivers/infiniband/core/cgroup.c-51-\t\t\tresource_index);\n"
} |
| 13/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 17943 output: 36 thoughts: 270 Thoughts: **Investigating the `dmem_cgroup_register_region` Callers** Okay, let's step back and see *who* is actually using `dmem_cgroup_register_region`. My initial grep produced `drmm_cgroup_register_region`, and then, unsurprisingly, `amdgpu_vram_mgr.c` and `xe_ttm_vram_mgr.c`. Is that *it* though? Are there any other callers lurking in the kernel? I need to be thorough here. Alright, let's drill down and see *who* is calling `drmm_cgroup_register_region`. Okay, just `amdgpu_vram_mgr.c` and `xe_ttm_vram_mgr.c`, nothing new. Wait a second... isn't the whole *point* of `dmem_cgroup_register_region` something related to cgroups themselves? Of *course*. Hang on, isn't `kernel/cgroup/dmem.c` itself a cgroup controller? Yes! That's it. It's dmem.c! Now, the important question is: can a user manipulate dmem through cgroupfs in a v2 environment? That seems like the right next question. If `dmem_cgroup_register_region` is *only* called by amdgpu and xe drivers, does *any* driver register a dmem region if there's no AMD or Intel Xe hardware present? That seems like the pertinent question for today. I need to dive into the core of this. Let's start with `kernel/cgroup/dmem.c`. I need to understand exactly how cgroups interact with dmem at a granular level. Reading `dmem.c` will give me that insight. |
| 14/2 | 2026/09/23 02:59 | tool | read-file |
0mArgs:{
"File": "kernel/cgroup/dmem.c",
"FirstLine": 1,
"LineCount": 100
}Results: {
"Contents": " 1:\t// SPDX-License-Identifier: GPL-2.0\n 2:\t/*\n 3:\t * Copyright 2023-2024 Intel Corporation (Maarten Lankhorst \u003cdev@lankhorst.se\u003e)\n 4:\t * Copyright 2024 Red Hat (Maxime Ripard \u003cmripard@kernel.org\u003e)\n 5:\t * Partially based on the rdma and misc controllers, which bear the following copyrights:\n 6:\t *\n 7:\t * Copyright 2020 Google LLC\n 8:\t * Copyright (C) 2016 Parav Pandit \u003cpandit.parav@gmail.com\u003e\n 9:\t */\n 10:\t\n 11:\t#include \u003clinux/cgroup.h\u003e\n 12:\t#include \u003clinux/cgroup_dmem.h\u003e\n 13:\t#include \u003clinux/list.h\u003e\n 14:\t#include \u003clinux/mutex.h\u003e\n 15:\t#include \u003clinux/page_counter.h\u003e\n 16:\t#include \u003clinux/parser.h\u003e\n 17:\t#include \u003clinux/refcount.h\u003e\n 18:\t#include \u003clinux/rculist.h\u003e\n 19:\t#include \u003clinux/slab.h\u003e\n 20:\t\n 21:\tstruct dmem_cgroup_region {\n 22:\t\t/**\n 23:\t\t * @ref: References keeping the region alive.\n 24:\t\t * Keeps the region reference alive after a succesful RCU lookup.\n 25:\t\t */\n 26:\t\tstruct kref ref;\n 27:\t\n 28:\t\t/** @rcu: RCU head for freeing */\n 29:\t\tstruct rcu_head rcu;\n 30:\t\n 31:\t\t/**\n 32:\t\t * @region_node: Linked into \u0026dmem_cgroup_regions list.\n 33:\t\t * Protected by RCU and global spinlock.\n 34:\t\t */\n 35:\t\tstruct list_head region_node;\n 36:\t\n 37:\t\t/**\n 38:\t\t * @pools: List of pools linked to this region.\n 39:\t\t * Protected by global spinlock only\n 40:\t\t */\n 41:\t\tstruct list_head pools;\n 42:\t\n 43:\t\t/** @size: Size of region, in bytes */\n 44:\t\tu64 size;\n 45:\t\n 46:\t\t/** @name: Name describing the node, set by dmem_cgroup_register_region */\n 47:\t\tchar *name;\n 48:\t\n 49:\t\t/**\n 50:\t\t * @unregistered: Whether the region is unregistered by its caller.\n 51:\t\t * No new pools should be added to the region afterwards.\n 52:\t\t */\n 53:\t\tbool unregistered;\n 54:\t};\n 55:\t\n 56:\tstruct dmemcg_state {\n 57:\t\tstruct cgroup_subsys_state css;\n 58:\t\n 59:\t\tstruct list_head pools;\n 60:\t};\n 61:\t\n 62:\tstruct dmem_cgroup_pool_state {\n 63:\t\tstruct dmem_cgroup_region *region;\n 64:\t\tstruct dmemcg_state *cs;\n 65:\t\n 66:\t\t/* css node, RCU protected against region teardown */\n 67:\t\tstruct list_head\tcss_node;\n 68:\t\n 69:\t\t/* dev node, no RCU protection required */\n 70:\t\tstruct list_head\tregion_node;\n 71:\t\n 72:\t\tstruct rcu_head rcu;\n 73:\t\n 74:\t\tstruct page_counter cnt;\n 75:\t\tstruct dmem_cgroup_pool_state *parent;\n 76:\t\n 77:\t\trefcount_t ref;\n 78:\t\tbool inited;\n 79:\t};\n 80:\t\n 81:\t/*\n 82:\t * 3 operations require locking protection:\n 83:\t * - Registering and unregistering region to/from list, requires global lock.\n 84:\t * - Adding a dmem_cgroup_pool_state to a CSS, removing when CSS is freed.\n 85:\t * - Adding a dmem_cgroup_pool_state to a region list.\n 86:\t *\n 87:\t * Since for the most common operations RCU provides enough protection, I\n 88:\t * do not think more granular locking makes sense. Most protection is offered\n 89:\t * by RCU and the lockless operating page_counter.\n 90:\t */\n 91:\tstatic DEFINE_SPINLOCK(dmemcg_lock);\n 92:\tstatic LIST_HEAD(dmem_cgroup_regions);\n 93:\t\n 94:\tstatic void dmemcg_free_region(struct kref *ref);\n 95:\tstatic void dmemcg_pool_free_rcu(struct rcu_head *rcu);\n 96:\t\n 97:\tstatic inline struct dmemcg_state *\n 98:\tcss_to_dmemcs(struct cgroup_subsys_state *css)\n 99:\t{\n 100:\t\treturn container_of(css, struct dmemcg_state, css);\n"
} |
| 15/2 | 2026/09/23 02:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 20005 output: 37 thoughts: 84 Thoughts: Okay, let's break this down. **Diving into cgroup dmem operations** Alright, so I'm trying to understand how dynamic memory (`dmem`) is handled within the cgroup framework. My initial thought process is to trace what happens when a new cgroup is created or when there are reads and writes to the cgroup filesystem, specifically focusing on how it relates to dynamic memory management. My first move is to look at the `kernel/cgroup/dmem.c` file. This seems like the most logical starting point for understanding dynamic memory related activities in the context of cgroups. I've got my eye on the `files[]` array within that file. I expect it to hold the file operations relevant to the `dmem` subsystem. Specifically, I'm noting the functions `dmem_cgroup_region_high_write` and `dmem_cgroup_region_high_show`. These names hint at operations related to writing and displaying (showing) high-priority memory regions within a cgroup. Now, I need to figure out how this `files[]` structure is actually registered within the cgroup framework and, more importantly, *how* those `write` and `show` functions are actually used. That's the key to understanding how dynamic memory limits and accounting are enforced at the cgroup level. |
| 16/2 | 2026/09/23 03:00 | tool | read-file |
0mArgs:{
"File": "kernel/cgroup/dmem.c",
"FirstLine": 950,
"LineCount": 60
}Results: {
"Contents": " 950:\t\t\t.name = \"capacity\",\n 951:\t\t\t.seq_show = dmem_cgroup_region_capacity_show,\n 952:\t\t\t.flags = CFTYPE_ONLY_ON_ROOT,\n 953:\t\t},\n 954:\t\t{\n 955:\t\t\t.name = \"current\",\n 956:\t\t\t.seq_show = dmem_cgroup_region_current_show,\n 957:\t\t},\n 958:\t\t{\n 959:\t\t\t.name = \"min\",\n 960:\t\t\t.write = dmem_cgroup_region_min_write,\n 961:\t\t\t.seq_show = dmem_cgroup_region_min_show,\n 962:\t\t\t.flags = CFTYPE_NOT_ON_ROOT,\n 963:\t\t},\n 964:\t\t{\n 965:\t\t\t.name = \"low\",\n 966:\t\t\t.write = dmem_cgroup_region_low_write,\n 967:\t\t\t.seq_show = dmem_cgroup_region_low_show,\n 968:\t\t\t.flags = CFTYPE_NOT_ON_ROOT,\n 969:\t\t},\n 970:\t\t{\n 971:\t\t\t.name = \"high\",\n 972:\t\t\t.write = dmem_cgroup_region_high_write,\n 973:\t\t\t.seq_show = dmem_cgroup_region_high_show,\n 974:\t\t\t.flags = CFTYPE_NOT_ON_ROOT,\n 975:\t\t},\n 976:\t\t{\n 977:\t\t\t.name = \"max\",\n 978:\t\t\t.write = dmem_cgroup_region_max_write,\n 979:\t\t\t.seq_show = dmem_cgroup_region_max_show,\n 980:\t\t\t.flags = CFTYPE_NOT_ON_ROOT,\n 981:\t\t},\n 982:\t\t{ } /* Zero entry terminates. */\n 983:\t};\n 984:\t\n 985:\tstruct cgroup_subsys dmem_cgrp_subsys = {\n 986:\t\t.css_alloc\t= dmemcs_alloc,\n 987:\t\t.css_free\t= dmemcs_free,\n 988:\t\t.css_offline\t= dmemcs_offline,\n 989:\t\t.legacy_cftypes\t= files,\n 990:\t\t.dfl_cftypes\t= files,\n 991:\t};\n"
} |
| 17/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 21070 output: 37 thoughts: 173 Thoughts: **Understanding the "dmem" cgroup Controller** Okay, so I'm looking at this `dmem_cgrp_subsys` definition. It's clear this defines a "dmem" cgroup controller, which is interesting. Right, let's see, it looks like this `dmem` subsystem is available whether we're dealing with `cgroup v2` or the older `cgroup v1`. That's good to know for compatibility. It's integrated as a subsystem through `SUBSYS(dmem)` in `cgroup_subsys.h`. Now, if `CONFIG_CGROUP_DMEM` is enabled, and we have the cgroup filesystem mounted, I'd expect to see some files related to `dmem` in the cgroup directory. I need to understand what those files are exactly and how they're managed. I'm wondering what controls are exposed to the user. Alright, let's trace this back. I should examine how these files are exposed. I suspect there will be calls to `cgroup_add_dfl_cftypes` or `dfl_cftypes` from `cgroup_subsys`. Now, I'm thinking about the control files and what kinds of functions they support. I'm going to look at the write and show functions: specifically, `dmemcg_limit_write` and `dmemcg_limit_show`. That should give me the details on how this `dmem` controller actually works, and what limits are exposed. That's the key to understanding its purpose. |
| 18/2 | 2026/09/23 03:00 | tool | read-file |
0mArgs:{
"File": "kernel/cgroup/dmem.c",
"FirstLine": 790,
"LineCount": 60
}Results: {
"Contents": " 790:\t\trcu_read_lock();\n 791:\t\tlist_for_each_entry_rcu(region, \u0026dmem_cgroup_regions, region_node) {\n 792:\t\t\tseq_puts(sf, region-\u003ename);\n 793:\t\t\tseq_printf(sf, \" %llu\\n\", region-\u003esize);\n 794:\t\t}\n 795:\t\trcu_read_unlock();\n 796:\t\treturn 0;\n 797:\t}\n 798:\t\n 799:\tstatic int dmemcg_parse_limit(char *options, u64 *new_limit)\n 800:\t{\n 801:\t\tchar *end;\n 802:\t\n 803:\t\tif (!strcmp(options, \"max\")) {\n 804:\t\t\t*new_limit = PAGE_COUNTER_MAX;\n 805:\t\t\treturn 0;\n 806:\t\t}\n 807:\t\n 808:\t\t*new_limit = memparse(options, \u0026end);\n 809:\t\tif (*end != '\\0')\n 810:\t\t\treturn -EINVAL;\n 811:\t\n 812:\t\treturn 0;\n 813:\t}\n 814:\t\n 815:\tstatic ssize_t dmemcg_limit_write(struct kernfs_open_file *of,\n 816:\t\t\t\t\t char *buf, size_t nbytes, loff_t off,\n 817:\t\t\t\t\t void (*apply)(struct dmem_cgroup_pool_state *, u64))\n 818:\t{\n 819:\t\tstruct dmemcg_state *dmemcs = css_to_dmemcs(of_css(of));\n 820:\t\tint err = 0;\n 821:\t\n 822:\t\twhile (buf \u0026\u0026 !err) {\n 823:\t\t\tstruct dmem_cgroup_pool_state *pool = NULL;\n 824:\t\t\tchar *options, *region_name;\n 825:\t\t\tstruct dmem_cgroup_region *region;\n 826:\t\t\tu64 new_limit;\n 827:\t\n 828:\t\t\toptions = buf;\n 829:\t\t\tbuf = strchr(buf, '\\n');\n 830:\t\t\tif (buf)\n 831:\t\t\t\t*buf++ = '\\0';\n 832:\t\n 833:\t\t\toptions = strstrip(options);\n 834:\t\n 835:\t\t\t/* eat empty lines */\n 836:\t\t\tif (!options[0])\n 837:\t\t\t\tcontinue;\n 838:\t\n 839:\t\t\tregion_name = strsep(\u0026options, \" \\t\");\n 840:\t\t\tif (!region_name[0])\n 841:\t\t\t\tcontinue;\n 842:\t\n 843:\t\t\tif (!options || !*options)\n 844:\t\t\t\treturn -EINVAL;\n 845:\t\n 846:\t\t\trcu_read_lock();\n 847:\t\t\tregion = dmemcg_get_region_by_name(region_name);\n 848:\t\t\trcu_read_unlock();\n 849:\t\n"
} |
| 19/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 22464 output: 37 thoughts: 41 Thoughts: Okay, let's break this down. In the `dmemcg_limit_write` function... wait, if the `region` isn't actually *found* in the first place, what's the control flow? That's the critical question here. I need to be sure I understand the error handling or the fallback behavior. I should probably focus on lines 845-870, just to confirm. |
| 20/2 | 2026/09/23 03:00 | tool | read-file |
0mArgs:{
"File": "kernel/cgroup/dmem.c",
"FirstLine": 845,
"LineCount": 40
}Results: {
"Contents": " 845:\t\n 846:\t\t\trcu_read_lock();\n 847:\t\t\tregion = dmemcg_get_region_by_name(region_name);\n 848:\t\t\trcu_read_unlock();\n 849:\t\n 850:\t\t\tif (!region)\n 851:\t\t\t\treturn -EINVAL;\n 852:\t\n 853:\t\t\terr = dmemcg_parse_limit(options, \u0026new_limit);\n 854:\t\t\tif (err \u003c 0)\n 855:\t\t\t\tgoto out_put;\n 856:\t\n 857:\t\t\tpool = get_cg_pool_unlocked(dmemcs, region);\n 858:\t\t\tif (IS_ERR(pool)) {\n 859:\t\t\t\terr = PTR_ERR(pool);\n 860:\t\t\t\tgoto out_put;\n 861:\t\t\t}\n 862:\t\n 863:\t\t\t/* And commit */\n 864:\t\t\tapply(pool, new_limit);\n 865:\t\t\tdmemcg_pool_put(pool);\n 866:\t\n 867:\tout_put:\n 868:\t\t\tkref_put(\u0026region-\u003eref, dmemcg_free_region);\n 869:\t\t}\n 870:\t\n 871:\t\n 872:\t\treturn err ?: nbytes;\n 873:\t}\n 874:\t\n 875:\tstatic int dmemcg_limit_show(struct seq_file *sf, void *v,\n 876:\t\t\t\t u64 (*fn)(struct dmem_cgroup_pool_state *))\n 877:\t{\n 878:\t\tstruct dmemcg_state *dmemcs = css_to_dmemcs(seq_css(sf));\n 879:\t\tstruct dmem_cgroup_region *region;\n 880:\t\n 881:\t\trcu_read_lock();\n 882:\t\tlist_for_each_entry_rcu(region, \u0026dmem_cgroup_regions, region_node) {\n 883:\t\t\tstruct dmem_cgroup_pool_state *pool = find_cg_pool_locked(dmemcs, region);\n 884:\t\t\tu64 val;\n"
} |
| 21/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 23230 output: 20 thoughts: 866 Thoughts: **Analyzing the dmemcg Limit and Potential QEMU Integration** Okay, let's break this down. First, I'm looking at how the `dmemcg_limit_show` function works. It seems that when a user reads `/sys/fs/cgroup/.../dmem.high`, the system calls `dmem_cgroup_region_high_show`. This function, in turn, iterates through a list, `dmem_cgroup_regions`, using `list_for_each_entry_rcu`. Even if that list is empty, reading `dmem.high` will still lead to the execution of `dmemcg_limit_show`. But if the list is empty it only loops zero times and returns zero - so that's not a concern. Now, my key question is whether any `dmem_cgroup_region` could possibly be registered within a QEMU virtual machine environment. I need to figure out which components register these dmem regions. I've already seen that `amdgpu_vram_mgr.c` and `xe_ttm_vram_mgr.c` are involved. But, hold on... QEMU doesn't emulate AMDGPU or Intel XE directly; those are actual physical GPU cards! So that's probably not the vector. Does virtio-gpu, qxl, or any other virtual GPU in QEMU utilize dmem? I need to know. I'll search for calls to `drmm_cgroup_register_region` or `dmem_cgroup_register_region`. Quick search results: just `amdgpu` and `xe` show up. Wait, what about TTM tests? There are some relevant changes in `drivers/gpu/drm/ttm/tests/ttm_bo_test.c`, `drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c`, and `drivers/gpu/drm/ttm/tests/ttm_resource_test.c`. But those are KUnit tests. The question is whether they can somehow be triggered. Does syzkaller fuzz KUnit tests? No, Syzkaller focuses on system calls, ioctls, netlink, and file systems, not KUnit tests directly. The documentation explicitly states that KUnit tests, samples, or user-space directories don't directly affect the kernel image, and syzkaller doesn't fuzz them. Alright, what about the other parts of the patch? There were also changes to `drivers/gpu/drm/ttm/ttm_bo.c`, `drivers/gpu/drm/ttm/ttm_resource.c`, `include/drm/ttm/ttm_resource.h`, `include/linux/cgroup_dmem.h`, and `kernel/cgroup/dmem.c`. Okay, I'll need to carefully check TTM use. Does TTM *actually* get used in QEMU? I need to find out who specifically uses TTM in a standard QEMU setup. Let's grep for `ttm_bo_init_reserved`, `ttm_device_init`, or other similar TTM functions. |
| 22/2 | 2026/09/23 03:00 | tool | grepper |
0mArgs:{
"Expression": "ttm_device_init"
}Results: {
"Output": "drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c=2066=int amdgpu_ttm_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c-2072-\t/* No others user of address space so set it to 0 */\ndrivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c:2073:\tr = ttm_device_init(\u0026adev-\u003emman.bdev, \u0026amdgpu_bo_driver, adev-\u003edev,\ndrivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c-2074-\t\t\t adev_to_drm(adev)-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/drm_gem_vram_helper.c=849=static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,\n--\ndrivers/gpu/drm/drm_gem_vram_helper.c-856-\ndrivers/gpu/drm/drm_gem_vram_helper.c:857:\tret = ttm_device_init(\u0026vmm-\u003ebdev, \u0026bo_driver, dev-\u003edev,\ndrivers/gpu/drm/drm_gem_vram_helper.c-858-\t\t\t\t dev-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/i915/i915_driver.c=234=static int i915_driver_early_probe(struct drm_i915_private *dev_priv)\n--\ndrivers/gpu/drm/i915/i915_driver.c-261-\ndrivers/gpu/drm/i915/i915_driver.c:262:\tret = intel_region_ttm_device_init(dev_priv);\ndrivers/gpu/drm/i915/i915_driver.c-263-\tif (ret)\n--\ndrivers/gpu/drm/i915/intel_region_ttm.c-25-/**\ndrivers/gpu/drm/i915/intel_region_ttm.c:26: * intel_region_ttm_device_init - Initialize a TTM device\ndrivers/gpu/drm/i915/intel_region_ttm.c-27- * @dev_priv: Pointer to an i915 device private structure.\n--\ndrivers/gpu/drm/i915/intel_region_ttm.c-30- */\ndrivers/gpu/drm/i915/intel_region_ttm.c:31:int intel_region_ttm_device_init(struct drm_i915_private *dev_priv)\ndrivers/gpu/drm/i915/intel_region_ttm.c-32-{\n--\ndrivers/gpu/drm/i915/intel_region_ttm.c-34-\ndrivers/gpu/drm/i915/intel_region_ttm.c:35:\treturn ttm_device_init(\u0026dev_priv-\u003ebdev, i915_ttm_driver(),\ndrivers/gpu/drm/i915/intel_region_ttm.c-36-\t\t\t drm-\u003edev, drm-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/i915/intel_region_ttm.h=15=struct ttm_device_funcs;\ndrivers/gpu/drm/i915/intel_region_ttm.h-16-\ndrivers/gpu/drm/i915/intel_region_ttm.h:17:int intel_region_ttm_device_init(struct drm_i915_private *dev_priv);\ndrivers/gpu/drm/i915/intel_region_ttm.h-18-\n--\ndrivers/gpu/drm/i915/selftests/mock_gem_device.c=141=struct drm_i915_private *mock_gem_device(void)\n--\ndrivers/gpu/drm/i915/selftests/mock_gem_device.c-217-\ndrivers/gpu/drm/i915/selftests/mock_gem_device.c:218:\tret = intel_region_ttm_device_init(i915);\ndrivers/gpu/drm/i915/selftests/mock_gem_device.c-219-\tif (ret)\n--\ndrivers/gpu/drm/loongson/lsdc_ttm.c=539=int lsdc_ttm_init(struct lsdc_device *ldev)\n--\ndrivers/gpu/drm/loongson/lsdc_ttm.c-545-\ndrivers/gpu/drm/loongson/lsdc_ttm.c:546:\tret = ttm_device_init(\u0026ldev-\u003ebdev, \u0026lsdc_bo_driver, ddev-\u003edev,\ndrivers/gpu/drm/loongson/lsdc_ttm.c-547-\t\t\t ddev-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/nouveau/nouveau_ttm.c=262=nouveau_ttm_init(struct nouveau_drm *drm)\n--\ndrivers/gpu/drm/nouveau/nouveau_ttm.c-301-\ndrivers/gpu/drm/nouveau/nouveau_ttm.c:302:\tret = ttm_device_init(\u0026drm-\u003ettm.bdev, \u0026nouveau_bo_driver, drm-\u003edev-\u003edev,\ndrivers/gpu/drm/nouveau/nouveau_ttm.c-303-\t\t\t\t dev-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/qxl/qxl_ttm.c=191=int qxl_ttm_init(struct qxl_device *qdev)\n--\ndrivers/gpu/drm/qxl/qxl_ttm.c-196-\t/* No others user of address space so set it to 0 */\ndrivers/gpu/drm/qxl/qxl_ttm.c:197:\tr = ttm_device_init(\u0026qdev-\u003emman.bdev, \u0026qxl_bo_driver, NULL,\ndrivers/gpu/drm/qxl/qxl_ttm.c-198-\t\t\t qdev-\u003eddev.anon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/radeon/radeon_ttm.c=678=int radeon_ttm_init(struct radeon_device *rdev)\n--\ndrivers/gpu/drm/radeon/radeon_ttm.c-682-\t/* No others user of address space so set it to 0 */\ndrivers/gpu/drm/radeon/radeon_ttm.c:683:\tr = ttm_device_init(\u0026rdev-\u003emman.bdev, \u0026radeon_bo_driver, rdev-\u003edev,\ndrivers/gpu/drm/radeon/radeon_ttm.c-684-\t\t\t rdev_to_drm(rdev)-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c=12=struct ttm_device_test_case {\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-17-\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:18:static void ttm_device_init_basic(struct kunit *test)\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-19-{\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-46-\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:47:static void ttm_device_init_multiple(struct kunit *test)\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-48-{\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c=74=static void ttm_device_fini_basic(struct kunit *test)\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-96-\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:97:static void ttm_device_init_no_vma_man(struct kunit *test)\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-98-{\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c=147=KUNIT_ARRAY_PARAM(ttm_device, ttm_device_cases, ttm_device_case_desc);\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-148-\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:149:static void ttm_device_init_pools(struct kunit *test)\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-150-{\n--\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c=187=static struct kunit_case ttm_device_test_cases[] = {\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:188:\tKUNIT_CASE(ttm_device_init_basic),\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:189:\tKUNIT_CASE(ttm_device_init_multiple),\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-190-\tKUNIT_CASE(ttm_device_fini_basic),\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:191:\tKUNIT_CASE(ttm_device_init_no_vma_man),\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c:192:\tKUNIT_CASE_PARAM(ttm_device_init_pools, ttm_device_gen_params),\ndrivers/gpu/drm/ttm/tests/ttm_device_test.c-193-\t{}\n--\ndrivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c=118=static int ttm_device_kunit_init_with_funcs(struct ttm_test_devices *priv,\n--\ndrivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c-125-\ndrivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c:126:\terr = ttm_device_init(ttm, funcs, drm-\u003edev,\ndrivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c-127-\t\t\t drm-\u003eanon_inode-\u003ei_mapping,\n--\ndrivers/gpu/drm/ttm/ttm_device.c=189=EXPORT_SYMBOL(ttm_device_swapout);\n--\ndrivers/gpu/drm/ttm/ttm_device.c-191-/**\ndrivers/gpu/drm/ttm/ttm_device.c:192: * ttm_device_init\ndrivers/gpu/drm/ttm/ttm_device.c-193- *\n--\ndrivers/gpu/drm/ttm/ttm_device.c-204- */\ndrivers/gpu/drm/ttm/ttm_device.c:205:int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs,\ndrivers/gpu/drm/ttm/ttm_device.c-206-\t\t struct device *dev, struct address_space *mapping,\n--\ndrivers/gpu/drm/ttm/ttm_device.c-248-}\ndrivers/gpu/drm/ttm/ttm_device.c:249:EXPORT_SYMBOL(ttm_device_init);\ndrivers/gpu/drm/ttm/ttm_device.c-250-\n--\ndrivers/gpu/drm/vmwgfx/vmwgfx_drv.c=833=static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)\n--\ndrivers/gpu/drm/vmwgfx/vmwgfx_drv.c-1021-\ndrivers/gpu/drm/vmwgfx/vmwgfx_drv.c:1022:\tret = ttm_device_init(\u0026dev_priv-\u003ebdev, \u0026vmw_bo_driver,\ndrivers/gpu/drm/vmwgfx/vmwgfx_drv.c-1023-\t\t\t dev_priv-\u003edrm.dev,\n--\ndrivers/gpu/drm/xe/xe_device.c=438=struct xe_device *xe_device_create(struct pci_dev *pdev,\n--\ndrivers/gpu/drm/xe/xe_device.c-453-\ndrivers/gpu/drm/xe/xe_device.c:454:\terr = ttm_device_init(\u0026xe-\u003ettm, \u0026xe_ttm_funcs, xe-\u003edrm.dev,\ndrivers/gpu/drm/xe/xe_device.c-455-\t\t\t xe-\u003edrm.anon_inode-\u003ei_mapping,\n--\ninclude/drm/ttm/ttm_device.h=291=static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type,\n--\ninclude/drm/ttm/ttm_device.h-297-\ninclude/drm/ttm/ttm_device.h:298:int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs,\ninclude/drm/ttm/ttm_device.h-299-\t\t struct device *dev, struct address_space *mapping,\n"
} |
| 23/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 28284 output: 41 thoughts: 144 Thoughts: **TTM Usage in the DRM Subsystem** Alright, let's see. It appears that `drivers/gpu/drm/qxl` is leveraging TTM, specifically within `qxl_ttm.c`. Interesting. And, `drivers/gpu/drm/vmwgfx` is also a user, using TTM too, as per `vmwgfx_drv.c`. Now, `drivers/gpu/drm/drm_gem_vram_helper.c` is also making use of TTM. I wonder, who is calling that file? Let's trace the usage of `drm_gem_vram_helper.c` – ah, it's bochs, ast, and mgag200. Bochs... that's QEMU's emulated device, isn't it? Let's see what that implies in relation to bochs. |
| 24/2 | 2026/09/23 03:00 | tool | grepper |
0mArgs:{
"Expression": "drm_vram_helper|bochs",
"PathPrefix": "drivers/gpu/drm/tiny/bochs.c"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 518 lines.\nUse more precise expression if possible.\n\ndrivers/gpu/drm/tiny/bochs.c-61-\ndrivers/gpu/drm/tiny/bochs.c:62:static int bochs_modeset = -1;\ndrivers/gpu/drm/tiny/bochs.c-63-static int defx = 1024;\ndrivers/gpu/drm/tiny/bochs.c=64=static int defy = 768;\ndrivers/gpu/drm/tiny/bochs.c-65-\ndrivers/gpu/drm/tiny/bochs.c:66:module_param_named(modeset, bochs_modeset, int, 0444);\ndrivers/gpu/drm/tiny/bochs.c-67-MODULE_PARM_DESC(modeset, \"enable/disable kernel modesetting\");\n--\ndrivers/gpu/drm/tiny/bochs.c=72=MODULE_PARM_DESC(defy, \"default y resolution\");\n--\ndrivers/gpu/drm/tiny/bochs.c-75-\ndrivers/gpu/drm/tiny/bochs.c:76:enum bochs_types {\ndrivers/gpu/drm/tiny/bochs.c-77-\tBOCHS_QEMU_STDVGA,\n--\ndrivers/gpu/drm/tiny/bochs.c-81-\ndrivers/gpu/drm/tiny/bochs.c:82:struct bochs_device {\ndrivers/gpu/drm/tiny/bochs.c-83-\tstruct drm_device dev;\n--\ndrivers/gpu/drm/tiny/bochs.c-106-\ndrivers/gpu/drm/tiny/bochs.c:107:static struct bochs_device *to_bochs_device(const struct drm_device *dev)\ndrivers/gpu/drm/tiny/bochs.c-108-{\ndrivers/gpu/drm/tiny/bochs.c:109:\treturn container_of(dev, struct bochs_device, dev);\ndrivers/gpu/drm/tiny/bochs.c-110-}\n--\ndrivers/gpu/drm/tiny/bochs.c-113-\ndrivers/gpu/drm/tiny/bochs.c:114:static __always_inline bool bochs_uses_mmio(struct bochs_device *bochs)\ndrivers/gpu/drm/tiny/bochs.c-115-{\ndrivers/gpu/drm/tiny/bochs.c:116:\treturn !IS_ENABLED(CONFIG_HAS_IOPORT) || bochs-\u003emmio;\ndrivers/gpu/drm/tiny/bochs.c-117-}\ndrivers/gpu/drm/tiny/bochs.c-118-\ndrivers/gpu/drm/tiny/bochs.c:119:static void bochs_vga_writeb(struct bochs_device *bochs, u16 ioport, u8 val)\ndrivers/gpu/drm/tiny/bochs.c-120-{\n--\ndrivers/gpu/drm/tiny/bochs.c-123-\ndrivers/gpu/drm/tiny/bochs.c:124:\tif (bochs_uses_mmio(bochs)) {\ndrivers/gpu/drm/tiny/bochs.c-125-\t\tint offset = ioport - 0x3c0 + 0x400;\ndrivers/gpu/drm/tiny/bochs.c-126-\ndrivers/gpu/drm/tiny/bochs.c:127:\t\twriteb(val, bochs-\u003emmio + offset);\ndrivers/gpu/drm/tiny/bochs.c-128-\t} else {\n--\ndrivers/gpu/drm/tiny/bochs.c-132-\ndrivers/gpu/drm/tiny/bochs.c:133:static u8 bochs_vga_readb(struct bochs_device *bochs, u16 ioport)\ndrivers/gpu/drm/tiny/bochs.c-134-{\n--\ndrivers/gpu/drm/tiny/bochs.c-137-\ndrivers/gpu/drm/tiny/bochs.c:138:\tif (bochs_uses_mmio(bochs)) {\ndrivers/gpu/drm/tiny/bochs.c-139-\t\tint offset = ioport - 0x3c0 + 0x400;\ndrivers/gpu/drm/tiny/bochs.c-140-\ndrivers/gpu/drm/tiny/bochs.c:141:\t\treturn readb(bochs-\u003emmio + offset);\ndrivers/gpu/drm/tiny/bochs.c-142-\t} else {\n--\ndrivers/gpu/drm/tiny/bochs.c-146-\ndrivers/gpu/drm/tiny/bochs.c:147:static u16 bochs_dispi_read(struct bochs_device *bochs, u16 reg)\ndrivers/gpu/drm/tiny/bochs.c-148-{\n--\ndrivers/gpu/drm/tiny/bochs.c-150-\ndrivers/gpu/drm/tiny/bochs.c:151:\tif (bochs_uses_mmio(bochs)) {\ndrivers/gpu/drm/tiny/bochs.c-152-\t\tint offset = 0x500 + (reg \u003c\u003c 1);\ndrivers/gpu/drm/tiny/bochs.c-153-\ndrivers/gpu/drm/tiny/bochs.c:154:\t\tret = readw(bochs-\u003emmio + offset);\ndrivers/gpu/drm/tiny/bochs.c-155-\t} else {\n--\ndrivers/gpu/drm/tiny/bochs.c-161-\ndrivers/gpu/drm/tiny/bochs.c:162:static void bochs_dispi_write(struct bochs_device *bochs, u16 reg, u16 val)\ndrivers/gpu/drm/tiny/bochs.c-163-{\ndrivers/gpu/drm/tiny/bochs.c:164:\tif (bochs_uses_mmio(bochs)) {\ndrivers/gpu/drm/tiny/bochs.c-165-\t\tint offset = 0x500 + (reg \u003c\u003c 1);\ndrivers/gpu/drm/tiny/bochs.c-166-\ndrivers/gpu/drm/tiny/bochs.c:167:\t\twritew(val, bochs-\u003emmio + offset);\ndrivers/gpu/drm/tiny/bochs.c-168-\t} else {\n--\ndrivers/gpu/drm/tiny/bochs.c-173-\ndrivers/gpu/drm/tiny/bochs.c:174:static void bochs_hw_set_big_endian(struct bochs_device *bochs)\ndrivers/gpu/drm/tiny/bochs.c-175-{\ndrivers/gpu/drm/tiny/bochs.c:176:\tif (bochs-\u003eqext_size \u003c 8)\ndrivers/gpu/drm/tiny/bochs.c-177-\t\treturn;\ndrivers/gpu/drm/tiny/bochs.c-178-\ndrivers/gpu/drm/tiny/bochs.c:179:\twritel(0xbebebebe, bochs-\u003emmio + 0x604);\ndrivers/gpu/drm/tiny/bochs.c-180-}\ndrivers/gpu/drm/tiny/bochs.c-181-\ndrivers/gpu/drm/tiny/bochs.c:182:static void bochs_hw_set_little_endian(struct bochs_device *bochs)\ndrivers/gpu/drm/tiny/bochs.c-183-{\ndrivers/gpu/drm/tiny/bochs.c:184:\tif (bochs-\u003eqext_size \u003c 8)\ndrivers/gpu/drm/tiny/bochs.c-185-\t\treturn;\ndrivers/gpu/drm/tiny/bochs.c-186-\ndrivers/gpu/drm/tiny/bochs.c:187:\twritel(0x1e1e1e1e, bochs-\u003emmio + 0x604);\ndrivers/gpu/drm/tiny/bochs.c-188-}\n--\ndrivers/gpu/drm/tiny/bochs.c-190-#ifdef __BIG_ENDIAN\ndrivers/gpu/drm/tiny/bochs.c:191:#define bochs_hw_set_native_endian(_b) bochs_hw_set_big_endian(_b)\ndrivers/gpu/drm/tiny/bochs.c-192-#else\ndrivers/gpu/drm/tiny/bochs.c:193:#define bochs_hw_set_native_endian(_b) bochs_hw_set_little_endian(_b)\ndrivers/gpu/drm/tiny/bochs.c-194-#endif\ndrivers/gpu/drm/tiny/bochs.c-195-\ndrivers/gpu/drm/tiny/bochs.c:196:static int bochs_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)\ndrivers/gpu/drm/tiny/bochs.c-197-{\ndrivers/gpu/drm/tiny/bochs.c:198:\tstruct bochs_device *bochs = data;\ndrivers/gpu/drm/tiny/bochs.c-199-\tsize_t i, start = block * EDID_LENGTH;\ndrivers/gpu/drm/tiny/bochs.c-200-\ndrivers/gpu/drm/tiny/bochs.c:201:\tif (!bochs-\u003emmio)\ndrivers/gpu/drm/tiny/bochs.c-202-\t\treturn -1;\n--\ndrivers/gpu/drm/tiny/bochs.c-207-\tfor (i = 0; i \u003c len; i++)\ndrivers/gpu/drm/tiny/bochs.c:208:\t\tbuf[i] = readb(bochs-\u003emmio + start + i);\ndrivers/gpu/drm/tiny/bochs.c-209-\n--\ndrivers/gpu/drm/tiny/bochs.c-212-\ndrivers/gpu/drm/tiny/bochs.c:213:static const struct drm_edid *bochs_hw_read_edid(struct drm_connector *connector)\ndrivers/gpu/drm/tiny/bochs.c-214-{\ndrivers/gpu/drm/tiny/bochs.c-215-\tstruct drm_device *dev = connector-\u003edev;\ndrivers/gpu/drm/tiny/bochs.c:216:\tstruct bochs_device *bochs = to_bochs_device(dev);\ndrivers/gpu/drm/tiny/bochs.c-217-\tu8 header[8];\n--\ndrivers/gpu/drm/tiny/bochs.c-219-\t/* check header to detect whenever edid support is enabled in qemu */\ndrivers/gpu/drm/tiny/bochs.c:220:\tbochs_get_edid_block(bochs, header, 0, ARRAY_SIZE(header));\ndrivers/gpu/drm/tiny/bochs.c-221-\tif (drm_edid_header_is_valid(header) != 8)\n--\ndrivers/gpu/drm/tiny/bochs.c-225-\ndrivers/gpu/drm/tiny/bochs.c:226:\treturn drm_edid_read_custom(connector, bochs_get_edid_block, bochs);\ndrivers/gpu/drm/tiny/bochs.c-227-}\ndrivers/gpu/drm/tiny/bochs.c-228-\ndrivers/gpu/drm/tiny/bochs.c:229:static int bochs_hw_init(struct bochs_device *bochs)\ndrivers/gpu/drm/tiny/bochs.c-230-{\ndrivers/gpu/drm/tiny/bochs.c:231:\tstruct drm_device *dev = \u0026bochs-\u003edev;\ndrivers/gpu/drm/tiny/bochs.c-232-\tstruct pci_dev *pdev = to_pci_dev(dev-\u003edev);\n--\ndrivers/gpu/drm/tiny/bochs.c-238-\t\tiosize = pci_resource_len(pdev, 2);\ndrivers/gpu/drm/tiny/bochs.c:239:\t\t/* mmio bar with vga and bochs registers present */\ndrivers/gpu/drm/tiny/bochs.c:240:\t\tif (!devm_request_mem_region(\u0026pdev-\u003edev, ioaddr, iosize, \"bochs-drm\")) {\ndrivers/gpu/drm/tiny/bochs.c-241-\t\t\tDRM_ERROR(\"Cannot request mmio region\\n\");\n--\ndrivers/gpu/drm/tiny/bochs.c-243-\t\t}\ndrivers/gpu/drm/tiny/bochs.c:244:\t\tbochs-\u003emmio = devm_ioremap(\u0026pdev-\u003edev, ioaddr, iosize);\ndrivers/gpu/drm/tiny/bochs.c:245:\t\tif (bochs-\u003emmio == NULL) {\ndrivers/gpu/drm/tiny/bochs.c-246-\t\t\tDRM_ERROR(\"Cannot map mmio region\\n\");\n--\ndrivers/gpu/drm/tiny/bochs.c-251-\t\tiosize = 2;\ndrivers/gpu/drm/tiny/bochs.c:252:\t\tif (!devm_request_region(\u0026pdev-\u003edev, ioaddr, iosize, \"bochs-drm\")) {\ndrivers/gpu/drm/tiny/bochs.c-253-\t\t\tDRM_ERROR(\"Cannot request ioports\\n\");\n--\ndrivers/gpu/drm/tiny/bochs.c-255-\t\t}\ndrivers/gpu/drm/tiny/bochs.c:256:\t\tbochs-\u003eioports = 1;\ndrivers/gpu/drm/tiny/bochs.c-257-\t} else {\n--\ndrivers/gpu/drm/tiny/bochs.c-261-\ndrivers/gpu/drm/tiny/bochs.c:262:\tid = bochs_dispi_read(bochs, VBE_DISPI_INDEX_ID);\ndrivers/gpu/drm/tiny/bochs.c:263:\tmem = bochs_dispi_read(bochs, VBE_DISPI_INDEX_VIDEO_MEMORY_64K)\ndrivers/gpu/drm/tiny/bochs.c-264-\t\t* 64 * 1024;\n--\ndrivers/gpu/drm/tiny/bochs.c-276-\tif (size != mem) {\ndrivers/gpu/drm/tiny/bochs.c:277:\t\tDRM_ERROR(\"Size mismatch: pci=%ld, bochs=%ld\\n\",\ndrivers/gpu/drm/tiny/bochs.c-278-\t\t\tsize, mem);\n--\ndrivers/gpu/drm/tiny/bochs.c-281-\ndrivers/gpu/drm/tiny/bochs.c:282:\tif (!devm_request_mem_region(\u0026pdev-\u003edev, addr, size, \"bochs-drm\"))\ndrivers/gpu/drm/tiny/bochs.c-283-\t\tDRM_WARN(\"Cannot request framebuffer, boot fb still active?\\n\");\ndrivers/gpu/drm/tiny/bochs.c-284-\ndrivers/gpu/drm/tiny/bochs.c:285:\tbochs-\u003efb_map = devm_ioremap_wc(\u0026pdev-\u003edev, addr, size);\ndrivers/gpu/drm/tiny/bochs.c:286:\tif (bochs-\u003efb_map == NULL) {\ndrivers/gpu/drm/tiny/bochs.c-287-\t\tDRM_ERROR(\"Cannot map framebuffer\\n\");\n--\ndrivers/gpu/drm/tiny/bochs.c-289-\t}\ndrivers/gpu/drm/tiny/bochs.c:290:\tbochs-\u003efb_base = addr;\ndrivers/gpu/drm/tiny/bochs.c:291:\tbochs-\u003efb_size = size;\ndrivers/gpu/drm/tiny/bochs.c-292-\ndrivers/gpu/drm/tiny/bochs.c:293:\tDRM_INFO(\"Found bochs VGA, ID 0x%x.\\n\", id);\ndrivers/gpu/drm/tiny/bochs.c-294-\tDRM_INFO(\"Framebuffer size %ld kB @ 0x%lx, %s @ 0x%lx.\\n\",\ndrivers/gpu/drm/tiny/bochs.c-295-\t\t size / 1024, addr,\ndrivers/gpu/drm/tiny/bochs.c:296:\t\t bochs-\u003eioports ? \"ioports\" : \"mmio\",\ndrivers/gpu/drm/tiny/bochs.c-297-\t\t ioaddr);\ndrivers/gpu/drm/tiny/bochs.c-298-\ndrivers/gpu/drm/tiny/bochs.c:299:\tif (bochs-\u003emmio \u0026\u0026 pdev-\u003erevision \u003e= 2) {\ndrivers/gpu/drm/tiny/bochs.c:300:\t\tbochs-\u003eqext_size = readl(bochs-\u003emmio + 0x600);\ndrivers/gpu/drm/tiny/bochs.c:301:\t\tif (bochs-\u003eqext_size \u003c 4 || bochs-\u003eqext_size \u003e iosize) {\ndrivers/gpu/drm/tiny/bochs.c:302:\t\t\tbochs-\u003eqext_size = 0;\ndrivers/gpu/drm/tiny/bochs.c-303-\t\t\tgoto noext;\n--\ndrivers/gpu/drm/tiny/bochs.c-305-\t\tDRM_DEBUG(\"Found qemu ext regs, size %ld\\n\",\ndrivers/gpu/drm/tiny/bochs.c:306:\t\t\t bochs-\u003eqext_size);\ndrivers/gpu/drm/tiny/bochs.c:307:\t\tbochs_hw_set_native_endian(bochs);\ndrivers/gpu/drm/tiny/bochs.c-308-\t}\n--\ndrivers/gpu/drm/tiny/bochs.c-313-\ndrivers/gpu/drm/tiny/bochs.c:314:static void bochs_hw_blank(struct bochs_device *bochs, bool blank)\ndrivers/gpu/drm/tiny/bochs.c-315-{\n--\ndrivers/gpu/drm/tiny/bochs.c-317-\t/* enable color bit (so VGA_IS1_RC access works) */\ndrivers/gpu/drm/tiny/bochs.c:318:\tbochs_vga_writeb(bochs, VGA_MIS_W, VGA_MIS_COLOR);\ndrivers/gpu/drm/tiny/bochs.c-319-\t/* discard ar_flip_flop */\ndrivers/gpu/drm/tiny/bochs.c:320:\t(void)bochs_vga_readb(bochs, VGA_IS1_RC);\ndrivers/gpu/drm/tiny/bochs.c-321-\t/* blank or unblank; we need only update index and set 0x20 */\ndrivers/gpu/drm/tiny/bochs.c:322:\tbochs_vga_writeb(bochs, VGA_ATT_W, blank ? 0 : 0x20);\ndrivers/gpu/drm/tiny/bochs.c-323-}\ndrivers/gpu/drm/tiny/bochs.c-324-\ndrivers/gpu/drm/tiny/bochs.c:325:static void bochs_hw_setmode(struct bochs_device *bochs, struct drm_display_mode *mode)\ndrivers/gpu/drm/tiny/bochs.c-326-{\n--\ndrivers/gpu/drm/tiny/bochs.c-328-\ndrivers/gpu/drm/tiny/bochs.c:329:\tif (!drm_dev_enter(\u0026bochs-\u003edev, \u0026idx))\ndrivers/gpu/drm/tiny/bochs.c-330-\t\treturn;\ndrivers/gpu/drm/tiny/bochs.c-331-\ndrivers/gpu/drm/tiny/bochs.c:332:\tbochs-\u003exres = mode-\u003ehdisplay;\ndrivers/gpu/drm/tiny/bochs.c:333:\tbochs-\u003eyres = mode-\u003evdisplay;\ndrivers/gpu/drm/tiny/bochs.c:334:\tbochs-\u003ebpp = 32;\ndrivers/gpu/drm/tiny/bochs.c:335:\tbochs-\u003estride = mode-\u003ehdisplay * (bochs-\u003ebpp / 8);\ndrivers/gpu/drm/tiny/bochs.c:336:\tbochs-\u003eyres_virtual = bochs-\u003efb_size / bochs-\u003estride;\ndrivers/gpu/drm/tiny/bochs.c-337-\ndrivers/gpu/drm/tiny/bochs.c-338-\tDRM_DEBUG_DRIVER(\"%dx%d @ %d bpp, vy %d\\n\",\ndrivers/gpu/drm/tiny/bochs.c:339:\t\t\t bochs-\u003exres, bochs-\u003eyres, bochs-\u003ebpp,\ndrivers/gpu/drm/tiny/bochs.c:340:\t\t\t bochs-\u003eyres_virtual);\ndrivers/gpu/drm/tiny/bochs.c-341-\ndrivers/gpu/drm/tiny/bochs.c:342:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE, 0);\ndrivers/gpu/drm/tiny/bochs.c:343:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_BPP, bochs-\u003ebpp);\ndrivers/gpu/drm/tiny/bochs.c:344:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_XRES, bochs-\u003exres);\ndrivers/gpu/drm/tiny/bochs.c:345:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_YRES, bochs-\u003eyres);\ndrivers/gpu/drm/tiny/bochs.c:346:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_BANK, 0);\ndrivers/gpu/drm/tiny/bochs.c:347:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_VIRT_WIDTH, bochs-\u003exres);\ndrivers/gpu/drm/tiny/bochs.c:348:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_VIRT_HEIGHT,\ndrivers/gpu/drm/tiny/bochs.c:349:\t\t\t bochs-\u003eyres_virtual);\ndrivers/gpu/drm/tiny/bochs.c:350:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_X_OFFSET, 0);\ndrivers/gpu/drm/tiny/bochs.c:351:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_Y_OFFSET, 0);\ndrivers/gpu/drm/tiny/bochs.c-352-\ndrivers/gpu/drm/tiny/bochs.c:353:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE,\ndrivers/gpu/drm/tiny/bochs.c-354-\t\t\t VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);\n--\ndrivers/gpu/drm/tiny/bochs.c-358-\ndrivers/gpu/drm/tiny/bochs.c:359:static void bochs_hw_setformat(struct bochs_device *bochs, const struct drm_format_info *format)\ndrivers/gpu/drm/tiny/bochs.c-360-{\n--\ndrivers/gpu/drm/tiny/bochs.c-362-\ndrivers/gpu/drm/tiny/bochs.c:363:\tif (!drm_dev_enter(\u0026bochs-\u003edev, \u0026idx))\ndrivers/gpu/drm/tiny/bochs.c-364-\t\treturn;\n--\ndrivers/gpu/drm/tiny/bochs.c-373-\tcase DRM_FORMAT_XRGB8888:\ndrivers/gpu/drm/tiny/bochs.c:374:\t\tbochs_hw_set_little_endian(bochs);\ndrivers/gpu/drm/tiny/bochs.c-375-\t\tbreak;\ndrivers/gpu/drm/tiny/bochs.c-376-\tcase DRM_FORMAT_BGRX8888:\ndrivers/gpu/drm/tiny/bochs.c:377:\t\tbochs_hw_set_big_endian(bochs);\ndrivers/gpu/drm/tiny/bochs.c-378-\t\tbreak;\n--\ndrivers/gpu/drm/tiny/bochs.c-388-\ndrivers/gpu/drm/tiny/bochs.c:389:static void bochs_hw_setbase(struct bochs_device *bochs, int x, int y, int stride, u64 addr)\ndrivers/gpu/drm/tiny/bochs.c-390-{\n--\ndrivers/gpu/drm/tiny/bochs.c-393-\ndrivers/gpu/drm/tiny/bochs.c:394:\tif (!drm_dev_enter(\u0026bochs-\u003edev, \u0026idx))\ndrivers/gpu/drm/tiny/bochs.c-395-\t\treturn;\ndrivers/gpu/drm/tiny/bochs.c-396-\ndrivers/gpu/drm/tiny/bochs.c:397:\tbochs-\u003estride = stride;\ndrivers/gpu/drm/tiny/bochs.c-398-\toffset = (unsigned long)addr +\ndrivers/gpu/drm/tiny/bochs.c:399:\t\ty * bochs-\u003estride +\ndrivers/gpu/drm/tiny/bochs.c:400:\t\tx * (bochs-\u003ebpp / 8);\ndrivers/gpu/drm/tiny/bochs.c:401:\tvy = offset / bochs-\u003estride;\ndrivers/gpu/drm/tiny/bochs.c:402:\tvx = (offset % bochs-\u003estride) * 8 / bochs-\u003ebpp;\ndrivers/gpu/drm/tiny/bochs.c:403:\tvwidth = stride * 8 / bochs-\u003ebpp;\ndrivers/gpu/drm/tiny/bochs.c-404-\n--\ndrivers/gpu/drm/tiny/bochs.c-406-\t\t\t x, y, addr, offset, vx, vy);\ndrivers/gpu/drm/tiny/bochs.c:407:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_VIRT_WIDTH, vwidth);\ndrivers/gpu/drm/tiny/bochs.c:408:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_X_OFFSET, vx);\ndrivers/gpu/drm/tiny/bochs.c:409:\tbochs_dispi_write(bochs, VBE_DISPI_INDEX_Y_OFFSET, vy);\ndrivers/gpu/drm/tiny/bochs.c-410-\n--\ndrivers/gpu/drm/tiny/bochs.c-415-\ndrivers/gpu/drm/tiny/bochs.c:416:static const uint32_t bochs_primary_plane_formats[] = {\ndrivers/gpu/drm/tiny/bochs.c-417-\tDRM_FORMAT_XRGB8888,\n--\ndrivers/gpu/drm/tiny/bochs.c-420-\ndrivers/gpu/drm/tiny/bochs.c:421:static int bochs_primary_plane_helper_atomic_check(struct drm_plane *plane,\ndrivers/gpu/drm/tiny/bochs.c-422-\t\t\t\t\t\t struct drm_atomic_state *state)\n--\ndrivers/gpu/drm/tiny/bochs.c-443-\ndrivers/gpu/drm/tiny/bochs.c:444:static void bochs_primary_plane_helper_atomic_update(struct drm_plane *plane,\ndrivers/gpu/drm/tiny/bochs.c-445-\t\t\t\t\t\t struct drm_atomic_state *state)\n--\ndrivers/gpu/drm/tiny/bochs.c-447-\tstruct drm_device *dev = plane-\u003edev;\ndrivers/gpu/drm/tiny/bochs.c:448:\tstruct bochs_device *bochs = to_bochs_device(dev);\ndrivers/gpu/drm/tiny/bochs.c-449-\tstruct drm_plane_state *plane_state = plane-\u003estate;\n--\ndrivers/gpu/drm/tiny/bochs.c-455-\ndrivers/gpu/drm/tiny/bochs.c:456:\tif (!fb || !bochs-\u003estride)\ndrivers/gpu/drm/tiny/bochs.c-457-\t\treturn;\n--\ndrivers/gpu/drm/tiny/bochs.c-460-\tdrm_atomic_for_each_plane_damage(\u0026iter, \u0026damage) {\ndrivers/gpu/drm/tiny/bochs.c:461:\t\tstruct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(bochs-\u003efb_map);\ndrivers/gpu/drm/tiny/bochs.c-462-\n--\ndrivers/gpu/drm/tiny/bochs.c-467-\t/* Always scanout image at VRAM offset 0 */\ndrivers/gpu/drm/tiny/bochs.c:468:\tbochs_hw_setbase(bochs,\ndrivers/gpu/drm/tiny/bochs.c-469-\t\t\t plane_state-\u003ecrtc_x,\n--\ndrivers/gpu/drm/tiny/bochs.c-472-\t\t\t 0);\ndrivers/gpu/drm/tiny/bochs.c:473:\tbochs_hw_setformat(bochs, fb-\u003eformat);\ndrivers/gpu/drm/tiny/bochs.c-474-}\ndrivers/gpu/drm/tiny/bochs.c-475-\ndrivers/gpu/drm/tiny/bochs.c:476:static int bochs_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane,\ndrivers/gpu/drm/tiny/bochs.c-477-\t\t\t\t\t\t\t struct drm_scanout_buffer *sb)\ndrivers/gpu/drm/tiny/bochs.c-478-{\ndrivers/gpu/drm/tiny/bochs.c:479:\tstruct bochs_device *bochs = to_bochs_device(plane-\u003edev);\ndrivers/gpu/drm/tiny/bochs.c:480:\tstruct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(bochs-\u003efb_map);\ndrivers/gpu/drm/tiny/bochs.c-481-\n--\ndrivers/gpu/drm/tiny/bochs.c-492-\ndrivers/gpu/drm/tiny/bochs.c:493:static const struct drm_plane_helper_funcs bochs_primary_plane_helper_funcs = {\ndrivers/gpu/drm/tiny/bochs.c-494-\tDRM_GEM_SHADOW_PLANE_HELPER_FUNCS,\ndrivers/gpu/drm/tiny/bochs.c:495:\t.atomic_check = bochs_primary_plane_helper_atomic_check,\ndrivers/gpu/drm/tiny/bochs.c:496:\t.atomic_update = bochs_primary_plane_helper_atomic_update,\ndrivers/gpu/drm/tiny/bochs.c:497:\t.get_scanout_buffer = bochs_primary_plane_helper_get_scanout_buffer,\ndrivers/gpu/drm/tiny/bochs.c-498-};\ndrivers/gpu/drm/tiny/bochs.c-499-\ndrivers/gpu/drm/tiny/bochs.c:500:static const struct drm_plane_funcs bochs_primary_plane_funcs = {\ndrivers/gpu/drm/tiny/bochs.c-501-\t.update_plane = drm_atomic_helper_update_plane,\n--\ndrivers/gpu/drm/tiny/bochs.c-506-\ndrivers/gpu/drm/tiny/bochs.c:507:static void bochs_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)\ndrivers/gpu/drm/tiny/bochs.c-508-{\ndrivers/gpu/drm/tiny/bochs.c:509:\tstruct bochs_device *bochs = to_bochs_device(crtc-\u003edev);\ndrivers/gpu/drm/tiny/bochs.c-510-\tstruct drm_crtc_state *crtc_state = crtc-\u003estate;\ndrivers/gpu/drm/tiny/bochs.c-511-\ndrivers/gpu/drm/tiny/bochs.c:512:\tbochs_hw_setmode(bochs, \u0026crtc_state-\u003emode);\ndrivers/gpu/drm/tiny/bochs.c-513-}\ndrivers/gpu/drm/tiny/bochs.c-514-\ndrivers/gpu/drm/tiny/bochs.c:515:static int bochs_crtc_helper_atomic_check(struct drm_crtc *crtc,\ndrivers/gpu/drm/tiny/bochs.c-516-\t\t\t\t\t struct drm_atomic_state *state)\n--\ndrivers/gpu/drm/tiny/bochs.c-525-\ndrivers/gpu/drm/tiny/bochs.c:526:static void bochs_crtc_helper_atomic_enable(struct drm_crtc *crtc,\ndrivers/gpu/drm/tiny/bochs.c-527-\t\t\t\t\t struct drm_atomic_state *state)\ndrivers/gpu/drm/tiny/bochs.c-528-{\ndrivers/gpu/drm/tiny/bochs.c:529:\tstruct bochs_device *bochs = to_bochs_device(crtc-\u003edev);\ndrivers/gpu/drm/tiny/bochs.c-530-\ndrivers/gpu/drm/tiny/bochs.c:531:\tbochs_hw_blank(bochs, false);\ndrivers/gpu/drm/tiny/bochs.c-532-\tdrm_crtc_vblank_on(crtc);\n--\ndrivers/gpu/drm/tiny/bochs.c-534-\ndrivers/gpu/drm/tiny/bochs.c:535:static void bochs_crtc_helper_atomic_disable(struct drm_crtc *crtc,\ndrivers/gpu/drm/tiny/bochs.c-536-\t\t\t\t\t struct drm_atomic_state *crtc_state)\ndrivers/gpu/drm/tiny/bochs.c-537-{\ndrivers/gpu/drm/tiny/bochs.c:538:\tstruct bochs_device *bochs = to_bochs_device(crtc-\u003edev);\ndrivers/gpu/drm/tiny/bochs.c-539-\ndrivers/gpu/drm/tiny/bochs.c-540-\tdrm_crtc_vblank_off(crtc);\ndrivers/gpu/drm/tiny/bochs.c:541:\tbochs_hw_blank(bochs, true);\ndrivers/gpu/drm/tiny/bochs.c-542-}\ndrivers/gpu/drm/tiny/bochs.c-543-\ndrivers/gpu/drm/tiny/bochs.c:544:static const struct drm_crtc_helper_funcs bochs_crtc_helper_funcs = {\ndrivers/gpu/drm/tiny/bochs.c:545:\t.mode_set_nofb = bochs_crtc_helper_mode_set_nofb,\ndrivers/gpu/drm/tiny/bochs.c:546:\t.atomic_check = bochs_crtc_helper_atomic_check,\ndrivers/gpu/drm/tiny/bochs.c-547-\t.atomic_flush = drm_crtc_vblank_atomic_flush,\ndrivers/gpu/drm/tiny/bochs.c:548:\t.atomic_enable = bochs_crtc_helper_atomic_enable,\ndrivers/gpu/drm/tiny/bochs.c:549:\t.atomic_disable = bochs_crtc_helper_atomic_disable,\ndrivers/gpu/drm/tiny/bochs.c-550-};\ndrivers/gpu/drm/tiny/bochs.c-551-\ndrivers/gpu/drm/tiny/bochs.c:552:static const struct drm_crtc_funcs bochs_crtc_funcs = {\ndrivers/gpu/drm/tiny/bochs.c-553-\t.reset = drm_atomic_helper_crtc_reset,\n--\ndrivers/gpu/drm/tiny/bochs.c-561-\ndrivers/gpu/drm/tiny/bochs.c:562:static const struct drm_encoder_funcs bochs_encoder_funcs = {\ndrivers/gpu/drm/tiny/bochs.c-563-\t.destroy = drm_encoder_cleanup,\n--\ndrivers/gpu/drm/tiny/bochs.c-565-\ndrivers/gpu/drm/tiny/bochs.c:566:static int bochs_connector_helper_get_modes(struct drm_connector *connector)\ndrivers/gpu/drm/tiny/bochs.c-567-{\n--\ndrivers/gpu/drm/tiny/bochs.c-570-\ndrivers/gpu/drm/tiny/bochs.c:571:\tedid = bochs_hw_read_edid(connector);\ndrivers/gpu/drm/tiny/bochs.c-572-\n--\ndrivers/gpu/drm/tiny/bochs.c-585-\ndrivers/gpu/drm/tiny/bochs.c:586:static const struct drm_connector_helper_funcs bochs_connector_helper_funcs = {\ndrivers/gpu/drm/tiny/bochs.c:587:\t.get_modes = bochs_connector_helper_get_modes,\ndrivers/gpu/drm/tiny/bochs.c-588-};\ndrivers/gpu/drm/tiny/bochs.c-589-\ndrivers/gpu/drm/tiny/bochs.c:590:static const struct drm_connector_funcs bochs_connector_funcs = {\ndrivers/gpu/drm/tiny/bochs.c-591-\t.fill_modes = drm_helper_probe_single_connector_modes,\n--\ndrivers/gpu/drm/tiny/bochs.c-597-\ndrivers/gpu/drm/tiny/bochs.c:598:static enum drm_mode_status bochs_mode_config_mode_valid(struct drm_device *dev,\ndrivers/gpu/drm/tiny/bochs.c-599-\t\t\t\t\t\t\t const struct drm_display_mode *mode)\ndrivers/gpu/drm/tiny/bochs.c-600-{\ndrivers/gpu/drm/tiny/bochs.c:601:\tstruct bochs_device *bochs = to_bochs_device(dev);\ndrivers/gpu/drm/tiny/bochs.c-602-\tconst struct drm_format_info *format = drm_format_info(DRM_FORMAT_XRGB8888);\n--\ndrivers/gpu/drm/tiny/bochs.c-610-\t\treturn MODE_BAD_WIDTH;\ndrivers/gpu/drm/tiny/bochs.c:611:\tif (mode-\u003evdisplay \u003e DIV_ROUND_DOWN_ULL(bochs-\u003efb_size, pitch))\ndrivers/gpu/drm/tiny/bochs.c-612-\t\treturn MODE_MEM;\n--\ndrivers/gpu/drm/tiny/bochs.c-616-\ndrivers/gpu/drm/tiny/bochs.c:617:static const struct drm_mode_config_funcs bochs_mode_config_funcs = {\ndrivers/gpu/drm/tiny/bochs.c-618-\t.fb_create = drm_gem_fb_create_with_dirty,\ndrivers/gpu/drm/tiny/bochs.c:619:\t.mode_valid = bochs_mode_config_mode_valid,\ndrivers/gpu/drm/tiny/bochs.c-620-\t.atomic_check = drm_atomic_helper_check,\n--\ndrivers/gpu/drm/tiny/bochs.c-623-\ndrivers/gpu/drm/tiny/bochs.c:624:static int bochs_kms_init(struct bochs_device *bochs)\ndrivers/gpu/drm/tiny/bochs.c-625-{\ndrivers/gpu/drm/tiny/bochs.c:626:\tstruct drm_device *dev = \u0026bochs-\u003edev;\ndrivers/gpu/drm/tiny/bochs.c-627-\tstruct drm_plane *primary_plane;\n--\ndrivers/gpu/drm/tiny/bochs.c-642-\ndrivers/gpu/drm/tiny/bochs.c:643:\tdev-\u003emode_config.funcs = \u0026bochs_mode_config_funcs;\ndrivers/gpu/drm/tiny/bochs.c-644-\ndrivers/gpu/drm/tiny/bochs.c:645:\tprimary_plane = \u0026bochs-\u003eprimary_plane;\ndrivers/gpu/drm/tiny/bochs.c-646-\tret = drm_universal_plane_init(dev, primary_plane, 0,\ndrivers/gpu/drm/tiny/bochs.c:647:\t\t\t\t \u0026bochs_primary_plane_funcs,\ndrivers/gpu/drm/tiny/bochs.c:648:\t\t\t\t bochs_primary_plane_formats,\ndrivers/gpu/drm/tiny/bochs.c:649:\t\t\t\t ARRAY_SIZE(bochs_primary_plane_formats),\ndrivers/gpu/drm/tiny/bochs.c-650-\t\t\t\t NULL,\n--\ndrivers/gpu/drm/tiny/bochs.c-653-\t\treturn ret;\ndrivers/gpu/drm/tiny/bochs.c:654:\tdrm_plane_helper_add(primary_plane, \u0026bochs_primary_plane_helper_funcs);\ndrivers/gpu/drm/tiny/bochs.c-655-\tdrm_plane_enable_fb_damage_clips(primary_plane);\ndrivers/gpu/drm/tiny/bochs.c-656-\ndrivers/gpu/drm/tiny/bochs.c:657:\tcrtc = \u0026bochs-\u003ecrtc;\ndrivers/gpu/drm/tiny/bochs.c-658-\tret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL,\ndrivers/gpu/drm/tiny/bochs.c:659:\t\t\t\t\t\u0026bochs_crtc_funcs, NULL);\ndrivers/gpu/drm/tiny/bochs.c-660-\tif (ret)\ndrivers/gpu/drm/tiny/bochs.c-661-\t\treturn ret;\ndrivers/gpu/drm/tiny/bochs.c:662:\tdrm_crtc_helper_add(crtc, \u0026bochs_crtc_helper_funcs);\ndrivers/gpu/drm/tiny/bochs.c-663-\ndrivers/gpu/drm/tiny/bochs.c:664:\tencoder = \u0026bochs-\u003eencoder;\ndrivers/gpu/drm/tiny/bochs.c:665:\tret = drm_encoder_init(dev, encoder, \u0026bochs_encoder_funcs,\ndrivers/gpu/drm/tiny/bochs.c-666-\t\t\t DRM_MODE_ENCODER_VIRTUAL, NULL);\n--\ndrivers/gpu/drm/tiny/bochs.c-670-\ndrivers/gpu/drm/tiny/bochs.c:671:\tconnector = \u0026bochs-\u003econnector;\ndrivers/gpu/drm/tiny/bochs.c:672:\tret = drm_connector_init(dev, connector, \u0026bochs_connector_funcs,\ndrivers/gpu/drm/tiny/bochs.c-673-\t\t\t\t DRM_MODE_CONNECTOR_VIRTUAL);\n--\ndrivers/gpu/drm/tiny/bochs.c-675-\t\treturn ret;\ndrivers/gpu/drm/tiny/bochs.c:676:\tdrm_connector_helper_add(connector, \u0026bochs_connector_helper_funcs);\ndrivers/gpu/drm/tiny/bochs.c-677-\tdrm_connector_attach_edid_property(connector);\n--\ndrivers/gpu/drm/tiny/bochs.c-691-\ndrivers/gpu/drm/tiny/bochs.c:692:static int bochs_load(struct bochs_device *bochs)\ndrivers/gpu/drm/tiny/bochs.c-693-{\n--\ndrivers/gpu/drm/tiny/bochs.c-695-\ndrivers/gpu/drm/tiny/bochs.c:696:\tret = bochs_hw_init(bochs);\ndrivers/gpu/drm/tiny/bochs.c-697-\tif (ret)\n--\ndrivers/gpu/drm/tiny/bochs.c-699-\ndrivers/gpu/drm/tiny/bochs.c:700:\tret = bochs_kms_init(bochs);\ndrivers/gpu/drm/tiny/bochs.c-701-\tif (ret)\n--\ndrivers/gpu/drm/tiny/bochs.c-706-\ndrivers/gpu/drm/tiny/bochs.c:707:DEFINE_DRM_GEM_FOPS(bochs_fops);\ndrivers/gpu/drm/tiny/bochs.c-708-\ndrivers/gpu/drm/tiny/bochs.c:709:static const struct drm_driver bochs_driver = {\ndrivers/gpu/drm/tiny/bochs.c-710-\t.driver_features\t= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,\ndrivers/gpu/drm/tiny/bochs.c:711:\t.fops\t\t\t= \u0026bochs_fops,\ndrivers/gpu/drm/tiny/bochs.c:712:\t.name\t\t\t= \"bochs-drm\",\ndrivers/gpu/drm/tiny/bochs.c:713:\t.desc\t\t\t= \"bochs dispi vga interface (qemu stdvga)\",\ndrivers/gpu/drm/tiny/bochs.c-714-\t.major\t\t\t= 1,\n--\ndrivers/gpu/drm/tiny/bochs.c-723-#ifdef CONFIG_PM_SLEEP\ndrivers/gpu/drm/tiny/bochs.c:724:static int bochs_pm_suspend(struct device *dev)\ndrivers/gpu/drm/tiny/bochs.c-725-{\n--\ndrivers/gpu/drm/tiny/bochs.c-730-\ndrivers/gpu/drm/tiny/bochs.c:731:static int bochs_pm_resume(struct device *dev)\ndrivers/gpu/drm/tiny/bochs.c-732-{\n--\ndrivers/gpu/drm/tiny/bochs.c-738-\ndrivers/gpu/drm/tiny/bochs.c:739:static const struct dev_pm_ops bochs_pm_ops = {\ndrivers/gpu/drm/tiny/bochs.c:740:\tSET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,\ndrivers/gpu/drm/tiny/bochs.c:741:\t\t\t\tbochs_pm_resume)\ndrivers/gpu/drm/tiny/bochs.c-742-};\n--\ndrivers/gpu/drm/tiny/bochs.c-746-\ndrivers/gpu/drm/tiny/bochs.c:747:static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\ndrivers/gpu/drm/tiny/bochs.c-748-{\ndrivers/gpu/drm/tiny/bochs.c:749:\tstruct bochs_device *bochs;\ndrivers/gpu/drm/tiny/bochs.c-750-\tstruct drm_device *dev;\n--\ndrivers/gpu/drm/tiny/bochs.c-752-\ndrivers/gpu/drm/tiny/bochs.c:753:\tret = aperture_remove_conflicting_pci_devices(pdev, bochs_driver.name);\ndrivers/gpu/drm/tiny/bochs.c-754-\tif (ret)\n--\ndrivers/gpu/drm/tiny/bochs.c-756-\ndrivers/gpu/drm/tiny/bochs.c:757:\tbochs = devm_drm_dev_alloc(\u0026pdev-\u003edev, \u0026bochs_driver, struct bochs_device, dev);\ndrivers/gpu/drm/tiny/bochs.c:758:\tif (IS_ERR(bochs))\ndrivers/gpu/drm/tiny/bochs.c:759:\t\treturn PTR_ERR(bochs);\ndrivers/gpu/drm/tiny/bochs.c:760:\tdev = \u0026bochs-\u003edev;\ndrivers/gpu/drm/tiny/bochs.c-761-\n--\ndrivers/gpu/drm/tiny/bochs.c-767-\ndrivers/gpu/drm/tiny/bochs.c:768:\tret = bochs_load(bochs);\ndrivers/gpu/drm/tiny/bochs.c-769-\tif (ret)\n--\ndrivers/gpu/drm/tiny/bochs.c-780-\ndrivers/gpu/drm/tiny/bochs.c:781:static void bochs_pci_remove(struct pci_dev *pdev)\ndrivers/gpu/drm/tiny/bochs.c-782-{\n--\ndrivers/gpu/drm/tiny/bochs.c-788-\ndrivers/gpu/drm/tiny/bochs.c:789:static void bochs_pci_shutdown(struct pci_dev *pdev)\ndrivers/gpu/drm/tiny/bochs.c-790-{\n--\ndrivers/gpu/drm/tiny/bochs.c-793-\ndrivers/gpu/drm/tiny/bochs.c:794:static const struct pci_device_id bochs_pci_tbl[] = {\ndrivers/gpu/drm/tiny/bochs.c-795-\t{\n\n"
} |
| 25/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41219 output: 36 thoughts: 60 Thoughts: Here's my take on the thought process: **Investigating the TTM Dependency** Okay, so `drm_gem_vram_helper.c` is leveraging TTM, which immediately raises a flag. I need to understand the scope of this dependency. The key question is: what modules or functions actually *use* this helper? I'll need to trace back from `drm_gem_vram_helper.c` to identify the callers. Let's start with a focused search. I'll look for direct usages of `drm_gem_vram_helper` itself and, just to be thorough and catch any variations, I'll also check for any instances of `DRM_GEM_VRAM_HELPER`. This should give me a good handle on who relies on this piece of the infrastructure. |
| 26/2 | 2026/09/23 03:00 | tool | grepper |
0mError:no matches Args: {
"Expression": "select DRM_GEM_VRAM_HELPER|depends on DRM_GEM_VRAM_HELPER"
}Results: {
"error": "no matches"
} |
| 27/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41504 output: 24 thoughts: 17 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person: **Analyzing the DRM_GEM_VRAM_HELPER Code Path** Alright, so I'm thinking about digging into the graphics driver code again. Specifically, I'm going to start with a grep search. The target is `DRM_GEM_VRAM_HELPER`. This likely involves some critical VRAM management functionality, so it's a good place to start my investigation. I'm guessing this might lead me to the core allocation, tracking, or eviction mechanisms within the GEM (Graphics Execution Manager) layer, potentially at the driver-specific level or kernel interface layer. I'm anticipating that this helper function will be key to understanding the interplay between the DRM (Direct Rendering Manager) framework and the underlying hardware. Knowing this entry point will give me a better understanding of the VRAM usage and hopefully a direction in which to look. |
| 28/2 | 2026/09/23 03:00 | tool | grepper |
0mArgs:{
"Expression": "DRM_GEM_VRAM_HELPER"
}Results: {
"Output": "include/drm/drm_gem_vram_helper.h-2-\ninclude/drm/drm_gem_vram_helper.h:3:#ifndef DRM_GEM_VRAM_HELPER_H\ninclude/drm/drm_gem_vram_helper.h:4:#define DRM_GEM_VRAM_HELPER_H\ninclude/drm/drm_gem_vram_helper.h-5-\n"
} |
| 29/2 | 2026/09/23 03:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41853 output: 34 thoughts: 19 Thoughts: Okay, here's my summarized thought process, geared towards a user who knows their way around kernel development and build systems: **Hunting Down `drm_gem_vram_helper`** Alright, time to get to work. My immediate instinct is to figure out where `drm_gem_vram_helper` is actually *used* within the build process. I need to understand how it's linked into the relevant modules or built into the kernel. So, the most direct approach is a good old fashioned `grep`. I'll focus my search on the `Makefile` landscape first. That's usually where the dependencies and build rules are defined. Let's see what turns up. It's a quick and dirty way to get a map of the landscape. |
| 30/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "drm_gem_vram_helper",
"PathPrefix": "drivers/gpu/drm/"
}Results: {
"Output": "drivers/gpu/drm/Makefile=129=obj-$(CONFIG_DRM_SUBALLOC_HELPER) += drm_suballoc_helper.o\ndrivers/gpu/drm/Makefile-130-\ndrivers/gpu/drm/Makefile:131:drm_vram_helper-y := drm_gem_vram_helper.o\ndrivers/gpu/drm/Makefile-132-obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o\n--\ndrivers/gpu/drm/drm_gem_vram_helper.c-14-#include \u003cdrm/drm_gem_ttm_helper.h\u003e\ndrivers/gpu/drm/drm_gem_vram_helper.c:15:#include \u003cdrm/drm_gem_vram_helper.h\u003e\ndrivers/gpu/drm/drm_gem_vram_helper.c-16-#include \u003cdrm/drm_managed.h\u003e\n--\ndrivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c-18-#include \u003cdrm/drm_fourcc.h\u003e\ndrivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c:19:#include \u003cdrm/drm_gem_vram_helper.h\u003e\ndrivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c-20-#include \u003cdrm/drm_vblank.h\u003e\n--\ndrivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c-22-#include \u003cdrm/drm_gem_framebuffer_helper.h\u003e\ndrivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c:23:#include \u003cdrm/drm_gem_vram_helper.h\u003e\ndrivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c-24-#include \u003cdrm/drm_managed.h\u003e\n--\ndrivers/gpu/drm/vboxvideo/vbox_drv.h-19-#include \u003cdrm/drm_gem.h\u003e\ndrivers/gpu/drm/vboxvideo/vbox_drv.h:20:#include \u003cdrm/drm_gem_vram_helper.h\u003e\ndrivers/gpu/drm/vboxvideo/vbox_drv.h-21-\n"
} |
| 31/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 42629 output: 32 thoughts: 403 Thoughts: **Analyzing DRM VRAM Helper Initialization** Okay, let's break this down. First, I'm looking at `CONFIG_DRM_VRAM_HELPER`. Right, who actually selects that? Ah, `vboxvideo` and `hibmc`. Noted. Then we have `QXL` that selects `DRM_TTM` and `DRM_TTM_HELPER`, and `vmwgfx` does the same. Now, where is `CONFIG_DRM_TTM` actually *used*? `qxl`, emulated in QEMU with `-vga qxl` or `-device qxl-vga`; `vmwgfx` also emulated in QEMU, using `-vga vmware` or `-device vmware-svga`. And, of course, the usual suspects: `nouveau`, `radeon`, `amdgpu`, `xe`, `loongson`, and `drm_gem_vram_helper` which, as we know, is used by `vboxvideo`. Now, here's the tricky part. Does `qxl` or `vmwgfx` initialize `man->cg`? This is critical for resource management, so let's see. I need to find all the occurrences of `->cg` to trace its initialization. Okay, let's see... 1. `drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c` initializes `man->cg` with `drmm_cgroup_register_region`. 2. `drivers/gpu/drm/xe/xe_ttm_vram_mgr.c` initializes `man->cg` with `drmm_cgroup_register_region`. Neither `qxl` nor `vmwgfx` are present in either of those locations. That's a problem, and the key, so I need to make sure I am not missing something. I must check, is there anyone else initializing `man->cg`? Let's check through `include/drm/ttm/` to make sure! |
| 32/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "\\bcg\\b",
"PathPrefix": "include/drm/ttm/"
}Results: {
"Output": "include/drm/ttm/ttm_resource.h=199=struct ttm_resource_manager {\n--\ninclude/drm/ttm/ttm_resource.h-226-\t/**\ninclude/drm/ttm/ttm_resource.h:227:\t * @cg: \u0026dmem_cgroup_region used for memory accounting, if not NULL.\ninclude/drm/ttm/ttm_resource.h-228-\t */\ninclude/drm/ttm/ttm_resource.h:229:\tstruct dmem_cgroup_region *cg;\ninclude/drm/ttm/ttm_resource.h-230-};\n"
} |
| 33/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 43692 output: 28 thoughts: 23 Thoughts: Here's my summary, as if I were thinking these thoughts: **Analyzing `cg` in `ttm_resource_manager`** Alright, time to get down to brass tacks. I need to comprehensively understand the role of `cg` within `ttm_resource_manager`. This means a meticulous examination of *every single instance* where `cg` is assigned a value, used as a variable, passed as an argument, or referenced in any way within that module. There's no room for assumptions; I need to follow the data flow completely. This is critical for assessing its impact, particularly if it's related to any specific resource management or allocation strategies. I have to make sure I don't miss any subtle interactions or dependencies. Time to dig in and trace every single reference. |
| 34/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "-\u003ecg",
"PathPrefix": "drivers/gpu/drm/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 2685 lines.\nUse more precise expression if possible.\n\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c=972=static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c-1015-\tconfig[no_regs++] = adev-\u003epg_flags;\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1016:\tconfig[no_regs++] = lower_32_bits(adev-\u003ecg_flags);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c-1017-\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c-1032-\tconfig[no_regs++] = 0;\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1033:\tconfig[no_regs++] = upper_32_bits(adev-\u003ecg_flags);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c-1034-\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_device.c=1926=static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_device.c-2110-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_device.c:2111:\tadev-\u003ecg_flags \u0026= amdgpu_cg_mask;\ndrivers/gpu/drm/amd/amdgpu/amdgpu_device.c-2112-\tadev-\u003epg_flags \u0026= amdgpu_pg_mask;\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c=38=void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev, int xcc_id)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c-46-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c:47:\tif (adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c-48-\t (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c=63=void amdgpu_gfx_rlc_exit_safe_mode(struct amdgpu_device *adev, int xcc_id)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c-71-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c:72:\tif (adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c-73-\t (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_virt.c=68=void amdgpu_virt_init_setting(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_virt.c-80-\tddev-\u003edriver_features \u0026= ~DRIVER_ATOMIC;\ndrivers/gpu/drm/amd/amdgpu/amdgpu_virt.c:81:\tadev-\u003ecg_flags = 0;\ndrivers/gpu/drm/amd/amdgpu/amdgpu_virt.c-82-\tadev-\u003epg_flags = 0;\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c=915=int amdgpu_vram_mgr_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-920-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921:\tman-\u003ecg = drmm_cgroup_register_region(adev_to_drm(adev), \"vram\", adev-\u003egmc.real_vram_size);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:922:\tif (IS_ERR(man-\u003ecg))\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:923:\t\treturn PTR_ERR(man-\u003ecg);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-924-\tttm_resource_manager_init(man, \u0026adev-\u003emman.bdev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c=32=static void athub_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c-38-\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c:39:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_MC_MGCG))\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c-40-\t\tdata |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c=48=static void athub_update_medium_grain_light_sleep(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c-54-\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c:55:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_MC_LS) \u0026\u0026\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c:56:\t (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_HDP_LS))\ndrivers/gpu/drm/amd/amdgpu/athub_v1_0.c-57-\t\tdata |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c=34=athub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c-38-\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c:39:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_MC_MGCG))\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c-40-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c=54=athub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c-58-\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c:59:\tif (!((adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_MC_LS) \u0026\u0026\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c:60:\t (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_HDP_LS)))\ndrivers/gpu/drm/amd/amdgpu/athub_v2_0.c-61-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c=33=athub_v2_1_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c-39-\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c:40:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_MC_MGCG))\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c-41-\t\tdata |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c=50=athub_v2_1_update_medium_grain_light_sleep(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c-56-\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c:57:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_MC_LS) \u0026\u0026\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c:58:\t (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_HDP_LS))\ndrivers/gpu/drm/amd/amdgpu/athub_v2_1.c-59-\t\tdata |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c=71=athub_v3_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c-77-\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c:78:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_ATHUB_MGCG))\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c-79-\t\tdata |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c=88=athub_v3_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c-94-\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c:95:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_ATHUB_LS))\ndrivers/gpu/drm/amd/amdgpu/athub_v3_0.c-96-\t\tdata |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c=57=athub_v4_1_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c-63-\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c:64:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_ATHUB_MGCG))\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c-65-\t\tdata |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c=74=athub_v4_1_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c-80-\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c:81:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_ATHUB_LS))\ndrivers/gpu/drm/amd/amdgpu/athub_v4_1_0.c-82-\t\tdata |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/cik.c=1983=static int cik_common_early_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/cik.c-2001-\tcase CHIP_BONAIRE:\ndrivers/gpu/drm/amd/amdgpu/cik.c:2002:\t\tadev-\u003ecg_flags =\ndrivers/gpu/drm/amd/amdgpu/cik.c-2003-\t\t\tAMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/cik.c-2022-\tcase CHIP_HAWAII:\ndrivers/gpu/drm/amd/amdgpu/cik.c:2023:\t\tadev-\u003ecg_flags =\ndrivers/gpu/drm/amd/amdgpu/cik.c-2024-\t\t\tAMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/cik.c-2042-\tcase CHIP_KAVERI:\ndrivers/gpu/drm/amd/amdgpu/cik.c:2043:\t\tadev-\u003ecg_flags =\ndrivers/gpu/drm/amd/amdgpu/cik.c-2044-\t\t\tAMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/cik.c-2078-\tcase CHIP_MULLINS:\ndrivers/gpu/drm/amd/amdgpu/cik.c:2079:\t\tadev-\u003ecg_flags =\ndrivers/gpu/drm/amd/amdgpu/cik.c-2080-\t\t\tAMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c=872=static void cik_enable_sdma_mgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c-876-\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c:877:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_SDMA_MGCG)) {\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c-878-\t\tWREG32(mmSDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET, 0x00000100);\n--\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c=893=static void cik_enable_sdma_mgls(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c-897-\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c:898:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_SDMA_LS)) {\ndrivers/gpu/drm/amd/amdgpu/cik_sdma.c-899-\t\torig = data = RREG32(mmSDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET);\n--\ndrivers/gpu/drm/amd/amdgpu/df_v1_7.c=79=static void df_v1_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/df_v1_7.c-86-\ndrivers/gpu/drm/amd/amdgpu/df_v1_7.c:87:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_DF_MGCG)) {\ndrivers/gpu/drm/amd/amdgpu/df_v1_7.c-88-\t\ttmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);\n--\ndrivers/gpu/drm/amd/amdgpu/df_v3_6.c=304=static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/df_v3_6.c-308-\ndrivers/gpu/drm/amd/amdgpu/df_v3_6.c:309:\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_DF_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/df_v3_6.c-310-\t\t/* Put DF on broadcast mode */\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c=7927=static void gfx_v10_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7931-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7932:\tif (!(adev-\u003ecg_flags \u0026 (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)))\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7933-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7935-\t/* It is disabled by HW by default */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7936:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG)) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7937-\t\t/* 0 - Disable some blocks' MGCG */\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7955-\t\t/* MGLS is a global flag to control all MGLS in GFX */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7956:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGLS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7957-\t\t\t/* 2 - RLC memory Light sleep */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7958:\t\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_RLC_LS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7959-\t\t\t\tdef = data = RREG32_SOC15(GC, 0, mmRLC_MEM_SLP_CNTL);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7964-\t\t\t/* 3 - CP memory Light sleep */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7965:\t\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CP_LS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7966-\t\t\t\tdef = data = RREG32_SOC15(GC, 0, mmCP_MEM_SLP_CNTL);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7971-\t\t}\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7972:\t} else if (!enable || !(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG)) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-7973-\t\t/* 1 - MGCG_OVERRIDE */\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c=8001=static void gfx_v10_0_update_3d_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8005-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8006:\tif (!(adev-\u003ecg_flags \u0026 (AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS)))\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8007-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8014-\t\t/* unset CGCG override */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8015:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8016-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_GFX3D_CG_OVERRIDE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8025-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8026:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8027-\t\t\tdata = (0x36 \u003c\u003c RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8029-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8030:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8031-\t\t\tdata |= (0x000F \u003c\u003c RLC_CGCG_CGLS_CTRL_3D__CGLS_REP_COMPANSAT_DELAY__SHIFT) |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8047-\t\t/* disable cgcg, cgls should be disabled */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8048:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8049-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8050-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8051:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8052-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c=8060=static void gfx_v10_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8064-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8065:\tif (!(adev-\u003ecg_flags \u0026 (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)))\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8066-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8071-\t\t/* unset CGCG override */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8072:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8073-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGCG_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8074-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8075:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8076-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGLS_OVERRIDE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8085-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8086:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8087-\t\t\tdata = (0x36 \u003c\u003c RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8089-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8090:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8091-\t\t\tdata |= (0x000F \u003c\u003c RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY__SHIFT) |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8106-\t\t/* reset CGCG/CGLS bits */\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8107:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8108-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8109-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8110:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8111-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c=8119=static void gfx_v10_0_update_fine_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8123-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8124:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8125-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c=8249=static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8285-\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:8286:\tif (adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v10_0.c-8287-\t (AMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=1589=static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-1751-\t amdgpu_sriov_is_pp_one_vf(adev))\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:1752:\t\tadev-\u003ecg_flags = AMD_CG_SUPPORT_GFX_CGCG;\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-1753-\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=5404=static void gfx_v11_0_update_perf_clk(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5408-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5409:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_PERF_CLK))\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5410-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=5423=static void gfx_v11_0_update_sram_fgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5427-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5428:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5429-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=5442=static void gfx_v11_0_update_repeater_fgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5446-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5447:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_REPEATER_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5448-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=5461=static void gfx_v11_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5465-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5466:\tif (!(adev-\u003ecg_flags \u0026 (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)))\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5467-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5470-\tif (enable) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5471:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5472-\t\t\t/* 1 - RLC_CGTT_MGCG_OVERRIDE */\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5482-\t} else {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5483:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5484-\t\t\tdef = data = RREG32_SOC15(GC, 0, regRLC_CGTT_MGCG_OVERRIDE);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=5496=static void gfx_v11_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5500-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5501:\tif (!(adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5502-\t (AMD_CG_SUPPORT_GFX_CGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5511-\t\t/* unset CGCG override */\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5512:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5513-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGCG_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5514:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5515-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGLS_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5516:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG ||\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5517:\t\t adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5518-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_GFX3D_CG_OVERRIDE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5526-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5527:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5528-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5532-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5533:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5534-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5544-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5545:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5546-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5550-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5551:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5552-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGLS_REP_COMPANSAT_DELAY_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5590-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5591:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5592-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5593-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5594:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5595-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5602-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5603:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5604-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5605:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5606-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c=5624=static int gfx_v11_0_update_gfx_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5638-\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5639:\tif (adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v11_0.c-5640-\t (AMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c=3984=static void gfx_v12_0_update_perf_clk(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-3988-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:3989:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_PERF_CLK))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-3990-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c=4080=static void gfx_v12_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4084-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4085:\tif (!(adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4086-\t (AMD_CG_SUPPORT_GFX_CGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4095-\t\t/* unset CGCG override */\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4096:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4097-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGCG_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4098:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4099-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGLS_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4100:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG ||\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4101:\t\t adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4102-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_GFX3D_CG_OVERRIDE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4110-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4111:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4112-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4116-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4117:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4118-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4128-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4129:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4130-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4134-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4135:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4136-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGLS_REP_COMPANSAT_DELAY_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4174-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4175:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4176-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4177-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4178:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4179-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4186-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4187:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4188-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4189:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4190-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL_3D__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c=4197=static void gfx_v12_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4200-\tuint32_t data, def;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4201:\tif (!(adev-\u003ecg_flags \u0026 (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4202-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4205-\tif (enable) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4206:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4207-\t\t\t/* 1 - RLC_CGTT_MGCG_OVERRIDE */\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4217-\t} else {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4218:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4219-\t\t\tdef = data = RREG32_SOC15(GC, 0, regRLC_CGTT_MGCG_OVERRIDE);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c=4231=static void gfx_v12_0_update_repeater_fgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4235-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4236:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_REPEATER_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4237-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c=4252=static void gfx_v12_0_update_sram_fgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4256-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4257:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4258-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c=4271=static int gfx_v12_0_update_gfx_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4285-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c:4286:\tif (adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_0.c-4287-\t (AMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c=3063=static void gfx_v12_1_xcc_update_coarse_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3067-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3068:\tif (!(adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3069-\t (AMD_CG_SUPPORT_GFX_CGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3079-\t\t/* unset CGCG override */\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3080:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3081-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGCG_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3082:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3083-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_CGLS_OVERRIDE_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3084:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGCG ||\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3085:\t\t adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_3D_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3086-\t\t\tdata \u0026= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_GFX3D_CG_OVERRIDE_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3095-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3096:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3097-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3101-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3102:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3103-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3132-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3133:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3134-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3135-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3136:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGLS)\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3137-\t\t\tdata \u0026= ~RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c=3144=static void gfx_v12_1_xcc_update_medium_grain_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3147-\tuint32_t data, def;\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3148:\tif (!(adev-\u003ecg_flags \u0026 (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3149-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3152-\tif (enable) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3153:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3154-\t\t\t/* 1 - RLC_CGTT_MGCG_OVERRIDE */\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3164-\t} else {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3165:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3166-\t\t\tdef = data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regRLC_CGTT_MGCG_OVERRIDE);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c=3178=static void gfx_v12_1_xcc_update_repeater_fgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3182-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3183:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_REPEATER_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3184-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c=3199=static void gfx_v12_1_xcc_update_sram_fgcg(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3203-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3204:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_FGCG))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3205-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c=3218=static void gfx_v12_1_xcc_update_perf_clk(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3222-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3223:\tif (!(adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_PERF_CLK))\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3224-\t\treturn;\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c=3237=static int gfx_v12_1_xcc_update_gfx_clock_gating(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3251-\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c:3252:\tif (adev-\u003ecg_flags \u0026\ndrivers/gpu/drm/amd/amdgpu/gfx_v12_1.c-3253-\t (AMD_CG_SUPPORT_GFX_MGCG |\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c=2613=static void gfx_v6_0_enable_cgcg(struct amdgpu_device *adev, bool enable)\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c-2618-\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c:2619:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c-2620-\t\tgfx_v6_0_enable_gui_idle_interrupt(adev, true);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c=2652=static void gfx_v6_0_enable_mgcg(struct amdgpu_device *adev, bool enable)\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c-2656-\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c:2657:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG)) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c-2658-\t\torig = data = RREG32(mmCGTS_SM_CTRL_REG);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c-2662-\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c:2663:\t\tif (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CP_LS) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v6_0.c-2664-\t\t\torig = data = RREG32(mmCP_MEM_SLP_CNTL);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c=3483=static void gfx_v7_0_enable_cgcg(struct amdgpu_device *adev, bool enable)\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c-3488-\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c:3489:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_CGCG)) {\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c-3490-\t\tgfx_v7_0_enable_gui_idle_interrupt(adev, true);\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c=3526=static void gfx_v7_0_enable_mgcg(struct amdgpu_device *adev, bool enable)\n--\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c-3529-\ndrivers/gpu/drm/amd/amdgpu/gfx_v7_0.c:3530:\tif (enable \u0026\u0026 (adev-\u003ecg_flags \u0026 AMD_CG_SUPPORT_GFX_MGCG)) {\n\n"
} |
| 35/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 60169 output: 21 thoughts: 15 Thoughts: Okay, here's my interpretation of that prompt, and my response: **Filtering for the Specific Regex** Alright, I'm thinking, let's get right to the heart of the matter. I need to filter. My goal here is to zero in on specific data. Specifically, I'm looking for a pattern, a string, a concept, whatever, that matches the regular expression `\bman->cg\b`. I see the `\b`s indicating word boundaries, so I know I'm looking for the literal word "man", the literal "->", and then the literal "cg". This is the needle in the haystack. I need to extract this and I understand the tools at my disposal. This is a very specific and efficient targeting approach. I need to find the instances where that sequence shows up as a standalone "word", not just part of a larger string. This filter will get me what I need. |
| 36/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "\\bman-\u003ecg\\b"
}Results: {
"Output": "drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c=915=int amdgpu_vram_mgr_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-920-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921:\tman-\u003ecg = drmm_cgroup_register_region(adev_to_drm(adev), \"vram\", adev-\u003egmc.real_vram_size);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:922:\tif (IS_ERR(man-\u003ecg))\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:923:\t\treturn PTR_ERR(man-\u003ecg);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-924-\tttm_resource_manager_init(man, \u0026adev-\u003emman.bdev,\n--\ndrivers/gpu/drm/ttm/ttm_resource.c=389=int ttm_resource_alloc(struct ttm_buffer_object *bo,\n--\ndrivers/gpu/drm/ttm/ttm_resource.c-399-\ndrivers/gpu/drm/ttm/ttm_resource.c:400:\tif (man-\u003ecg) {\ndrivers/gpu/drm/ttm/ttm_resource.c:401:\t\tret = dmem_cgroup_try_charge(man-\u003ecg, bo-\u003ebase.size, \u0026pool,\ndrivers/gpu/drm/ttm/ttm_resource.c-402-\t\t\t\t\t ret_limit_pool, ret_over_high_pool);\n--\ndrivers/gpu/drm/ttm/ttm_resource.c=430=void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)\n--\ndrivers/gpu/drm/ttm/ttm_resource.c-445-\t*res = NULL;\ndrivers/gpu/drm/ttm/ttm_resource.c:446:\tif (man-\u003ecg)\ndrivers/gpu/drm/ttm/ttm_resource.c-447-\t\tdmem_cgroup_uncharge(pool, bo-\u003ebase.size);\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c=299=int __xe_ttm_vram_mgr_init(struct xe_device *xe, struct xe_ttm_vram_mgr *mgr,\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-307-\t\tconst char *name = mem_type == XE_PL_VRAM0 ? \"vram0\" : \"vram1\";\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308:\t\tman-\u003ecg = drmm_cgroup_register_region(\u0026xe-\u003edrm, name, size);\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:309:\t\tif (IS_ERR(man-\u003ecg))\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:310:\t\t\treturn PTR_ERR(man-\u003ecg);\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-311-\t}\n"
} |
| 37/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 61268 output: 27 thoughts: 1867 Thoughts: **Deep Dive into `dmem` and its Interaction with Graphics Drivers** Okay, so here's what I've been thinking about: the `man->cg` pointer, crucial for dmem cgroup integration, is only initialized in `amdgpu_vram_mgr.c` and `xe_ttm_vram_mgr.c`. That's a red flag. The question is, what happens if we look at `ttm_bo.c` and how it uses `man->cg`? I started by examining `ttm_bo_alloc_resource` and found that `ttm_resource_alloc` ultimately leverages `man->cg`. If `man->cg` *is* non-NULL (like in AMDGPU or Intel Xe), the code attempts to charge the buffer object's size to the cgroup. If that charge succeeds (or fails gracefully), the core allocation proceeds. Crucially, though, if `man->cg` *is* NULL (which is the *default* in other drivers), the code path for "over_high_pool" and `ttm_bo_proactive_evict_high` is entirely skipped. This means the proactive eviction logic is *never* triggered in the absence of AMDGPU or Intel Xe hardware. But I need to go deeper. Is there any way for `man->cg` to become non-NULL *without* specific AMD or Intel hardware? I have to be careful here: The documentation is very clear about the *hardware* requirement for AMD and Intel drivers, and emulating them with QEMU won't cut it. Let's keep digging and make sure there isn't some backdoor or some other interaction. Now, let's step back and consider `kernel/cgroup/dmem.c`. If `CONFIG_CGROUP_DMEM` is enabled, `dmem` becomes a cgroup subsystem in cgroup v2. So, I had to understand what happens when you *interact* with it through sysfs. It's a key part of the puzzle. I looked at the files defined within the `dmem` cgroup subsystem: `capacity`, `current`, `min`, `low`, `high`, `max`. That's where things get interesting. If a user reads or writes to, say, `/sys/fs/cgroup/.../dmem.high`, what happens? The `dmem_cgroup_region_high_show` function, in turn, calls `dmemcg_limit_show`. This function iterates through `dmem_cgroup_regions`. Now, this is *critical*. If `dmem_cgroup_regions` is empty—because no driver registered a memory region—that loop *doesn't run*. Therefore `get_resource_high` is *never* called, and we don't have access to the value. Similarly, if you *write* to `/sys/fs/cgroup/.../dmem.high`, the code calls `dmemcg_limit_write`, which tries to find a region by name. If `dmem_cgroup_regions` is empty, no region is found and it returns -EINVAL. The actual limit-setting function, `set_resource_high` will not be called. So I'm quite sure that unless you're using AMD or Intel hardware with the corresponding drivers, your interaction with the `dmem` cgroup subsystem is effectively a no-op. The resource limits are never initialized. |
| 38/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "reset_all_resource_limits|set_resource_high"
}Results: {
"Output": "kernel/cgroup/dmem.c=159=static void\nkernel/cgroup/dmem.c:160:set_resource_high(struct dmem_cgroup_pool_state *pool, u64 val)\nkernel/cgroup/dmem.c-161-{\n--\nkernel/cgroup/dmem.c=191=static u64 get_resource_current(struct dmem_cgroup_pool_state *pool)\n--\nkernel/cgroup/dmem.c-195-\nkernel/cgroup/dmem.c:196:static void reset_all_resource_limits(struct dmem_cgroup_pool_state *rpool)\nkernel/cgroup/dmem.c-197-{\n--\nkernel/cgroup/dmem.c-199-\tset_resource_low(rpool, 0);\nkernel/cgroup/dmem.c:200:\tset_resource_high(rpool, PAGE_COUNTER_MAX);\nkernel/cgroup/dmem.c-201-\tset_resource_max(rpool, PAGE_COUNTER_MAX);\n--\nkernel/cgroup/dmem.c=204=static void dmemcs_offline(struct cgroup_subsys_state *css)\n--\nkernel/cgroup/dmem.c-210-\tlist_for_each_entry_rcu(pool, \u0026dmemcs-\u003epools, css_node)\nkernel/cgroup/dmem.c:211:\t\treset_all_resource_limits(pool);\nkernel/cgroup/dmem.c-212-\trcu_read_unlock();\n--\nkernel/cgroup/dmem.c=409=alloc_pool_single(struct dmemcg_state *dmemcs, struct dmem_cgroup_region *region,\n--\nkernel/cgroup/dmem.c-431-\t\t\t ppool ? \u0026ppool-\u003ecnt : NULL, true);\nkernel/cgroup/dmem.c:432:\treset_all_resource_limits(pool);\nkernel/cgroup/dmem.c-433-\trefcount_set(\u0026pool-\u003eref, 1);\n--\nkernel/cgroup/dmem.c=931=static ssize_t dmem_cgroup_region_high_write(struct kernfs_open_file *of,\n--\nkernel/cgroup/dmem.c-933-{\nkernel/cgroup/dmem.c:934:\treturn dmemcg_limit_write(of, buf, nbytes, off, set_resource_high);\nkernel/cgroup/dmem.c-935-}\n"
} |
| 39/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64586 output: 19 thoughts: 78 Thoughts: Here's my analysis of the provided code snippet: **Investigating Resource Limit Reset** Okay, so `reset_all_resource_limits` is popping up in a couple of places. I see it's called within `dmemcs_offline`, specifically during the iteration over the `dmemcs->pools` structure. That's one location. The other place it's being called, from what the code suggests, is from `alloc_pool_single`. Now, I need to understand when `alloc_pool_single` is triggered to fully understand the scope of these resource limit resets. Therefore, I need to check the call graph for `alloc_pool_single`. I'll zero in on `kernel/cgroup/dmem.c` to see all of its callers. |
| 40/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "alloc_pool_single"
}Results: {
"Output": "kernel/cgroup/dmem.c=408=static struct dmem_cgroup_pool_state *\nkernel/cgroup/dmem.c:409:alloc_pool_single(struct dmemcg_state *dmemcs, struct dmem_cgroup_region *region,\nkernel/cgroup/dmem.c-410-\t\t struct dmem_cgroup_pool_state **allocpool)\n--\nkernel/cgroup/dmem.c=451=get_cg_pool_locked(struct dmemcg_state *dmemcs, struct dmem_cgroup_region *region,\n--\nkernel/cgroup/dmem.c-463-\t\tif (!pool)\nkernel/cgroup/dmem.c:464:\t\t\tpool = alloc_pool_single(p, region, allocpool);\nkernel/cgroup/dmem.c-465-\n"
} |
| 41/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 65080 output: 20 thoughts: 369 Thoughts: **My Analysis of `alloc_pool_single` and `dmem_cgroup_register_region` Usage** Okay, so `alloc_pool_single` is only ever called if there's a `struct dmem_cgroup_region *region`, which is key. The question now becomes: how do we *get* that `struct dmem_cgroup_region` in the first place? My initial thought is that it's exclusively created via `dmem_cgroup_register_region`. Seems straightforward enough... but I need to be absolutely sure. This warrants a more thorough check. The next step is to methodically scour the entire kernel source tree to confirm my hypothesis. Let's see... I've already `grepped` for `dmem_cgroup_register_region` and identified a few relevant files. 1. `drivers/gpu/drm/drm_drv.c`: Specifically, we have `drmm_cgroup_register_region` in this one. 2. `kernel/cgroup/dmem.c`: Implementation details here. 3. `include/linux/cgroup_dmem.h`: The declaration and some inline stub are present here. And the intriguing thing is `drmm_cgroup_register_region`. It looks like it's used in these files: 1. `drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921` 2. `drivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308` 3. `drivers/gpu/drm/drm_drv.c:964` (definition) 4. `include/drm/drm_drv.h:441` (declaration) Okay, so after meticulously reviewing these files, it's starting to look like *that's it*! There are no other calls to either `dmem_cgroup_register_region` or `drmm_cgroup_register_region` anywhere else in the entire kernel tree. But before I can confidently conclude, I should double-check to cover all possible cases. Just in case there's some kind of virtual device, mock device, or something else that's eluding the direct search, let's broaden the search a bit. Let's run a broader search for things that might be *similar* to `cgroup_register_region` or something like that. Always good to cover my bases. |
| 42/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "cgroup_register_region"
}Results: {
"Output": "drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c=915=int amdgpu_vram_mgr_init(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-920-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921:\tman-\u003ecg = drmm_cgroup_register_region(adev_to_drm(adev), \"vram\", adev-\u003egmc.real_vram_size);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c-922-\tif (IS_ERR(man-\u003ecg))\n--\ndrivers/gpu/drm/drm_drv.c=950=static void drmm_cg_unregister_region(struct drm_device *dev, void *arg)\n--\ndrivers/gpu/drm/drm_drv.c-955-/**\ndrivers/gpu/drm/drm_drv.c:956: * drmm_cgroup_register_region - Register a region of a DRM device to cgroups\ndrivers/gpu/drm/drm_drv.c-957- * @dev: device for region\n--\ndrivers/gpu/drm/drm_drv.c-963- */\ndrivers/gpu/drm/drm_drv.c:964:struct dmem_cgroup_region *drmm_cgroup_register_region(struct drm_device *dev, const char *region_name, u64 size)\ndrivers/gpu/drm/drm_drv.c-965-{\n--\ndrivers/gpu/drm/drm_drv.c-968-\ndrivers/gpu/drm/drm_drv.c:969:\tregion = dmem_cgroup_register_region(size, \"drm/%s/%s\", dev-\u003eunique, region_name);\ndrivers/gpu/drm/drm_drv.c-970-\tif (IS_ERR_OR_NULL(region))\n--\ndrivers/gpu/drm/drm_drv.c-978-}\ndrivers/gpu/drm/drm_drv.c:979:EXPORT_SYMBOL_GPL(drmm_cgroup_register_region);\ndrivers/gpu/drm/drm_drv.c-980-\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c=299=int __xe_ttm_vram_mgr_init(struct xe_device *xe, struct xe_ttm_vram_mgr *mgr,\n--\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-307-\t\tconst char *name = mem_type == XE_PL_VRAM0 ? \"vram0\" : \"vram1\";\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308:\t\tman-\u003ecg = drmm_cgroup_register_region(\u0026xe-\u003edrm, name, size);\ndrivers/gpu/drm/xe/xe_ttm_vram_mgr.c-309-\t\tif (IS_ERR(man-\u003ecg))\n--\ninclude/drm/drm_drv.h=440=struct dmem_cgroup_region *\ninclude/drm/drm_drv.h:441:drmm_cgroup_register_region(struct drm_device *dev,\ninclude/drm/drm_drv.h-442-\t\t\t const char *region_name, u64 size);\n--\ninclude/linux/cgroup_dmem.h=15=struct dmem_cgroup_region;\n--\ninclude/linux/cgroup_dmem.h-17-#if IS_ENABLED(CONFIG_CGROUP_DMEM)\ninclude/linux/cgroup_dmem.h:18:struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *name_fmt, ...) __printf(2,3);\ninclude/linux/cgroup_dmem.h-19-void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region);\n--\ninclude/linux/cgroup_dmem.h=31=static inline __printf(2,3) struct dmem_cgroup_region *\ninclude/linux/cgroup_dmem.h:32:dmem_cgroup_register_region(u64 size, const char *name_fmt, ...)\ninclude/linux/cgroup_dmem.h-33-{\n--\nkernel/cgroup/dmem.c=21=struct dmem_cgroup_region {\n--\nkernel/cgroup/dmem.c-45-\nkernel/cgroup/dmem.c:46:\t/** @name: Name describing the node, set by dmem_cgroup_register_region */\nkernel/cgroup/dmem.c-47-\tchar *name;\n--\nkernel/cgroup/dmem.c=509=static void dmemcg_free_region(struct kref *ref)\n--\nkernel/cgroup/dmem.c-519- *\nkernel/cgroup/dmem.c:520: * This function undoes dmem_cgroup_register_region.\nkernel/cgroup/dmem.c-521- */\n--\nkernel/cgroup/dmem.c=550=EXPORT_SYMBOL_GPL(dmem_cgroup_unregister_region);\n--\nkernel/cgroup/dmem.c-552-/**\nkernel/cgroup/dmem.c:553: * dmem_cgroup_register_region() - Register a regions for dev cgroup.\nkernel/cgroup/dmem.c-554- * @size: Size of region to register, in bytes.\n--\nkernel/cgroup/dmem.c-562- */\nkernel/cgroup/dmem.c:563:struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *fmt, ...)\nkernel/cgroup/dmem.c-564-{\n--\nkernel/cgroup/dmem.c-594-}\nkernel/cgroup/dmem.c:595:EXPORT_SYMBOL_GPL(dmem_cgroup_register_region);\nkernel/cgroup/dmem.c-596-\n"
} |
| 43/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 67577 output: 22 thoughts: 807 Thoughts: **Fuzzing Eligibility Assessment** Okay, hold on a second. I need to carefully analyze this. Section 2 lays out the "NEGATIVE CRITERIA," the conditions under which changes *shouldn't* trigger a fuzzing run. I'm going to internalize this list to ensure my assessment is accurate. Right, so, the key is to determine if any of the changes within `dmem.c`, `ttm_bo.c`, or `ttm_resource.c` fall under these negative criteria. I see that `ttm_resource_alloc` was modified in `ttm_resource.c`, and `ttm_bo_alloc_resource` was modified in `ttm_bo.c`. The change within `ttm_resource_alloc` includes `dmem_cgroup_pool_state` modifications. The change within `ttm_bo_alloc_resource` calls `ttm_resource_alloc`. Now, the crucial question: can we reach these functions in a fuzzable environment? Since these are TTM-related, they're likely used by *many* drivers. I can see that `ttm_resource_alloc` is called by many drivers using TTM, and `ttm_bo_alloc_resource` is called by several drivers as well! The killer question: is this reachable in QEMU? Absolutely! Think `qxl`, `vmwgfx`, or even `bochs`. These virtualized graphics drivers *will* use these TTM functions. So yes, these changes are not limited to structurally unreachable hardware. So, in conclusion, since the functions `ttm_resource_alloc` and `ttm_bo_alloc_resource` are reachable in a fuzzable environment, these modifications are *likely* eligible for fuzzing. To be absolutely certain, I need to check which drivers use `ttm_bo_alloc_resource` and `ttm_resource_alloc`. |
| 44/2 | 2026/09/23 03:01 | tool | grepper |
0mArgs:{
"Expression": "ttm_bo_alloc_resource"
}Results: {
"Output": "drivers/gpu/drm/ttm/ttm_bo.c=697=static int ttm_bo_add_pipelined_eviction_fences(struct ttm_buffer_object *bo,\n--\ndrivers/gpu/drm/ttm/ttm_bo.c-725-/**\ndrivers/gpu/drm/ttm/ttm_bo.c:726: * ttm_bo_alloc_resource - Allocate backing store for a BO\ndrivers/gpu/drm/ttm/ttm_bo.c-727- *\n--\ndrivers/gpu/drm/ttm/ttm_bo.c-743- */\ndrivers/gpu/drm/ttm/ttm_bo.c:744:static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,\ndrivers/gpu/drm/ttm/ttm_bo.c-745-\t\t\t\t struct ttm_placement *placement,\n--\ndrivers/gpu/drm/ttm/ttm_bo.c-827-/*\ndrivers/gpu/drm/ttm/ttm_bo.c:828: * ttm_bo_mem_space - Wrapper around ttm_bo_alloc_resource\ndrivers/gpu/drm/ttm/ttm_bo.c-829- *\n--\ndrivers/gpu/drm/ttm/ttm_bo.c-835- * Tries both idle allocation and forcefully eviction of buffers. See\ndrivers/gpu/drm/ttm/ttm_bo.c:836: * ttm_bo_alloc_resource for details.\ndrivers/gpu/drm/ttm/ttm_bo.c-837- */\ndrivers/gpu/drm/ttm/ttm_bo.c=838=int ttm_bo_mem_space(struct ttm_buffer_object *bo,\n--\ndrivers/gpu/drm/ttm/ttm_bo.c-846-\tdo {\ndrivers/gpu/drm/ttm/ttm_bo.c:847:\t\tret = ttm_bo_alloc_resource(bo, placement, ctx,\ndrivers/gpu/drm/ttm/ttm_bo.c-848-\t\t\t\t\t force_space, res);\n--\ndrivers/gpu/drm/ttm/ttm_bo.c=871=int ttm_bo_validate(struct ttm_buffer_object *bo,\n--\ndrivers/gpu/drm/ttm/ttm_bo.c-908-\t\t */\ndrivers/gpu/drm/ttm/ttm_bo.c:909:\t\tret = ttm_bo_alloc_resource(bo, placement, ctx, force_space,\ndrivers/gpu/drm/ttm/ttm_bo.c-910-\t\t\t\t\t \u0026res);\n"
} |
| 45/2 | 2026/09/23 03:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 69512 output: 25 thoughts: 5674 Thoughts: **Analysis of Reachability in TTM/DMEM Code Modifications**
Okay, let's break this down systematically. I've been looking at this TTM and DMEM code, specifically in the context of fuzzing and reachability. My goal is to determine if the changes are *actually* testable within a standard QEMU or GCE environment using something like syzkaller.
1. **Initial Focus: `ttm_bo.c` and Related Files:** I started by examining `ttm_bo_validate`, `ttm_bo_mem_space`, and more importantly, what happens when we allocate resources (`ttm_bo_alloc_resource`). I immediately honed in on the `dmem_cgroup_try_charge` function and the `over_high_pool` variable, which seemed to be the key to triggering any significant code paths. I then tracked the changes and followed where `over_high_pool` is used, and it led me to `ttm_bo_proactive_evict_high` and `dmem_cgroup_state_evict_valuable`.
2. **The Critical Path: `man->cg` and `dmem_cgroup_try_charge`:** The `man->cg` variable is only set when a DMEM cgroup region has been registered by a driver which is only done by `amdgpu` and `xe`. Since QEMU doesn't emulate these, `man->cg` will ALWAYS be NULL, which is the problem. Therefore, `over_high_pool` is always NULL, the `if (!ret && over_high_pool)` block is NEVER entered. This causes `ttm_bo_proactive_evict_high` to NEVER be called. This prevents any of the code related to high memory limits from being executed.
3. **Investigating `dmem_cgroup_state_evict_valuable`:** Even if `man->cg` *were* set, the crucial function becomes `dmem_cgroup_state_evict_valuable`. Without `man->cg`, it's called with NULL for both `limit_pool` and `test_pool`. Because of this, even if `CONFIG_CGROUP_DMEM` is set, `dmem_cgroup_state_evict_valuable` always returns `true`, and the if-statement is skipped. Therefore, the logic added by this patch, in the default QEMU setup, isn't active.
4. **DMEM cgroup Interaction:** I then turned my attention to the `kernel/cgroup/dmem.c` changes, because even if the previous path isn't reachable, can a user space process interact with the DMEM code via cgroupfs? After following the logic in both read and write, I learned the critical thing is the list in `dmem_cgroup_regions`.
* **Reading:** When a user reads from a `/sys/fs/cgroup/.../dmem.high` file, the `dmem_cgroup_region_high_show` function, is called, and that in turn calls `dmemcg_limit_show`. But the list `dmem_cgroup_regions` is empty. So there is nothing to read and therefore, no execution in that code path.
* **Writing:** When a user writes to `/sys/fs/cgroup/.../dmem.high`, the `dmem_cgroup_region_high_write` function is called and then it calls `dmemcg_limit_write`. However, `dmemcg_limit_write` calls `dmemcg_get_region_by_name`, but this also will return NULL since no regions have been initialized.
5. **KUnit Tests:** I noticed some KUnit tests were added. However, syzkaller does not run KUnit tests during fuzzing and they are therefore irrelevant to reachability for fuzzing.
6. **Conclusion: Unreachable Code in Standard Environments:** Based on this analysis, *none* of the modifications are reachable in a standard QEMU/GCE environment using syzkaller, since QEMU does not emulate the relevant GPU or other hardware that are needed to trigger the dmem path.
|
| 46/2 | 2026/09/23 03:02 | tool | grepper |
0mArgs:{
"Expression": "dmemcg_get_region_by_name"
}Results: {
"Output": "kernel/cgroup/dmem.c=595=EXPORT_SYMBOL_GPL(dmem_cgroup_register_region);\nkernel/cgroup/dmem.c-596-\nkernel/cgroup/dmem.c:597:static struct dmem_cgroup_region *dmemcg_get_region_by_name(const char *name)\nkernel/cgroup/dmem.c-598-{\n--\nkernel/cgroup/dmem.c=815=static ssize_t dmemcg_limit_write(struct kernfs_open_file *of,\n--\nkernel/cgroup/dmem.c-846-\t\trcu_read_lock();\nkernel/cgroup/dmem.c:847:\t\tregion = dmemcg_get_region_by_name(region_name);\nkernel/cgroup/dmem.c-848-\t\trcu_read_unlock();\n"
} |
| 47/2 | 2026/09/23 03:02 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 76369 output: 37 thoughts: 17 Thoughts: Okay, here's my interpretation of what's going through my mind as I approach the code: **Diving into `dmemcg_get_region_by_name`** Alright, let's get into this `dmemcg_get_region_by_name` function. I see the name, so I'm immediately thinking, "Okay, this has something to do with retrieving a memory region, likely based on a name, and in the context of dmemcg, which suggests direct memory access within a cgroup." Immediately I start to wonder about the data structures involved, namely, how regions are defined, how they are named, how the cgroup hierarchy fits in, and what kind of error conditions I should expect. I'm already anticipating the use of some kind of lookup mechanism, probably a hash table or a list, but I'm curious about the specific implementation choices here, particularly concerning lock contention in a multi-threaded system. My mind is already racing, looking for any optimization hints or potential bottlenecks. I'll be focused on how this function integrates with the overall dmemcg architecture. Is this a critical path function? Does it hold any locks? If so, what are the implications for concurrency? I'm ready to dive in and understand the details. |
| 48/2 | 2026/09/23 03:02 | tool | read-file |
0mArgs:{
"File": "kernel/cgroup/dmem.c",
"FirstLine": 597,
"LineCount": 20
}Results: {
"Contents": " 597:\tstatic struct dmem_cgroup_region *dmemcg_get_region_by_name(const char *name)\n 598:\t{\n 599:\t\tstruct dmem_cgroup_region *region;\n 600:\t\n 601:\t\tlist_for_each_entry_rcu(region, \u0026dmem_cgroup_regions, region_node, spin_is_locked(\u0026dmemcg_lock))\n 602:\t\t\tif (!strcmp(name, region-\u003ename) \u0026\u0026\n 603:\t\t\t kref_get_unless_zero(\u0026region-\u003eref))\n 604:\t\t\t\treturn region;\n 605:\t\n 606:\t\treturn NULL;\n 607:\t}\n 608:\t\n 609:\t/**\n 610:\t * dmem_cgroup_pool_state_put() - Drop a reference to a dmem_cgroup_pool_state\n 611:\t * @pool: \u0026dmem_cgroup_pool_state\n 612:\t *\n 613:\t * Called to drop a reference to the limiting pool returned by\n 614:\t * dmem_cgroup_try_charge().\n 615:\t */\n 616:\tvoid dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool)\n"
} |
| 49/2 | 2026/09/23 03:02 | llm | patch-evaluator-compressor |
0mModel:gemini-3.8-flash Args: null Results: null Reply: ### 1. Approaches Tried and Results
- **Patch Diff Inspection**:
- Identified modifications across DRM TTM core (`ttm_bo.c`, `ttm_resource.c`, `include/drm/ttm/ttm_resource.h`), KUnit tests (`ttm_bo_test.c`, `ttm_bo_validate_test.c`, `ttm_resource_test.c`), generic cgroup dmem controller (`kernel/cgroup/dmem.c`), and its header (`include/linux/cgroup_dmem.h`).
- Added proactive reclaim logic for memory pools exceeding soft limit `dmem.high` (`ttm_bo_proactive_evict_high`), plumbed `try_high` and ancestor checks into `dmem_cgroup_state_evict_valuable` and `dmem_cgroup_try_charge`, and exposed the `high` cgroup attribute.
- **Kconfig and Subsystem Analysis for `CGROUP_DMEM`**:
- Inspected `init/Kconfig` and build files. `CONFIG_CGROUP_DMEM` selects `PAGE_COUNTER` and enables the `dmem` cgroup controller (`kernel/cgroup/dmem.c`).
- Controller registers `dmem_cgrp_subsys` with cftypes `capacity`, `current`, `min`, `low`, `high`, `max`.
- **Region Registration Caller Analysis**:
- Searched kernel tree for `dmem_cgroup_register_region`. Found it is wrapped by `drmm_cgroup_register_region` in `drivers/gpu/drm/drm_drv.c`.
- Searched tree for callers of `drmm_cgroup_register_region`:
- `drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921` (`amdgpu_vram_mgr_init`)
- `drivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308` (`__xe_ttm_vram_mgr_init`)
- No other drivers anywhere in the kernel register a `dmem_cgroup_region`.
- **Inspection of TTM Resource Manager `man->cg` Users**:
- `man->cg` is populated exclusively by `amdgpu_vram_mgr.c` and `xe_ttm_vram_mgr.c`.
- Emulated/virtual display drivers in QEMU (`qxl`, `bochs-drm`, `vmwgfx`, `virtio-gpu`) either do not use TTM resource manager cgroups or do not set `man->cg`.
- **Analysis of `kernel/cgroup/dmem.c` cgroupfs Entrypoints Without Hardware**:
- Investigated if reading/writing `dmem.high` or other cgroup files can execute modified logic without a registered region:
- Reading `dmem.high` invokes `dmem_cgroup_region_high_show` -> `dmemcg_limit_show`. Iterates `dmem_cgroup_regions`. With no regions registered, the list is empty and it returns 0 immediately without calling `get_resource_high`.
- Writing `dmem.high` invokes `dmem_cgroup_region_high_write` -> `dmemcg_limit_write`. Looks up region by name (`dmemcg_get_region_by_name`). If `!region`, returns `-EINVAL` immediately before calling `set_resource_high`.
- **Dead-ends**:
- Broad grep for `->cg` in `drivers/gpu/drm/` matched hundreds of clock-gating (`cg_flags`) macros in AMDGPU rather than `ttm_resource_manager->cg`. Clarified that only `amdgpu_vram_mgr.c` and `xe_ttm_vram_mgr.c` touch the field.
---
### 2. Current Hypotheses and Active Lines of Investigation
- **Hardware Reachability Assessment**:
- The patch modifies core DRM TTM files (`ttm_bo.c`, `ttm_resource.c`) and core cgroup code (`kernel/cgroup/dmem.c`).
- However, execution of all new and modified code paths (`ttm_bo_proactive_evict_high`, `dmem_cgroup_try_charge`'s `ret_over_high_pool` handling, `dmem_cgroup_state_evict_valuable`'s `try_high` ancestor evaluation, `set_resource_high`, and `get_resource_high`) strictly requires at least one registered `dmem_cgroup_region`.
- Only physical ASIC GPU drivers (`amdgpu` and Intel `xe`) register regions. Standard QEMU/syzkaller virtual environments do not emulate AMDGPU or Intel Xe ASICs.
- Per Section 2 of the triage criteria:
> "Structurally unreachable hardware: Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU."
- Working hypothesis: The changes are structurally unreachable in QEMU/syzkaller fuzzing environments because they require physical AMD or Intel Xe GPU hardware, and the cgroupfs entrypoints are inert stubs when no region is registered.
---
### 3. Critical Files, Code Snippets, and Configuration Values
- **`kernel/cgroup/dmem.c`**:
- High watermark setter and getter:
```c
static void set_resource_high(struct dmem_cgroup_pool_state *pool, u64 val)
{
page_counter_set_high(&pool->cnt, val);
}
static u64 get_resource_high(struct dmem_cgroup_pool_state *pool)
{
return pool ? READ_ONCE(pool->cnt.high) : PAGE_COUNTER_MAX;
}
```
- Gate in `dmemcg_limit_write`:
```c
rcu_read_lock();
region = dmemcg_get_region_by_name(region_name);
rcu_read_unlock();
if (!region)
return -EINVAL;
```
(Writing to `dmem.high` without a registered region fails before calling `set_resource_high`).
- Gate in `dmemcg_limit_show`:
```c
rcu_read_lock();
list_for_each_entry_rcu(region, &dmem_cgroup_regions, region_node) {
...
}
rcu_read_unlock();
```
(Reading `dmem.high` without a registered region returns empty/0 without calling `get_resource_high`).
- **`drivers/gpu/drm/ttm/ttm_resource.c`**:
```c
if (man->cg) {
ret = dmem_cgroup_try_charge(man->cg, bo->base.size, &pool,
ret_limit_pool, ret_over_high_pool);
```
Only runs when `man->cg` is set.
- **Callers registering regions**:
- `drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:921`:
`man->cg = drmm_cgroup_register_region(adev_to_drm(adev), "vram", adev->gmc.real_vram_size);`
- `drivers/gpu/drm/xe/xe_ttm_vram_mgr.c:308`:
`man->cg = drmm_cgroup_register_region(&xe->drm, name, size);`
- **Configurations**:
- `CONFIG_CGROUP_DMEM` (`init/Kconfig`)
- `CONFIG_DRM_AMDGPU`
- `CONFIG_DRM_XE`
- `CONFIG_DRM_TTM`
---
### 4. Watch Out for Repetitive Loops or Errors
- **Grepping for `cg` without boundaries**: Grepping `->cg` or `cg` in `drivers/gpu/drm` matches thousands of AMDGPU clock-gating lines (`adev->cg_flags`, `AMD_CG_SUPPORT_*`). Use strict symbol/field matching (`man->cg` or struct-specific searches).
- **Assuming core/cgroup changes are automatically reachable**: Even though `ttm_bo.c` and `dmem.c` are core files, their new paths are gated behind `man->cg` and `dmem_cgroup_regions`, which depend strictly on physical AMD or Intel Xe GPU hardware. Do not re-investigate QEMU virtual display drivers (confirmed none set `man->cg`).Tokens: input: 62076 output: 2037 thoughts: 2020 |
| 50/2 | 2026/09/23 03:02 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 21721 output: 192 thoughts: 2175 Thoughts: **Analysis of the Patch: Structural Unreachability and Fuzzing Considerations** Alright, let's break this down. My initial concern was about ensuring every aspect of this patch is sound, especially regarding its potential for interaction with the fuzzing environment. I see that the core of this patch introduces updates to DRM TTM (Translation Table Manager) components. The changes involve modifying `ttm_bo_evict_cb` to handle a `try_high` flag for dmem cgroup eviction, defining `ttm_bo_proactive_evict_high`, and integrating these elements with resource allocation (`ttm_bo_alloc_resource` and `ttm_resource_alloc`). We're also seeing new functions (`set_resource_high`, `get_resource_high`) and cgroupfs interface (`high`) for the `dmem` cgroup controller. The critical question is always reachability. I understand that the patch introduces changes related to the `dmem` cgroup controller and integrates it with the DRM TTM code. I immediately think, where are these changes relevant? I'm observing that code paths are conditionally enabled based on the presence of a `man->cg` (cgroup) pointer in `ttm_resource_manager`. My analysis shows this pointer is only set by the AMDGPU and Intel Xe drivers, which are the only ones registering `dmem_cgroup_region`. I remember the triage rules. My quick scan confirms: hardware that isn't emulated in standard QEMU environments – vendor-specific PCIe cards, switches, SmartNICs, or GPU drivers like AMDGPU, are considered structurally unreachable. It is clear that standard virtualization doesn't emulate AMDGPU or Xe. So, digging deeper, I see that the `dmem.high` cgroupfs interface, which controls the high memory watermark for eviction, is ineffective without a registered region. If the `dmem_cgroup_regions` list is empty, which it is in the absence of a registered region, write operations to `dmem.high` return `-EINVAL` immediately, and read operations don't execute. This reinforces the conditional behavior tied to AMDGPU or Xe. No pools are allocated or accessed because the cgroup region isn't registered. I also notice the KUnit tests that were modified. However, the triage guidance explicitly states that in-kernel unit tests are irrelevant since they do not impact the compiled kernel image. Putting all of this together, I'm confident in assessing this. The entire code path, including all the changes, is only reachable under the presence of AMDGPU or Xe hardware. Therefore, given the triage rules, `WorthFuzzing` should be `false`. My reasoning rests on the fact that the changes are unreachable without specific, unsupported hardware. My configuration should be empty. Finally, no particular symbols are worth targeting. I'm ready to `set-results`. |
| 51/2 | 2026/09/23 03:02 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch implements proactive reclaim and high watermark threshold handling for the dmem cgroup controller and DRM TTM. All runtime code paths introduced or modified (including proactive eviction in ttm_bo.c, dmem charge tracking, high limit checks, and the dmem.high cgroup control interface) strictly require registered dmem memory regions and a configured TTM manager cgroup (man-\u003ecg). The only drivers in the kernel that register dmem regions and set man-\u003ecg are amdgpu and Intel xe, both of which require physical GPU ASICs that are not emulated in standard virtualized environments (QEMU/syzkaller). Without registered regions, cgroup operations on dmem.high fail immediately with -EINVAL or return 0, leaving all modified logic structurally unreachable.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch implements proactive reclaim and high watermark threshold handling for the dmem cgroup controller and DRM TTM. All runtime code paths introduced or modified (including proactive eviction in ttm_bo.c, dmem charge tracking, high limit checks, and the dmem.high cgroup control interface) strictly require registered dmem memory regions and a configured TTM manager cgroup (man-\u003ecg). The only drivers in the kernel that register dmem regions and set man-\u003ecg are amdgpu and Intel xe, both of which require physical GPU ASICs that are not emulated in standard virtualized environments (QEMU/syzkaller). Without registered regions, cgroup operations on dmem.high fail immediately with -EINVAL or return 0, leaving all modified logic structurally unreachable.",
"WorthFuzzing": false
} |
| 52/1 | 2026/09/23 03:02 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|