On Wed, 2017-06-28 at 17:41 +0200, Michał Winiarski wrote:
> Testing LNCFCMOCS values on non-render engines is tricky. The values
> in
> those registers are lost on RC6, which means that if users of non-
> render
> engines want to see the proper values, they need to obtain a
> forcewake
> and execute something on render (relying on it to restore the values)
> before using non-render engine.
> Previous version of the test did exactly that - we were relying on
> the
> fact that we're taking forcewake (hidden by
> intel_register_access_init,
> even though the test is not doing any mmio accesses) before iterating
> through engines (and render is before other engines, so job done).
> I really hope that this is not an ABI and those registers are not
> used
> on non-render in any way. Let's limit testing LNCFCMOCS to render
> engine only.
> The other non-render issue is that when we're using I915_EXEC_BSD, we
> can't be sure which BSD ring we'll end up executing on. Let's
> explicitly select BSD1 and BSD2 in our tests.
> While we're here, let's also remove the duplicated code and add some
> structure by extracting moving more content into subtests.
> We're only doing tests that involve "dirtying" the registers for the
> render engine - since it's the only one that has those registers in
> its
> context.
> 
> Cc: Arkadiusz Hiler <[email protected]>
> Cc: Chris Wilson <[email protected]>
> Cc: David Weinehall <[email protected]>
> Cc: Łukasz Kałamarz <[email protected]>
> Signed-off-by: Michał Winiarski <[email protected]>

Reviewed-By: Lukasz Kalamarz <[email protected]>

-- 
Lukasz

> ---
>  tests/gem_mocs_settings.c | 353 ++++++++++++++--------------------
> ------------
>  1 file changed, 108 insertions(+), 245 deletions(-)
> 
> diff --git a/tests/gem_mocs_settings.c b/tests/gem_mocs_settings.c
> index a96aa66..9760c0e 100644
> --- a/tests/gem_mocs_settings.c
> +++ b/tests/gem_mocs_settings.c
> @@ -32,14 +32,28 @@
>  #include "igt_sysfs.h"
>  
>  #define MAX_NUMBER_MOCS_REGISTERS    (64)
> -
>  enum {
>       NONE,
>       RESET,
> +     RC6,
>       SUSPEND,
> -     HIBERNATE
> +     HIBERNATE,
> +     MAX_MOCS_TEST_MODES
> +};
> +
> +static const char * const test_modes[] = {
> +     [NONE] = "settings",
> +     [RESET] = "reset",
> +     [RC6] = "rc6",
> +     [SUSPEND] = "suspend",
> +     [HIBERNATE] = "hibernate"
>  };
>  
> +#define MOCS_NON_DEFAULT_CTX (1<<0)
> +#define MOCS_DIRTY_VALUES    (1<<1)
> +#define ALL_MOCS_FLAGS               (MOCS_NON_DEFAULT_CTX | \
> +                              MOCS_DIRTY_VALUES)
> +
>  #define GEN9_LNCFCMOCS0              (0xB020)        /* L3 Cache
> Control base */
>  #define GEN9_GFX_MOCS_0              (0xc800)        /* Graphics
> MOCS base register*/
>  #define GEN9_MFX0_MOCS_0     (0xc900)        /* Media 0 MOCS base
> register*/
> @@ -117,19 +131,18 @@ static bool get_mocs_settings(int fd, struct
> mocs_table *table, bool dirty)
>       return result;
>  }
>  
> +#define LOCAL_I915_EXEC_BSD1 (I915_EXEC_BSD | (1<<13))
> +#define LOCAL_I915_EXEC_BSD2 (I915_EXEC_BSD | (2<<13))
> +
>  static uint32_t get_engine_base(uint32_t engine)
>  {
> -     /* Note we cannot test BSD1 or BSD2 due to limitations of
> current ANI */
>       switch (engine) {
> -     case I915_EXEC_BSD:     return GEN9_MFX0_MOCS_0;
> -/*
> -     case I915_EXEC_BSD1:    return GEN9_MFX0_MOCS_0;
> -     case I915_EXEC_BSD2:    return GEN9_MFX1_MOCS_0;
> -*/
> -     case I915_EXEC_RENDER:  return GEN9_GFX_MOCS_0;
> -     case I915_EXEC_BLT:     return GEN9_BLT_MOCS_0;
> -     case I915_EXEC_VEBOX:   return GEN9_VEBOX_MOCS_0;
> -     default:                return 0;
> +     case LOCAL_I915_EXEC_BSD1:      return GEN9_MFX0_MOCS_0;
> +     case LOCAL_I915_EXEC_BSD2:      return GEN9_MFX1_MOCS_0;
> +     case I915_EXEC_RENDER:          return
> GEN9_GFX_MOCS_0;
> +     case I915_EXEC_BLT:             return GEN9_BLT_MOCS_0;
> +     case I915_EXEC_VEBOX:           return
> GEN9_VEBOX_MOCS_0;
> +     default:                        return 0;
>       }
>  }
>  
> @@ -252,7 +265,7 @@ static void check_control_registers(int fd,
>                                   uint32_t ctx_id,
>                                   bool dirty)
>  {
> -     const uint32_t reg_base  = get_engine_base(engine);
> +     const uint32_t reg_base = get_engine_base(engine);
>       uint32_t dst_handle = gem_create(fd, 4096);
>       uint32_t *read_regs;
>       struct mocs_table table;
> @@ -299,6 +312,7 @@ static void check_l3cc_registers(int fd,
>       read_regs = gem_mmap__cpu(fd, dst_handle, 0, 4096,
> PROT_READ);
>  
>       gem_set_domain(fd, dst_handle, I915_GEM_DOMAIN_CPU, 0);
> +
>       for (index = 0; index < table.size / 2; index++) {
>               igt_assert_eq_u32(read_regs[index] & 0xffff,
>                                 table.table[index *
> 2].l3cc_value);
> @@ -314,183 +328,65 @@ static void check_l3cc_registers(int fd,
>       gem_close(fd, dst_handle);
>  }
>  
> -static void test_context_mocs_values(int fd, unsigned engine)
> -{
> -     int local_fd;
> -     uint32_t ctx_id = 0;
> -
> -     local_fd = fd;
> -     if (local_fd == -1)
> -             local_fd = drm_open_driver_master(DRIVER_INTEL);
> -
> -     check_control_registers(local_fd, engine, ctx_id, false);
> -     check_l3cc_registers(local_fd, engine, ctx_id, false);
> -
> -     if (engine == I915_EXEC_RENDER) {
> -             ctx_id = gem_context_create(local_fd);
> -
> -             check_control_registers(local_fd, engine, ctx_id,
> false);
> -             check_l3cc_registers(local_fd, engine, ctx_id,
> false);
> -
> -             gem_context_destroy(local_fd, ctx_id);
> -     }
> -
> -     if (local_fd != fd)
> -             close(local_fd);
> -}
>  
> -static bool local_has_ring(int fd, unsigned engine)
> +static uint32_t rc6_residency(int dir)
>  {
> -     bool has_ring;
> -     int local_fd;
> -
> -     if (get_engine_base(engine) == 0)
> -             return false;
> -
> -     if (fd == -1)
> -             local_fd = drm_open_driver_master(DRIVER_INTEL);
> -     else
> -             local_fd = fd;
> -
> -     has_ring = gem_has_ring(local_fd, engine);
> -     if (local_fd != fd)
> -             close(local_fd);
> -
> -     return has_ring;
> +     return igt_sysfs_get_u32(dir, "power/rc6_residency_ms");
>  }
>  
> -static void test_mocs_values(int fd)
> +static void rc6_wait(int fd)
>  {
> -     const struct intel_execution_engine *e;
> +     int sysfs;
> +     uint32_t residency;
>  
> -     for (e = intel_execution_engines; e->name; e++) {
> -             unsigned engine = e->exec_id | e->flags;
> +     sysfs = igt_sysfs_open(fd, NULL);
> +     igt_assert_lte(0, sysfs);
>  
> -             if (!local_has_ring(fd, engine))
> -                     continue;
> +     residency = rc6_residency(sysfs);
> +     igt_require(igt_wait(rc6_residency(sysfs) != residency,
> 10000, 2));
>  
> -             igt_debug("Testing %s\n", e->name);
> -             test_context_mocs_values(fd, engine);
> -     }
> +     close(sysfs);
>  }
>  
> -static void default_context_tests(unsigned mode)
> +static void check_mocs_values(int fd, unsigned engine, uint32_t
> ctx_id, bool dirty)
>  {
> -     int fd = drm_open_driver_master(DRIVER_INTEL);
> +     check_control_registers(fd, engine, ctx_id, dirty);
>  
> -     igt_debug("Testing Non/Default Context Engines\n");
> -     test_mocs_values(fd);
> -
> -     switch (mode) {
> -     case NONE:      break;
> -     case RESET:     igt_force_gpu_reset(fd);        break;
> -     case SUSPEND:   igt_system_suspend_autoresume(SUSPEND_S
> TATE_MEM,
> -                                                   SUSPEND_TEST_N
> ONE); break;
> -     case HIBERNATE: igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
> -                                                   SUSPEND_TEST_N
> ONE); break;
> -     }
> -
> -     test_mocs_values(fd);
> -     close(fd);
> -
> -     igt_debug("Testing Pristine Defaults\n");
> -     test_mocs_values(-1);
> +     if (engine == I915_EXEC_RENDER)
> +             check_l3cc_registers(fd, engine, ctx_id, dirty);
>  }
>  
> -static void default_dirty_tests(unsigned mode)
> +static void write_dirty_mocs(int fd, unsigned engine, uint32_t
> ctx_id)
>  {
> -     const struct intel_execution_engine *e;
> -     int fd = drm_open_driver_master(DRIVER_INTEL);
> -
> -     igt_debug("Testing Dirty Default Context Engines\n");
> -     test_mocs_values(fd);
> -
> -     for (e = intel_execution_engines; e->name; e++) {
> -             unsigned engine = e->exec_id | e->flags;
> +     write_registers(fd, ctx_id, get_engine_base(engine),
> +                     write_values, ARRAY_SIZE(write_values),
> +                     engine);
>  
> -             if (!local_has_ring(fd, engine))
> -                     continue;
> -
> -             write_registers(fd, 0,
> -                             GEN9_GFX_MOCS_0,
> +     if (engine == I915_EXEC_RENDER)
> +             write_registers(fd, ctx_id, GEN9_LNCFCMOCS0,
>                               write_values,
> ARRAY_SIZE(write_values),
>                               engine);
> -
> -             write_registers(fd, 0,
> -                             GEN9_LNCFCMOCS0,
> -                             write_values,
> ARRAY_SIZE(write_values),
> -                             engine);
> -     }
> -
> -     switch (mode) {
> -     case NONE:      break;
> -     case RESET:     igt_force_gpu_reset(fd);        break;
> -     case SUSPEND:   igt_system_suspend_autoresume(SUSPEND_S
> TATE_MEM,
> -                                                   SUSPEND_TEST_N
> ONE); break;
> -     case HIBERNATE: igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
> -                                                   SUSPEND_TEST_N
> ONE); break;
> -     }
> -
> -     close(fd);
> -
> -     igt_debug("Testing Pristine after Dirty Defaults\n");
> -     test_mocs_values(-1);
>  }
>  
> -static void context_save_restore_test(unsigned mode)
> +static void run_test(int fd, unsigned engine, unsigned flags,
> unsigned mode)
>  {
> -     int fd = drm_open_driver_master(DRIVER_INTEL);
> -     uint32_t ctx_id = gem_context_create(fd);
> +     uint32_t ctx_id = 0;
> +     uint32_t ctx_clean_id;
> +     uint32_t ctx_dirty_id;
>  
> -     igt_debug("Testing Save Restore\n");
> +     /* Skip if we don't know where the registers are for this
> engine */
> +     igt_require(get_engine_base(engine));
>  
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> +     if (flags & MOCS_NON_DEFAULT_CTX)
> +             ctx_id = gem_context_create(fd);
>  
> -     switch (mode) {
> -     case NONE:      break;
> -     case RESET:     igt_force_gpu_reset(fd);        break;
> -     case SUSPEND:   igt_system_suspend_autoresume(SUSPEND_S
> TATE_MEM,
> -                                                   SUSPEND_TEST_N
> ONE); break;
> -     case HIBERNATE: igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
> -                                                   SUSPEND_TEST_N
> ONE); break;
> +     if (flags & MOCS_DIRTY_VALUES) {
> +             ctx_dirty_id = gem_context_create(fd);
> +             write_dirty_mocs(fd, engine, ctx_dirty_id);
> +             check_mocs_values(fd, engine, ctx_dirty_id, true);
>       }
>  
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -
> -     close(fd);
> -}
> -
> -static void context_dirty_test(unsigned mode)
> -{
> -     int fd = drm_open_driver_master(DRIVER_INTEL);
> -     uint32_t ctx_id = gem_context_create(fd);
> -
> -     igt_debug("Testing Dirty Context\n");
> -     test_mocs_values(fd);
> -
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -
> -     /* XXX !RCS as well */
> -
> -     write_registers(fd,
> -                     ctx_id,
> -                     GEN9_GFX_MOCS_0,
> -                     write_values,
> -                     ARRAY_SIZE(write_values),
> -                     I915_EXEC_RENDER);
> -
> -     write_registers(fd,
> -                     ctx_id,
> -                     GEN9_LNCFCMOCS0,
> -                     write_values,
> -                     ARRAY_SIZE(write_values),
> -                     I915_EXEC_RENDER);
> -
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> +     check_mocs_values(fd, engine, ctx_id, false);
>  
>       switch (mode) {
>       case NONE:      break;
> @@ -499,99 +395,66 @@ static void context_dirty_test(unsigned mode)
>                                                     SUSPEND_TEST_N
> ONE); break;
>       case HIBERNATE: igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
>                                                     SUSPEND_TEST_N
> ONE); break;
> +     case RC6:       rc6_wait(fd);                   break;
>       }
>  
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> -
> -     close(fd);
> -
> -     /* Check that unmodified contexts are pristine */
> -     igt_debug("Testing Prestine Context (after dirty)\n");
> -     test_mocs_values(-1);
> -}
> -
> -static void run_tests(unsigned mode)
> -{
> -     struct pci_device *pci_dev;
> -     int fd;
> -
> -     pci_dev = intel_get_pci_device();
> -     igt_require(pci_dev);
> -
> -     fd = drm_open_driver_master(DRIVER_INTEL);
> -     intel_register_access_init(pci_dev, 0, fd);
> -     close(fd);
> -
> -     default_context_tests(mode);
> -     default_dirty_tests(mode);
> -     context_save_restore_test(mode);
> -     context_dirty_test(mode);
> +     check_mocs_values(fd, engine, ctx_id, false);
>  
> -     intel_register_access_fini();
> -}
> -
> -static int rc6_residency(int dir)
> -{
> -     return igt_sysfs_get_u32(dir, "power/rc6_residency_ms");
> -}
> -
> -static void context_rc6_test(void)
> -{
> -     int fd = drm_open_driver(DRIVER_INTEL);
> -     uint32_t ctx_id = gem_context_create(fd);
> -     int residency;
> -     int timeout;
> -     int sysfs;
> -
> -     igt_debug("RC6 Context Test\n");
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -
> -     sysfs = igt_sysfs_open(fd, NULL);
> -
> -     timeout = 3000 / 2;
> -     residency = rc6_residency(sysfs);
> -     while (rc6_residency(sysfs) == residency && --timeout)
> -             usleep(2000);
> -     igt_require(timeout);
> -
> -     close(sysfs);
> +     if (flags & MOCS_DIRTY_VALUES) {
> +             ctx_clean_id = gem_context_create(fd);
> +             check_mocs_values(fd, engine, ctx_dirty_id, true);
> +             check_mocs_values(fd, engine, ctx_clean_id, false);
> +             gem_context_destroy(fd, ctx_dirty_id);
> +             gem_context_destroy(fd, ctx_clean_id);
> +     }
>  
> -     check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -     check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -     close(fd);
> +     if (ctx_id)
> +             gem_context_destroy(fd, ctx_id);
>  }
>  
> -
> -static void test_requirements(void)
> +igt_main
>  {
> -     int fd = drm_open_driver_master(DRIVER_INTEL);
> +     const struct intel_execution_engine *e;
>       struct mocs_table table;
> +     int fd = -1;
>  
> -     gem_require_mocs_registers(fd);
> -     igt_require(get_mocs_settings(fd, &table, false));
> -     close(fd);
> -}
> -
> -igt_main
> -{
>       igt_fixture {
> -             test_requirements();
> +             fd = drm_open_driver(DRIVER_INTEL);
> +             igt_require_gem(fd);
> +             gem_require_mocs_registers(fd);
> +             igt_require(get_mocs_settings(fd, &table, false));
>       }
>  
> -     igt_subtest("mocs-settings")
> -             run_tests(NONE);
> -
> -     igt_subtest("mocs-rc6")
> -             context_rc6_test();
> -
> -     igt_subtest("mocs-reset")
> -             run_tests(RESET);
> +     for (e = intel_execution_engines; e->name; e++) {
> +             /* We don't know which engine will be assigned to us
> if we're
> +              * using plain I915_EXEC_BSD, I915_EXEC_DEFAULT is
> just
> +              * duplicating render
> +              */
> +             if (e->exec_id == I915_EXEC_BSD ||
> +                 e->exec_id == I915_EXEC_DEFAULT)
> +                     continue;
>  
> -     igt_subtest("mocs-suspend")
> -             run_tests(SUSPEND);
> +             for (unsigned mode = NONE; mode <
> MAX_MOCS_TEST_MODES; mode++) {
> +                     for (unsigned flags = 0; flags <
> ALL_MOCS_FLAGS + 1; flags++) {
> +                             /* Trying to test non-render engines
> for dirtying MOCS
> +                              * values from one context having
> effect on different
> +                              * context is bound to fail - only
> render engine is
> +                              * doing context save/restore of
> MOCS registers
> +                              */
> +                             if (flags & MOCS_DIRTY_VALUES && e-
> >exec_id != I915_EXEC_RENDER)
> +                                     continue;
> +
> +                             igt_subtest_f("mocs-%s%s%s-%s",
> +                                           test_modes[mode],
> +                                           flags &
> MOCS_NON_DEFAULT_CTX ? "-ctx": "",
> +                                           flags &
> MOCS_DIRTY_VALUES ? "-dirty" : "",
> +                                           e->name) {
> +                                     run_test(fd, e->exec_id | e-
> >flags, flags, mode);
> +                             }
> +                     }
> +             }
> +     }
>  
> -     igt_subtest("mocs-hibernate")
> -             run_tests(HIBERNATE);
> +     igt_fixture
> +             close(fd);
>  }
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to