From b41116dcd70724b79aaa2770c5c372cdcf216785 Mon Sep 17 00:00:00 2001 From: franciscozdo <44414770+franciscozdo@users.noreply.github.com> Date: Tue, 9 Jan 2024 08:05:39 +0100 Subject: [PATCH 1/2] Don't perform cow page fault when we are the only owner of anon (#1421) Signed-off-by: franciscozdo --- sys/kern/vm_map.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/kern/vm_map.c b/sys/kern/vm_map.c index 957a517e7..76f4d3d9b 100644 --- a/sys/kern/vm_map.c +++ b/sys/kern/vm_map.c @@ -539,6 +539,11 @@ static int cow_page_fault(vm_map_t *map, vm_map_entry_t *ent, size_t off, if (old == NULL) return 0; + /* This check is safe. We are the only owner of this anon and the ref count + * will not change because we are under vm_map:mtx. */ + if (old->ref_cnt == 1) + return 0; + /* Current mapping will be replaced with new one so remove it from pmap. */ vaddr_t fault_page = off * PAGESIZE + ent->start; pmap_remove(map->pmap, fault_page, fault_page + PAGESIZE); From 71ac66a50aa2ae67b204ce2a001572c6f16f411b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoni=20Pokusi=C5=84ski?= <43579310+panantoni01@users.noreply.github.com> Date: Tue, 9 Jan 2024 08:07:11 +0100 Subject: [PATCH 2/2] Add pselect syscall as a wrapper of kevent (#1419) * [libc] add pselect * [libc] pselect: make pointer arguments restrict * [libc] pselect: set sigmask before kqueue call --- lib/libc/sys/select.c | 48 +++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/libc/sys/select.c b/lib/libc/sys/select.c index 5e8454010..52fd2e378 100644 --- a/lib/libc/sys/select.c +++ b/lib/libc/sys/select.c @@ -5,32 +5,30 @@ #include #include #include +#include -int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, - fd_set *restrict exceptfds, struct timeval *restrict timeout) { +int pselect(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, + fd_set *restrict exceptfds, const struct timespec *restrict timeout, + const sigset_t *restrict sigmask) { int kq; int ret; - struct timespec timeout_ts; struct kevent *events; int nevents = 0; + sigset_t sigs; if (nfds < 0) { errno = EINVAL; return -1; } - if (timeout != NULL) { - if (timeout->tv_sec < 0 || timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) { - errno = EINVAL; - return -1; - } - - tv2ts(timeout, &timeout_ts); - } + if (sigmask && sigprocmask(SIG_SETMASK, sigmask, &sigs)) + return -1; kq = kqueue1(O_CLOEXEC); - if (kq < 0) - return -1; + if (kq < 0) { + ret = -1; + goto restore_sigs; + } events = malloc(2 * nfds * sizeof(struct kevent)); if (!events) { @@ -50,8 +48,8 @@ int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, FD_ZERO(readfds); if (writefds != NULL) FD_ZERO(writefds); - - ret = kevent(kq, events, nevents, events, nevents, timeout == NULL ? NULL : &timeout_ts); + + ret = kevent(kq, events, nevents, events, nevents, timeout); if (ret == -1) goto end; @@ -71,5 +69,25 @@ int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, free(events); close_kq: close(kq); +restore_sigs: + if (sigmask && sigprocmask(SIG_SETMASK, &sigs, NULL)) + ret = -1; return ret; } + +int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, + fd_set *restrict exceptfds, struct timeval *restrict timeout) { + struct timespec timeout_ts; + + if (timeout != NULL) { + if (timeout->tv_sec < 0 || timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) { + errno = EINVAL; + return -1; + } + + tv2ts(timeout, &timeout_ts); + } + + return pselect(nfds, readfds, writefds, exceptfds, + timeout == NULL ? NULL : &timeout_ts , NULL); +}