From: Greg Depoire--Ferrer <greg@gregdf.com>
To: nouveau@lists.freedesktop.org
Subject: [Nouveau] Busy poll during commit
Date: Mon, 8 Aug 2022 22:57:30 +0200 (CEST) [thread overview]
Message-ID: <20220808205757.8C1DC7DE6C6@gregdf.com> (raw)
Hi,
Moving the cursor in circles on Linux 5.18 with a GTX 1070 mobile and a 120 Hz
display uses ~30% CPU.
Using perf shows most of the instructions are spent polling in
base507c_ntfy_wait_begun in drivers/gpu/drm/nouveau/dispnv50/base507c.c:
int
base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device)
{
s64 time = nvif_msec(device, 2000ULL,
if (NVBO_TD32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, STATUS, ==, BEGUN))
break;
usleep_range(1, 2);
);
return time < 0 ? time : 0;
}
That function is called from drivers/gpu/drm/nouveau/dispnv50/wndw.c:
int
nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
struct nv50_disp *disp = nv50_disp(wndw->plane.dev);
if (asyw->set.ntfy) {
return wndw->func->ntfy_wait_begun(disp->sync,
asyw->ntfy.offset,
wndw->wndw.base.device);
}
return 0;
}
Which in turn is called from nv50_disp_atomic_commit_tail in
drivers/gpu/drm/nouveau/dispnv50/disp.c:
/* Wait for HW to signal completion. */
for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
int ret = nv50_wndw_wait_armed(wndw, asyw);
if (ret)
NV_ERROR(drm, "%s: timeout\n", plane->name);
}
I haven't found many resources on how commits work. Could busy polling be
replaced by something else?
Additional information that might be helpful: with printks I found that
nv50_head_vblank_handler in drivers/gpu/drm/nouveau/dispnv50/head.c is always
called right before base507c_ntfy_wait_begun finished.
So for instance this patch drops the CPU usage by making sure that
base507c_ntfy_wait_begun does not even enter the loop using
drm_atomic_helper_wait_for_vblanks to wait for the vblank.
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 5863a689818c..f535ded86b2f 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2186,6 +2186,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
if (atom->lock_core)
mutex_unlock(&disp->mutex);
+ drm_atomic_helper_wait_for_vblanks(dev, state);
+
/* Wait for HW to signal completion. */
for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
Regards,
Greg
reply other threads:[~2022-08-08 20:58 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20220808205757.8C1DC7DE6C6@gregdf.com \
--to=greg@gregdf.com \
--cc=nouveau@lists.freedesktop.org \
/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.