* [PATCH 2/2] drm/i915: rc6 in sysfs
2012-03-28 1:59 [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Ben Widawsky
@ 2012-03-28 1:59 ` Ben Widawsky
2012-04-10 9:42 ` Chris Wilson
2012-03-28 1:59 ` [PATCH 1/3] build: make sure we have asprintf Ben Widawsky
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Ben Widawsky @ 2012-03-28 1:59 UTC (permalink / raw)
To: intel-gfx; +Cc: Ben Widawsky, f, Daniel Vetter, Ben Widawsky, Arjan van de Ven
Merge rc6 information into the power group for our device. Until now the
i915 driver has not had any sysfs entries (aside from the connector
stuff enabled by drm core). Since it seems like we're likely to have
more in the future I created a new file for sysfs stubs, as well as the
rc6 sysfs functions which don't really belong elsewhere (perhaps
i915_suspend, but most of the stuff is in intel_display,c).
displays rc6 modes enabled (as a hex mask):
cat /sys/class/drm/card0/power/rc6_enable
displays #ms GPU has been in rc6 since boot:
cat /sys/class/drm/card0/power/rc6
displays #ms GPU has been in deep rc6 since boot:
cat /sys/class/drm/card0/power/rc6p
displays #ms GPU has been in deepest rc6 since boot:
cat /sys/class/drm/card0/power/rc6pp
Important note: I've seen on SNB that even when RC6 is *not* enabled the
rc6 register seems to have a random value in it. I can only guess at the
reason reason for this. Those writing tools that utilize this value need
to be careful and probably want to scrutinize the value very carefully.
v2: use common rc6 residency units to milliseconds for the other RC6 types
v3: don't create sysfs files for GEN <= 5
add a rc6_enable to show a mask of enabled rc6 types
use unmerge instead of remove for sysfs group
squash intel_enable_rc6() extraction into this patch
CC: Chris Wilson <chris@chris-wilson.co.uk>
CC: Daniel Vetter <daniel.vetter@ffwll.ch>f
CC: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_dma.c | 4 ++
drivers/gpu/drm/i915/i915_drv.h | 5 ++
drivers/gpu/drm/i915/i915_sysfs.c | 113 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 2 +-
5 files changed, 124 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/i915/i915_sysfs.c
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index ce7fc77..f801330 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -12,6 +12,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
i915_gem_execbuffer.o \
i915_gem_gtt.o \
i915_gem_tiling.o \
+ i915_sysfs.o \
i915_trace_points.o \
intel_display.o \
intel_crt.o \
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index cadf43b..ece4fb6 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2115,6 +2115,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}
}
+ i915_setup_sysfs(dev);
+
/* Must be done after probing outputs */
intel_opregion_init(dev);
acpi_video_register();
@@ -2166,6 +2168,8 @@ int i915_driver_unload(struct drm_device *dev)
i915_mch_dev = NULL;
spin_unlock(&mchdev_lock);
+ i915_teardown_sysfs(dev);
+
if (dev_priv->mm.inactive_shrinker.shrink)
unregister_shrinker(&dev_priv->mm.inactive_shrinker);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bbbc1a4..e267774 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1365,6 +1365,10 @@ extern int i915_restore_state(struct drm_device *dev);
extern int i915_save_state(struct drm_device *dev);
extern int i915_restore_state(struct drm_device *dev);
+/* i915_sysfs.c */
+void i915_setup_sysfs(struct drm_device *dev_priv);
+void i915_teardown_sysfs(struct drm_device *dev_priv);
+
/* intel_i2c.c */
extern int intel_setup_gmbus(struct drm_device *dev);
extern void intel_teardown_gmbus(struct drm_device *dev);
@@ -1414,6 +1418,7 @@ extern void ironlake_enable_rc6(struct drm_device *dev);
extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void intel_detect_pch(struct drm_device *dev);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
+extern int intel_enable_rc6(const struct drm_device *dev);
extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
new file mode 100644
index 0000000..b7525e4
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Ben Widawsky <ben@bwidawsk.net>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/sysfs.h>
+#include "i915_drv.h"
+
+static u32 calc_residency(struct drm_device *dev, const u32 reg)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u64 raw_time; /* 32b value may overflow during fixed point math */
+ u32 residency;
+
+ if (!intel_enable_rc6(dev))
+ return 0;
+
+ raw_time = I915_READ(reg) * 128ULL;
+ residency = DIV_ROUND_CLOSEST(raw_time, 1000) / 100;
+ return residency;
+}
+
+static ssize_t
+show_rc6_mask(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ return snprintf(buf, PAGE_SIZE, "%x", intel_enable_rc6(dminor->dev));
+}
+
+static ssize_t
+show_rc6_ms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6);
+ return snprintf(buf, PAGE_SIZE, "%u", rc6_residency);
+}
+
+static ssize_t
+show_rc6p_ms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
+ return snprintf(buf, PAGE_SIZE, "%u", rc6p_residency);
+}
+
+static ssize_t
+show_rc6pp_ms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
+ return snprintf(buf, PAGE_SIZE, "%u", rc6pp_residency);
+}
+
+static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
+static DEVICE_ATTR(rc6, S_IRUGO, show_rc6_ms, NULL);
+static DEVICE_ATTR(rc6p, S_IRUGO, show_rc6p_ms, NULL);
+static DEVICE_ATTR(rc6pp, S_IRUGO, show_rc6pp_ms, NULL);
+
+static struct attribute *rc6_attrs[] = {
+ &dev_attr_rc6_enable.attr,
+ &dev_attr_rc6.attr,
+ &dev_attr_rc6p.attr,
+ &dev_attr_rc6pp.attr,
+ NULL
+};
+
+static struct attribute_group rc6_attr_group = {
+ .name = power_group_name,
+ .attrs = rc6_attrs
+};
+
+void i915_setup_sysfs(struct drm_device *dev)
+{
+ int ret;
+
+ /* ILK doesn't have any residency information */
+ if (INTEL_INFO(dev)->gen < 6)
+ return;
+
+ ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
+ if (ret)
+ DRM_ERROR("sysfs setup failed\n");
+}
+
+void i915_teardown_sysfs(struct drm_device *dev)
+{
+ sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ab62c96..efbf709 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8235,7 +8235,7 @@ void intel_init_emon(struct drm_device *dev)
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
}
-static int intel_enable_rc6(struct drm_device *dev)
+int intel_enable_rc6(const struct drm_device *dev)
{
/*
* Respect the kernel parameter if it is set
--
1.7.9.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 2/2] drm/i915: rc6 in sysfs
2012-03-28 1:59 ` [PATCH 2/2] drm/i915: rc6 in sysfs Ben Widawsky
@ 2012-04-10 9:42 ` Chris Wilson
0 siblings, 0 replies; 8+ messages in thread
From: Chris Wilson @ 2012-04-10 9:42 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter, Ben Widawsky, f, Arjan van de Ven, Ben Widawsky
On Tue, 27 Mar 2012 18:59:39 -0700, Ben Widawsky <ben@bwidawsk.net> wrote:
> Merge rc6 information into the power group for our device. Until now the
> i915 driver has not had any sysfs entries (aside from the connector
> stuff enabled by drm core). Since it seems like we're likely to have
> more in the future I created a new file for sysfs stubs, as well as the
> rc6 sysfs functions which don't really belong elsewhere (perhaps
> i915_suspend, but most of the stuff is in intel_display,c).
>
> displays rc6 modes enabled (as a hex mask):
> cat /sys/class/drm/card0/power/rc6_enable
>
> displays #ms GPU has been in rc6 since boot:
> cat /sys/class/drm/card0/power/rc6
>
> displays #ms GPU has been in deep rc6 since boot:
> cat /sys/class/drm/card0/power/rc6p
>
> displays #ms GPU has been in deepest rc6 since boot:
> cat /sys/class/drm/card0/power/rc6pp
Last comments, I promise.
/sys/class/drm/card0/power/rc6_uptime_ms or
/sys/class/drm/card0/power/rc6_total[_ms] or
/sys/class/drm/card0/power/rc6_residency[_ms]
A plain (rc6, rc6p, rc6pp) is just too vague and so may conflict with a
future knob we wish to expose via sysfs.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/3] build: make sure we have asprintf
2012-03-28 1:59 [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Ben Widawsky
2012-03-28 1:59 ` [PATCH 2/2] drm/i915: rc6 in sysfs Ben Widawsky
@ 2012-03-28 1:59 ` Ben Widawsky
2012-03-28 1:59 ` [PATCH 2/3] drm/i915: extract card getting Ben Widawsky
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Ben Widawsky @ 2012-03-28 1:59 UTC (permalink / raw)
To: intel-gfx; +Cc: Ben Widawsky
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
configure.ac | 2 ++
1 file changed, 2 insertions(+)
diff --git a/configure.ac b/configure.ac
index f778a9a..567f10d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,6 +32,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_USE_SYSTEM_EXTENSIONS
AC_SYS_LARGEFILE
+AC_GNU_SOURCE
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_PATH_PYTHON([3],, [:])
@@ -43,6 +44,7 @@ AC_CHECK_MEMBERS([struct sysinfo.totalram],[],[],[AC_INCLUDES_DEFAULT
#include <sys/sysinfo.h>
])
AC_CHECK_FUNCS([swapctl])
+AC_CHECK_FUNCS([asprintf])
# Initialize libtool
AC_DISABLE_STATIC
--
1.7.9.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/3] drm/i915: extract card getting
2012-03-28 1:59 [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Ben Widawsky
2012-03-28 1:59 ` [PATCH 2/2] drm/i915: rc6 in sysfs Ben Widawsky
2012-03-28 1:59 ` [PATCH 1/3] build: make sure we have asprintf Ben Widawsky
@ 2012-03-28 1:59 ` Ben Widawsky
2012-03-28 1:59 ` [PATCH] tests: rc6 residency test Ben Widawsky
2012-04-10 9:52 ` [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Daniel Vetter
4 siblings, 0 replies; 8+ messages in thread
From: Ben Widawsky @ 2012-03-28 1:59 UTC (permalink / raw)
To: intel-gfx; +Cc: Ben Widawsky
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
lib/drmtest.c | 122 +++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 83 insertions(+), 39 deletions(-)
diff --git a/lib/drmtest.c b/lib/drmtest.c
index f9b7a6f..063b5c5 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -26,6 +26,8 @@
*
*/
+#define _GNU_SOURCE
+#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
@@ -112,70 +114,112 @@ void gem_quiescent_gpu(int fd)
gem_sync(fd, handle);
}
-/** Open the first DRM device we can find, searching up to 16 device nodes */
-int drm_open_any(void)
+static bool is_master(int fd)
{
- char name[20];
+ drm_client_t client;
+ int ret;
+
+ /* Check that we're the only opener and authed. */
+ client.idx = 0;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ assert (ret == 0);
+ if (!client.auth) {
+ return 0;
+ }
+ client.idx = 1;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ if (ret != -1 || errno != EINVAL) {
+ return 0;
+ }
+ return 1;
+}
+
+/**
+ * drm_get_card() - get an intel card number for use in /dev or /sys
+ *
+ * @master: -1 not a master, 0 don't care, 1 is the master
+ *
+ * returns -1 on error
+ */
+int drm_get_card(int master)
+{
+ char *name;
int i, fd;
for (i = 0; i < 16; i++) {
- sprintf(name, "/dev/dri/card%d", i);
+ int ret;
+
+ ret = asprintf(&name, "/dev/dri/card%u", i);
+ if (ret == -1)
+ return -1;
fd = open(name, O_RDWR);
+ free(name);
+
if (fd == -1)
continue;
- if (is_intel(fd)) {
+ if (is_intel(fd) && master == 0) {
gem_quiescent_gpu(fd);
- return fd;
+ break;
+ }
+
+ if (master == 1 && is_master(fd)) {
+ close(fd);
+ break;
+ }
+
+ if (master == -1 && !is_master(fd)) {
+ close(fd);
+ break;
}
close(fd);
}
- fprintf(stderr, "failed to open any drm device. retry as root?\n");
- abort();
+
+ return i;
}
+/** Open the first DRM device we can find, searching up to 16 device nodes */
+int drm_open_any(void)
+{
+ char *name;
+ int ret, fd;
+
+ ret = asprintf(&name, "/dev/dri/card%d", drm_get_card(0));
+ if (ret == -1)
+ return -1;
+
+ fd = open(name, O_RDWR);
+ free(name);
+
+ if (fd == -1)
+ fprintf(stderr, "failed to open any drm device. retry as root?\n");
+
+ assert(is_intel(fd));
+
+ return fd;
+}
/**
* Open the first DRM device we can find where we end up being the master.
*/
int drm_open_any_master(void)
{
- char name[20];
- int i, fd;
+ char *name;
+ int ret, fd;
- for (i = 0; i < 16; i++) {
- drm_client_t client;
- int ret;
+ ret = asprintf(&name, "/dev/dri/card%d", drm_get_card(1));
+ if (ret == -1)
+ return -1;
- sprintf(name, "/dev/dri/card%d", i);
- fd = open(name, O_RDWR);
- if (fd == -1)
- continue;
+ fd = open(name, O_RDWR);
+ free(name);
+ if (fd == -1)
+ fprintf(stderr, "Couldn't find an un-controlled DRM device\n");
- if (!is_intel(fd)) {
- close(fd);
- continue;
- }
+ assert(is_intel(fd));
- /* Check that we're the only opener and authed. */
- client.idx = 0;
- ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
- assert (ret == 0);
- if (!client.auth) {
- close(fd);
- continue;
- }
- client.idx = 1;
- ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
- if (ret != -1 || errno != EINVAL) {
- close(fd);
- continue;
- }
- return fd;
- }
- fprintf(stderr, "Couldn't find an un-controlled DRM device\n");
- abort();
+ return fd;
}
void gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
--
1.7.9.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH] tests: rc6 residency test
2012-03-28 1:59 [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Ben Widawsky
` (2 preceding siblings ...)
2012-03-28 1:59 ` [PATCH 2/3] drm/i915: extract card getting Ben Widawsky
@ 2012-03-28 1:59 ` Ben Widawsky
2012-03-28 2:31 ` Ben Widawsky
2012-04-10 9:52 ` [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Daniel Vetter
4 siblings, 1 reply; 8+ messages in thread
From: Ben Widawsky @ 2012-03-28 1:59 UTC (permalink / raw)
To: intel-gfx; +Cc: Ben Widawsky, Ben Widawsky
This is meant to test the sysfs entry for showing rc6 residency in
milliseconds. Remember, sysfs is a permanent interface.
v2: use new get_card interface to try "all" devices
check rc6p and rc6pp in addition to rc6
v3: rename rc6_residency.c to sysfs_rc6_residency.c
print better error messages
skip test if rc6 isn't enabled
Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
---
lib/drmtest.h | 1 +
tests/Makefile.am | 1 +
tests/sysfs_rc6_residency.c | 107 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 109 insertions(+)
create mode 100644 tests/sysfs_rc6_residency.c
diff --git a/lib/drmtest.h b/lib/drmtest.h
index 96fbf1a..42f238c 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -35,6 +35,7 @@
#include "xf86drm.h"
#include "intel_batchbuffer.h"
+int drm_get_card(int master);
int drm_open_any(void);
int drm_open_any_master(void);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6544ec7..9c3b058 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -56,6 +56,7 @@ TESTS_progs = \
drm_vma_limiter_cpu \
drm_vma_limiter_gtt \
drm_vma_limiter_cached \
+ sysfs_rc6_residency \
$(NULL)
# IMPORTANT: The ZZ_ tests need to be run last!
diff --git a/tests/sysfs_rc6_residency.c b/tests/sysfs_rc6_residency.c
new file mode 100644
index 0000000..1772c87
--- /dev/null
+++ b/tests/sysfs_rc6_residency.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Ben Widawsky <ben@bwidawsk.net>
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "drmtest.h"
+
+#define SLEEP_DURATION 3000 // in milliseconds
+#define RC6_FUDGE 900 // in milliseconds
+
+static unsigned int readit(const char *path)
+{
+ unsigned int ret;
+
+ FILE *file;
+ file = fopen(path, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Couldn't open %s (%d)\n", path, errno);
+ abort();
+ }
+ fscanf(file, "%u", &ret);
+ fclose(file);
+
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ const int device = drm_get_card(0);
+ char *path, *pathp, *pathpp;
+ int fd, ret;
+ unsigned int value1, value1p, value1pp, value2, value2p, value2pp;
+ int diff;
+
+ /* Use drm_open_any to verify device existence */
+ fd = drm_open_any();
+ close(fd);
+
+ ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6", device);
+ assert(ret != -1);
+
+ if (readit(path) == 0)
+ exit(EXIT_SUCCESS);
+
+ ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6", device);
+ assert(ret != -1);
+ ret = asprintf(&pathp, "/sys/class/drm/card%d/power/rc6p", device);
+ assert(ret != -1);
+ ret = asprintf(&pathpp, "/sys/class/drm/card%d/power/rc6pp", device);
+ assert(ret != -1);
+
+ value1 = readit(path);
+ value1p = readit(pathp);
+ value1pp = readit(pathpp);
+ sleep(SLEEP_DURATION / 1000);
+ value2 = readit(path);
+ value2p = readit(pathp);
+ value2pp = readit(pathpp);
+
+ free(pathpp);
+ free(pathp);
+ free(path);
+
+ diff = (value2pp - value1pp) +
+ (value2p - value1p) +
+ (value2 - value1);
+
+ if (diff > (SLEEP_DURATION + RC6_FUDGE)) {
+ fprintf(stderr, "Diff was too high. That is unpossible\n");
+ exit(EXIT_FAILURE);
+ }
+ if (diff < (SLEEP_DURATION - RC6_FUDGE)) {
+ fprintf(stderr, "GPU was not in RC6 long enough. Check that "
+ "the GPU is as idle as possible (ie. no X, "
+ "running and running no other tests)\n");
+ exit(EXIT_FAILURE);
+ }
+
+ exit(EXIT_SUCCESS);
+}
--
1.7.9.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] tests: rc6 residency test
2012-03-28 1:59 ` [PATCH] tests: rc6 residency test Ben Widawsky
@ 2012-03-28 2:31 ` Ben Widawsky
0 siblings, 0 replies; 8+ messages in thread
From: Ben Widawsky @ 2012-03-28 2:31 UTC (permalink / raw)
To: Ben Widawsky; +Cc: intel-gfx, Ben Widawsky
On Tue, 27 Mar 2012 18:59:42 -0700
Ben Widawsky <ben@bwidawsk.net> wrote:
> This is meant to test the sysfs entry for showing rc6 residency in
> milliseconds. Remember, sysfs is a permanent interface.
>
> v2: use new get_card interface to try "all" devices
> check rc6p and rc6pp in addition to rc6
>
> v3: rename rc6_residency.c to sysfs_rc6_residency.c
> print better error messages
> skip test if rc6 isn't enabled
>
> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
> ---
> lib/drmtest.h | 1 +
> tests/Makefile.am | 1 +
> tests/sysfs_rc6_residency.c | 107 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 109 insertions(+)
> create mode 100644 tests/sysfs_rc6_residency.c
>
> diff --git a/lib/drmtest.h b/lib/drmtest.h
> index 96fbf1a..42f238c 100644
> --- a/lib/drmtest.h
> +++ b/lib/drmtest.h
> @@ -35,6 +35,7 @@
> #include "xf86drm.h"
> #include "intel_batchbuffer.h"
>
> +int drm_get_card(int master);
> int drm_open_any(void);
> int drm_open_any_master(void);
>
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 6544ec7..9c3b058 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -56,6 +56,7 @@ TESTS_progs = \
> drm_vma_limiter_cpu \
> drm_vma_limiter_gtt \
> drm_vma_limiter_cached \
> + sysfs_rc6_residency \
> $(NULL)
>
> # IMPORTANT: The ZZ_ tests need to be run last!
> diff --git a/tests/sysfs_rc6_residency.c b/tests/sysfs_rc6_residency.c
> new file mode 100644
> index 0000000..1772c87
> --- /dev/null
> +++ b/tests/sysfs_rc6_residency.c
> @@ -0,0 +1,107 @@
> +/*
> + * Copyright © 2012 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + * Ben Widawsky <ben@bwidawsk.net>
> + *
> + */
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include "drmtest.h"
> +
> +#define SLEEP_DURATION 3000 // in milliseconds
> +#define RC6_FUDGE 900 // in milliseconds
> +
> +static unsigned int readit(const char *path)
> +{
> + unsigned int ret;
> +
> + FILE *file;
> + file = fopen(path, "r");
> + if (file == NULL) {
> + fprintf(stderr, "Couldn't open %s (%d)\n", path, errno);
> + abort();
> + }
> + fscanf(file, "%u", &ret);
> + fclose(file);
> +
> + return ret;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + const int device = drm_get_card(0);
> + char *path, *pathp, *pathpp;
> + int fd, ret;
> + unsigned int value1, value1p, value1pp, value2, value2p, value2pp;
> + int diff;
> +
> + /* Use drm_open_any to verify device existence */
> + fd = drm_open_any();
> + close(fd);
> +
> + ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6", device);
> + assert(ret != -1);
Copy+paste bug here. Imagine it says rc6_enabled instead of rc6.
> +
> + if (readit(path) == 0)
> + exit(EXIT_SUCCESS);
> +
> + ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6", device);
> + assert(ret != -1);
> + ret = asprintf(&pathp, "/sys/class/drm/card%d/power/rc6p", device);
> + assert(ret != -1);
> + ret = asprintf(&pathpp, "/sys/class/drm/card%d/power/rc6pp", device);
> + assert(ret != -1);
> +
> + value1 = readit(path);
> + value1p = readit(pathp);
> + value1pp = readit(pathpp);
> + sleep(SLEEP_DURATION / 1000);
> + value2 = readit(path);
> + value2p = readit(pathp);
> + value2pp = readit(pathpp);
> +
> + free(pathpp);
> + free(pathp);
> + free(path);
> +
> + diff = (value2pp - value1pp) +
> + (value2p - value1p) +
> + (value2 - value1);
> +
> + if (diff > (SLEEP_DURATION + RC6_FUDGE)) {
> + fprintf(stderr, "Diff was too high. That is unpossible\n");
> + exit(EXIT_FAILURE);
> + }
> + if (diff < (SLEEP_DURATION - RC6_FUDGE)) {
> + fprintf(stderr, "GPU was not in RC6 long enough. Check that "
> + "the GPU is as idle as possible (ie. no X, "
> + "running and running no other tests)\n");
> + exit(EXIT_FAILURE);
> + }
> +
> + exit(EXIT_SUCCESS);
> +}
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] drm/i915: add rc6 residency times to debugfs
2012-03-28 1:59 [PATCH 1/2] drm/i915: add rc6 residency times to debugfs Ben Widawsky
` (3 preceding siblings ...)
2012-03-28 1:59 ` [PATCH] tests: rc6 residency test Ben Widawsky
@ 2012-04-10 9:52 ` Daniel Vetter
4 siblings, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2012-04-10 9:52 UTC (permalink / raw)
To: Ben Widawsky; +Cc: intel-gfx, Ben Widawsky
On Tue, Mar 27, 2012 at 06:59:38PM -0700, Ben Widawsky wrote:
> RC6 residency should be in intervals of 1.28us, and the counter wraps.
> Here is an example using awk to get the various RC6 and RC6+ residency
> times in seconds, since boot.
>
> cat /sys/kernel/debug/dri/0/i915_drpc_info | grep residency | awk -F':' -F' ' '{print $5 * 1.28 / 1000000}'
>
> This is primarily for QA, but has other applications as well. An
> upcoming patch to add interfaces should be more interesting to
> application developers.
>
> v2: move comment to the correct place
>
> v3: display with %u instead of %d, for Ouping
>
> CC: Ouping Zhang <ouping.zhang@intel.com>
> Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
Queued for -next, thanks for the patch. I've stalled on the 2nd one due to
Chris' bikeshed. Personally, I prefer the _residency_ms names.
Also, please update the i-g-t patches when resending.
Thanks, Daniel
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 11 +++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 5 +++++
> 2 files changed, 16 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 66c90d4..0b9c1e8 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1133,6 +1133,17 @@ static int gen6_drpc_info(struct seq_file *m)
>
> seq_printf(m, "Core Power Down: %s\n",
> yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK));
> +
> + /* Not exactly sure what this is */
> + seq_printf(m, "RC6 \"Locked to RPn\" residency since boot: %u\n",
> + I915_READ(GEN6_GT_GFX_RC6_LOCKED));
> + seq_printf(m, "RC6 residency since boot: %u\n",
> + I915_READ(GEN6_GT_GFX_RC6));
> + seq_printf(m, "RC6+ residency since boot: %u\n",
> + I915_READ(GEN6_GT_GFX_RC6p));
> + seq_printf(m, "RC6++ residency since boot: %u\n",
> + I915_READ(GEN6_GT_GFX_RC6pp));
> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index f3609f2..b1c3d35 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3799,6 +3799,11 @@
> GEN6_PM_RP_DOWN_THRESHOLD | \
> GEN6_PM_RP_DOWN_TIMEOUT)
>
> +#define GEN6_GT_GFX_RC6_LOCKED 0x138104
> +#define GEN6_GT_GFX_RC6 0x138108
> +#define GEN6_GT_GFX_RC6p 0x13810C
> +#define GEN6_GT_GFX_RC6pp 0x138110
> +
> #define GEN6_PCODE_MAILBOX 0x138124
> #define GEN6_PCODE_READY (1<<31)
> #define GEN6_READ_OC_PARAMS 0xc
> --
> 1.7.9.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48
^ permalink raw reply [flat|nested] 8+ messages in thread