aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 16:52:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 16:52:08 -0400
commit5dd0bf621e84b9f48cbee8f4a31f4d68568aeaee (patch)
treea8b9ec9288c92794842b8380e6699bb0c2b9c3a6 /tools
parent1571a03daf626ff34705e5fb40404879d00ac463 (diff)
parentd78388dbec256b179f1c42e714cf4acf630067c6 (diff)
Merge tag 'linux-kselftest-4.8-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest updates from Shuah Khan: "This contains new tests and fixes: - a few fixes to existing tests - new media tests for testing driver unbind, and device removal paths while an user application is actively making system calls and ioctls" * tag 'linux-kselftest-4.8-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: selftests: media_tests add a new video device test selftests: media_tests - Add media_device_open to .gitignore selftests: add media controller regression test scripts and document selftests: add media_device_open test selftests: media_device_test change it to randomize loop count selftests/vm: Don't mlockall MCL_CURRENT in on-fault-limit test selftests/vm: write strlen length instead of sizeof to nr_hugepages selftests/lib: set printf.sh executable
Diffstat (limited to 'tools')
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/lib/printf.sh0
-rw-r--r--tools/testing/selftests/media_tests/.gitignore2
-rw-r--r--tools/testing/selftests/media_tests/Makefile4
-rwxr-xr-xtools/testing/selftests/media_tests/bind_unbind_sample.sh12
-rw-r--r--tools/testing/selftests/media_tests/media_device_open.c81
-rw-r--r--tools/testing/selftests/media_tests/media_device_test.c19
-rwxr-xr-xtools/testing/selftests/media_tests/open_loop_test.sh10
-rw-r--r--tools/testing/selftests/media_tests/regression_test.txt43
-rw-r--r--tools/testing/selftests/media_tests/video_device_test.c100
-rw-r--r--tools/testing/selftests/vm/compaction_test.c8
-rw-r--r--tools/testing/selftests/vm/on-fault-limit.c2
11 files changed, 268 insertions, 13 deletions
diff --git a/tools/testing/selftests/lib/printf.sh b/tools/testing/selftests/lib/printf.sh
index 4fdc70fe6980..4fdc70fe6980 100644..100755
--- a/tools/testing/selftests/lib/printf.sh
+++ b/tools/testing/selftests/lib/printf.sh
diff --git a/tools/testing/selftests/media_tests/.gitignore b/tools/testing/selftests/media_tests/.gitignore
index 1c0711708b98..8745eba39012 100644
--- a/tools/testing/selftests/media_tests/.gitignore
+++ b/tools/testing/selftests/media_tests/.gitignore
@@ -1 +1,3 @@
1media_device_test 1media_device_test
2media_device_open
3video_device_test
diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile
index 7071bcc1d066..6b34a0199468 100644
--- a/tools/testing/selftests/media_tests/Makefile
+++ b/tools/testing/selftests/media_tests/Makefile
@@ -1,7 +1,7 @@
1TEST_PROGS := media_device_test 1TEST_PROGS := media_device_test media_device_open video_device_test
2all: $(TEST_PROGS) 2all: $(TEST_PROGS)
3 3
4include ../lib.mk 4include ../lib.mk
5 5
6clean: 6clean:
7 rm -fr media_device_test 7 rm -fr media_device_test media_device_open video_device_test
diff --git a/tools/testing/selftests/media_tests/bind_unbind_sample.sh b/tools/testing/selftests/media_tests/bind_unbind_sample.sh
new file mode 100755
index 000000000000..9f362f10631a
--- /dev/null
+++ b/tools/testing/selftests/media_tests/bind_unbind_sample.sh
@@ -0,0 +1,12 @@
1#!/bin/bash
2# Find device number in /sys/bus/usb/drivers/drivername
3# Edit this file to update the driver numer and name
4# Example test for uvcvideo driver
5#i=0
6# while :; do
7# i=$((i+1))
8# echo 1-5:1.0 > /sys/bus/usb/drivers/uvcvideo/unbind;
9# echo 1-5:1.0 > /sys/bus/usb/drivers/uvcvideo/bind;
10# clear
11# echo $i
12#done
diff --git a/tools/testing/selftests/media_tests/media_device_open.c b/tools/testing/selftests/media_tests/media_device_open.c
new file mode 100644
index 000000000000..44343c091a20
--- /dev/null
+++ b/tools/testing/selftests/media_tests/media_device_open.c
@@ -0,0 +1,81 @@
1/*
2 * media_device_open.c - Media Controller Device Open Test
3 *
4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 *
7 * This file is released under the GPLv2.
8 */
9
10/*
11 * This file adds a test for Media Controller API.
12 * This test should be run as root and should not be
13 * included in the Kselftest run. This test should be
14 * run when hardware and driver that makes use Media
15 * Controller API are present in the system.
16 *
17 * This test opens user specified Media Device and calls
18 * MEDIA_IOC_DEVICE_INFO ioctl, closes the file, and exits.
19 *
20 * Usage:
21 * sudo ./media_device_open -d /dev/mediaX
22 *
23 * Run this test is a loop and run bind/unbind on the driver.
24*/
25
26#include <stdio.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <string.h>
31#include <fcntl.h>
32#include <sys/ioctl.h>
33#include <sys/stat.h>
34#include <linux/media.h>
35
36int main(int argc, char **argv)
37{
38 int opt;
39 char media_device[256];
40 int count = 0;
41 struct media_device_info mdi;
42 int ret;
43 int fd;
44
45 if (argc < 2) {
46 printf("Usage: %s [-d </dev/mediaX>]\n", argv[0]);
47 exit(-1);
48 }
49
50 /* Process arguments */
51 while ((opt = getopt(argc, argv, "d:")) != -1) {
52 switch (opt) {
53 case 'd':
54 strncpy(media_device, optarg, sizeof(media_device) - 1);
55 media_device[sizeof(media_device)-1] = '\0';
56 break;
57 default:
58 printf("Usage: %s [-d </dev/mediaX>]\n", argv[0]);
59 exit(-1);
60 }
61 }
62
63 if (getuid() != 0) {
64 printf("Please run the test as root - Exiting.\n");
65 exit(-1);
66 }
67
68 /* Open Media device and keep it open */
69 fd = open(media_device, O_RDWR);
70 if (fd == -1) {
71 printf("Media Device open errno %s\n", strerror(errno));
72 exit(-1);
73 }
74
75 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi);
76 if (ret < 0)
77 printf("Media Device Info errno %s\n", strerror(errno));
78 else
79 printf("Media device model %s driver %s\n",
80 mdi.model, mdi.driver);
81}
diff --git a/tools/testing/selftests/media_tests/media_device_test.c b/tools/testing/selftests/media_tests/media_device_test.c
index cbf53a032ab5..5d49943e77d0 100644
--- a/tools/testing/selftests/media_tests/media_device_test.c
+++ b/tools/testing/selftests/media_tests/media_device_test.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * media_devkref_test.c - Media Controller Device Kref API Test 2 * media_device_test.c - Media Controller Device ioctl loop Test
3 * 3 *
4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com> 4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd. 5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -35,13 +35,14 @@
35#include <fcntl.h> 35#include <fcntl.h>
36#include <sys/ioctl.h> 36#include <sys/ioctl.h>
37#include <sys/stat.h> 37#include <sys/stat.h>
38#include <time.h>
38#include <linux/media.h> 39#include <linux/media.h>
39 40
40int main(int argc, char **argv) 41int main(int argc, char **argv)
41{ 42{
42 int opt; 43 int opt;
43 char media_device[256]; 44 char media_device[256];
44 int count = 0; 45 int count;
45 struct media_device_info mdi; 46 struct media_device_info mdi;
46 int ret; 47 int ret;
47 int fd; 48 int fd;
@@ -69,6 +70,10 @@ int main(int argc, char **argv)
69 exit(-1); 70 exit(-1);
70 } 71 }
71 72
73 /* Generate random number of interations */
74 srand((unsigned int) time(NULL));
75 count = rand();
76
72 /* Open Media device and keep it open */ 77 /* Open Media device and keep it open */
73 fd = open(media_device, O_RDWR); 78 fd = open(media_device, O_RDWR);
74 if (fd == -1) { 79 if (fd == -1) {
@@ -82,14 +87,16 @@ int main(int argc, char **argv)
82 "other Oops in the dmesg. Enable KaSan kernel\n" 87 "other Oops in the dmesg. Enable KaSan kernel\n"
83 "config option for use-after-free error detection.\n\n"); 88 "config option for use-after-free error detection.\n\n");
84 89
85 while (count < 100) { 90 printf("Running test for %d iternations\n", count);
91
92 while (count > 0) {
86 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); 93 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi);
87 if (ret < 0) 94 if (ret < 0)
88 printf("Media Device Info errno %s\n", strerror(errno)); 95 printf("Media Device Info errno %s\n", strerror(errno));
89 else 96 else
90 printf("Media device model %s driver %s\n", 97 printf("Media device model %s driver %s - count %d\n",
91 mdi.model, mdi.driver); 98 mdi.model, mdi.driver, count);
92 sleep(10); 99 sleep(10);
93 count++; 100 count--;
94 } 101 }
95} 102}
diff --git a/tools/testing/selftests/media_tests/open_loop_test.sh b/tools/testing/selftests/media_tests/open_loop_test.sh
new file mode 100755
index 000000000000..dcd3c17efc17
--- /dev/null
+++ b/tools/testing/selftests/media_tests/open_loop_test.sh
@@ -0,0 +1,10 @@
1#!/bin/bash
2 i=0
3file=/dev/media$1
4 while :; do
5 echo $file
6 i=$((i+1))
7 R=$(./media_device_open -d $file);
8 # clear
9 echo -e "Loop $i\n$R"
10 done
diff --git a/tools/testing/selftests/media_tests/regression_test.txt b/tools/testing/selftests/media_tests/regression_test.txt
new file mode 100644
index 000000000000..2627367681f7
--- /dev/null
+++ b/tools/testing/selftests/media_tests/regression_test.txt
@@ -0,0 +1,43 @@
1Testing for regressions in Media Controller API register, ioctl, syscall,
2and unregister paths. There have a few problems that result in user-after
3free on media_device, media_devnode, and cdev pointers when the driver is
4unbound while ioctl is in progress.
5
6Test Procedure:
7
8Run bin/unbind loop while ioctls are in progress.
9Run rmmod and modprobe.
10Disconnect the device.
11
12Setup:
13
14Build media_device_test
15cd tools/testing/selftests/media_tests
16make
17
18Regressions test for cdev user-after free error on /dev/mediaX when driver
19is unbound:
20
21Start media_device_test to regression test media devnode dynamic alloc
22and cdev user-after-free fixes. This opens media dev files and sits in
23a loop running media ioctl MEDIA_IOC_DEVICE_INFO command once every 10
24seconds. The idea is when device file goes away, media devnode and cdev
25should stick around until this test exits.
26
27The test for a random number of iterations or until user kills it with a
28sleep 10 in between the ioctl calls.
29
30sudo ./media_device_test -d /dev/mediaX
31
32Regression test for media_devnode unregister race with ioctl_syscall:
33
34Start 6 open_loop_test.sh tests with different /dev/mediaX files. When
35device file goes away after unbind, device file name changes. Start the
36test with possible device names. If we start with /dev/media0 for example,
37after unbind, /dev/media1 or /dev/media2 could get created. The idea is
38keep ioctls going while bind/unbind runs.
39
40Copy bind_unbind_sample.txt and make changes to specify the driver name
41and number to run bind and unbind. Start the bind_unbind.sh
42
43Run dmesg looking for any user-after free errors or mutex lock errors.
diff --git a/tools/testing/selftests/media_tests/video_device_test.c b/tools/testing/selftests/media_tests/video_device_test.c
new file mode 100644
index 000000000000..66d419c28653
--- /dev/null
+++ b/tools/testing/selftests/media_tests/video_device_test.c
@@ -0,0 +1,100 @@
1/*
2 * video_device_test - Video Device Test
3 *
4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 *
7 * This file is released under the GPLv2.
8 */
9
10/*
11 * This file adds a test for Video Device. This test should not be included
12 * in the Kselftest run. This test should be run when hardware and driver
13 * that makes use of V4L2 API is present.
14 *
15 * This test opens user specified Video Device and calls video ioctls in a
16 * loop once every 10 seconds.
17 *
18 * Usage:
19 * sudo ./video_device_test -d /dev/videoX
20 *
21 * While test is running, remove the device or unbind the driver and
22 * ensure there are no use after free errors and other Oops in the
23 * dmesg.
24 * When possible, enable KaSan kernel config option for use-after-free
25 * error detection.
26*/
27
28#include <stdio.h>
29#include <unistd.h>
30#include <stdlib.h>
31#include <errno.h>
32#include <string.h>
33#include <fcntl.h>
34#include <sys/ioctl.h>
35#include <sys/stat.h>
36#include <time.h>
37#include <linux/videodev2.h>
38
39int main(int argc, char **argv)
40{
41 int opt;
42 char video_dev[256];
43 int count;
44 struct v4l2_tuner vtuner;
45 struct v4l2_capability vcap;
46 int ret;
47 int fd;
48
49 if (argc < 2) {
50 printf("Usage: %s [-d </dev/videoX>]\n", argv[0]);
51 exit(-1);
52 }
53
54 /* Process arguments */
55 while ((opt = getopt(argc, argv, "d:")) != -1) {
56 switch (opt) {
57 case 'd':
58 strncpy(video_dev, optarg, sizeof(video_dev) - 1);
59 video_dev[sizeof(video_dev)-1] = '\0';
60 break;
61 default:
62 printf("Usage: %s [-d </dev/videoX>]\n", argv[0]);
63 exit(-1);
64 }
65 }
66
67 /* Generate random number of interations */
68 srand((unsigned int) time(NULL));
69 count = rand();
70
71 /* Open Video device and keep it open */
72 fd = open(video_dev, O_RDWR);
73 if (fd == -1) {
74 printf("Video Device open errno %s\n", strerror(errno));
75 exit(-1);
76 }
77
78 printf("\nNote:\n"
79 "While test is running, remove the device or unbind\n"
80 "driver and ensure there are no use after free errors\n"
81 "and other Oops in the dmesg. When possible, enable KaSan\n"
82 "kernel config option for use-after-free error detection.\n\n");
83
84 while (count > 0) {
85 ret = ioctl(fd, VIDIOC_QUERYCAP, &vcap);
86 if (ret < 0)
87 printf("VIDIOC_QUERYCAP errno %s\n", strerror(errno));
88 else
89 printf("Video device driver %s\n", vcap.driver);
90
91 ret = ioctl(fd, VIDIOC_G_TUNER, &vtuner);
92 if (ret < 0)
93 printf("VIDIOC_G_TUNER, errno %s\n", strerror(errno));
94 else
95 printf("type %d rangelow %d rangehigh %d\n",
96 vtuner.type, vtuner.rangelow, vtuner.rangehigh);
97 sleep(10);
98 count--;
99 }
100}
diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c
index 00c4f65d12da..6d1437f895b8 100644
--- a/tools/testing/selftests/vm/compaction_test.c
+++ b/tools/testing/selftests/vm/compaction_test.c
@@ -101,7 +101,7 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
101 101
102 /* Start with the initial condition of 0 huge pages*/ 102 /* Start with the initial condition of 0 huge pages*/
103 if (write(fd, "0", sizeof(char)) != sizeof(char)) { 103 if (write(fd, "0", sizeof(char)) != sizeof(char)) {
104 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 104 perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n");
105 goto close_fd; 105 goto close_fd;
106 } 106 }
107 107
@@ -110,14 +110,14 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
110 /* Request a large number of huge pages. The Kernel will allocate 110 /* Request a large number of huge pages. The Kernel will allocate
111 as much as it can */ 111 as much as it can */
112 if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { 112 if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {
113 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 113 perror("Failed to write 100000 to /proc/sys/vm/nr_hugepages\n");
114 goto close_fd; 114 goto close_fd;
115 } 115 }
116 116
117 lseek(fd, 0, SEEK_SET); 117 lseek(fd, 0, SEEK_SET);
118 118
119 if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { 119 if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) {
120 perror("Failed to read from /proc/sys/vm/nr_hugepages\n"); 120 perror("Failed to re-read from /proc/sys/vm/nr_hugepages\n");
121 goto close_fd; 121 goto close_fd;
122 } 122 }
123 123
@@ -138,7 +138,7 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
138 138
139 if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) 139 if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages))
140 != strlen(initial_nr_hugepages)) { 140 != strlen(initial_nr_hugepages)) {
141 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 141 perror("Failed to write value to /proc/sys/vm/nr_hugepages\n");
142 goto close_fd; 142 goto close_fd;
143 } 143 }
144 144
diff --git a/tools/testing/selftests/vm/on-fault-limit.c b/tools/testing/selftests/vm/on-fault-limit.c
index 245acccce42d..0ae458f32fdb 100644
--- a/tools/testing/selftests/vm/on-fault-limit.c
+++ b/tools/testing/selftests/vm/on-fault-limit.c
@@ -20,7 +20,7 @@ static int test_limit(void)
20 return ret; 20 return ret;
21 } 21 }
22 22
23 if (mlockall(MCL_CURRENT | MCL_ONFAULT | MCL_FUTURE)) { 23 if (mlockall(MCL_ONFAULT | MCL_FUTURE)) {
24 perror("mlockall"); 24 perror("mlockall");
25 return ret; 25 return ret;
26 } 26 }