5 #include <sys/syscall.h>
12 #include <sys/select.h>
13 #include <sys/epoll.h>
16 #include <sys/resource.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 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
);
90 void test_pselect(void)
98 FD_SET(wait_fd
, &rfds
);
101 tv
.tv_nsec
= timeout
* MSEC_PER_NSEC
;
104 ret
= pselect(1, &rfds
, NULL
, NULL
, &tv
, NULL
);
106 ret
= pselect(1, &rfds
, NULL
, NULL
, NULL
, NULL
);
112 printf("# [pselect] data available\n");
113 ret
= read(wait_fd
, buf
, BUF_SIZE
);
115 perror("[pselect] read");
118 printf("# [pselect] timeout\n");
123 void test_select(void)
131 FD_SET(wait_fd
, &rfds
);
134 tv
.tv_usec
= timeout
* MSEC_PER_USEC
;
137 ret
= select(1, &rfds
, NULL
, NULL
, &tv
);
139 ret
= select(1, &rfds
, NULL
, NULL
, NULL
);
145 printf("# [select] data available\n");
146 ret
= read(wait_fd
, buf
, BUF_SIZE
);
148 perror("[select] read");
151 printf("# [select] timeout\n");
158 struct pollfd ufds
[NB_FD
];
162 ufds
[0].fd
= wait_fd
;
163 ufds
[0].events
= POLLIN
|POLLPRI
;
165 ret
= poll(ufds
, 1, timeout
);
169 } else if (ret
> 0) {
170 printf("# [poll] data available\n");
171 ret
= read(wait_fd
, buf
, BUF_SIZE
);
173 perror("[poll] read");
176 printf("# [poll] timeout\n");
180 void test_ppoll(void)
182 struct pollfd ufds
[NB_FD
];
187 ufds
[0].fd
= wait_fd
;
188 ufds
[0].events
= POLLIN
|POLLPRI
;
192 ts
.tv_nsec
= timeout
* MSEC_PER_NSEC
;
193 ret
= ppoll(ufds
, 1, &ts
, NULL
);
195 ret
= ppoll(ufds
, 1, NULL
, NULL
);
201 } else if (ret
> 0) {
202 printf("# [ppoll] data available\n");
203 ret
= read(wait_fd
, buf
, BUF_SIZE
);
205 perror("[ppoll] read");
208 printf("# [ppoll] timeout\n");
212 void test_ppoll_big(void)
214 struct pollfd ufds
[MAX_FDS
];
216 int ret
, i
, fds
[MAX_FDS
];
218 for (i
= 0; i
< MAX_FDS
; i
++) {
219 fds
[i
] = dup(wait_fd
);
223 ufds
[i
].events
= POLLIN
|POLLPRI
;
226 ret
= ppoll(ufds
, MAX_FDS
, NULL
, NULL
);
230 } else if (ret
> 0) {
231 printf("# [ppoll] data available\n");
232 ret
= read(wait_fd
, buf
, BUF_SIZE
);
234 perror("[ppoll] read");
237 printf("# [ppoll] timeout\n");
240 for (i
= 0; i
< MAX_FDS
; i
++) {
249 void test_epoll(void)
253 struct epoll_event epoll_event
;
255 epollfd
= epoll_create(NB_FD
);
257 perror("[epoll] create");
261 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
262 epoll_event
.data
.fd
= wait_fd
;
263 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
265 perror("[epoll] add");
270 ret
= epoll_wait(epollfd
, &epoll_event
, 1, timeout
);
272 ret
= epoll_wait(epollfd
, &epoll_event
, 1, -1);
276 printf("# [epoll] data available\n");
277 ret
= read(wait_fd
, buf
, BUF_SIZE
);
279 perror("[epoll] read");
281 } else if (ret
== 0) {
282 printf("# [epoll] timeout\n");
284 perror("epoll_wait");
291 void test_pepoll(void)
295 struct epoll_event epoll_event
;
297 epollfd
= epoll_create(NB_FD
);
299 perror("[eppoll] create");
303 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
304 epoll_event
.data
.fd
= wait_fd
;
305 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
307 perror("[eppoll] add");
312 ret
= epoll_pwait(epollfd
, &epoll_event
, 1, timeout
, NULL
);
314 ret
= epoll_pwait(epollfd
, &epoll_event
, 1, -1, NULL
);
318 printf("# [eppoll] data available\n");
319 ret
= read(wait_fd
, buf
, BUF_SIZE
);
321 perror("[eppoll] read");
323 } else if (ret
== 0) {
324 printf("# [eppoll] timeout\n");
326 perror("epoll_pwait");
333 void should_work(void)
340 * When launched with the run.sh script, stdin randomly
341 * receives some garbage that make the timeout cases
342 * fail, use a dummy pipe for this test.
344 ret
= pipe(pipe_fds
);
349 wait_fd
= pipe_fds
[0];
360 ret
= close(pipe_fds
[0]);
363 ret
= close(pipe_fds
[1]);
373 * Ask for 100 FDs in a buffer for allocated for only 1 FD, should
374 * segfault (eventually with a "*** stack smashing detected ***" message).
375 * The event should contain an array of 100 FDs filled with garbage.
377 void ppoll_fds_buffer_overflow(void)
379 struct pollfd ufds
[NB_FD
];
383 ufds
[0].fd
= wait_fd
;
384 ufds
[0].events
= POLLIN
|POLLPRI
;
386 ret
= syscall(SYS_ppoll
, ufds
, 100, NULL
, NULL
);
390 } else if (ret
> 0) {
391 printf("# [ppoll] data available\n");
392 ret
= read(wait_fd
, buf
, BUF_SIZE
);
394 perror("[ppoll] read");
397 printf("# [ppoll] timeout\n");
404 * Ask for ULONG_MAX FDs in a buffer for allocated for only 1 FD, should
405 * cleanly fail with a "Invalid argument".
406 * The event should contain an empty array of FDs and overflow = 1.
408 void ppoll_fds_ulong_max(void)
410 struct pollfd ufds
[NB_FD
];
414 ufds
[0].fd
= wait_fd
;
415 ufds
[0].events
= POLLIN
|POLLPRI
;
417 ret
= syscall(SYS_ppoll
, ufds
, ULONG_MAX
, NULL
, NULL
);
421 } else if (ret
> 0) {
422 printf("# [ppoll] data available\n");
423 ret
= read(wait_fd
, buf
, BUF_SIZE
);
425 perror("[ppoll] read");
428 printf("# [ppoll] timeout\n");
435 * Select is limited to 1024 FDs, should output a pselect event
438 void pselect_fd_too_big(void)
446 * Test if nfds > 1024.
447 * Make sure ulimit is set correctly (ulimit -n 2048).
449 fd2
= dup2(wait_fd
, 2047);
457 ret
= syscall(SYS_pselect6
, fd2
+ 1, &rfds
, NULL
, NULL
, NULL
, NULL
);
460 perror("# pselect()");
462 printf("# [pselect] data available\n");
463 ret
= read(wait_fd
, buf
, BUF_SIZE
);
465 perror("[pselect] read");
468 printf("# [pselect] timeout\n");
474 * Invalid pointer as writefds, should output a ppoll event
477 void pselect_invalid_pointer(void)
482 void *invalid
= (void *) 0x42;
485 FD_SET(wait_fd
, &rfds
);
487 ret
= syscall(SYS_pselect6
, 1, &rfds
, (fd_set
*) invalid
, NULL
, NULL
,
491 perror("# pselect()");
493 printf("# [pselect] data available\n");
494 ret
= read(wait_fd
, buf
, BUF_SIZE
);
496 perror("[pselect] read");
499 printf("# [pselect] timeout\n");
505 * Pass an invalid pointer to epoll_pwait, should fail with
506 * "Bad address", the event returns 0 FDs.
508 void epoll_pwait_invalid_pointer(void)
512 struct epoll_event epoll_event
;
513 void *invalid
= (void *) 0x42;
515 epollfd
= epoll_create(NB_FD
);
517 perror("[eppoll] create");
521 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
522 epoll_event
.data
.fd
= wait_fd
;
523 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
525 perror("[eppoll] add");
529 ret
= syscall(SYS_epoll_pwait
, epollfd
,
530 (struct epoll_event
*) invalid
, 1, -1, NULL
);
533 printf("# [eppoll] data available\n");
534 ret
= read(wait_fd
, buf
, BUF_SIZE
);
536 perror("[eppoll] read");
538 } else if (ret
== 0) {
539 printf("# [eppoll] timeout\n");
541 perror("# epoll_pwait");
549 * Set maxevents to INT_MAX, should output "Invalid argument"
550 * The event should return an empty array.
552 void epoll_pwait_int_max(void)
556 struct epoll_event epoll_event
;
558 epollfd
= epoll_create(NB_FD
);
560 perror("[eppoll] create");
564 epoll_event
.events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
565 epoll_event
.data
.fd
= wait_fd
;
566 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, wait_fd
, &epoll_event
);
568 perror("[eppoll] add");
572 ret
= syscall(SYS_epoll_pwait
, epollfd
, &epoll_event
, INT_MAX
, -1,
576 printf("# [eppoll] data available\n");
577 ret
= read(wait_fd
, buf
, BUF_SIZE
);
579 perror("[eppoll] read");
581 } else if (ret
== 0) {
582 printf("# [eppoll] timeout\n");
584 perror("# epoll_pwait");
591 void *ppoll_writer(void *arg
)
593 struct ppoll_thread_data
*data
= (struct ppoll_thread_data
*) arg
;
595 while (!stop_thread
) {
596 memset(data
->ufds
, data
->value
,
597 MAX_FDS
* sizeof(struct pollfd
));
604 void do_ppoll(int *fds
, struct pollfd
*ufds
)
611 ts
.tv_nsec
= 1 * MSEC_PER_NSEC
;
613 for (i
= 0; i
< MAX_FDS
; i
++) {
615 ufds
[i
].events
= POLLIN
|POLLPRI
;
618 ret
= ppoll(ufds
, MAX_FDS
, &ts
, NULL
);
622 } else if (ret
> 0) {
623 printf("# [ppoll] data available\n");
624 ret
= read(wait_fd
, buf
, BUF_SIZE
);
626 perror("[ppoll] read");
629 printf("# [ppoll] timeout\n");
633 void stress_ppoll(int *fds
, int value
)
637 struct ppoll_thread_data thread_data
;
638 struct pollfd ufds
[MAX_FDS
];
640 thread_data
.ufds
= ufds
;
641 thread_data
.value
= value
;
644 pthread_create(&writer
, NULL
, &ppoll_writer
, (void *) &thread_data
);
645 for (iter
= 0; iter
< NR_ITER
; iter
++) {
649 pthread_join(writer
, NULL
);
653 * 3 rounds of NR_ITER iterations with concurrent updates of the pollfd
657 * - memset to INT_MAX
658 * Waits for input, but also set a timeout in case the input FD is overwritten
659 * before entering in the syscall. We use MAX_FDS FDs (dup of stdin), so the
660 * resulting trace is big (20MB).
662 * ppoll should work as expected and the trace should be readable at the end.
664 void ppoll_concurrent_write(void)
666 int i
, ret
, fds
[MAX_FDS
];
668 for (i
= 0; i
< MAX_FDS
; i
++) {
669 fds
[i
] = dup(wait_fd
);
674 stress_ppoll(fds
, 0);
675 stress_ppoll(fds
, 1);
676 stress_ppoll(fds
, INT_MAX
);
678 for (i
= 0; i
< MAX_FDS
; i
++) {
687 void *epoll_pwait_writer(void *addr
)
691 while (!stop_thread
) {
693 munmap(addr
, MAX_FDS
* sizeof(struct epoll_event
));
700 * epoll_pwait on MAX_FDS fds while a concurrent thread munmaps the
701 * buffer allocated for the returned data. This should randomly segfault.
702 * The trace should be readable and no kernel OOPS should occur.
704 void epoll_pwait_concurrent_munmap(void)
706 int ret
, epollfd
, i
, fds
[MAX_FDS
];
708 struct epoll_event
*epoll_event
;
713 epollfd
= epoll_create(MAX_FDS
);
715 perror("[eppoll] create");
719 epoll_event
= mmap(addr
, MAX_FDS
* sizeof(struct epoll_event
),
720 PROT_READ
| PROT_WRITE
, MAP_PRIVATE
| MAP_ANONYMOUS
,
722 if (epoll_event
== MAP_FAILED
) {
727 for (i
= 0; i
< MAX_FDS
; i
++) {
728 fds
[i
] = dup(wait_fd
);
731 epoll_event
[i
].events
= EPOLLIN
| EPOLLPRI
| EPOLLET
;
732 epoll_event
[i
].data
.fd
= fds
[i
];
733 ret
= epoll_ctl(epollfd
, EPOLL_CTL_ADD
, fds
[i
], epoll_event
);
735 perror("[eppoll] add");
740 pthread_create(&writer
, NULL
, &epoll_pwait_writer
, (void *) epoll_event
);
742 ret
= epoll_pwait(epollfd
, epoll_event
, 1, 1, NULL
);
745 printf("# [eppoll] data available\n");
746 ret
= read(wait_fd
, buf
, BUF_SIZE
);
748 perror("[eppoll] read");
750 } else if (ret
== 0) {
751 printf("# [eppoll] timeout\n");
753 perror("# epoll_pwait");
757 pthread_join(writer
, NULL
);
760 for (i
= 0; i
< MAX_FDS
; i
++) {
766 ret
= munmap(addr
, MAX_FDS
* sizeof(struct epoll_event
));
774 void usage(poptContext optCon
, int exitcode
, char *error
, char *addl
)
776 poptPrintUsage(optCon
, stderr
, 0);
778 fprintf(stderr
, "%s: %s\n", error
, addl
);
782 void print_list(void)
784 fprintf(stderr
, "Test list (-t X):\n");
785 fprintf(stderr
, "\t1: Working cases for select, pselect6, poll, ppoll "
786 "and epoll, waiting for input\n");
787 fprintf(stderr
, "\t2: Timeout cases (1ms) for select, pselect6, poll, "
788 "ppoll and epoll\n");
789 fprintf(stderr
, "\t3: pselect with a FD > 1023\n");
790 fprintf(stderr
, "\t4: ppoll with %d FDs\n", MAX_FDS
);
791 fprintf(stderr
, "\t5: ppoll buffer overflow, should segfault, waits "
793 fprintf(stderr
, "\t6: pselect with invalid pointer, waits for "
795 fprintf(stderr
, "\t7: ppoll with ulong_max fds, waits for input\n");
796 fprintf(stderr
, "\t8: epoll_pwait with invalid pointer, waits for "
798 fprintf(stderr
, "\t9: epoll_pwait with maxevents set to INT_MAX, "
799 "waits for input\n");
800 fprintf(stderr
, "\t10: ppoll with concurrent updates of the structure "
801 "from user-space, stress test (3000 iterations), "
802 "waits for input + timeout 1ms\n");
803 fprintf(stderr
, "\t11: epoll_pwait with concurrent munmap of the buffer "
804 "from user-space, should randomly segfault, run "
805 "multiple times, waits for input + timeout 1ms\n");
808 int main(int argc
, const char **argv
)
810 int c
, ret
, test
= -1;
812 struct rlimit open_lim
;
814 struct poptOption optionsTable
[] = {
815 { "test", 't', POPT_ARG_INT
, &test
, 0,
816 "Test to run", NULL
},
817 { "list", 'l', 0, 0, 'l',
818 "List of tests (-t X)", NULL
},
820 { NULL
, 0, 0, NULL
, 0 }
823 optCon
= poptGetContext(NULL
, argc
, argv
, optionsTable
, 0);
826 poptPrintUsage(optCon
, stderr
, 0);
833 while ((c
= poptGetNextOpt(optCon
)) >= 0) {
841 open_lim
.rlim_cur
= MAX_FDS
+ MIN_NR_FDS
;
842 open_lim
.rlim_max
= MAX_FDS
+ MIN_NR_FDS
;
844 ret
= setrlimit(RLIMIT_NOFILE
, &open_lim
);
851 * Some tests might segfault, but we need the getpid() to be output
852 * for the validation, disabling the buffering on stdout works.
854 setbuf(stdout
, NULL
);
855 printf("%d\n", getpid());
857 wait_fd
= STDIN_FILENO
;
869 pselect_fd_too_big();
875 ppoll_fds_buffer_overflow();
878 pselect_invalid_pointer();
881 ppoll_fds_ulong_max();
884 epoll_pwait_invalid_pointer();
887 epoll_pwait_int_max();
890 ppoll_concurrent_write();
893 epoll_pwait_concurrent_munmap();
896 poptPrintUsage(optCon
, stderr
, 0);
902 poptFreeContext(optCon
);