Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Cc: <intel-xe@lists.freedesktop.org>,
	<dri-devel@lists.freedesktop.org>,
	Christian Koenig <christian.koenig@amd.com>,
	Huang Rui <ray.huang@amd.com>,
	Matthew Auld <matthew.auld@intel.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	<linux-kernel@vger.kernel.org>, <stable@vger.kernel.org>
Subject: Re: [PATCH v7] drm/ttm/pool: back up at native page order
Date: Wed, 15 Jul 2026 11:51:47 -0700	[thread overview]
Message-ID: <alfWw2PJVFHSOGqy@gsse-cloud1.jf.intel.com> (raw)
In-Reply-To: <f58b1d99-6485-4ef7-8a5f-c63e6fad9ba8@linux.intel.com>

On Wed, Jul 15, 2026 at 06:13:30PM +0200, Thomas Hellström wrote:
> 
> On 7/15/26 10:00, Matthew Brost wrote:
> > ttm_pool_split_for_swap() unconditionally splits high-order pool pages
> > into order-0 pages before backup, so every compound the shrinker
> > touches is shattered even when the rest of the system would prefer it
> > stay intact. Under sustained kswapd pressure this fragments memory
> > enough to drive other parts of MM into recovery loops.
> > 
> > Back up each compound at its native order instead. In
> > ttm_pool_backup(), hand the full compound to the new
> > ttm_backup_backup_folio(), which backs up subpages to a contiguous
> > range of shmem indices and returns the base handle plus the number of
> > subpages actually backed up (@nr_backed). On full success, free the
> > compound once at its native order -- no split_page(), no per-4K
> > refcount juggling.
> > 
> > A per-folio backup can't be made fully atomic under memory pressure:
> > ttm_backup_backup_folio() must allocate shmem folios before source
> > subpages can be released, so under true OOM any subpage may fail
> > while the rest of the compound is still live. Two mechanisms handle
> > this without regressing reclaim behaviour:
> > 
> >    - alloc_gfp gets __GFP_NOMEMALLOC whenever order > 0 (cleared again
> >      for order-0), so a high-order backup fails fast with -ENOMEM
> >      instead of draining kernel reserves, leaving them for other
> >      allocations under the same pressure.
> > 
> >    - If ttm_backup_backup_folio() still returns a short @nr_backed with
> >      a valid handle for the successfully-backed prefix, split the
> >      source compound with ttm_pool_split_for_swap(), free the prefix as
> >      order-0 pages (already safely in shmem), and retry the remaining
> >      subpages at order 0, where __GFP_NOMEMALLOC is cleared and
> >      reserves may be used as a last resort.
> > 
> > This preserves the original split-on-OOM fallback while keeping the
> > common case fragmentation-free, and preserves the "partial backup is
> > allowed" contract (shrunken is incremented per subpage backed up).
> > 
> > The restore-side leftover-page split in ttm_pool_restore_commit() is
> > left as-is: it's unreachable in practice and not worth complicating
> > the restore state machine to avoid.
> > 
> > Testing: the existing backup_fault_inject point only truncated
> > tt->num_pages, which never exercised the reactive split path above
> > since it never left a compound partially backed up. Wire fault
> > injection into ttm_backup_backup_folio() itself: past the first
> > subpage of a compound, synthesize a -ENOMEM in place of
> > shmem_read_folio_gfp() when should_fail() trips, producing the same
> > short @nr_pages_backed a real failure would and forcing
> > ttm_pool_backup() through the split-and-retry path. The fault_attr
> > stays private to ttm_pool.c; ttm_backup.c reaches it through
> > ttm_backup_fault_inject_folio(), declared in ttm_pool_internal.h.
> > 
> > While converting the writeback branch to operate on the whole folio,
> > the unlock condition after shmem_writeout() also changed from `if
> > (ret)` to `if (ret == AOP_WRITEPAGE_ACTIVATE)`, matching the actual
> > contract: shmem_writeout()/swap_writeout() only leave the folio locked
> > when returning AOP_WRITEPAGE_ACTIVATE; any other return (including a
> > hard error from arch_prepare_to_swap()) means the folio was already
> > unlocked internally. The old `if (ret)` check would have double-
> > unlocked in that hard-error case.
> > 
> > Cc: Christian Koenig <christian.koenig@amd.com>
> > Cc: Huang Rui <ray.huang@amd.com>
> > Cc: Matthew Auld <matthew.auld@intel.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: Maxime Ripard <mripard@kernel.org>
> > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > Cc: David Airlie <airlied@gmail.com>
> > Cc: Simona Vetter <simona@ffwll.ch>
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: linux-kernel@vger.kernel.org
> > Cc: stable@vger.kernel.org
> > Fixes: b63d715b8090 ("drm/ttm/pool, drm/ttm/tt: Provide a helper to shrink pages")
> > Suggested-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> > Assisted-by: Claude:claude-opus-4.6
> > Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> > ---
> >   drivers/gpu/drm/ttm/ttm_backup.c        | 138 +++++++++++++++---------
> >   drivers/gpu/drm/ttm/ttm_pool.c          |  89 ++++++++++++---
> >   drivers/gpu/drm/ttm/ttm_pool_internal.h |   8 ++
> >   include/drm/ttm/ttm_backup.h            |  12 +--
> >   4 files changed, 178 insertions(+), 69 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/ttm/ttm_backup.c b/drivers/gpu/drm/ttm/ttm_backup.c
> > index 81df4cb5606b..a8f0b12c86d2 100644
> > --- a/drivers/gpu/drm/ttm/ttm_backup.c
> > +++ b/drivers/gpu/drm/ttm/ttm_backup.c
> > @@ -6,23 +6,25 @@
> >   #include <drm/ttm/ttm_backup.h>
> >   #include <linux/export.h>
> > -#include <linux/page-flags.h>
> >   #include <linux/swap.h>
> > +#include "ttm_pool_internal.h"
> > +
> >   /*
> >    * Need to map shmem indices to handle since a handle value
> >    * of 0 means error, following the swp_entry_t convention.
> >    */
> > -static unsigned long ttm_backup_shmem_idx_to_handle(pgoff_t idx)
> > -{
> > -	return (unsigned long)idx + 1;
> > -}
> >   static pgoff_t ttm_backup_handle_to_shmem_idx(pgoff_t handle)
> >   {
> >   	return handle - 1;
> >   }
> > +static unsigned long ttm_backup_shmem_idx_to_handle(pgoff_t idx)
> > +{
> > +	return (unsigned long)idx + 1;
> > +}
> > +
> 
> This seems like an unrelated change?
> 

Yes, let me drop this.

> 
> >   /**
> >    * ttm_backup_drop() - release memory associated with a handle
> >    * @backup: The struct backup pointer used to obtain the handle
> > @@ -68,17 +70,23 @@ int ttm_backup_copy_page(struct file *backup, struct page *dst,
> >   }
> >   /**
> > - * ttm_backup_backup_page() - Backup a page
> > + * ttm_backup_backup_folio() - Backup a folio
> >    * @backup: The struct backup pointer to use.
> > - * @page: The page to back up.
> > - * @writeback: Whether to perform immediate writeback of the page.
> > + * @folio: The folio to back up.
> > + * @order: The allocation order of @folio.  Since TTM allocates higher-order
> > + *         pages without __GFP_COMP, folio_nr_pages(@folio) would always
> > + *         return 1; the caller must pass the true order explicitly.
> > + * @writeback: Whether to perform immediate writeback of the folio's pages.
> >    * This may have performance implications.
> > - * @idx: A unique integer for each page and each struct backup.
> > + * @idx: A unique integer for the first page of the folio and each struct backup.
> >    * This allows the backup implementation to avoid managing
> >    * its address space separately.
> > - * @page_gfp: The gfp value used when the page was allocated.
> > - * This is used for accounting purposes.
> > + * @folio_gfp: The gfp value used when the folio was allocated.
> > + * Currently unused.
> >    * @alloc_gfp: The gfp to be used when allocating memory.
> > + * @nr_pages_backed: Output. On a successful return, set to the number of
> > + * pages actually backed up, which may be less than (1 << @order)
> > + * if an -ENOMEM was encountered mid-folio.
> >    *
> >    * Context: If called from reclaim context, the caller needs to
> >    * assert that the shrinker gfp has __GFP_FS set, to avoid
> > @@ -87,53 +95,87 @@ int ttm_backup_copy_page(struct file *backup, struct page *dst,
> >    * that the shrinker gfp has __GFP_IO set, since without it,
> >    * we're not allowed to start backup IO.
> >    *
> > - * Return: A handle on success. Negative error code on failure.
> > - *
> > - * Note: This function could be extended to back up a folio and
> > - * implementations would then split the folio internally if needed.
> > - * Drawback is that the caller would then have to keep track of
> > - * the folio size- and usage.
> > + * Return: A handle for the first backed-up page on success (handles for
> > + * subsequent pages follow sequentially). -ENOMEM if no pages could be backed
> > + * up. Any other negative error code if a non-ENOMEM failure occurred; in that
> > + * case any pages backed up so far are truncated before returning.
> >    */
> >   s64
> > -ttm_backup_backup_page(struct file *backup, struct page *page,
> > -		       bool writeback, pgoff_t idx, gfp_t page_gfp,
> > -		       gfp_t alloc_gfp)
> > +ttm_backup_backup_folio(struct file *backup, struct folio *folio,
> > +			unsigned int order, bool writeback, pgoff_t idx,
> > +			gfp_t folio_gfp, gfp_t alloc_gfp,
> > +			pgoff_t *nr_pages_backed)
> >   {
> >   	struct address_space *mapping = backup->f_mapping;
> > -	unsigned long handle = 0;
> > +	int nr_pages = 1 << order;
> >   	struct folio *to_folio;
> > -	int ret;
> > -
> > -	to_folio = shmem_read_folio_gfp(mapping, idx, alloc_gfp);
> > -	if (IS_ERR(to_folio))
> > -		return PTR_ERR(to_folio);
> > -
> > -	folio_mark_accessed(to_folio);
> > -	folio_lock(to_folio);
> > -	folio_mark_dirty(to_folio);
> > -	copy_highpage(folio_file_page(to_folio, idx), page);
> > -	handle = ttm_backup_shmem_idx_to_handle(idx);
> > -
> > -	if (writeback && !folio_mapped(to_folio) &&
> > -	    folio_clear_dirty_for_io(to_folio)) {
> > -		folio_set_reclaim(to_folio);
> > -		ret = shmem_writeout(to_folio, NULL, NULL);
> > -		if (!folio_test_writeback(to_folio))
> > -			folio_clear_reclaim(to_folio);
> > +	int ret, i;
> > +
> > +	*nr_pages_backed = 0;
> > +
> > +	for (i = 0; i < nr_pages; ) {
> > +		int to_nr, j;
> > +
> >   		/*
> > -		 * If writeout succeeds, it unlocks the folio.	errors
> > -		 * are otherwise dropped, since writeout is only best
> > -		 * effort here.
> > +		 * Only inject past the first subpage so *nr_pages_backed is
> > +		 * always > 0 here, matching a genuine mid-compound -ENOMEM
> > +		 * and driving the caller's reactive split fallback instead
> > +		 * of an early, no-progress failure.
> >   		 */
> > -		if (ret)
> > +		if (IS_ENABLED(CONFIG_FAULT_INJECTION) && i &&
> > +		    ttm_backup_fault_inject_folio())
> > +			to_folio = ERR_PTR(-ENOMEM);
> > +		else
> > +			to_folio = shmem_read_folio_gfp(mapping, idx + i, alloc_gfp);
> > +		if (IS_ERR(to_folio)) {
> > +			int err = PTR_ERR(to_folio);
> > +
> > +			if (err == -ENOMEM && *nr_pages_backed)
> > +				return ttm_backup_shmem_idx_to_handle(idx);
> > +
> > +			if (*nr_pages_backed) {
> > +				shmem_truncate_range(file_inode(backup),
> > +						     (loff_t)idx << PAGE_SHIFT,
> > +						     ((loff_t)(idx + i) << PAGE_SHIFT) - 1);
> > +				/*
> > +				 * The pages just truncated are no longer
> > +				 * backed up; don't let the caller mistake
> > +				 * them for valid handles.
> > +				 */
> > +				*nr_pages_backed = 0;
> > +			}
> > +			return err;
> > +		}
> > +
> > +		to_nr = min_t(int, nr_pages - i,
> > +			      folio_next_index(to_folio) - (idx + i));
> > +
> > +		folio_mark_accessed(to_folio);
> > +		folio_lock(to_folio);
> > +		folio_mark_dirty(to_folio);
> > +
> > +		for (j = 0; j < to_nr; j++)
> > +			copy_highpage(folio_file_page(to_folio, idx + i + j),
> > +				      folio_page(folio, i + j));
> > +
> > +		if (writeback && !folio_mapped(to_folio) &&
> > +		    folio_clear_dirty_for_io(to_folio)) {
> > +			folio_set_reclaim(to_folio);
> > +			ret = shmem_writeout(to_folio, NULL, NULL);
> > +			if (!folio_test_writeback(to_folio))
> > +				folio_clear_reclaim(to_folio);
> > +			if (ret == AOP_WRITEPAGE_ACTIVATE)
> > +				folio_unlock(to_folio);
> Actually, it may be that the whole above block (setting reclaim etc) is

The check for AOP_WRITEPAGE_ACTIVATE was also missing from the old code.
This was flagged by a separate core MM patch that performed some
tree-wide cleanup around shmem_writeout(). Reading through the
shmem_writeout() implementation, the need for this check appears fairly
obvious.

> duplicating what shmem_writeout already does and that got missed in the
> conversion to shmem_writeout. In any case, that might belong in a separate

It is less obvious whether folio_set_reclaim() is called somewhere
along the shmem_writeout() path, and it is possible that we have this
part wrong. I think I agree that we should follow up on this and post a
separate patch if needed.

> patch. Note also that if shmem happened to allocate a 2M page, and we call
> shmem_writeout on it, it might be split on further copies to it, like if
> we're trying to back up a 4K-populated bo to a 2M shmem page. Also
> pre-existing.
> 

I don't think we pass in the original folio which what we trying to
avoid splitting in this patch, but I do see code around 'to_folio' being
split, so we may need a follow up here too?

Matt

> 
> > +		} else {
> >   			folio_unlock(to_folio);
> > -	} else {
> > -		folio_unlock(to_folio);
> > -	}
> > +		}
> > -	folio_put(to_folio);
> > +		folio_put(to_folio);
> > +		i += to_nr;
> > +		*nr_pages_backed = i;
> > +	}
> > -	return handle;
> > +	return ttm_backup_shmem_idx_to_handle(idx);
> >   }
> >   /**
> > diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> > index 80d0ad41456a..1bf37023fed6 100644
> > --- a/drivers/gpu/drm/ttm/ttm_pool.c
> > +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> > @@ -53,8 +53,23 @@
> >   #ifdef CONFIG_FAULT_INJECTION
> >   #include <linux/fault-inject.h>
> >   static DECLARE_FAULT_ATTR(backup_fault_inject);
> > +
> > +/*
> > + * Exposed to ttm_backup.c so a mid-compound subpage can be made to fail
> > + * with -ENOMEM, exercising the reactive split-and-retry fallback in
> > + * ttm_pool_backup() for high-order backups.
> > + */
> > +bool ttm_backup_fault_inject_folio(void)
> > +{
> > +	return should_fail(&backup_fault_inject, 1);
> > +}
> >   #else
> >   #define should_fail(...) false
> > +
> > +bool ttm_backup_fault_inject_folio(void)
> > +{
> > +	return false;
> > +}
> >   #endif
> >   /**
> > @@ -492,7 +507,7 @@ static void ttm_pool_split_for_swap(struct ttm_pool *pool, struct page *p)
> >   /**
> >    * DOC: Partial backup and restoration of a struct ttm_tt.
> >    *
> > - * Swapout using ttm_backup_backup_page() and swapin using
> > + * Swapout using ttm_backup_backup_folio() and swapin using
> >    * ttm_backup_copy_page() may fail.
> >    * The former most likely due to lack of swap-space or memory, the latter due
> >    * to lack of memory or because of signal interruption during waits.
> > @@ -1050,12 +1065,12 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
> >   {
> >   	struct file *backup = tt->backup;
> >   	struct page *page;
> > -	unsigned long handle;
> >   	gfp_t alloc_gfp;
> >   	gfp_t gfp;
> >   	int ret = 0;
> >   	pgoff_t shrunken = 0;
> > -	pgoff_t i, num_pages;
> > +	pgoff_t i, j, num_pages, npages;
> > +	pgoff_t nr_backed;
> >   	if (WARN_ON(ttm_tt_is_backed_up(tt)))
> >   		return -EINVAL;
> > @@ -1133,9 +1148,11 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
> >   	if (IS_ENABLED(CONFIG_FAULT_INJECTION) && should_fail(&backup_fault_inject, 1))
> >   		num_pages = DIV_ROUND_UP(num_pages, 2);
> > -	for (i = 0; i < num_pages; ++i) {
> > -		s64 shandle;
> > +	for (i = 0; i < num_pages; i += npages) {
> > +		unsigned int order;
> > +		s64 handle;
> > +		npages = 1;
> >   		page = tt->pages[i];
> >   		if (unlikely(!page))
> >   			continue;
> > @@ -1144,19 +1161,61 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
> >   		if (unlikely(ttm_backup_page_ptr_is_handle(page)))
> >   			continue;
> > -		ttm_pool_split_for_swap(pool, page);
> > +		order = ttm_pool_page_order(pool, page);
> > +		npages = 1UL << order;
> > +
> > +		/*
> > +		 * We don't allow dipping kernel reserves for high order backup
> > +		 */
> > +		if (order)
> > +			alloc_gfp |= __GFP_NOMEMALLOC;
> > +		else
> > +			alloc_gfp &= ~__GFP_NOMEMALLOC;
> > +
> > +		/*
> > +		 * Back up the compound atomically at its native order. If
> > +		 * fault injection truncated num_pages mid-compound, skip
> > +		 * the partial tail rather than splitting.
> > +		 */
> > +		if (unlikely(i + npages > num_pages))
> > +			break;
> > -		shandle = ttm_backup_backup_page(backup, page, flags->writeback, i,
> > -						 gfp, alloc_gfp);
> > -		if (shandle < 0) {
> > -			/* We allow partially shrunken tts */
> > -			ret = shandle;
> > +		handle = ttm_backup_backup_folio(backup, page_folio(page),
> > +						 order, flags->writeback, i,
> > +						 gfp, alloc_gfp,
> > +						 &nr_backed);
> > +		/*
> > +		 * Zero progress on this compound (whether order 0 or a
> > +		 * high-order compound that failed before backing up even
> > +		 * its first subpage) is unrecoverable: bail out rather than
> > +		 * looping forever with npages == nr_backed == 0 below.
> > +		 */
> > +		if (unlikely(handle < 0 && !nr_backed)) {
> > +			ret = handle;
> >   			break;
> >   		}
> > -		handle = shandle;
> > -		tt->pages[i] = ttm_backup_handle_to_page_ptr(handle);
> > -		__free_pages_gpu_account(page, 0, false);
> > -		shrunken++;
> > +
> > +		for (j = 0; j < nr_backed; j++)
> > +			tt->pages[i + j] = ttm_backup_handle_to_page_ptr(handle + j);
> > +
> > +		shrunken += nr_backed;
> > +
> > +		if (unlikely(nr_backed < npages)) {
> > +			/*
> > +			 * Partial OOM backup: split the compound and free the
> > +			 * subpages whose content is now in shmem. Continue the
> > +			 * loop from the first un-backed order-0 page.
> > +			 */
> > +			ttm_pool_split_for_swap(pool, page);
> > +			for (j = 0; j < nr_backed; j++)
> > +				__free_pages_gpu_account(page + j, 0, false);
> > +			npages = nr_backed;
> > +			continue;
> > +		}
> > +
> > +		/* Fully backed up: free at native order. */
> > +		page->private = 0;
> > +		__free_pages_gpu_account(page, order, false);
> >   	}
> >   	return shrunken ? shrunken : ret;
> > diff --git a/drivers/gpu/drm/ttm/ttm_pool_internal.h b/drivers/gpu/drm/ttm/ttm_pool_internal.h
> > index 24c179fd69d1..cbb17a2129fe 100644
> > --- a/drivers/gpu/drm/ttm/ttm_pool_internal.h
> > +++ b/drivers/gpu/drm/ttm/ttm_pool_internal.h
> > @@ -22,4 +22,12 @@ static inline unsigned int ttm_pool_beneficial_order(struct ttm_pool *pool)
> >   	return pool->alloc_flags & 0xff;
> >   }
> > +/*
> > + * Implemented in ttm_pool.c, used by ttm_backup.c. Returns true if a fault
> > + * should be injected mid-compound to test the reactive split-and-retry
> > + * fallback in ttm_pool_backup(). Always returns false when
> > + * CONFIG_FAULT_INJECTION is disabled.
> > + */
> > +bool ttm_backup_fault_inject_folio(void);
> > +
> >   #endif
> > diff --git a/include/drm/ttm/ttm_backup.h b/include/drm/ttm/ttm_backup.h
> > index 29b9c855af77..49efa713e87c 100644
> > --- a/include/drm/ttm/ttm_backup.h
> > +++ b/include/drm/ttm/ttm_backup.h
> > @@ -13,9 +13,8 @@
> >    * ttm_backup_handle_to_page_ptr() - Convert handle to struct page pointer
> >    * @handle: The handle to convert.
> >    *
> > - * Converts an opaque handle received from the
> > - * ttm_backup_backup_page() function to an (invalid)
> > - * struct page pointer suitable for a struct page array.
> > + * Converts an opaque handle received from a ttm_backup_backup_*()
> > + * function to an (invalid) struct page pointer suitable for a struct page array.
> >    *
> >    * Return: An (invalid) struct page pointer.
> >    */
> > @@ -59,9 +58,10 @@ int ttm_backup_copy_page(struct file *backup, struct page *dst,
> >   			 pgoff_t handle, bool intr, gfp_t additional_gfp);
> >   s64
> > -ttm_backup_backup_page(struct file *backup, struct page *page,
> > -		       bool writeback, pgoff_t idx, gfp_t page_gfp,
> > -		       gfp_t alloc_gfp);
> > +ttm_backup_backup_folio(struct file *backup, struct folio *folio,
> > +			unsigned int order, bool writeback, pgoff_t idx,
> > +			gfp_t folio_gfp, gfp_t alloc_gfp,
> > +			pgoff_t *nr_pages_backed);
> >   void ttm_backup_fini(struct file *backup);
> Otherwise LGTM.
> 
> /Thomas
> 
> 

      reply	other threads:[~2026-07-15 18:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-15  8:00 [PATCH v7] drm/ttm/pool: back up at native page order Matthew Brost
2026-07-15  8:08 ` ✓ CI.KUnit: success for drm/ttm/pool: back up at native page order (rev3) Patchwork
2026-07-15  8:57 ` ✓ Xe.CI.BAT: " Patchwork
2026-07-15  9:28 ` ✓ Xe.CI.FULL: " Patchwork
2026-07-15 16:13 ` [PATCH v7] drm/ttm/pool: back up at native page order Thomas Hellström
2026-07-15 18:51   ` Matthew Brost [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=alfWw2PJVFHSOGqy@gsse-cloud1.jf.intel.com \
    --to=matthew.brost@intel.com \
    --cc=airlied@gmail.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthew.auld@intel.com \
    --cc=mripard@kernel.org \
    --cc=ray.huang@amd.com \
    --cc=simona@ffwll.ch \
    --cc=stable@vger.kernel.org \
    --cc=thomas.hellstrom@linux.intel.com \
    --cc=tzimmermann@suse.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox