> +static struct folio *__kvm_gmem_get_folio(struct address_space *mapping,
> +                                       pgoff_t index,
> +                                       struct mempolicy *policy)
> +{
> +     const gfp_t gfp = mapping_gfp_mask(mapping);
> +     struct folio *folio;
> +     int err;
> +
> +     folio = filemap_lock_folio(mapping, index);
> +     if (!IS_ERR(folio))
> +             return folio;
> +
> +     folio = filemap_alloc_folio(gfp, 0, policy);
> +     if (!folio)
> +             return ERR_PTR(-ENOMEM);
> +
> +     err = mem_cgroup_charge(folio, NULL, gfp);
> +     if (err)
> +             goto err_put;
> +
> +     __folio_set_locked(folio);
> +
> +     err = __filemap_add_folio(mapping, folio, index, gfp, NULL);
> +     if (err) {
                 mem_cgroup_uncharge(folio);

> +             __folio_clear_locked(folio);
> +             goto err_put;
> +     }
> +
> +     return folio;
> +
> +err_put:
> +     folio_put(folio);
> +     return ERR_PTR(err);
> +}
> +
>  /*
>   * Returns a locked folio on success.  The caller is responsible for
>   * setting the up-to-date flag before the memory is mapped into the guest.
> @@ -160,6 +195,7 @@ static struct mempolicy *kvm_gmem_get_folio_policy(struct 
> gmem_inode *gi,
>  static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index)
>  {
>       /* TODO: Support huge pages. */
> +     struct address_space *mapping = inode->i_mapping;
>       struct mempolicy *policy;
>       struct folio *folio;
>  
> @@ -167,16 +203,17 @@ static struct folio *kvm_gmem_get_folio(struct inode 
> *inode, pgoff_t index)
>        * Fast-path: See if folio is already present in mapping to avoid
>        * policy_lookup.
>        */
> -     folio = filemap_lock_folio(inode->i_mapping, index);
> +     folio = filemap_lock_folio(mapping, index);
>       if (!IS_ERR(folio))
>               return folio;
>  
>       policy = kvm_gmem_get_folio_policy(GMEM_I(inode), index);
> -     folio = __filemap_get_folio_mpol(inode->i_mapping, index,
> -                                      FGP_LOCK | FGP_CREAT,
> -                                      mapping_gfp_mask(inode->i_mapping), 
> policy);
> -     mpol_cond_put(policy);
>  
> +     do {
> +             folio = __kvm_gmem_get_folio(mapping, index, policy);
> +     } while (IS_ERR(folio) && PTR_ERR(folio) == -EEXIST);
Why not just return ERR_PTR(-EEXIST) up to kvm_gmem_get_pfn() and have a higher
level retry?

> +     mpol_cond_put(policy);
>       return folio;
>  }
 

Reply via email to