mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-10 09:26:10 +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_fence_thrash \
|
||||
gem_flink \
|
||||
gem_flink_race \
|
||||
gem_gtt_concurrent_blit \
|
||||
gem_linear_blits \
|
||||
gem_mmap_gtt \
|
||||
@ -61,7 +62,6 @@ TESTS_progs = \
|
||||
gem_exec_faulting_reloc \
|
||||
gem_exec_lut_handle \
|
||||
gem_fenced_exec_thrash \
|
||||
gem_flink_race \
|
||||
gem_gtt_cpu_tlb \
|
||||
gem_gtt_speed \
|
||||
gem_hangcheck_forcewake \
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -47,7 +48,26 @@
|
||||
volatile int pls_die = 0;
|
||||
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;
|
||||
int ret;
|
||||
@ -57,24 +77,25 @@ static void *thread_fn(void *p)
|
||||
|
||||
open_struct.name = 1;
|
||||
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);
|
||||
else
|
||||
} else
|
||||
assert(errno == ENOENT);
|
||||
}
|
||||
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static void test_flink_name(void)
|
||||
{
|
||||
int num_threads;
|
||||
pthread_t *threads;
|
||||
int r, i;
|
||||
int r, i, num_threads;
|
||||
void *status;
|
||||
|
||||
drmtest_skip_on_simulation();
|
||||
|
||||
num_threads = sysconf(_SC_NPROCESSORS_ONLN) - 1;
|
||||
if (!num_threads)
|
||||
num_threads = 1;
|
||||
@ -85,7 +106,8 @@ int main(int argc, char **argv)
|
||||
assert(fd >= 0);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -110,6 +132,84 @@ int main(int argc, char **argv)
|
||||
assert(fd >= 0);
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user