5 #include <sys/syscall.h>
12 #include <sys/select.h>
13 #include <sys/epoll.h>
16 #include <sys/resource.h>
20 #include <common/compat/time.h>
25 #define NR_ITER 1000 /* for stress-tests */
27 #define MIN_NR_FDS 5 /* the minimum number of open FDs required for the test to run */
28 #define BIG_SELECT_FD 1022
30 #define MSEC_PER_USEC 1000
31 #define MSEC_PER_NSEC (MSEC_PER_USEC * 1000)
33 static int timeout
; /* seconds, -1 to disable */
34 volatile static int stop_thread
;
37 struct ppoll_thread_data
{
42 void test_select_big(void)
44 fd_set rfds
, wfds
, exfds
;
54 fd2
= dup2(wait_fd
, BIG_SELECT_FD
);
62 tv
.tv_usec
= timeout
* MSEC_PER_USEC
;
65 ret
= select(fd2
+ 1, &rfds
, &wfds
, &exfds
, &tv
);
67 ret
= select(fd2
+ 1, &rfds
, &wfds
, &exfds
, NULL
);
73 printf("# [select] data available\n");
74 ret
= read(wait_fd
, buf
, BUF_SIZE
);
76 perror("[select] read");
79 printf("# [select] timeout\n");
82 ret
= close(BIG_SELECT_FD
);
91 void test_pselect(void)
99 FD_SET(wait_fd
, &rfds
);
102 tv
.tv_nsec
= timeout
* MSEC_PER_NSEC
;
105 ret
= pselect(1, &rfds
, NULL
, NULL
, &tv
, NULL
);
107 ret
= pselect(1, &rfds
, NULL
, NULL
, NULL
, NULL
);
113 printf("# [pselect] data available\n");
114 ret
= read(wait_fd
, buf
, BUF_SIZE
);
116 perror("[pselect] read");
119 printf("# [pselect] timeout\n");
124 void test_select(void)
132 FD_SET(wait_fd
, &rfds
);
135 tv
.tv_usec
= timeout
* MSEC_PER_USEC
;
138 ret
= select(1, &rfds
, NULL
, NULL
, &tv
);
140 ret
= select(1, &rfds
, NULL
, NULL
, NULL
);
146 printf("# [select] data available\n");
147 ret
= read(wait_fd
, buf
, BUF_SIZE
);
149 perror("[select] read");
152 printf("# [select] timeout\n");
159 struct pollfd ufds
[NB_FD
];
163 ufds
[0].fd
= wait_fd
;
164 ufds
[0].events
= POLLIN
|POLLPRI
;
166 ret
= poll(ufds
, 1, timeout
);
170 } else if (ret
> 0) {
171 printf("# [poll] data available\n");
172 ret
= read(wait_fd
, buf
, BUF_SIZE
);
174 perror("[poll] read");
177 printf("# [poll] timeout\n");
181 void test_ppoll(void)
183 struct pollfd ufds
[NB_FD
];
188 ufds
[0].fd
= wait_fd
;
189 ufds
[0].events
= POLLIN
|POLLPRI
;
193 ts
.tv_nsec
= timeout
* MSEC_PER_NSEC
;
194 ret
= ppoll(ufds
, 1, &ts
, NULL
);
196 ret
= ppoll(ufds
, 1, NULL
, NULL
);
202 } else if (ret
> 0) {
203 printf("# [ppoll] data available\n");
204 ret
= read(wait_fd
, buf
, BUF_SIZE
);
206 perror("[ppoll] read");
209 printf("# [ppoll] timeout\n");
213 void test_ppoll_big(void)
215 struct pollfd ufds
[MAX_FDS
];
217 int ret
, i
, fds
[MAX_FDS
];
219 for (i
= 0; i
< MAX_FDS
; i
++) {
220 fds
[i
] = dup(wait_fd
);
225 ufds
[i
].events
= POLLIN
|POLLPRI
;
228 ret
= ppoll(ufds
, MAX_FDS
, NULL
, NULL
);
232 } else if (ret
> 0) {
233 printf("# [ppoll] data available\n");
234 ret
= read(wait_fd
, buf
, BUF_SIZE
);
236 perror("[ppoll] read");
239 printf("# [ppoll] timeout\n");
242 for (i
= 0; i
< MAX_FDS
; i
++) {
252 void test_epoll(void)
256 struct epoll_event epoll_event
;
258 epollfd
= epoll_create(NB_FD
);
260 perror("[epoll] create");
264 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
265 epoll_event
.data
.fd
= wait_fd
;
266 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
268 perror("[epoll] add");
273 ret
= epoll_wait(epollfd
, &epoll_event
, 1, timeout
);
275 ret
= epoll_wait(epollfd
, &epoll_event
, 1, -1);
279 printf("# [epoll] data available\n");
280 ret
= read(wait_fd
, buf
, BUF_SIZE
);
282 perror("[epoll] read");
284 } else if (ret
== 0) {
285 printf("# [epoll] timeout\n");
287 perror("epoll_wait");
294 void test_pepoll(void)
298 struct epoll_event epoll_event
;
300 epollfd
= epoll_create(NB_FD
);
302 perror("[eppoll] create");
306 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
307 epoll_event
.data
.fd
= wait_fd
;
308 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
310 perror("[eppoll] add");
315 ret
= epoll_pwait(epollfd
, &epoll_event
, 1, timeout
, NULL
);
317 ret
= epoll_pwait(epollfd
, &epoll_event
, 1, -1, NULL
);
321 printf("# [eppoll] data available\n");
322 ret
= read(wait_fd
, buf
, BUF_SIZE
);
324 perror("[eppoll] read");
326 } else if (ret
== 0) {
327 printf("# [eppoll] timeout\n");
329 perror("epoll_pwait");
336 void run_working_cases(void)
343 * We need an input pipe for some cases and stdin might
344 * have random data, so we create a dummy pipe for this
345 * test to make sure we are running under clean conditions.
347 ret
= pipe(pipe_fds
);
352 wait_fd
= pipe_fds
[0];
363 ret
= close(pipe_fds
[0]);
367 ret
= close(pipe_fds
[1]);
378 * Ask for 100 FDs in a buffer for allocated for only 1 FD, should
379 * segfault (eventually with a "*** stack smashing detected ***" message).
380 * The event should contain an array of 100 FDs filled with garbage.
382 void ppoll_fds_buffer_overflow(void)
384 struct pollfd ufds
[NB_FD
];
388 ufds
[0].fd
= wait_fd
;
389 ufds
[0].events
= POLLIN
|POLLPRI
;
391 ret
= syscall(SYS_ppoll
, ufds
, 100, NULL
, NULL
);
395 } else if (ret
> 0) {
396 printf("# [ppoll] data available\n");
397 ret
= read(wait_fd
, buf
, BUF_SIZE
);
399 perror("[ppoll] read");
402 printf("# [ppoll] timeout\n");
409 * Ask for ULONG_MAX FDs in a buffer for allocated for only 1 FD, should
410 * cleanly fail with a "Invalid argument".
411 * The event should contain an empty array of FDs and overflow = 1.
413 void ppoll_fds_ulong_max(void)
415 struct pollfd ufds
[NB_FD
];
419 ufds
[0].fd
= wait_fd
;
420 ufds
[0].events
= POLLIN
|POLLPRI
;
422 ret
= syscall(SYS_ppoll
, ufds
, ULONG_MAX
, NULL
, NULL
);
426 } else if (ret
> 0) {
427 printf("# [ppoll] data available\n");
428 ret
= read(wait_fd
, buf
, BUF_SIZE
);
430 perror("[ppoll] read");
433 printf("# [ppoll] timeout\n");
440 * Select is limited to 1024 FDs, should output a pselect event
443 void pselect_fd_too_big(void)
445 long rfds
[2048 / (sizeof(long) * CHAR_BIT
)] = { 0 };
451 * Test if nfds > 1024.
452 * Make sure ulimit is set correctly (ulimit -n 2048).
454 fd2
= dup2(wait_fd
, 2047);
460 FD_SET(fd2
, (fd_set
*) &rfds
);
461 ret
= syscall(SYS_pselect6
, fd2
+ 1, &rfds
, NULL
, NULL
, NULL
, NULL
);
464 perror("# pselect()");
466 printf("# [pselect] data available\n");
467 ret
= read(wait_fd
, buf
, BUF_SIZE
);
469 perror("[pselect] read");
472 printf("# [pselect] timeout\n");
478 * Invalid pointer as writefds, should output a ppoll event
481 void pselect_invalid_pointer(void)
486 void *invalid
= (void *) 0x42;
489 FD_SET(wait_fd
, &rfds
);
491 ret
= syscall(SYS_pselect6
, 1, &rfds
, (fd_set
*) invalid
, NULL
, NULL
,
495 perror("# pselect()");
497 printf("# [pselect] data available\n");
498 ret
= read(wait_fd
, buf
, BUF_SIZE
);
500 perror("[pselect] read");
503 printf("# [pselect] timeout\n");
509 * Pass an invalid pointer to epoll_pwait, should fail with
510 * "Bad address", the event returns 0 FDs.
512 void epoll_pwait_invalid_pointer(void)
516 struct epoll_event epoll_event
;
517 void *invalid
= (void *) 0x42;
519 epollfd
= epoll_create(NB_FD
);
521 perror("[eppoll] create");
525 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
526 epoll_event
.data
.fd
= wait_fd
;
527 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
529 perror("[eppoll] add");
533 ret
= syscall(SYS_epoll_pwait
, epollfd
,
534 (struct epoll_event
*) invalid
, 1, -1, NULL
);
537 printf("# [eppoll] data available\n");
538 ret
= read(wait_fd
, buf
, BUF_SIZE
);
540 perror("[eppoll] read");
542 } else if (ret
== 0) {
543 printf("# [eppoll] timeout\n");
545 perror("# epoll_pwait");
553 * Set maxevents to INT_MAX, should output "Invalid argument"
554 * The event should return an empty array.
556 void epoll_pwait_int_max(void)
560 struct epoll_event epoll_event
;
562 epollfd
= epoll_create(NB_FD
);
564 perror("[eppoll] create");
568 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
569 epoll_event
.data
.fd
= wait_fd
;
570 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
572 perror("[eppoll] add");
576 ret
= syscall(SYS_epoll_pwait
, epollfd
, &epoll_event
, INT_MAX
, -1,
580 printf("# [eppoll] data available\n");
581 ret
= read(wait_fd
, buf
, BUF_SIZE
);
583 perror("[eppoll] read");
585 } else if (ret
== 0) {
586 printf("# [eppoll] timeout\n");
588 perror("# epoll_pwait");
595 void *ppoll_writer(void *arg
)
597 struct ppoll_thread_data
*data
= (struct ppoll_thread_data
*) arg
;
599 while (!stop_thread
) {
600 memset(data
->ufds
, data
->value
,
601 MAX_FDS
* sizeof(struct pollfd
));
608 void do_ppoll(int *fds
, struct pollfd
*ufds
)
615 ts
.tv_nsec
= 1 * MSEC_PER_NSEC
;
617 for (i
= 0; i
< MAX_FDS
; i
++) {
619 ufds
[i
].events
= POLLIN
|POLLPRI
;
622 ret
= ppoll(ufds
, MAX_FDS
, &ts
, NULL
);
626 } else if (ret
> 0) {
627 printf("# [ppoll] data available\n");
628 ret
= read(wait_fd
, buf
, BUF_SIZE
);
630 perror("[ppoll] read");
633 printf("# [ppoll] timeout\n");
637 void stress_ppoll(int *fds
, int value
)
641 struct ppoll_thread_data thread_data
;
642 struct pollfd ufds
[MAX_FDS
];
644 thread_data
.ufds
= ufds
;
645 thread_data
.value
= value
;
648 ret
= pthread_create(&writer
, NULL
, &ppoll_writer
, (void *) &thread_data
);
650 fprintf(stderr
, "[error] pthread_create\n");
653 for (iter
= 0; iter
< NR_ITER
; iter
++) {
657 ret
= pthread_join(writer
, NULL
);
659 fprintf(stderr
, "[error] pthread_join\n");
667 * 3 rounds of NR_ITER iterations with concurrent updates of the pollfd
671 * - memset to INT_MAX
672 * Waits for input, but also set a timeout in case the input FD is overwritten
673 * before entering in the syscall. We use MAX_FDS FDs (dup of stdin), so the
674 * resulting trace is big (20MB).
676 * ppoll should work as expected and the trace should be readable at the end.
678 void ppoll_concurrent_write(void)
680 int i
, ret
, fds
[MAX_FDS
];
682 for (i
= 0; i
< MAX_FDS
; i
++) {
683 fds
[i
] = dup(wait_fd
);
689 stress_ppoll(fds
, 0);
690 stress_ppoll(fds
, 1);
691 stress_ppoll(fds
, INT_MAX
);
693 for (i
= 0; i
< MAX_FDS
; i
++) {
703 void *epoll_pwait_writer(void *addr
)
707 while (!stop_thread
) {
709 munmap(addr
, MAX_FDS
* sizeof(struct epoll_event
));
716 * epoll_pwait on MAX_FDS fds while a concurrent thread munmaps the
717 * buffer allocated for the returned data. This should randomly segfault.
718 * The trace should be readable and no kernel OOPS should occur.
720 void epoll_pwait_concurrent_munmap(void)
722 int ret
, epollfd
, i
, fds
[MAX_FDS
];
724 struct epoll_event
*epoll_event
;
727 epollfd
= epoll_create(MAX_FDS
);
729 perror("[eppoll] create");
733 epoll_event
= mmap(NULL
, MAX_FDS
* sizeof(struct epoll_event
),
734 PROT_READ
| PROT_WRITE
, MAP_PRIVATE
| MAP_ANONYMOUS
,
736 if (epoll_event
== MAP_FAILED
) {
741 for (i
= 0; i
< MAX_FDS
; i
++) {
742 fds
[i
] = dup(wait_fd
);
746 epoll_event
[i
].events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
747 epoll_event
[i
].data
.fd
= fds
[i
];
748 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, fds
[i
], epoll_event
);
750 perror("[eppoll] add");
755 ret
= pthread_create(&writer
, NULL
, &epoll_pwait_writer
,
756 (void *) epoll_event
);
758 fprintf(stderr
, "[error] pthread_create\n");
762 ret
= epoll_pwait(epollfd
, epoll_event
, 1, 1, NULL
);
765 printf("# [eppoll] data available\n");
766 ret
= read(wait_fd
, buf
, BUF_SIZE
);
768 perror("[eppoll] read");
770 } else if (ret
== 0) {
771 printf("# [eppoll] timeout\n");
773 perror("# epoll_pwait");
777 ret
= pthread_join(writer
, NULL
);
779 fprintf(stderr
, "[error] pthread_join\n");
783 for (i
= 0; i
< MAX_FDS
; i
++) {
790 ret
= munmap(epoll_event
, MAX_FDS
* sizeof(struct epoll_event
));
799 void usage(poptContext optCon
, int exitcode
, char *error
, char *addl
)
801 poptPrintUsage(optCon
, stderr
, 0);
803 fprintf(stderr
, "%s: %s\n", error
, addl
);
808 void print_list(void)
810 fprintf(stderr
, "Test list (-t X):\n");
811 fprintf(stderr
, "\t1: Working cases for select, pselect6, poll, ppoll "
812 "and epoll, waiting for input\n");
813 fprintf(stderr
, "\t2: Timeout cases (1ms) for select, pselect6, poll, "
814 "ppoll and epoll\n");
815 fprintf(stderr
, "\t3: pselect with a FD > 1023\n");
816 fprintf(stderr
, "\t4: ppoll with %d FDs\n", MAX_FDS
);
817 fprintf(stderr
, "\t5: ppoll buffer overflow, should segfault, waits "
819 fprintf(stderr
, "\t6: pselect with invalid pointer, waits for "
821 fprintf(stderr
, "\t7: ppoll with ulong_max fds, waits for input\n");
822 fprintf(stderr
, "\t8: epoll_pwait with invalid pointer, waits for "
824 fprintf(stderr
, "\t9: epoll_pwait with maxevents set to INT_MAX, "
825 "waits for input\n");
826 fprintf(stderr
, "\t10: ppoll with concurrent updates of the structure "
827 "from user-space, stress test (3000 iterations), "
828 "waits for input + timeout 1ms\n");
829 fprintf(stderr
, "\t11: epoll_pwait with concurrent munmap of the buffer "
830 "from user-space, should randomly segfault, run "
831 "multiple times, waits for input + timeout 1ms\n");
834 int main(int argc
, const char **argv
)
836 int c
, ret
, test
= -1;
838 struct rlimit open_lim
;
840 struct poptOption optionsTable
[] = {
841 { "test", 't', POPT_ARG_INT
, &test
, 0,
842 "Test to run", NULL
},
843 { "list", 'l', 0, 0, 'l',
844 "List of tests (-t X)", NULL
},
846 { NULL
, 0, 0, NULL
, 0 }
849 optCon
= poptGetContext(NULL
, argc
, argv
, optionsTable
, 0);
852 poptPrintUsage(optCon
, stderr
, 0);
859 while ((c
= poptGetNextOpt(optCon
)) >= 0) {
867 open_lim
.rlim_cur
= MAX_FDS
+ MIN_NR_FDS
;
868 open_lim
.rlim_max
= MAX_FDS
+ MIN_NR_FDS
;
870 ret
= setrlimit(RLIMIT_NOFILE
, &open_lim
);
877 * Some tests might segfault, but we need the getpid() to be output
878 * for the validation, disabling the buffering on stdout works.
880 setbuf(stdout
, NULL
);
881 printf("%d\n", getpid());
883 wait_fd
= STDIN_FILENO
;
895 pselect_fd_too_big();
901 ppoll_fds_buffer_overflow();
904 pselect_invalid_pointer();
907 ppoll_fds_ulong_max();
910 epoll_pwait_invalid_pointer();
913 epoll_pwait_int_max();
916 ppoll_concurrent_write();
919 epoll_pwait_concurrent_munmap();
922 poptPrintUsage(optCon
, stderr
, 0);
928 poptFreeContext(optCon
);