Continue unloading shmem_sg_alloc_table by placing reading
folios and shrink call into a new helper.
Remove the loop, since calling shrink multiple times does not
bring any benefits.

Signed-off-by: Krzysztof Karas <[email protected]>
---
v4:
 * Removed do-while loop;

 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 103 ++++++++++++----------
 1 file changed, 56 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index f35b7efa1fc2..ac8022997553 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -79,6 +79,56 @@ static int set_page_count_from_size(size_t size, unsigned 
int *page_count,
        return 0;
 }
 
+static struct folio *shmem_shrink_get_folio(struct address_space *mapping,
+                                           unsigned long folio_index,
+                                           gfp_t gfp, unsigned int page_count,
+                                           struct drm_i915_private *i915)
+{
+       struct folio *folio = NULL;
+
+       cond_resched();
+       folio = shmem_read_folio_gfp(mapping, folio_index, gfp);
+       if (IS_ERR(folio)) {
+               i915_gem_shrink(NULL, i915, 2 * page_count, NULL,
+                               I915_SHRINK_BOUND | I915_SHRINK_UNBOUND);
+
+               /*
+                * We've tried hard to allocate the memory by reaping
+                * our own buffer, now let the real VM do its job and
+                * go down in flames if truly OOM.
+                *
+                * However, since graphics tend to be disposable,
+                * defer the oom here by reporting the ENOMEM back
+                * to userspace.
+                *
+                * Reclaim and warn, but no oom.
+                */
+               gfp = mapping_gfp_mask(mapping);
+
+               /*
+                * Our bo are always dirty and so we require
+                * kswapd to reclaim our pages (direct reclaim
+                * does not effectively begin pageout of our
+                * buffers on its own). However, direct reclaim
+                * only waits for kswapd when under allocation
+                * congestion. So as a result __GFP_RECLAIM is
+                * unreliable and fails to actually reclaim our
+                * dirty pages -- unless you try over and over
+                * again with !__GFP_NORETRY. However, we still
+                * want to fail this allocation rather than
+                * trigger the out-of-memory killer and for
+                * this we want __GFP_RETRY_MAYFAIL.
+                */
+               gfp |= __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
+
+               /* Retry once after shrinking and gfp modification. */
+               cond_resched();
+               folio = shmem_read_folio_gfp(mapping, folio_index, gfp);
+       }
+
+       return folio;
+}
+
 int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
                         size_t size, struct intel_memory_region *mr,
                         struct address_space *mapping,
@@ -119,57 +169,16 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
        for (i = 0; i < page_count; i++) {
                unsigned long folio_page_index = 0;
                unsigned long nr_pages;
-               const unsigned int shrink[] = {
-                       I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
-                       0,
-               }, *s = shrink;
                gfp_t gfp = noreclaim;
 
                /* Grab the next folio if we exhausted the current one. */
                if (!i || i > folio_end) {
-                       do {
-                               cond_resched();
-                               folio = shmem_read_folio_gfp(mapping, i, gfp);
-                               if (!IS_ERR(folio))
-                                       break;
-
-                               if (!*s) {
-                                       ret = PTR_ERR(folio);
-                                       goto err_sg;
-                               }
-
-                               i915_gem_shrink(NULL, i915, 2 * page_count, 
NULL, *s++);
-
-                               /*
-                               * We've tried hard to allocate the memory by 
reaping
-                               * our own buffer, now let the real VM do its 
job and
-                               * go down in flames if truly OOM.
-                               *
-                               * However, since graphics tend to be disposable,
-                               * defer the oom here by reporting the ENOMEM 
back
-                               * to userspace.
-                               */
-                               if (!*s) {
-                                       /* reclaim and warn, but no oom */
-                                       gfp = mapping_gfp_mask(mapping);
-
-                                       /*
-                                        * Our bo are always dirty and so we 
require
-                                        * kswapd to reclaim our pages (direct 
reclaim
-                                        * does not effectively begin pageout 
of our
-                                        * buffers on its own). However, direct 
reclaim
-                                        * only waits for kswapd when under 
allocation
-                                        * congestion. So as a result 
__GFP_RECLAIM is
-                                        * unreliable and fails to actually 
reclaim our
-                                        * dirty pages -- unless you try over 
and over
-                                        * again with !__GFP_NORETRY. However, 
we still
-                                        * want to fail this allocation rather 
than
-                                        * trigger the out-of-memory killer and 
for
-                                        * this we want __GFP_RETRY_MAYFAIL.
-                                        */
-                                       gfp |= __GFP_RETRY_MAYFAIL | 
__GFP_NOWARN;
-                               }
-                       } while (1);
+                       folio = shmem_shrink_get_folio(mapping, i, gfp,
+                                                      page_count, i915);
+                       if (IS_ERR(folio)) {
+                               ret = PTR_ERR(folio);
+                               goto err_sg;
+                       }
 
                        folio_start = folio_pgoff(folio);
                        folio_end = folio_start + folio_nr_pages(folio) - 1;
-- 
2.34.1

Reply via email to