Hey,

Den 2026-02-27 kl. 17:00, skrev Thomas Hellström:
> In situations where the system is very short on RAM, the shmem
> readback from swap-space may invoke the OOM killer.
> 
> However, since this might be a recoverable situation where the caller
> is indicating this by setting
> struct ttm_operation_ctx::gfp_retry_mayfail to true, adjust the gfp
> value used by the allocation accordingly.
> 
> Signed-off-by: Thomas Hellström <[email protected]>
> ---
>  drivers/gpu/drm/ttm/ttm_backup.c | 6 ++++--
>  drivers/gpu/drm/ttm/ttm_pool.c   | 5 ++++-
>  include/drm/ttm/ttm_backup.h     | 2 +-
>  3 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ttm/ttm_backup.c 
> b/drivers/gpu/drm/ttm/ttm_backup.c
> index 6bd4c123d94c..81df4cb5606b 100644
> --- a/drivers/gpu/drm/ttm/ttm_backup.c
> +++ b/drivers/gpu/drm/ttm/ttm_backup.c
> @@ -44,18 +44,20 @@ void ttm_backup_drop(struct file *backup, pgoff_t handle)
>   * @dst: The struct page to copy into.
>   * @handle: The handle returned when the page was backed up.
>   * @intr: Try to perform waits interruptible or at least killable.
> + * @additional_gfp: GFP mask to add to the default GFP mask if any.
>   *
>   * Return: 0 on success, Negative error code on failure, notably
>   * -EINTR if @intr was set to true and a signal is pending.
>   */
>  int ttm_backup_copy_page(struct file *backup, struct page *dst,
> -                      pgoff_t handle, bool intr)
> +                      pgoff_t handle, bool intr, gfp_t additional_gfp)
>  {
>       struct address_space *mapping = backup->f_mapping;
>       struct folio *from_folio;
>       pgoff_t idx = ttm_backup_handle_to_shmem_idx(handle);
>  
> -     from_folio = shmem_read_folio(mapping, idx);
> +     from_folio = shmem_read_folio_gfp(mapping, idx, 
> mapping_gfp_mask(mapping)
> +                                       | additional_gfp);
>       if (IS_ERR(from_folio))
>               return PTR_ERR(from_folio);
>  
> diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> index 8fa9e09f6ee5..aa41099c5ecf 100644
> --- a/drivers/gpu/drm/ttm/ttm_pool.c
> +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> @@ -530,6 +530,8 @@ static int ttm_pool_restore_commit(struct 
> ttm_pool_tt_restore *restore,
>               p = first_page[i];
>               if (ttm_backup_page_ptr_is_handle(p)) {
>                       unsigned long handle = ttm_backup_page_ptr_to_handle(p);
> +                     gfp_t additional_gfp = ctx->gfp_retry_mayfail ?
> +                             __GFP_RETRY_MAYFAIL | __GFP_NOWARN : 0;
>  
>                       if (IS_ENABLED(CONFIG_FAULT_INJECTION) && 
> ctx->interruptible &&
>                           should_fail(&backup_fault_inject, 1)) {
> @@ -543,7 +545,8 @@ static int ttm_pool_restore_commit(struct 
> ttm_pool_tt_restore *restore,
>                       }
>  
>                       ret = ttm_backup_copy_page(backup, 
> restore->alloced_page + i,
> -                                                handle, ctx->interruptible);
> +                                                handle, ctx->interruptible,
> +                                                additional_gfp);
>                       if (ret)
>                               break;
>  
> diff --git a/include/drm/ttm/ttm_backup.h b/include/drm/ttm/ttm_backup.h
> index c33cba111171..29b9c855af77 100644
> --- a/include/drm/ttm/ttm_backup.h
> +++ b/include/drm/ttm/ttm_backup.h
> @@ -56,7 +56,7 @@ ttm_backup_page_ptr_to_handle(const struct page *page)
>  void ttm_backup_drop(struct file *backup, pgoff_t handle);
>  
>  int ttm_backup_copy_page(struct file *backup, struct page *dst,
> -                      pgoff_t handle, bool intr);
> +                      pgoff_t handle, bool intr, gfp_t additional_gfp);
>  
>  s64
>  ttm_backup_backup_page(struct file *backup, struct page *page,

Reviewed-by: Maarten Lankhorst <[email protected]>

Kind regards,
Maarten Lankhorst

Reply via email to