Commit 747d4f71 authored by Monk Liu's avatar Monk Liu Committed by Alex Deucher
Browse files

drm/amdgpu: fix calltrace during kmd unload(v3)



issue:
kernel would report a warning from a double unpin
during the driver unloading on the CSB bo

why:
we unpin it during hw_fini, and there will be another
unpin in sw_fini on CSB bo.

fix:
actually we don't need to pin/unpin it during
hw_init/fini since it is created with kernel pinned,
we only need to fullfill the CSB again during hw_init
to prevent CSB/VRAM lost after S3

v2:
get_csb in init_rlc so hw_init() will make CSIB content
back even after reset or s3

v3:
use bo_create_kernel instead of bo_create_reserved for CSB
otherwise the bo_free_kernel() on CSB is not aligned and
would lead to its internal reserve pending there forever

take care of gfx7/8 as well

Signed-off-by: default avatarMonk Liu <Monk.Liu@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: default avatarXiaojie Yuan <xiaojie.yuan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fa2b93e3
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -124,13 +124,12 @@ int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws)
 */
int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
{
	volatile u32 *dst_ptr;
	u32 dws;
	int r;

	/* allocate clear state block */
	adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev);
	r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
	r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
				      AMDGPU_GEM_DOMAIN_VRAM,
				      &adev->gfx.rlc.clear_state_obj,
				      &adev->gfx.rlc.clear_state_gpu_addr,
@@ -141,13 +140,6 @@ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
		return r;
	}

	/* set up the cs buffer */
	dst_ptr = adev->gfx.rlc.cs_ptr;
	adev->gfx.rlc.funcs->get_csb_buffer(adev, dst_ptr);
	amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
	amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);

	return 0;
}

+1 −57
Original line number Diff line number Diff line
@@ -993,39 +993,6 @@ static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
	return 0;
}

static int gfx_v10_0_csb_vram_pin(struct amdgpu_device *adev)
{
	int r;

	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
	if (unlikely(r != 0))
		return r;

	r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
			AMDGPU_GEM_DOMAIN_VRAM);
	if (!r)
		adev->gfx.rlc.clear_state_gpu_addr =
			amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);

	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);

	return r;
}

static void gfx_v10_0_csb_vram_unpin(struct amdgpu_device *adev)
{
	int r;

	if (!adev->gfx.rlc.clear_state_obj)
		return;

	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
	if (likely(r == 0)) {
		amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
	}
}

static void gfx_v10_0_mec_fini(struct amdgpu_device *adev)
{
	amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -1787,25 +1754,7 @@ static void gfx_v10_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,

static int gfx_v10_0_init_csb(struct amdgpu_device *adev)
{
	int r;

	if (adev->in_gpu_reset) {
		r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
		if (r)
			return r;

		r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj,
				   (void **)&adev->gfx.rlc.cs_ptr);
		if (!r) {
			adev->gfx.rlc.funcs->get_csb_buffer(adev,
					adev->gfx.rlc.cs_ptr);
			amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
		}

		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
		if (r)
			return r;
	}
	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);

	/* csib */
	WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI,
@@ -3776,10 +3725,6 @@ static int gfx_v10_0_hw_init(void *handle)
	int r;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	r = gfx_v10_0_csb_vram_pin(adev);
	if (r)
		return r;

	if (!amdgpu_emu_mode)
		gfx_v10_0_init_golden_registers(adev);

@@ -3867,7 +3812,6 @@ static int gfx_v10_0_hw_fini(void *handle)
	}
	gfx_v10_0_cp_enable(adev, false);
	gfx_v10_0_enable_gui_idle_interrupt(adev, false);
	gfx_v10_0_csb_vram_unpin(adev);

	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -4554,6 +4554,8 @@ static int gfx_v7_0_hw_init(void *handle)

	gfx_v7_0_constants_init(adev);

	/* init CSB */
	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
	/* init rlc */
	r = adev->gfx.rlc.funcs->resume(adev);
	if (r)
+1 −39
Original line number Diff line number Diff line
@@ -1321,39 +1321,6 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
	return 0;
}

static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev)
{
	int r;

	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
	if (unlikely(r != 0))
		return r;

	r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
			AMDGPU_GEM_DOMAIN_VRAM);
	if (!r)
		adev->gfx.rlc.clear_state_gpu_addr =
			amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);

	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);

	return r;
}

static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev)
{
	int r;

	if (!adev->gfx.rlc.clear_state_obj)
		return;

	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
	if (likely(r == 0)) {
		amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
	}
}

static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
{
	amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -3917,6 +3884,7 @@ static void gfx_v8_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,

static void gfx_v8_0_init_csb(struct amdgpu_device *adev)
{
	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
	/* csib */
	WREG32(mmRLC_CSIB_ADDR_HI,
			adev->gfx.rlc.clear_state_gpu_addr >> 32);
@@ -4837,10 +4805,6 @@ static int gfx_v8_0_hw_init(void *handle)
	gfx_v8_0_init_golden_registers(adev);
	gfx_v8_0_constants_init(adev);

	r = gfx_v8_0_csb_vram_pin(adev);
	if (r)
		return r;

	r = adev->gfx.rlc.funcs->resume(adev);
	if (r)
		return r;
@@ -4958,8 +4922,6 @@ static int gfx_v8_0_hw_fini(void *handle)
		pr_err("rlc is busy, skip halt rlc\n");
	amdgpu_gfx_rlc_exit_safe_mode(adev);

	gfx_v8_0_csb_vram_unpin(adev);

	return 0;
}

+1 −39
Original line number Diff line number Diff line
@@ -1695,39 +1695,6 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
	return 0;
}

static int gfx_v9_0_csb_vram_pin(struct amdgpu_device *adev)
{
	int r;

	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
	if (unlikely(r != 0))
		return r;

	r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
			AMDGPU_GEM_DOMAIN_VRAM);
	if (!r)
		adev->gfx.rlc.clear_state_gpu_addr =
			amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);

	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);

	return r;
}

static void gfx_v9_0_csb_vram_unpin(struct amdgpu_device *adev)
{
	int r;

	if (!adev->gfx.rlc.clear_state_obj)
		return;

	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
	if (likely(r == 0)) {
		amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
	}
}

static void gfx_v9_0_mec_fini(struct amdgpu_device *adev)
{
	amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -2415,6 +2382,7 @@ static void gfx_v9_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,

static void gfx_v9_0_init_csb(struct amdgpu_device *adev)
{
	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
	/* csib */
	WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_HI),
			adev->gfx.rlc.clear_state_gpu_addr >> 32);
@@ -3706,10 +3674,6 @@ static int gfx_v9_0_hw_init(void *handle)

	gfx_v9_0_constants_init(adev);

	r = gfx_v9_0_csb_vram_pin(adev);
	if (r)
		return r;

	r = adev->gfx.rlc.funcs->resume(adev);
	if (r)
		return r;
@@ -3791,8 +3755,6 @@ static int gfx_v9_0_hw_fini(void *handle)
	gfx_v9_0_cp_enable(adev, false);
	adev->gfx.rlc.funcs->stop(adev);

	gfx_v9_0_csb_vram_unpin(adev);

	return 0;
}