All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Brian Geffon <bgeffon@google.com>
Cc: intel-gfx@lists.freedesktop.org, chris.p.wilson@intel.com,
	jani.saarinen@intel.com, tomasz.mistat@intel.com,
	vidya.srinivas@intel.com, jani.nikula@linux.intel.com,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Tomasz Figa <tfiga@google.com>
Subject: Re: [PATCH] drm/i915: Fix page cleanup on DMA remap failure
Date: Thu, 16 Jan 2025 16:51:38 +0200	[thread overview]
Message-ID: <Z4kc-sBdFz0sd4dJ@intel.com> (raw)
In-Reply-To: <Z4kWms-eFWxddspp@intel.com>

On Thu, Jan 16, 2025 at 04:24:26PM +0200, Ville Syrjälä wrote:
> On Thu, Jan 16, 2025 at 08:56:36AM -0500, Brian Geffon wrote:
> > When converting to folios the cleanup path of shmem_get_pages() was
> > missed. When a DMA remap fails and the max segment size is greater than
> > PAGE_SIZE it will attempt to retry the remap with a PAGE_SIZEd segment
> > size. The cleanup code isn't properly using the folio apis and as a
> > result isn't handling compound pages correctly.
> > 
> > Link: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13487
> > Fixes: 0b62af28f249 ("i915: convert shmem_sg_free_table() to use a folio_batch")
> > Signed-off-by: Brian Geffon <bgeffon@google.com>
> > Suggested-by: Tomasz Figa <tfiga@google.com>
> > ---
> >  drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 13 +++++--------
> >  1 file changed, 5 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> > index fe69f2c8527d..02ddab5bf5c0 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> > @@ -37,8 +37,6 @@ void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
> >  	struct folio *last = NULL;
> >  	struct page *page;
> >  
> > -	mapping_clear_unevictable(mapping);
> > -
> 
> The assymmetry here between the alloc vs. free is a bit annoying.
> Maybe we can just keep this here? 

Hmm, I guess with the current code that avoids the ping-pong
we (at least theoretically) could leak the mapping_set_unevictable()
if both i915_gem_gtt_prepare_pages() fails, and then the the
subsequent shmem_sg_alloc_table() retry fails early enough.

So looks to me like the ping-pong would be the only 100% correct
approach.

> 
> Or if avoiding the ping-pong actually mattes in the gtt prepare
> error case, then maybe we should rename this guy into
> __shmem_sg_free_table() without the mapping_clear_unevictable()
> and wrap it in a higher level shmem_sg_free_table() that does
> everything?
> 
> >  	folio_batch_init(&fbatch);
> >  	for_each_sgt_page(page, sgt_iter, st) {
> >  		struct folio *folio = page_folio(page);
> > @@ -180,10 +178,10 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
> >  	return 0;
> >  err_sg:
> >  	sg_mark_end(sg);
> > +	mapping_clear_unevictable(mapping);
> >  	if (sg != st->sgl) {
> >  		shmem_sg_free_table(st, mapping, false, false);
> >  	} else {
> > -		mapping_clear_unevictable(mapping);
> >  		sg_free_table(st);
> >  	}
> >  
> > @@ -209,8 +207,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
> >  	struct address_space *mapping = obj->base.filp->f_mapping;
> >  	unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
> >  	struct sg_table *st;
> > -	struct sgt_iter sgt_iter;
> > -	struct page *page;
> >  	int ret;
> >  
> >  	/*
> > @@ -239,9 +235,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
> >  		 * for PAGE_SIZE chunks instead may be helpful.
> >  		 */
> >  		if (max_segment > PAGE_SIZE) {
> > -			for_each_sgt_page(page, sgt_iter, st)
> > -				put_page(page);
> > -			sg_free_table(st);
> > +			/* Leave the mapping unevictable while we retry */
> > +			shmem_sg_free_table(st, mapping, false, false);
> >  			kfree(st);
> >  
> >  			max_segment = PAGE_SIZE;
> > @@ -265,6 +260,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
> >  	return 0;
> >  
> >  err_pages:
> > +	mapping_clear_unevictable(mapping);
> >  	shmem_sg_free_table(st, mapping, false, false);
> >  	/*
> >  	 * shmemfs first checks if there is enough memory to allocate the page
> > @@ -402,6 +398,7 @@ void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_
> >  	if (i915_gem_object_needs_bit17_swizzle(obj))
> >  		i915_gem_object_save_bit_17_swizzle(obj, pages);
> >  
> > +	mapping_clear_unevictable(file_inode(obj->base.filp)->i_mapping);
> >  	shmem_sg_free_table(pages, file_inode(obj->base.filp)->i_mapping,
> >  			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED);
> >  	kfree(pages);
> > -- 
> > 2.48.0.rc2.279.g1de40edade-goog
> 
> -- 
> Ville Syrjälä
> Intel

-- 
Ville Syrjälä
Intel

      parent reply	other threads:[~2025-01-16 14:51 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-16 13:56 [PATCH] drm/i915: Fix page cleanup on DMA remap failure Brian Geffon
2025-01-16 14:24 ` Ville Syrjälä
2025-01-16 14:36   ` Brian Geffon
2025-01-16 14:39     ` Ville Syrjälä
2025-01-16 14:37   ` Ville Syrjälä
2025-01-16 14:48     ` Brian Geffon
2025-01-16 14:44   ` Brian Geffon
2025-01-16 14:51   ` Ville Syrjälä [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z4kc-sBdFz0sd4dJ@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=bgeffon@google.com \
    --cc=chris.p.wilson@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=jani.saarinen@intel.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tfiga@google.com \
    --cc=tomasz.mistat@intel.com \
    --cc=vidya.srinivas@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.