summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_pipe.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* Set klist lock for pipes.visa2020-12-301-5/+15
| | | | OK anton@, mpi@
* Refactor klist insertion and removalvisa2020-12-251-4/+4
| | | | | | | | | | | | Rename klist_{insert,remove}() to klist_{insert,remove}_locked(). These functions assume that the caller has locked the klist. The current state of locking remains intact because the kernel lock is still used with all klists. Add new functions klist_insert() and klist_remove() that lock the klist internally. This allows some code simplification. OK mpi@
* Simplify filt_pipedetach()visa2020-12-111-18/+7
| | | | | | | | By storing pipe pointer in kn_hook, filt_pipedetach() does not need extra logic to find the correct pipe instance. This also lets the kernel clear the knote lists fully. OK anton@, mpi@
* Bring back revision 1.122 with a fix preventing a use-after-free byanton2020-06-291-52/+55
| | | | | | | | | | | | | | | | | serializing calls to pipe_buffer_free(). Repeating the previous commit message: Instead of performing three distinct allocations per created pipe, reduce it to a single one. Not only should this be more performant, it also solves a kqueue related issue found by visa@ who also requested this change: if you attach an EVFILT_WRITE filter to a pipe fd, the knote gets added to the peer's klist. This is a problem for kqueue because if you close the peer's fd, the knote is left in the list whose head is about to be freed. knote_fdclose() is not able to clear the knote because it is not registered with the peer's fd. FreeBSD also takes a similar approach to pipe allocations. once again ok mpi@ visa@
* backout pipe change, it crashes some archderaadt2020-06-191-53/+51
|
* Instead of performing three distinct allocations per created pipe,anton2020-06-171-51/+53
| | | | | | | | | | | | | reduce it to a single one. Not only should this be more performant, it also solves a kqueue related issue found by visa@ who also requested this change: if you attach an EVFILT_WRITE filter to a pipe fd, the knote gets added to the peer's klist. This is a problem for kqueue because if you close the peer's fd, the knote is left in the list whose head is about to be freed. knote_fdclose() is not able to clear the knote because it is not registered with the peer's fd. FreeBSD also takes a similar approach to pipe allocations. ok mpi@ visa@
* Set __EV_HUP when the conditions matching poll(2)'s POLLUP are found.mpi2020-06-151-1/+5
| | | | | | This is only done in poll-compatibility mode, when __EV_POLL is set. ok visa@, millert@
* Abstract the head of knote lists. This allows extending the lists,visa2020-04-071-5/+5
| | | | | | for example, with locking assertions. OK mpi@, anton@
* Replace field f_isfd with field f_flags in struct filterops to allowvisa2020-02-201-3/+3
| | | | | | adding more filter properties without cluttering the struct. OK mpi@, anton@
* Unconditionally acquiring a write lock in pipe_ioctl() is quiteanton2020-02-161-5/+5
| | | | | | | | excessive as only one command actually modifies the pipe. The sigio subsystem is already internally protected using its own lock. This is similar to what soo_ioctl() already does. ok mpi@ visa@
* Push the KERNEL_LOCK() insidge pgsigio() and selwakeup().mpi2020-02-141-8/+5
| | | | | | | | | | | The 3 subsystems: signal, poll/select and kqueue can now be addressed separatly. Note that bpf(4) and audio(4) currently delay the wakeups to a separate context in order to respect the KERNEL_LOCK() requirement. Sockets (UDP, TCP) and pipes spin to grab the lock for the sames reasons. ok anton@, visa@
* Back out previous. Nothing wrong with the diff per se but I should haveanton2020-02-011-3/+6
| | | | asked for more oks; my bad!
* Grab the kernel lock in pgsigio() as it's strictly needed whileanton2020-02-011-6/+3
| | | | | | | | | | operating on the process structure and issuing signals. This is similar to what sigio_setown() already does. With this in place, the pipe subsystem is no longer required to grab the kernel lock before calling pgsigio(). ok visa@
* condense commentanton2020-01-121-5/+2
|
* Get rid of redundant parenthesis.anton2020-01-121-11/+11
| | | | ok millert@ ratchov@ visa@
* Replace the global pipe_lock with a more fine-grained lock per pipeanton2020-01-091-60/+83
| | | | | | | pair. One lock per pipe pair is used to guarantee exclusive access to both ends of a pipe. Thanks to millert@ and tedu@ for the feedback and ok visa@
* Unify handling of ioctls FIOSETOWN/SIOCSPGRP/TIOCSPGRP andvisa2020-01-081-8/+6
| | | | | | | | | | | | FIOGETOWN/SIOCGPGRP/TIOCGPGRP. Do this by determining the meaning of the ID parameter inside the sigio code. Also add cases for FIOSETOWN and FIOGETOWN where there have been TIOCSPGRP and TIOCGPGRP before. These changes allow removing the ID translation from sys_fcntl() and sys_ioctl(). Idea from NetBSD OK mpi@, claudio@
* Constify instances of struct fileops.visa2020-01-051-2/+2
| | | | OK anton@, mpi@, bluhm@
* Eliminate some minor differences between pipe_read() and pipe_write():anton2020-01-041-6/+4
| | | | | | | * Sort local variables by size, name * No need to initialize error in pipe_write() ok millert@ visa@
* Rename the pipe I/O lock routines for improved clarity. This is just aanton2020-01-031-18/+18
| | | | | | mere preparation for introducing a dedicated lock per pipe pair. ok mpi@ visa@
* Use C99 designated initializers with struct filterops. In addition,visa2019-12-311-5/+14
| | | | | | make the structs const so that the data are put in .rodata. OK mpi@, deraadt@, anton@, bluhm@
* Remove the kernel lock in pipe read and write routines since everythinganton2019-12-271-12/+7
| | | | | | | | is serialized by the pipe_lock by now. The kernel lock is however still needed when interacting with kqueue in order to prevent a race and when potentially issuing SIGIO signals. ok visa@
* Condense a few multi line comments into single line ones. While hereanton2019-12-251-40/+13
| | | | turn them into proper sentences. Gets rid of 27 lines in total.
* Protect remaining fields of `struct pipe' using the pipe_lock. In orderanton2019-12-251-33/+53
| | | | | | | | | | | to simplify the locking pattern, revert back to using a hand-rolled I/O lock just like FreeBSD and NetBSD does. The state of pipes is quite different compared to when I made use of a rwlock for the I/O lock in revision 1.96. Most notably, the pipe_lock can now be used while sleeping. This does imply that witness(4) tracking of the I/O lock is lost but the implementation ends up being simpler. ok visa@
* Start protecting the pipe_peer member of `struct pipe' using theanton2019-12-191-26/+79
| | | | | | | | pipe_lock. This add a potential sleeping point in the kqueue filter routines which should be fine by now thanks to changes made to the kqueue subsystem by visa. ok visa@
* add missing parens around return expression and zap empty lineanton2019-11-291-3/+2
|
* Start protecting the pipe_busy field of struct pipe using a globalanton2019-11-291-24/+54
| | | | | | | | | | | | | rwlock. This lock is shared among all pipes for simplicity. In the future, the lock will probably be replaced with one lock per pipe pair, just like FreeBSD and NetBSD does. While here, extract the common rundown wakeup logic into a dedicated function. Thanks to cheloha@ for testing and feedback. ok mpi@ visa@
* When waiting on pipe I/O, simplify the unlock/relock logic usinganton2019-11-191-20/+36
| | | | | | | rwsleep(). All made possible by the recent switch to using a rwlock as the exclusive pipe lock. ok visa@
* Extended the scope of the pipelock() in pipe_write() making the lockinganton2019-11-111-46/+29
| | | | | | | pattern more similar to pipe_read(). This also eliminates two races caused by relocking. ok visa@
* Invert a conditional in pipe_write() for reduced indent and inanton2019-11-101-64/+66
| | | | | | preparation for further refactoring. ok cheloha@ mpi@ visa@
* Replace the hand-rolled pipe lock with a rwlock. A necessary first stepanton2019-11-091-15/+5
| | | | | | towards unlocking pipes. ok cheloha@ mpi@ visa@
* move the whole `struct pipe' allocation and initialization inside pipe_create()semarie2019-07-161-48/+52
| | | | | | rename pipclose() to pipe_destroy(), and return early instead of having the whole code in if-body. ok claudio@ anton@ visa@ mpi@
* revisit pipe initialization and buffer managementsemarie2019-07-151-35/+42
| | | | | | | | | | - in dopipe(), get an already zeroed struct (PR_ZERO) instead of manually initialize each member (in pipe_create) - rename pipespace() and pipe_free_kmem() to pipe_buffer_realloc() and pipe_buffer_free(): it is more evident that the functions works on the same thing - in pipe_buffer_free(), return early and move the if-body as function body No functional change intented. ok anton@ visa@ mpi@
* Do not relock fdp in fdrelease(). This prevents unnecessary lockingvisa2019-07-151-7/+10
| | | | | | in the common case. OK mpi@
* rename PIPE_WANT to PIPE_WANTD.semarie2019-07-141-9/+9
| | | | | | | | | | | | PIPE_WANT flag is used for signaling the pipe is about to be run-down. Pending readers/writers will wakeup the closing thread which is waiting. We already have PIPE_WANTR, PIPE_WANTW and PIPE_LWANT flags, so PIPE_WANT isn't really descriptive. No functional changes intented. ok visa@ anton@ mpi@
* pipe_write() do opportunistic buffer resizing, when the buffer is empty.semarie2019-07-131-2/+3
| | | | | | | | | | | | but there is a possible sleeping point between the check (cnt == 0) and the resize (pipespace() call), resulting resizing on possibly not empty buffer. fix it by rechecking the buffer usage once the exclusive lock is hold. it should be revisited later as part of larger work on pipe(2). ok visa@ anton@
* backout the unlock of pipe(2) and pipe2(2)semarie2019-07-091-13/+4
| | | | | | assert "cpipe->pipe_buffer.cnt == 0" occured whereas it shouldn't. Reported-by: syzbot+b559fa9d3292c3cb0343@syzkaller.appspotmail.com
* unlock pipe(2) and pipe2(2) syscallssemarie2019-07-091-4/+13
| | | | | | initial work from mpi@ ok visa@ mpi@
* push the KERNEL_LOCK deeper on read(2) and write(2)semarie2019-06-221-4/+13
| | | | | | | | | | | unlocks read(2) and write(2) syscalls families, and push the KERNEL_LOCK deeper in the code path. KERNEL_LOCK is managed per file type in fileops handlers (fo_read, fo_write, and fo_close). read(2) and write(2) on socket are KERNEL_LOCK-free. initial work from mpi@ and ians@ ok mpi@ kettenis@ visa@ ians@
* Fix fcntl(fd, F_GETOWN) with pipes. As a regressionvisa2018-11-131-2/+2
| | | | | | | of kern_descrip.c r1.177 and sys_pipe.c r1.82, the call always returned an error. OK jca@ anton@ mpi@
* Utilize sigio with pipes. This makes fcntl(fd, F_SETOWN, arg) correctlyvisa2018-11-121-8/+8
| | | | | | | | handle arg as a process ID if the value is positive and as a process group ID if the value is negative. In addition, now the signal sending checks privileges. OK mpi@
* Reorder checks in the read/write(2) family of syscalls to prepare makingmpi2018-08-201-5/+5
| | | | | | | | | | | | file operations mp-safe. This change makes it clear that `f_offset' is only accessed in vn_read() and vn_write(), which will help taking it out of the KERNEL_LOCK(). This refactoring uncovered a race in vn_read() which is now documented and will be addressed in a later diff. ok visa@
* Grab the KERNEL_LOCK() in MP-unsafe fo_close routines. This preventsvisa2018-08-151-1/+3
| | | | | | | a scenario where MP-unsafe code gets run without the kernel lock as a consequence of an unlocked system call. OK mpi@, kettenis@
* Make it possible to run pipe(2) and pipe2(2) mostly w/o KERNEL_LOCK():mpi2018-08-131-16/+23
| | | | | | | | - Update counters atomatically - Use IPL_MPFLOOR for pipe's pool. - Grab the KERNEL_LOCK() before calling km_alloc(9) & km_free(9) Inputs from kettenis@, ok visa@
* Move socket & pipe specific logic in their ioctl handler.mpi2018-07-101-1/+7
| | | | ok visa@, tb@
* Put file descriptors on shared data structures when they are completelympi2018-06-181-5/+8
| | | | | | | | | | | | | | | | | setup, take 3. LARVAL fd still exist, but they are no longer marked with a flag and no longer reachable via `fd_ofiles[]' or the global linked list. This allows us to simplifies a lot code grabbing new references to fds. All of this is now possible because dup2(2) refuses to clone LARVAL fds. Note that the `fdplock' could now be release in all open(2)-like syscalls, just like it is done in accept(2). With inputs from Mathieu Masson, visa@, guenther@ and art@ Previous version ok bluhm@, ok visa@, sthen@
* Revert introduction of fdinsert(), a sanitify check triggers whenmpi2018-06-051-8/+5
| | | | | | closing a LARVAL file. Found the hardway by sthen@.
* Put file descriptors on shared data structures when they are completelympi2018-06-021-5/+8
| | | | | | | | | | | | | | | | | setup. LARVAL fd still exist, but they are no longer marked with a flag and no longer reachable via `fd_ofiles[]'. This allows us to simplifies a lot code grabbing new references to fds. All of this is now possible because dup2(2) refuses to clone LARVAL fds. Note that the `fdplock' could now be release in all open(2)-like syscalls, just like it is done in accept(2). With inputs from Mathieu -, visa@, guenther@ and art@ ok visa@, bluhm@
* Convert 'struct fileops' definitions to C99.mpi2018-04-101-3/+8
| | | | ok millert@, deraadt@, florian@
* Stop assuming <sys/file.h> will pull in fcntl.h when _KERNEL is defined.guenther2018-01-021-1/+2
| | | | ok millert@ sthen@