Simplify UIO_SYSSPACE and UIO_NOCOPY paths in uiomove

Uiomove can only block when the segflag is UIO_USERSPACE,
otherwise we end up just doing a bcopy (or nothing) and
moving cursors. So only emit witness warnings and
set deadlock thread flags in the UIO_USERSPACE case.

Reviewed by:	kib
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D11489
This commit is contained in:
Andrew Gallatin 2017-07-06 15:03:54 +00:00
parent eaca103d94
commit a5169546ee
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320738

View File

@ -206,31 +206,32 @@ uiomove_nofault(void *cp, int n, struct uio *uio)
static int
uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault)
{
struct thread *td;
struct iovec *iov;
size_t cnt;
int error, newflags, save;
td = curthread;
error = 0;
KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
("uiomove: mode"));
KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == td,
KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
("uiomove proc"));
if (!nofault)
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"Calling uiomove()");
/* XXX does it make a sense to set TDP_DEADLKTREAT for UIO_SYSSPACE ? */
newflags = TDP_DEADLKTREAT;
if (uio->uio_segflg == UIO_USERSPACE && nofault) {
/*
* Fail if a non-spurious page fault occurs.
*/
newflags |= TDP_NOFAULTING | TDP_RESETSPUR;
if (uio->uio_segflg == UIO_USERSPACE) {
newflags = TDP_DEADLKTREAT;
if (nofault) {
/*
* Fail if a non-spurious page fault occurs.
*/
newflags |= TDP_NOFAULTING | TDP_RESETSPUR;
} else {
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"Calling uiomove()");
}
save = curthread_pflags_set(newflags);
} else {
KASSERT(nofault == 0, ("uiomove: nofault"));
}
save = curthread_pflags_set(newflags);
while (n > 0 && uio->uio_resid) {
iov = uio->uio_iov;
@ -272,7 +273,8 @@ uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault)
n -= cnt;
}
out:
curthread_pflags_restore(save);
if (uio->uio_segflg == UIO_USERSPACE)
curthread_pflags_restore(save);
return (error);
}