Skip to content

Commit f18f580

Browse files
mikelrChristianKoenigAMD
authored andcommitted
drm/radeon: Fix NULL dereference when updating memory stats
radeon_ttm_bo_destroy() is attempting to access the resource object to update memory counters. However, the resource object is already freed when ttm calls this function via the destroy callback. This causes an oops when a bo is freed: BUG: kernel NULL pointer dereference, address: 0000000000000010 RIP: 0010:radeon_ttm_bo_destroy+0x2c/0x100 [radeon] Call Trace: radeon_bo_unref+0x1a/0x30 [radeon] radeon_gem_object_free+0x33/0x50 [radeon] drm_gem_object_release_handle+0x69/0x70 [drm] drm_gem_handle_delete+0x62/0xa0 [drm] ? drm_mode_destroy_dumb+0x40/0x40 [drm] drm_ioctl_kernel+0xb2/0xf0 [drm] drm_ioctl+0x30a/0x3c0 [drm] ? drm_mode_destroy_dumb+0x40/0x40 [drm] radeon_drm_ioctl+0x49/0x80 [radeon] __x64_sys_ioctl+0x8e/0xd0 Avoid the issue by updating the counters in the delete_mem_notify callback instead. Also, fix memory statistic updating in radeon_bo_move() to identify the source type correctly. The source type needs to be saved before the move, because the moved from object may be altered by the move. Fixes: bfa3357 ("drm/ttm: allocate resource object instead of embedding it v2") Signed-off-by: Mikel Rychliski <[email protected]> Reviewed-by: Christian König <[email protected]> Signed-off-by: Christian König <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent cd8f318 commit f18f580

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

drivers/gpu/drm/radeon/radeon_object.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,23 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo);
4949
* function are calling it.
5050
*/
5151

52-
static void radeon_update_memory_usage(struct radeon_bo *bo,
53-
unsigned mem_type, int sign)
52+
static void radeon_update_memory_usage(struct ttm_buffer_object *bo,
53+
unsigned int mem_type, int sign)
5454
{
55-
struct radeon_device *rdev = bo->rdev;
55+
struct radeon_device *rdev = radeon_get_rdev(bo->bdev);
5656

5757
switch (mem_type) {
5858
case TTM_PL_TT:
5959
if (sign > 0)
60-
atomic64_add(bo->tbo.base.size, &rdev->gtt_usage);
60+
atomic64_add(bo->base.size, &rdev->gtt_usage);
6161
else
62-
atomic64_sub(bo->tbo.base.size, &rdev->gtt_usage);
62+
atomic64_sub(bo->base.size, &rdev->gtt_usage);
6363
break;
6464
case TTM_PL_VRAM:
6565
if (sign > 0)
66-
atomic64_add(bo->tbo.base.size, &rdev->vram_usage);
66+
atomic64_add(bo->base.size, &rdev->vram_usage);
6767
else
68-
atomic64_sub(bo->tbo.base.size, &rdev->vram_usage);
68+
atomic64_sub(bo->base.size, &rdev->vram_usage);
6969
break;
7070
}
7171
}
@@ -76,8 +76,6 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
7676

7777
bo = container_of(tbo, struct radeon_bo, tbo);
7878

79-
radeon_update_memory_usage(bo, bo->tbo.resource->mem_type, -1);
80-
8179
mutex_lock(&bo->rdev->gem.mutex);
8280
list_del_init(&bo->list);
8381
mutex_unlock(&bo->rdev->gem.mutex);
@@ -727,24 +725,21 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
727725
}
728726

729727
void radeon_bo_move_notify(struct ttm_buffer_object *bo,
730-
bool evict,
728+
unsigned int old_type,
731729
struct ttm_resource *new_mem)
732730
{
733731
struct radeon_bo *rbo;
734732

733+
radeon_update_memory_usage(bo, old_type, -1);
734+
if (new_mem)
735+
radeon_update_memory_usage(bo, new_mem->mem_type, 1);
736+
735737
if (!radeon_ttm_bo_is_radeon_bo(bo))
736738
return;
737739

738740
rbo = container_of(bo, struct radeon_bo, tbo);
739741
radeon_bo_check_tiling(rbo, 0, 1);
740742
radeon_vm_bo_invalidate(rbo->rdev, rbo);
741-
742-
/* update statistics */
743-
if (!new_mem)
744-
return;
745-
746-
radeon_update_memory_usage(rbo, bo->resource->mem_type, -1);
747-
radeon_update_memory_usage(rbo, new_mem->mem_type, 1);
748743
}
749744

750745
vm_fault_t radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)

drivers/gpu/drm/radeon/radeon_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
161161
extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
162162
bool force_drop);
163163
extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
164-
bool evict,
164+
unsigned int old_type,
165165
struct ttm_resource *new_mem);
166166
extern vm_fault_t radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
167167
extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);

drivers/gpu/drm/radeon/radeon_ttm.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
199199
struct ttm_resource *old_mem = bo->resource;
200200
struct radeon_device *rdev;
201201
struct radeon_bo *rbo;
202-
int r;
202+
int r, old_type;
203203

204204
if (new_mem->mem_type == TTM_PL_TT) {
205205
r = radeon_ttm_tt_bind(bo->bdev, bo->ttm, new_mem);
@@ -216,6 +216,9 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
216216
if (WARN_ON_ONCE(rbo->tbo.pin_count > 0))
217217
return -EINVAL;
218218

219+
/* Save old type for statistics update */
220+
old_type = old_mem->mem_type;
221+
219222
rdev = radeon_get_rdev(bo->bdev);
220223
if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
221224
ttm_bo_move_null(bo, new_mem);
@@ -261,7 +264,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
261264
out:
262265
/* update statistics */
263266
atomic64_add(bo->base.size, &rdev->num_bytes_moved);
264-
radeon_bo_move_notify(bo, evict, new_mem);
267+
radeon_bo_move_notify(bo, old_type, new_mem);
265268
return 0;
266269
}
267270

@@ -682,7 +685,11 @@ bool radeon_ttm_tt_is_readonly(struct radeon_device *rdev,
682685
static void
683686
radeon_bo_delete_mem_notify(struct ttm_buffer_object *bo)
684687
{
685-
radeon_bo_move_notify(bo, false, NULL);
688+
unsigned int old_type = TTM_PL_SYSTEM;
689+
690+
if (bo->resource)
691+
old_type = bo->resource->mem_type;
692+
radeon_bo_move_notify(bo, old_type, NULL);
686693
}
687694

688695
static struct ttm_device_funcs radeon_bo_driver = {

0 commit comments

Comments
 (0)