-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add more tests for userfaultfd #1280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add more tests for userfaultfd #1280
Conversation
45b04e6 to
bffe686
Compare
bffe686 to
9da6afe
Compare
metan-ucw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but there is too much duplicated code (should be mostly put into a common header) and some minor errors as well.
| SAFE_IOCTL(uffd, UFFDIO_REGISTER, &uffdio_register); | ||
|
|
||
| SAFE_PTHREAD_CREATE(&thr, NULL, | ||
| (void * (*)(void *)) handle_thread, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be just (void*) cast, but it would be better if the handle_thread function was defined as void * and returned NULL at the end.
| tst_brk(TBROK | TTERRNO, | ||
| "Could not create userfault file descriptor"); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sys_userfaultfd() should be in the test setup() so that things work properly when test is executed with -1 1000 parameter.
Also this pattern is repeated in all tests, so this piece of code should be put into a header as a static inline function and called from all tests that needs it.
| static struct tst_test test = { | ||
| .test_all = run, | ||
| .min_kver = "5.11", | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nearly the same as the userfaultfd01, it just adds the UFFD_USER_MODE_ONLY flag. It would be far better if we added .tcnt = 2 to the usefaultfd02.c and add the flag to the uffdio_register.mode only when n == 1 in order to avoid copy & paste of basically the same test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .min_kver is different though.
|
|
||
| /*\ | ||
| * Force a pagefault event and handle it using :man2:`userfaultfd` | ||
| * from a different thread using /dev/userfaultfd instead of syscall. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should mention the details here, in this case we do UFFDIO_COPY and use file descriptor created by USERFAULTFD_IOC_NEW
| SAFE_PTHREAD_CREATE(&thr, NULL, | ||
| (void * (*)(void *)) handle_thread, NULL); | ||
|
|
||
| (void)page[0xf]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think that we need this here, we are checking the page in the loop below, which will trigger read access anyways.
| pollfd.events = POLLIN; | ||
| nready = poll(&pollfd, 1, -1); | ||
| if (nready == -1) | ||
| tst_brk(TBROK | TERRNO, "Error on poll"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the poll() here? We are waiting indefinitely anyways so as long as uffd is not O_NONBLOCK (which should be default) we can just remove this and call the SAFE_READ() which will wait for the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the poll() here? We are waiting indefinitely anyways so as long as uffd is not O_NONBLOCK (which should be default) we can just remove this and call the SAFE_READ() which will wait for the data.
Technically no but uffd's are universally opened in non-blocking mode to use with poll as it seems it's the only way to catch some errors:
https://docs.kernel.org/admin-guide/mm/userfaultfd.html
Be sure to test for all errors including (pollfd[0].revents & POLLERR). This can happen, e.g. when ranges supplied were incorrect.
| uffdio_zeropage.range.len = page_size; | ||
| uffdio_zeropage.mode = 0; | ||
|
|
||
| SAFE_IOCTL(uffd, UFFDIO_ZEROPAGE, &uffdio_zeropage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that we need a test where we will attempt to map a ZEROPAGE for a write access, I suppose that we will get error from this ioctl()
| (void)page[0xf]; | ||
|
|
||
| for (int i = 0; i < page_size; i++) { | ||
| if (page[i] != '\0') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just use 0 instead of '\0'
| SAFE_READ(1, uffd, &msg, sizeof(msg)); | ||
|
|
||
| if (msg.event != UFFD_EVENT_PAGEFAULT) | ||
| tst_brk(TBROK | TERRNO, "Received unexpected UFFD_EVENT"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's TFAIL
|
|
||
| if (!(msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WP) || | ||
| !(msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE)) { | ||
| tst_brk(TBROK, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here as well TFAIL
Signed-off-by: Ricardo Branco <rbranco@suse.de>
9da6afe to
60ef374
Compare
Signed-off-by: Ricardo Branco <rbranco@suse.de>
Signed-off-by: Ricardo Branco <rbranco@suse.de>
Signed-off-by: Ricardo Branco <rbranco@suse.de>
Signed-off-by: Ricardo Branco <rbranco@suse.de>
Signed-off-by: Ricardo Branco <rbranco@suse.de>
Signed-off-by: Ricardo Branco <rbranco@suse.de>
60ef374 to
05b2ba2
Compare
Thanks for reviewing. I addressed most of your suggestions. Left some questions regarding further refactoring. |
Add more tests for userfaultfd: