Hi, kevent(2) system call is ulocked more than year ago. Since select(2) and pselect(2) are kqueue(2)/kevent(2) wrappers, it makes sense to unlock them too. select(2) does the temporary kernel event queue initialization for this call only and does queue scan with events conversion between kevent(2) and select(2) data formats.
pselect(2) is the same, but it also sets provided signal mask. sigset_t is unsigned int and only current thread does `p_sigmask' and `p_oldmask' modification, so dosigsuspend() call outside kernel lock is safe. claudio@, is this true? If so, I want to mark `p_sigmask' and `p_oldmask' as atomic in proc structure description. In dopselect() I used local `nfiles' variable to store p->p_fd->fd_nfiles value for `nd' normalisation. I'm the select(2) user and this unlocking makes sense for me, because the performance of select based programs increased by ~10-15%. Index: sys/kern/sys_generic.c =================================================================== RCS file: /cvs/src/sys/kern/sys_generic.c,v retrieving revision 1.151 diff -u -p -r1.151 sys_generic.c --- sys/kern/sys_generic.c 27 Dec 2022 20:13:03 -0000 1.151 +++ sys/kern/sys_generic.c 3 Feb 2023 21:37:37 -0000 @@ -596,15 +596,16 @@ dopselect(struct proc *p, int nd, fd_set struct timespec zerots = {}; fd_mask bits[6]; fd_set *pibits[3], *pobits[3]; - int error, ncollected = 0, nevents = 0; + int error, nfiles, ncollected = 0, nevents = 0; u_int ni; if (nd < 0) return (EINVAL); - if (nd > p->p_fd->fd_nfiles) { - /* forgiving; slightly wrong */ - nd = p->p_fd->fd_nfiles; - } + + nfiles = READ_ONCE(p->p_fd->fd_nfiles); + if (nd > nfiles) + nd = nfiles; + ni = howmany(nd, NFDBITS) * sizeof(fd_mask); if (ni > sizeof(bits[0])) { caddr_t mbits; Index: sys/kern/syscalls.master =================================================================== RCS file: /cvs/src/sys/kern/syscalls.master,v retrieving revision 1.239 diff -u -p -r1.239 syscalls.master --- sys/kern/syscalls.master 7 Jan 2023 05:24:58 -0000 1.239 +++ sys/kern/syscalls.master 3 Feb 2023 21:37:37 -0000 @@ -165,7 +165,7 @@ struct itimerval *oitv); } 70 STD NOLOCK { int sys_getitimer(int which, \ struct itimerval *itv); } -71 STD { int sys_select(int nd, fd_set *in, fd_set *ou, \ +71 STD NOLOCK { int sys_select(int nd, fd_set *in, fd_set *ou, \ fd_set *ex, struct timeval *tv); } 72 STD NOLOCK { int sys_kevent(int fd, \ const struct kevent *changelist, int nchanges, \ @@ -233,7 +233,7 @@ 109 STD { int sys_ppoll(struct pollfd *fds, \ u_int nfds, const struct timespec *ts, \ const sigset_t *mask); } -110 STD { int sys_pselect(int nd, fd_set *in, fd_set *ou, \ +110 STD NOLOCK { int sys_pselect(int nd, fd_set *in, fd_set *ou, \ fd_set *ex, const struct timespec *ts, \ const sigset_t *mask); } 111 STD { int sys_sigsuspend(int mask); }