Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

drm/amdgpu: delay job free to when it's finished (v2)



for those jobs submitted through scheduler, do not
free it immediately after scheduled, instead free it
in global workqueue by its sched fence signaling
callback function.

v2:
call uf's bo_undef after job_run()
call job's sync free after job_run()
no static inline __amdgpu_job_free() anymore, just use
kfree(job) to replace it.

Signed-off-by: default avatarMonk Liu <Monk.Liu@amd.com>
Reviewed-by: default avatarChunming Zhou <david1.zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 01c02a8b
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -2401,5 +2401,4 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
		       uint64_t addr, struct amdgpu_bo **bo);

#include "amdgpu_object.h"

#endif
+10 −1
Original line number Diff line number Diff line
@@ -28,6 +28,12 @@
#include "amdgpu.h"
#include "amdgpu_trace.h"

static void amdgpu_job_free_handler(struct work_struct *ws)
{
	struct amdgpu_job *job = container_of(ws, struct amdgpu_job, base.work_free_job);
	kfree(job);
}

int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
		     struct amdgpu_job **job)
{
@@ -45,6 +51,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
	(*job)->adev = adev;
	(*job)->ibs = (void *)&(*job)[1];
	(*job)->num_ibs = num_ibs;
	INIT_WORK(&(*job)->base.work_free_job, amdgpu_job_free_handler);

	amdgpu_sync_create(&(*job)->sync);

@@ -80,6 +87,8 @@ void amdgpu_job_free(struct amdgpu_job *job)

	amdgpu_bo_unref(&job->uf.bo);
	amdgpu_sync_free(&job->sync);

	if (!job->base.use_sched)
		kfree(job);
}

+8 −0
Original line number Diff line number Diff line
@@ -319,6 +319,11 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job)
	return added;
}

static void amd_sched_free_job(struct fence *f, struct fence_cb *cb) {
	struct amd_sched_job *job = container_of(cb, struct amd_sched_job, cb_free_job);
	schedule_work(&job->work_free_job);
}

/**
 * Submit a job to the job queue
 *
@@ -330,6 +335,9 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job)
{
	struct amd_sched_entity *entity = sched_job->s_entity;

	sched_job->use_sched = 1;
	fence_add_callback(&sched_job->s_fence->base,
					&sched_job->cb_free_job, amd_sched_free_job);
	trace_amd_sched_job(sched_job);
	wait_event(entity->sched->job_scheduled,
		   amd_sched_entity_in(sched_job));
+4 −1
Original line number Diff line number Diff line
@@ -82,6 +82,9 @@ struct amd_sched_job {
	struct amd_gpu_scheduler        *sched;
	struct amd_sched_entity         *s_entity;
	struct amd_sched_fence          *s_fence;
	bool	use_sched;	/* true if the job goes to scheduler */
	struct fence_cb                cb_free_job;
	struct work_struct             work_free_job;
};

extern const struct fence_ops amd_sched_fence_ops;