mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-11 01:46:14 +00:00
tests/gem_flink_race: actually make it somewhat useful
- Enable subtest support. - Add a check for the same flink name in the racing threads, which is an issue one of my recent patches actually fixes. - Add the test I've actually wanted to write which races an flink against gem close (with no open in between). That one does indeed leak. - Readd the leak check, but note that this needs a fixed kernel. Otherwise the leak counter will be utter garbage. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
dfe942edec
commit
24bbca9237
@ -25,6 +25,7 @@ TESTS_progs_M = \
|
|||||||
gem_exec_nop \
|
gem_exec_nop \
|
||||||
gem_fence_thrash \
|
gem_fence_thrash \
|
||||||
gem_flink \
|
gem_flink \
|
||||||
|
gem_flink_race \
|
||||||
gem_gtt_concurrent_blit \
|
gem_gtt_concurrent_blit \
|
||||||
gem_linear_blits \
|
gem_linear_blits \
|
||||||
gem_mmap_gtt \
|
gem_mmap_gtt \
|
||||||
@ -61,7 +62,6 @@ TESTS_progs = \
|
|||||||
gem_exec_faulting_reloc \
|
gem_exec_faulting_reloc \
|
||||||
gem_exec_lut_handle \
|
gem_exec_lut_handle \
|
||||||
gem_fenced_exec_thrash \
|
gem_fenced_exec_thrash \
|
||||||
gem_flink_race \
|
|
||||||
gem_gtt_cpu_tlb \
|
gem_gtt_cpu_tlb \
|
||||||
gem_gtt_speed \
|
gem_gtt_speed \
|
||||||
gem_hangcheck_forcewake \
|
gem_hangcheck_forcewake \
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
* Daniel Vetter <daniel.vetter@ffwll.ch>
|
* Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -47,7 +48,26 @@
|
|||||||
volatile int pls_die = 0;
|
volatile int pls_die = 0;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
static void *thread_fn(void *p)
|
static int get_object_count(void)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
int ret, scanned;
|
||||||
|
int device = drm_get_card(0);
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
ret = asprintf(&path, "/sys/kernel/debug/dri/%d/i915_gem_objects", device);
|
||||||
|
assert(ret != -1);
|
||||||
|
|
||||||
|
file = fopen(path, "r");
|
||||||
|
|
||||||
|
scanned = fscanf(file, "%i objects,", &ret);
|
||||||
|
assert(scanned == 1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *thread_fn_flink_name(void *p)
|
||||||
{
|
{
|
||||||
struct drm_gem_open open_struct;
|
struct drm_gem_open open_struct;
|
||||||
int ret;
|
int ret;
|
||||||
@ -57,24 +77,25 @@ static void *thread_fn(void *p)
|
|||||||
|
|
||||||
open_struct.name = 1;
|
open_struct.name = 1;
|
||||||
ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct);
|
ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct);
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
|
uint32_t name = gem_flink(fd, open_struct.handle);
|
||||||
|
|
||||||
|
assert(name == 1);
|
||||||
|
|
||||||
gem_close(fd, open_struct.handle);
|
gem_close(fd, open_struct.handle);
|
||||||
else
|
} else
|
||||||
assert(errno == ENOENT);
|
assert(errno == ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)0;
|
return (void *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
static void test_flink_name(void)
|
||||||
{
|
{
|
||||||
int num_threads;
|
|
||||||
pthread_t *threads;
|
pthread_t *threads;
|
||||||
int r, i;
|
int r, i, num_threads;
|
||||||
void *status;
|
void *status;
|
||||||
|
|
||||||
drmtest_skip_on_simulation();
|
|
||||||
|
|
||||||
num_threads = sysconf(_SC_NPROCESSORS_ONLN) - 1;
|
num_threads = sysconf(_SC_NPROCESSORS_ONLN) - 1;
|
||||||
if (!num_threads)
|
if (!num_threads)
|
||||||
num_threads = 1;
|
num_threads = 1;
|
||||||
@ -85,7 +106,8 @@ int main(int argc, char **argv)
|
|||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
for (i = 0; i < num_threads; i++) {
|
for (i = 0; i < num_threads; i++) {
|
||||||
r = pthread_create(&threads[i], NULL, thread_fn, NULL);
|
r = pthread_create(&threads[i], NULL,
|
||||||
|
thread_fn_flink_name, NULL);
|
||||||
assert(r == 0);
|
assert(r == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +132,84 @@ int main(int argc, char **argv)
|
|||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *thread_fn_flink_close(void *p)
|
||||||
|
{
|
||||||
|
struct drm_gem_flink flink;
|
||||||
|
struct drm_gem_close close_bo;
|
||||||
|
uint32_t handle;
|
||||||
|
|
||||||
|
while (!pls_die) {
|
||||||
|
/* We want to race gem close against flink on handle one.*/
|
||||||
|
handle = gem_create(fd, 4096);
|
||||||
|
if (handle != 1)
|
||||||
|
gem_close(fd, handle);
|
||||||
|
|
||||||
|
/* raw ioctl since we expect this to fail */
|
||||||
|
flink.handle = 1;
|
||||||
|
ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
|
||||||
|
|
||||||
|
close_bo.handle = 1;
|
||||||
|
ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_flink_close(void)
|
||||||
|
{
|
||||||
|
pthread_t *threads;
|
||||||
|
int r, i, num_threads;
|
||||||
|
int obj_count = get_object_count();
|
||||||
|
void *status;
|
||||||
|
|
||||||
|
num_threads = sysconf(_SC_NPROCESSORS_ONLN) - 1;
|
||||||
|
if (!num_threads)
|
||||||
|
num_threads = 1;
|
||||||
|
|
||||||
|
threads = calloc(num_threads, sizeof(pthread_t));
|
||||||
|
|
||||||
|
fd = drm_open_any();
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
for (i = 0; i < num_threads; i++) {
|
||||||
|
r = pthread_create(&threads[i], NULL,
|
||||||
|
thread_fn_flink_close, NULL);
|
||||||
|
assert(r == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
pls_die = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < num_threads; i++) {
|
||||||
|
pthread_join(threads[i], &status);
|
||||||
|
assert(status == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = drm_open_any();
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
obj_count = get_object_count() - obj_count;
|
||||||
|
|
||||||
|
printf("leaked %i objects\n", obj_count);
|
||||||
|
assert(obj_count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
drmtest_skip_on_simulation();
|
||||||
|
|
||||||
|
drmtest_subtest_init(argc, argv);
|
||||||
|
|
||||||
|
if (drmtest_run_subtest("flink_name"))
|
||||||
|
test_flink_name();
|
||||||
|
|
||||||
|
if (drmtest_run_subtest("flink_close"))
|
||||||
|
test_flink_close();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user