From: Ben Widawsky <benjamin.widawsky@intel.com>
To: DRI Development <dri-devel@lists.freedesktop.org>
Cc: Intel GFX <intel-gfx@lists.freedesktop.org>,
Ben Widawsky <ben@bwidawsk.net>,
Ben Widawsky <benjamin.widawsky@intel.com>
Subject: [PATCH 3/4] drm/cache: Return what type of cache flush occurred
Date: Sat, 13 Dec 2014 19:08:23 -0800 [thread overview]
Message-ID: <1418526504-26316-4-git-send-email-benjamin.widawsky@intel.com> (raw)
In-Reply-To: <1418526504-26316-1-git-send-email-benjamin.widawsky@intel.com>
The caller of the cache flush APIs can sometimes do useful things with the
information of how the cache was flushed. For instance, when giving buffers to
the GPU to read, we need to make sure all of them have properly invalidated the
caches (when not using LLC). If we can determine a wbinvd() occurred though, we
can skip trying to clflush all remaining objects.
There is a further optimization to be made here in the driver specific code
where it can try to flush the largest object first in hopes of it needing a
wbinvd(). I haven't implemented that yet.
The enum parts of this were very minimally considered for the sake of getting
the data for the profile.
Cc: Intel GFX <intel-gfx@lists.freedesktop.org>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/drm_cache.c | 34 +++++++++++++++++++++++++---------
include/drm/drmP.h | 13 ++++++++++---
2 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 6009c2d..433b15d 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -80,21 +80,25 @@ drm_cache_should_clflush(unsigned long num_pages)
}
#endif
-void
+int
drm_clflush_pages(struct page *pages[], unsigned long num_pages)
{
#if defined(CONFIG_X86)
if (cpu_has_clflush && drm_cache_should_clflush(num_pages)) {
drm_cache_flush_clflush(pages, num_pages);
- return;
+ return DRM_CACHE_FLUSH_CL;
}
- if (wbinvd_on_all_cpus())
+ if (wbinvd_on_all_cpus()) {
printk(KERN_ERR "Timed out waiting for cache flush.\n");
+ return DRM_CACHE_FLUSH_ERROR;
+ } else
+ return DRM_CACHE_FLUSH_WBINVD;
#elif defined(__powerpc__)
unsigned long i;
+ int ret = DRM_CACHE_FLUSH_NONE;
for (i = 0; i < num_pages; i++) {
struct page *page = pages[i];
void *page_virtual;
@@ -106,15 +110,19 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
flush_dcache_range((unsigned long)page_virtual,
(unsigned long)page_virtual + PAGE_SIZE);
kunmap_atomic(page_virtual);
+ ret = DRM_CACHE_FLUSH_DCACHE;
}
+ WARN_ON(ret == DRM_CACHE_FLUSH_NONE);
+ return ret;
#else
printk(KERN_ERR "Architecture has no drm_cache.c support\n");
WARN_ON_ONCE(1);
+ return DRM_CACHE_FLUSH_NONE;
#endif
}
EXPORT_SYMBOL(drm_clflush_pages);
-void
+int
drm_clflush_sg(struct sg_table *st)
{
#if defined(CONFIG_X86)
@@ -126,19 +134,23 @@ drm_clflush_sg(struct sg_table *st)
drm_clflush_page(sg_page_iter_page(&sg_iter));
mb();
- return;
+ return DRM_CACHE_FLUSH_CL;
}
- if (wbinvd_on_all_cpus())
+ if (wbinvd_on_all_cpus()) {
printk(KERN_ERR "Timed out waiting for cache flush.\n");
+ return DRM_CACHE_FLUSH_ERROR;
+ } else
+ return DRM_CACHE_FLUSH_WBINVD;
#else
printk(KERN_ERR "Architecture has no drm_cache.c support\n");
WARN_ON_ONCE(1);
+ return DRM_CACHE_FLUSH_NONE;
#endif
}
EXPORT_SYMBOL(drm_clflush_sg);
-void
+int
drm_clflush_virt_range(void *addr, unsigned long length)
{
#if defined(CONFIG_X86)
@@ -149,14 +161,18 @@ drm_clflush_virt_range(void *addr, unsigned long length)
clflushopt(addr);
clflushopt(end - 1);
mb();
- return;
+ return DRM_CACHE_FLUSH_CL;
}
- if (wbinvd_on_all_cpus())
+ if (wbinvd_on_all_cpus()) {
printk(KERN_ERR "Timed out waiting for cache flush.\n");
+ return DRM_CACHE_FLUSH_ERROR;
+ } else
+ return DRM_CACHE_FLUSH_WBINVD;
#else
printk(KERN_ERR "Architecture has no drm_cache.c support\n");
WARN_ON_ONCE(1);
+ return DRM_CACHE_FLUSH_NONE;
#endif
}
EXPORT_SYMBOL(drm_clflush_virt_range);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 8ba35c6..09ebe46 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -884,9 +884,16 @@ int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
/* Cache management (drm_cache.c) */
-void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
-void drm_clflush_sg(struct sg_table *st);
-void drm_clflush_virt_range(void *addr, unsigned long length);
+enum drm_cache_flush {
+ DRM_CACHE_FLUSH_NONE=0,
+ DRM_CACHE_FLUSH_ERROR,
+ DRM_CACHE_FLUSH_CL,
+ DRM_CACHE_FLUSH_WBINVD,
+ DRM_CACHE_FLUSH_DCACHE,
+};
+int drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+int drm_clflush_sg(struct sg_table *st);
+int drm_clflush_virt_range(void *addr, unsigned long length);
/*
* These are exported to drivers so that they can implement fencing using
--
2.1.3
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2014-12-14 3:08 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1418526504-26316-1-git-send-email-benjamin.widawsky@intel.com>
2014-12-14 3:08 ` [PATCH 1/4] drm/cache: Use wbinvd helpers Ben Widawsky
2014-12-14 12:43 ` Chris Wilson
2014-12-15 7:49 ` Daniel Vetter
2014-12-15 20:26 ` [PATCH] [v2] " Ben Widawsky
2014-12-16 2:26 ` shuang.he
2014-12-16 7:56 ` Daniel Vetter
2014-12-14 3:08 ` [PATCH 2/4] drm/cache: Try to be smarter about clflushing on x86 Ben Widawsky
2014-12-14 4:15 ` Matt Turner
2014-12-15 22:07 ` Ben Widawsky
2014-12-14 12:59 ` [Intel-gfx] " Chris Wilson
2014-12-15 4:06 ` Jesse Barnes
2014-12-15 19:54 ` Ben Widawsky
2014-12-14 3:08 ` Ben Widawsky [this message]
2014-12-14 3:08 ` [PATCH 4/4] drm/i915: Opportunistically reduce flushing at execbuf Ben Widawsky
2014-12-14 9:35 ` shuang.he
2014-12-14 13:12 ` [Intel-gfx] " Ville Syrjälä
2014-12-14 23:37 ` Ben Widawsky
2014-12-15 7:55 ` [Intel-gfx] " Daniel Vetter
2014-12-15 8:20 ` Chris Wilson
2014-12-15 19:56 ` Ben Widawsky
2014-12-15 20:39 ` Chris Wilson
2014-12-15 21:06 ` [Intel-gfx] " Ben Widawsky
2014-12-16 7:57 ` Chris Wilson
2014-12-16 19:38 ` Ben Widawsky
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=1418526504-26316-4-git-send-email-benjamin.widawsky@intel.com \
--to=benjamin.widawsky@intel.com \
--cc=ben@bwidawsk.net \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox