<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<div id="divtagdefaultwrapper" dir="ltr" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;">
<p style="margin-top:0; margin-bottom:0">Patch is Reviewed-by: David Francis <david.francis@amd.com></p>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Nicholas Kazlauskas <nicholas.kazlauskas@amd.com><br>
<b>Sent:</b> April 16, 2019 1:45:12 PM<br>
<b>To:</b> igt-dev@lists.freedesktop.org<br>
<b>Cc:</b> Kazlauskas, Nicholas; Francis, David; Li, Sun peng (Leo)<br>
<b>Subject:</b> [PATCH i-g-t] amdgpu/amd_abm: Fix getting and setting abm level property</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">This patch addresses a few problems:<br>
<br>
1. Inner loop that iterates over the properties uses the same iterator<br>
as the outer loop over connectors. If the eDP panel isn't on the first<br>
output, then it won't be checked and the tests will skip.<br>
<br>
2. We can get null pointer deferences if any of the DRM calls return<br>
NULL.<br>
<br>
3. The proplist isn't freed after being acquired.<br>
<br>
These can be fixed by using the kmstest_get_property helper to<br>
get the prop_id. The prop_id and KMS connector ID are then stored<br>
for use later in the test when we need to set the ABM level.<br>
<br>
All the necessary cached state has been placed into a data structure and<br>
many callsites have been updated to make use of this.<br>
<br>
Cc: David Francis <david.francis@amd.com><br>
Cc: Leo Li <sunpeng.li@amd.com><br>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com><br>
---<br>
tests/amdgpu/amd_abm.c | 147 ++++++++++++++++++-----------------------<br>
1 file changed, 63 insertions(+), 84 deletions(-)<br>
<br>
diff --git a/tests/amdgpu/amd_abm.c b/tests/amdgpu/amd_abm.c<br>
index 363b1e90..74156462 100644<br>
--- a/tests/amdgpu/amd_abm.c<br>
+++ b/tests/amdgpu/amd_abm.c<br>
@@ -34,6 +34,14 @@<br>
<br>
#define BACKLIGHT_PATH "/sys/class/backlight/amdgpu_bl0"<br>
<br>
+typedef struct data {<br>
+ igt_display_t display;<br>
+ int drm_fd;<br>
+ int debugfs;<br>
+ uint32_t output_id;<br>
+ uint32_t abm_prop_id;<br>
+} data_t;<br>
+<br>
static int read_current_backlight_pwm(int debugfs_dir)<br>
{<br>
char buf[20];<br>
@@ -76,35 +84,14 @@ static int backlight_write_brightness(int value)<br>
return 0;<br>
}<br>
<br>
-static void set_abm_level(igt_display_t *display, int level)<br>
+static void set_abm_level(data_t *data, int level)<br>
{<br>
- int i, ret;<br>
- int output_id;<br>
- drmModeObjectPropertiesPtr props;<br>
- uint32_t prop_id;<br>
- drmModePropertyPtr prop;<br>
uint32_t type = DRM_MODE_OBJECT_CONNECTOR;<br>
+ int ret;<br>
<br>
- for (i = 0; i < display->n_outputs; i++) {<br>
- output_id = display->outputs[i].id;<br>
- props = drmModeObjectGetProperties(display->drm_fd, output_id, type);<br>
-<br>
- for (i = 0; i < props->count_props; i++) {<br>
- prop_id = props->props[i];<br>
- prop = drmModeGetProperty(display->drm_fd, prop_id);<br>
-<br>
- igt_assert(prop);<br>
-<br>
- if (strcmp(prop->name, "abm level") == 0) {<br>
- ret = drmModeObjectSetProperty(display->drm_fd, output_id, type, prop_id, level);<br>
-<br>
- igt_assert_eq(ret, 0);<br>
- }<br>
-<br>
- drmModeFreeProperty(prop);<br>
- }<br>
- }<br>
-<br>
+ ret = drmModeObjectSetProperty(data->drm_fd, data->output_id, type,<br>
+ data->abm_prop_id, level);<br>
+ igt_assert_eq(ret, 0);<br>
}<br>
<br>
static int backlight_read_max_brightness(int *result)<br>
@@ -132,24 +119,21 @@ static int backlight_read_max_brightness(int *result)<br>
return errno;<br>
}<br>
<br>
-static void skip_if_incompatible(igt_display_t *display, int debugfs_dir)<br>
+static void test_init(data_t *data)<br>
{<br>
+ igt_display_t *display = &data->display;<br>
int ret, i;<br>
char buf[20];<br>
bool abm_prop_exists;<br>
- int output_id;<br>
- drmModeObjectPropertiesPtr props;<br>
uint32_t type = DRM_MODE_OBJECT_CONNECTOR;<br>
- uint32_t prop_id;<br>
- drmModePropertyPtr prop;<br>
<br>
- ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm",<br>
+ ret = igt_debugfs_simple_read(data->debugfs, "amdgpu_current_backlight_pwm",<br>
buf, sizeof(buf));<br>
<br>
if (ret < 0)<br>
igt_skip("No current backlight debugfs entry.\n");<br>
<br>
- ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm",<br>
+ ret = igt_debugfs_simple_read(data->debugfs, "amdgpu_target_backlight_pwm",<br>
buf, sizeof(buf));<br>
<br>
if (ret < 0)<br>
@@ -158,18 +142,14 @@ static void skip_if_incompatible(igt_display_t *display, int debugfs_dir)<br>
abm_prop_exists = false;<br>
<br>
for (i = 0; i < display->n_outputs; i++) {<br>
- output_id = display->outputs[i].id;<br>
- props = drmModeObjectGetProperties(display->drm_fd, output_id, type);<br>
+ data->output_id = display->outputs[i].id;<br>
<br>
- for (i = 0; i < props->count_props; i++) {<br>
- prop_id = props->props[i];<br>
- prop = drmModeGetProperty(display->drm_fd, prop_id);<br>
+ abm_prop_exists = kmstest_get_property(<br>
+ data->drm_fd, data->output_id, type, "abm level",<br>
+ &data->abm_prop_id, NULL, NULL);<br>
<br>
- if (strcmp(prop->name, "abm level") == 0)<br>
- abm_prop_exists = true;<br>
-<br>
- drmModeFreeProperty(prop);<br>
- }<br>
+ if (abm_prop_exists)<br>
+ break;<br>
}<br>
<br>
if (!abm_prop_exists)<br>
@@ -177,7 +157,7 @@ static void skip_if_incompatible(igt_display_t *display, int debugfs_dir)<br>
}<br>
<br>
<br>
-static void backlight_dpms_cycle(igt_display_t *display, int debugfs, igt_output_t *output)<br>
+static void backlight_dpms_cycle(data_t *data, igt_output_t *output)<br>
{<br>
int ret;<br>
int max_brightness;<br>
@@ -186,19 +166,19 @@ static void backlight_dpms_cycle(igt_display_t *display, int debugfs, igt_output<br>
ret = backlight_read_max_brightness(&max_brightness);<br>
igt_assert_eq(ret, 0);<br>
<br>
- set_abm_level(display, 0);<br>
+ set_abm_level(data, 0);<br>
backlight_write_brightness(max_brightness / 2);<br>
usleep(100000);<br>
- pwm_1 = read_target_backlight_pwm(debugfs);<br>
+ pwm_1 = read_target_backlight_pwm(data->debugfs);<br>
<br>
- kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_OFF);<br>
- kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_ON);<br>
+ kmstest_set_connector_dpms(data->drm_fd, output->config.connector, DRM_MODE_DPMS_OFF);<br>
+ kmstest_set_connector_dpms(data->drm_fd, output->config.connector, DRM_MODE_DPMS_ON);<br>
usleep(100000);<br>
- pwm_2 = read_target_backlight_pwm(debugfs);<br>
+ pwm_2 = read_target_backlight_pwm(data->debugfs);<br>
igt_assert_eq(pwm_1, pwm_2);<br>
}<br>
<br>
-static void backlight_monotonic_basic(igt_display_t *display, int debugfs)<br>
+static void backlight_monotonic_basic(data_t *data)<br>
{<br>
int ret;<br>
int max_brightness;<br>
@@ -211,23 +191,23 @@ static void backlight_monotonic_basic(igt_display_t *display, int debugfs)<br>
<br>
brightness_step = max_brightness / 10;<br>
<br>
- set_abm_level(display, 0);<br>
+ set_abm_level(data, 0);<br>
backlight_write_brightness(max_brightness);<br>
usleep(100000);<br>
- prev_pwm = read_target_backlight_pwm(debugfs);<br>
+ prev_pwm = read_target_backlight_pwm(data->debugfs);<br>
for (brightness = max_brightness - brightness_step;<br>
brightness > 0;<br>
brightness -= brightness_step) {<br>
backlight_write_brightness(brightness);<br>
usleep(100000);<br>
- pwm = read_target_backlight_pwm(debugfs);<br>
+ pwm = read_target_backlight_pwm(data->debugfs);<br>
igt_assert(pwm < prev_pwm);<br>
prev_pwm = pwm;<br>
}<br>
<br>
}<br>
<br>
-static void backlight_monotonic_abm(igt_display_t *display, int debugfs)<br>
+static void backlight_monotonic_abm(data_t *data)<br>
{<br>
int ret, i;<br>
int max_brightness;<br>
@@ -240,23 +220,23 @@ static void backlight_monotonic_abm(igt_display_t *display, int debugfs)<br>
<br>
brightness_step = max_brightness / 10;<br>
for (i = 1; i < 5; i++) {<br>
- set_abm_level(display, i);<br>
+ set_abm_level(data, i);<br>
backlight_write_brightness(max_brightness);<br>
usleep(100000);<br>
- prev_pwm = read_target_backlight_pwm(debugfs);<br>
+ prev_pwm = read_target_backlight_pwm(data->debugfs);<br>
for (brightness = max_brightness - brightness_step;<br>
brightness > 0;<br>
brightness -= brightness_step) {<br>
backlight_write_brightness(brightness);<br>
usleep(100000);<br>
- pwm = read_target_backlight_pwm(debugfs);<br>
+ pwm = read_target_backlight_pwm(data->debugfs);<br>
igt_assert(pwm < prev_pwm);<br>
prev_pwm = pwm;<br>
}<br>
}<br>
}<br>
<br>
-static void abm_enabled(igt_display_t *display, int debugfs)<br>
+static void abm_enabled(data_t *data)<br>
{<br>
int ret, i;<br>
int max_brightness;<br>
@@ -265,16 +245,16 @@ static void abm_enabled(igt_display_t *display, int debugfs)<br>
ret = backlight_read_max_brightness(&max_brightness);<br>
igt_assert_eq(ret, 0);<br>
<br>
- set_abm_level(display, 0);<br>
+ set_abm_level(data, 0);<br>
backlight_write_brightness(max_brightness);<br>
usleep(100000);<br>
- prev_pwm = read_target_backlight_pwm(debugfs);<br>
+ prev_pwm = read_target_backlight_pwm(data->debugfs);<br>
pwm_without_abm = prev_pwm;<br>
<br>
for (i = 1; i < 5; i++) {<br>
- set_abm_level(display, i);<br>
+ set_abm_level(data, i);<br>
usleep(100000);<br>
- pwm = read_target_backlight_pwm(debugfs);<br>
+ pwm = read_target_backlight_pwm(data->debugfs);<br>
igt_assert(pwm <= prev_pwm);<br>
igt_assert(pwm < pwm_without_abm);<br>
prev_pwm = pwm;<br>
@@ -282,7 +262,7 @@ static void abm_enabled(igt_display_t *display, int debugfs)<br>
<br>
}<br>
<br>
-static void abm_gradual(igt_display_t *display, int debugfs)<br>
+static void abm_gradual(data_t *data)<br>
{<br>
int ret, i;<br>
int convergence_delay = 15;<br>
@@ -293,71 +273,70 @@ static void abm_gradual(igt_display_t *display, int debugfs)<br>
<br>
igt_assert_eq(ret, 0);<br>
<br>
- set_abm_level(display, 0);<br>
+ set_abm_level(data, 0);<br>
backlight_write_brightness(max_brightness);<br>
<br>
sleep(convergence_delay);<br>
- prev_pwm = read_target_backlight_pwm(debugfs);<br>
- curr = read_current_backlight_pwm(debugfs);<br>
+ prev_pwm = read_target_backlight_pwm(data->debugfs);<br>
+ curr = read_current_backlight_pwm(data->debugfs);<br>
<br>
igt_assert_eq(prev_pwm, curr);<br>
- set_abm_level(display, 4);<br>
+ set_abm_level(data, 4);<br>
for (i = 0; i < 10; i++) {<br>
usleep(100000);<br>
- pwm = read_current_backlight_pwm(debugfs);<br>
+ pwm = read_current_backlight_pwm(data->debugfs);<br>
igt_assert(pwm < prev_pwm);<br>
prev_pwm = pwm;<br>
}<br>
<br>
sleep(convergence_delay - 1);<br>
<br>
- prev_pwm = read_target_backlight_pwm(debugfs);<br>
- curr = read_current_backlight_pwm(debugfs);<br>
+ prev_pwm = read_target_backlight_pwm(data->debugfs);<br>
+ curr = read_current_backlight_pwm(data->debugfs);<br>
<br>
igt_assert_eq(prev_pwm, curr);<br>
}<br>
<br>
igt_main<br>
{<br>
- igt_display_t display;<br>
- int debugfs;<br>
+ data_t data = { 0 };<br>
enum pipe pipe;<br>
igt_output_t *output;<br>
<br>
igt_skip_on_simulation();<br>
<br>
igt_fixture {<br>
- display.drm_fd = drm_open_driver_master(DRIVER_AMDGPU);<br>
+ data.drm_fd = drm_open_driver_master(DRIVER_AMDGPU);<br>
<br>
- if (display.drm_fd == -1)<br>
+ if (data.drm_fd == -1)<br>
igt_skip("Not an amdgpu driver.\n");<br>
<br>
- debugfs = igt_debugfs_dir(display.drm_fd);<br>
+ data.debugfs = igt_debugfs_dir(data.drm_fd);<br>
<br>
kmstest_set_vt_graphics_mode();<br>
<br>
- igt_display_require(&display, display.drm_fd);<br>
+ igt_display_require(&data.display, data.drm_fd);<br>
<br>
- skip_if_incompatible(&display, debugfs);<br>
+ test_init(&data);<br>
<br>
- for_each_pipe_with_valid_output(&display, pipe, output) {<br>
+ for_each_pipe_with_valid_output(&data.display, pipe, output) {<br>
if (output->config.connector->connector_type == DRM_MODE_CONNECTOR_eDP)<br>
break;<br>
}<br>
}<br>
<br>
igt_subtest("dpms_cycle")<br>
- backlight_dpms_cycle(&display, debugfs, output);<br>
+ backlight_dpms_cycle(&data, output);<br>
igt_subtest("backlight_monotonic_basic")<br>
- backlight_monotonic_basic(&display, debugfs);<br>
+ backlight_monotonic_basic(&data);<br>
igt_subtest("backlight_monotonic_abm")<br>
- backlight_monotonic_abm(&display, debugfs);<br>
+ backlight_monotonic_abm(&data);<br>
igt_subtest("abm_enabled")<br>
- abm_enabled(&display, debugfs);<br>
+ abm_enabled(&data);<br>
igt_subtest("abm_gradual")<br>
- abm_gradual(&display, debugfs);<br>
+ abm_gradual(&data);<br>
<br>
igt_fixture {<br>
- igt_display_fini(&display);<br>
+ igt_display_fini(&data.display);<br>
}<br>
}<br>
-- <br>
2.17.1<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>