<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>