[Intel-xe] [PATCH] drm/xe: Fix error paths of __xe_bo_create_locked

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Fri Jul 28 10:15:01 UTC 2023


Hey,

On 2023-07-25 19:22, Matthew Brost wrote:
> On Tue, Jul 25, 2023 at 05:12:39PM +0200, Maarten Lankhorst wrote:
>> ttm_bo_init_reserved() calls the destroy() callback if it fails.
>>
>> Because of this, __xe_bo_create_locked is required to be responsible
>> for freeing the bo even when it's passed in as argument.
>>
>> Additionally, if the placement check fails, the bo was kept alive.
>> Fix it too.
>>
>> Reported-by: Oded Gabbay <ogabbay at kernel.org>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
>> ---
>>   drivers/gpu/drm/xe/xe_bo.c | 8 ++++++--
>>   1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
>> index e240df6c7ae64..b63290540dd9b 100644
>> --- a/drivers/gpu/drm/xe/xe_bo.c
>> +++ b/drivers/gpu/drm/xe/xe_bo.c
>> @@ -1158,8 +1158,10 @@ struct xe_bo *__xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
>>   	/* Only kernel objects should set GT */
>>   	XE_BUG_ON(tile && type != ttm_bo_type_kernel);
>>   
>> -	if (XE_WARN_ON(!size))
>> +	if (XE_WARN_ON(!size)) {
>> +		xe_bo_free(bo);
>>   		return ERR_PTR(-EINVAL);
>> +	}
>>   
>>   	if (!bo) {
>>   		bo = xe_bo_alloc();
>> @@ -1197,8 +1199,10 @@ struct xe_bo *__xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
>>   
>>   	if (!(flags & XE_BO_FIXED_PLACEMENT_BIT)) {
>>   		err = __xe_bo_placement_for_flags(xe, bo, bo->flags);
>> -		if (WARN_ON(err))
>> +		if (WARN_ON(err)) {
>> +			xe_ttm_bo_destroy(&bo->ttm);
> 
> This doesn't look right as we haven't fully initialized the BO. An
> example of this is the snippet from xe_ttm_bo_destroy:
> 
> 1012         if (bo->vm && xe_bo_is_user(bo))
> 1013                 xe_vm_put(bo->vm);
bo->vm is only assigned later, see xe_bo_create_locked_range line 1300-1302.

> 
> This shouldn't be executed in this error path.
> 
> Also do we need to do a cleanup if ttm_bo_init_reserved fails?
No, it cleans up the bo by calling xe_ttm_bo_destroy itself on failure. 
This is also why it's safe to call xe_ttm_bo_destroy right before 
ttm_bo_init_reserved in our setup function; on failure it would have 
been called anyway.

Because of ttm_bo_init_reserved semantics, the function is slightly 
confusing, but still correct. From the ttm_bo_init_reserved docs:
"If a failure occurs, the function will call the @destroy function. 
Thus, after a failure, dereferencing @bo is illegal and will likely 
cause memory corruption."

This patch is correct, but the semantics are confusing.

~Maarten


More information about the Intel-xe mailing list