drm/amdgpu: use correct gfp_t for job allocation

For job allocation in GPU reset and page fault handling we must use
GFP_ATOMIC to guarantee that we don't cycle back and depend on a
dma_fence submission for the memory allocation.

Add gfp_flags argument to amdgpu_job_alloc() and expose the
gfp_flags of IB pools with amdgpu_ib_pool_gfp_flags() so that
we can use different flags when allocating jobs.

Assisted-by: Claude:Sonnet 4
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Christian König
2026-05-11 14:46:54 +02:00
committed by Alex Deucher
parent ba4af3ca26
commit 60bbdfb959
6 changed files with 22 additions and 7 deletions

View File

@@ -711,7 +711,8 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
goto err;
}
ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, 0, &job);
ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, 0, GFP_KERNEL,
&job);
if (ret)
goto err;

View File

@@ -268,7 +268,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
for (i = 0; i < p->gang_size; ++i) {
ret = amdgpu_job_alloc(p->adev, vm, p->entities[i], vm,
num_ibs[i], p->filp->client_id,
&p->jobs[i]);
GFP_KERNEL, &p->jobs[i]);
if (ret)
goto free_all_kdata;
switch (p->adev->enforce_isolation[fpriv->xcp_id]) {

View File

@@ -416,6 +416,17 @@ void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
adev->ib_pool_ready = false;
}
/**
* amdgpu_ib_pool_gfp_flags - Returns the gfp flags to use for each pool
* @adev: amdgpu device pointer
* @type: the IB pool type
*/
gfp_t amdgpu_ib_pool_gfp_flags(struct amdgpu_device *adev,
enum amdgpu_ib_pool_type type)
{
return adev->ib_pools[type].gfp_flags;
}
/**
* amdgpu_ib_ring_tests - test IBs on the rings
*

View File

@@ -199,7 +199,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct drm_sched_entity *entity, void *owner,
unsigned int num_ibs, u64 drm_client_id,
struct amdgpu_job **job)
gfp_t gfp_flags, struct amdgpu_job **job)
{
struct amdgpu_fence *af;
int r;
@@ -207,18 +207,18 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (num_ibs == 0)
return -EINVAL;
*job = kzalloc_flex(**job, ibs, num_ibs);
*job = kzalloc_flex(**job, ibs, num_ibs, gfp_flags);
if (!*job)
return -ENOMEM;
af = kzalloc_obj(struct amdgpu_fence);
af = kzalloc_obj(struct amdgpu_fence, gfp_flags);
if (!af) {
r = -ENOMEM;
goto err_job;
}
(*job)->hw_fence = af;
af = kzalloc_obj(struct amdgpu_fence);
af = kzalloc_obj(struct amdgpu_fence, gfp_flags);
if (!af) {
r = -ENOMEM;
goto err_fence;
@@ -257,6 +257,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
int r;
r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, k_job_id,
amdgpu_ib_pool_gfp_flags(adev, pool_type),
job);
if (r)
return r;

View File

@@ -116,7 +116,7 @@ static inline struct amdgpu_ring *amdgpu_job_ring(struct amdgpu_job *job)
int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct drm_sched_entity *entity, void *owner,
unsigned int num_ibs, u64 drm_client_id,
struct amdgpu_job **job);
gfp_t gfp_flags, struct amdgpu_job **job);
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
struct drm_sched_entity *entity, void *owner,
size_t size, enum amdgpu_ib_pool_type pool_type,

View File

@@ -583,6 +583,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
struct dma_fence **f);
int amdgpu_ib_pool_init(struct amdgpu_device *adev);
void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
gfp_t amdgpu_ib_pool_gfp_flags(struct amdgpu_device *adev,
enum amdgpu_ib_pool_type type);
int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring);
void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,