From: Rob Clark <robdclark@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org,
Rob Clark <robdclark@chromium.org>,
Rob Clark <robdclark@gmail.com>,
Abhinav Kumar <quic_abhinavk@quicinc.com>,
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
Sean Paul <sean@poorly.run>, David Airlie <airlied@linux.ie>,
Daniel Vetter <daniel@ffwll.ch>,
linux-kernel@vger.kernel.org (open list)
Subject: [PATCH v2 13/13] drm/msm/gem: Evict active GEM objects when necessary
Date: Tue, 19 Jul 2022 10:18:57 -0700 [thread overview]
Message-ID: <20220719171900.289265-14-robdclark@gmail.com> (raw)
In-Reply-To: <20220719171900.289265-1-robdclark@gmail.com>
From: Rob Clark <robdclark@chromium.org>
If we are under enough memory pressure, we should stall waiting for
active buffers to become idle in order to evict.
v2: Check for __GFP_ATOMIC before blocking
Signed-off-by: Rob Clark <robdclark@chromium.org>
---
drivers/gpu/drm/msm/msm_gem_shrinker.c | 70 +++++++++++++++++++++-----
drivers/gpu/drm/msm/msm_gpu_trace.h | 16 +++---
2 files changed, 68 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index 5cc05d669a08..f31054d25314 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -24,6 +24,13 @@ static bool can_swap(void)
return enable_eviction && get_nr_swap_pages() > 0;
}
+static bool can_block(struct shrink_control *sc)
+{
+ if (sc->gfp_mask & __GFP_ATOMIC)
+ return false;
+ return current_is_kswapd() || (sc->gfp_mask & __GFP_RECLAIM);
+}
+
static unsigned long
msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
{
@@ -65,26 +72,65 @@ evict(struct drm_gem_object *obj)
return true;
}
+static bool
+wait_for_idle(struct drm_gem_object *obj)
+{
+ enum dma_resv_usage usage = dma_resv_usage_rw(true);
+ return dma_resv_wait_timeout(obj->resv, usage, false, 1000) > 0;
+}
+
+static bool
+active_purge(struct drm_gem_object *obj)
+{
+ if (!wait_for_idle(obj))
+ return false;
+
+ return purge(obj);
+}
+
+static bool
+active_evict(struct drm_gem_object *obj)
+{
+ if (!wait_for_idle(obj))
+ return false;
+
+ return evict(obj);
+}
+
static unsigned long
msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
{
struct msm_drm_private *priv =
container_of(shrinker, struct msm_drm_private, shrinker);
+ struct {
+ struct drm_gem_lru *lru;
+ bool (*shrink)(struct drm_gem_object *obj);
+ bool cond;
+ unsigned long freed;
+ } stages[] = {
+ /* Stages of progressively more aggressive/expensive reclaim: */
+ { &priv->lru.dontneed, purge, true },
+ { &priv->lru.willneed, evict, can_swap() },
+ { &priv->lru.dontneed, active_purge, can_block(sc) },
+ { &priv->lru.willneed, active_evict, can_swap() && can_block(sc) },
+ };
long nr = sc->nr_to_scan;
- unsigned long freed, purged, evicted = 0;
-
- purged = drm_gem_lru_scan(&priv->lru.dontneed, nr, purge);
- nr -= purged;
-
- if (can_swap() && nr > 0) {
- evicted = drm_gem_lru_scan(&priv->lru.willneed, nr, evict);
- nr -= evicted;
+ unsigned long freed = 0;
+
+ for (unsigned i = 0; (nr > 0) && (i < ARRAY_SIZE(stages)); i++) {
+ if (!stages[i].cond)
+ continue;
+ stages[i].freed =
+ drm_gem_lru_scan(stages[i].lru, nr, stages[i].shrink);
+ nr -= stages[i].freed;
+ freed += stages[i].freed;
}
- freed = purged + evicted;
-
- if (freed)
- trace_msm_gem_shrink(sc->nr_to_scan, purged, evicted);
+ if (freed) {
+ trace_msm_gem_shrink(sc->nr_to_scan, stages[0].freed,
+ stages[1].freed, stages[2].freed,
+ stages[3].freed);
+ }
return (freed > 0) ? freed : SHRINK_STOP;
}
diff --git a/drivers/gpu/drm/msm/msm_gpu_trace.h b/drivers/gpu/drm/msm/msm_gpu_trace.h
index 8867fa0a0306..ac40d857bc45 100644
--- a/drivers/gpu/drm/msm/msm_gpu_trace.h
+++ b/drivers/gpu/drm/msm/msm_gpu_trace.h
@@ -116,22 +116,26 @@ TRACE_EVENT(msm_gmu_freq_change,
TRACE_EVENT(msm_gem_shrink,
- TP_PROTO(u32 nr_to_scan, u32 purged, u32 evicted),
- TP_ARGS(nr_to_scan, purged, evicted),
+ TP_PROTO(u32 nr_to_scan, u32 purged, u32 evicted,
+ u32 active_purged, u32 active_evicted),
+ TP_ARGS(nr_to_scan, purged, evicted, active_purged, active_evicted),
TP_STRUCT__entry(
__field(u32, nr_to_scan)
__field(u32, purged)
__field(u32, evicted)
+ __field(u32, active_purged)
+ __field(u32, active_evicted)
),
TP_fast_assign(
__entry->nr_to_scan = nr_to_scan;
__entry->purged = purged;
__entry->evicted = evicted;
+ __entry->active_purged = active_purged;
+ __entry->active_evicted = active_evicted;
),
- TP_printk("nr_to_scan=%u pages, purged=%u pages, evicted=%u pages",
- __entry->nr_to_scan,
- __entry->purged,
- __entry->evicted)
+ TP_printk("nr_to_scan=%u pg, purged=%u pg, evicted=%u pg, active_purged=%u pg, active_evicted=%u pg",
+ __entry->nr_to_scan, __entry->purged, __entry->evicted,
+ __entry->active_purged, __entry->active_evicted)
);
--
2.36.1
WARNING: multiple messages have this Message-ID (diff)
From: Rob Clark <robdclark@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Rob Clark <robdclark@chromium.org>,
David Airlie <airlied@linux.ie>,
linux-arm-msm@vger.kernel.org,
Abhinav Kumar <quic_abhinavk@quicinc.com>,
open list <linux-kernel@vger.kernel.org>,
Sean Paul <sean@poorly.run>,
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
freedreno@lists.freedesktop.org
Subject: [PATCH v2 13/13] drm/msm/gem: Evict active GEM objects when necessary
Date: Tue, 19 Jul 2022 10:18:57 -0700 [thread overview]
Message-ID: <20220719171900.289265-14-robdclark@gmail.com> (raw)
In-Reply-To: <20220719171900.289265-1-robdclark@gmail.com>
From: Rob Clark <robdclark@chromium.org>
If we are under enough memory pressure, we should stall waiting for
active buffers to become idle in order to evict.
v2: Check for __GFP_ATOMIC before blocking
Signed-off-by: Rob Clark <robdclark@chromium.org>
---
drivers/gpu/drm/msm/msm_gem_shrinker.c | 70 +++++++++++++++++++++-----
drivers/gpu/drm/msm/msm_gpu_trace.h | 16 +++---
2 files changed, 68 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index 5cc05d669a08..f31054d25314 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -24,6 +24,13 @@ static bool can_swap(void)
return enable_eviction && get_nr_swap_pages() > 0;
}
+static bool can_block(struct shrink_control *sc)
+{
+ if (sc->gfp_mask & __GFP_ATOMIC)
+ return false;
+ return current_is_kswapd() || (sc->gfp_mask & __GFP_RECLAIM);
+}
+
static unsigned long
msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
{
@@ -65,26 +72,65 @@ evict(struct drm_gem_object *obj)
return true;
}
+static bool
+wait_for_idle(struct drm_gem_object *obj)
+{
+ enum dma_resv_usage usage = dma_resv_usage_rw(true);
+ return dma_resv_wait_timeout(obj->resv, usage, false, 1000) > 0;
+}
+
+static bool
+active_purge(struct drm_gem_object *obj)
+{
+ if (!wait_for_idle(obj))
+ return false;
+
+ return purge(obj);
+}
+
+static bool
+active_evict(struct drm_gem_object *obj)
+{
+ if (!wait_for_idle(obj))
+ return false;
+
+ return evict(obj);
+}
+
static unsigned long
msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
{
struct msm_drm_private *priv =
container_of(shrinker, struct msm_drm_private, shrinker);
+ struct {
+ struct drm_gem_lru *lru;
+ bool (*shrink)(struct drm_gem_object *obj);
+ bool cond;
+ unsigned long freed;
+ } stages[] = {
+ /* Stages of progressively more aggressive/expensive reclaim: */
+ { &priv->lru.dontneed, purge, true },
+ { &priv->lru.willneed, evict, can_swap() },
+ { &priv->lru.dontneed, active_purge, can_block(sc) },
+ { &priv->lru.willneed, active_evict, can_swap() && can_block(sc) },
+ };
long nr = sc->nr_to_scan;
- unsigned long freed, purged, evicted = 0;
-
- purged = drm_gem_lru_scan(&priv->lru.dontneed, nr, purge);
- nr -= purged;
-
- if (can_swap() && nr > 0) {
- evicted = drm_gem_lru_scan(&priv->lru.willneed, nr, evict);
- nr -= evicted;
+ unsigned long freed = 0;
+
+ for (unsigned i = 0; (nr > 0) && (i < ARRAY_SIZE(stages)); i++) {
+ if (!stages[i].cond)
+ continue;
+ stages[i].freed =
+ drm_gem_lru_scan(stages[i].lru, nr, stages[i].shrink);
+ nr -= stages[i].freed;
+ freed += stages[i].freed;
}
- freed = purged + evicted;
-
- if (freed)
- trace_msm_gem_shrink(sc->nr_to_scan, purged, evicted);
+ if (freed) {
+ trace_msm_gem_shrink(sc->nr_to_scan, stages[0].freed,
+ stages[1].freed, stages[2].freed,
+ stages[3].freed);
+ }
return (freed > 0) ? freed : SHRINK_STOP;
}
diff --git a/drivers/gpu/drm/msm/msm_gpu_trace.h b/drivers/gpu/drm/msm/msm_gpu_trace.h
index 8867fa0a0306..ac40d857bc45 100644
--- a/drivers/gpu/drm/msm/msm_gpu_trace.h
+++ b/drivers/gpu/drm/msm/msm_gpu_trace.h
@@ -116,22 +116,26 @@ TRACE_EVENT(msm_gmu_freq_change,
TRACE_EVENT(msm_gem_shrink,
- TP_PROTO(u32 nr_to_scan, u32 purged, u32 evicted),
- TP_ARGS(nr_to_scan, purged, evicted),
+ TP_PROTO(u32 nr_to_scan, u32 purged, u32 evicted,
+ u32 active_purged, u32 active_evicted),
+ TP_ARGS(nr_to_scan, purged, evicted, active_purged, active_evicted),
TP_STRUCT__entry(
__field(u32, nr_to_scan)
__field(u32, purged)
__field(u32, evicted)
+ __field(u32, active_purged)
+ __field(u32, active_evicted)
),
TP_fast_assign(
__entry->nr_to_scan = nr_to_scan;
__entry->purged = purged;
__entry->evicted = evicted;
+ __entry->active_purged = active_purged;
+ __entry->active_evicted = active_evicted;
),
- TP_printk("nr_to_scan=%u pages, purged=%u pages, evicted=%u pages",
- __entry->nr_to_scan,
- __entry->purged,
- __entry->evicted)
+ TP_printk("nr_to_scan=%u pg, purged=%u pg, evicted=%u pg, active_purged=%u pg, active_evicted=%u pg",
+ __entry->nr_to_scan, __entry->purged, __entry->evicted,
+ __entry->active_purged, __entry->active_evicted)
);
--
2.36.1
next prev parent reply other threads:[~2022-07-19 17:19 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-19 17:18 [PATCH v2 00/13] drm+msm: Shrinker and LRU rework Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 01/13] drm/msm: Reorder lock vs submit alloc Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 02/13] drm/msm: Small submit cleanup Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 03/13] drm/msm: Split out idr_lock Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 04/13] drm/msm/gem: Check for active in shrinker path Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 05/13] drm/msm/gem: Rename update_inactive Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 06/13] drm/msm/gem: Rename to pin/unpin_pages Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 07/13] drm/msm/gem: Consolidate pin/unpin paths Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 08/13] drm/msm/gem: Remove active refcnt Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 09/13] drm/gem: Add LRU/shrinker helper Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 18:56 ` Dmitry Osipenko
2022-07-19 18:56 ` Dmitry Osipenko
2022-07-20 17:57 ` Rob Clark
2022-07-20 17:57 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 10/13] drm/msm/gem: Convert to using drm_gem_lru Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 11/13] drm/msm/gem: Unpin buffers earlier Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` [PATCH v2 12/13] drm/msm/gem: Consolidate shrinker trace Rob Clark
2022-07-19 17:18 ` Rob Clark
2022-07-19 17:18 ` Rob Clark [this message]
2022-07-19 17:18 ` [PATCH v2 13/13] drm/msm/gem: Evict active GEM objects when necessary Rob Clark
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=20220719171900.289265-14-robdclark@gmail.com \
--to=robdclark@gmail.com \
--cc=airlied@linux.ie \
--cc=daniel@ffwll.ch \
--cc=dmitry.baryshkov@linaro.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=quic_abhinavk@quicinc.com \
--cc=robdclark@chromium.org \
--cc=sean@poorly.run \
/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.