diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 5ad5272af7d8..787e44d6b3a3 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1281,8 +1281,10 @@ ktrwrite(struct ktr_desc *ktd, struct ktrace_entry *kte) struct ktrace_entry *top = kte; struct ktr_header *kth; file_t *fp = ktd->ktd_fp; + unsigned loopcount, zzzcount; int error; next: + loopcount = zzzcount = 0; auio.uio_iov = iov = &aiov[0]; auio.uio_offset = 0; auio.uio_rw = UIO_WRITE; @@ -1330,19 +1332,40 @@ next: auio.uio_iovcnt < sizeof(aiov) / sizeof(aiov[0]) - 1); again: + { + size_t resid = auio.uio_resid; + int i; + + for (i = 0; i < auio.uio_iovcnt; i++) { + KASSERTMSG(auio.uio_iov[i].iov_len <= resid, + "uio_iov[%u].iov_len=%zu > resid=%zu;" + " total=%zu loopcount=%u zzzcount=%u", + i, auio.uio_iov[i].iov_len, resid, + auio.uio_resid, loopcount, zzzcount); + resid -= auio.uio_iov[i].iov_len; + } + KASSERTMSG(resid == 0, "iovcnt=%d resid=%zu;" + " total=%zu loopcount=%u zzzcount=%u", + auio.uio_iovcnt, resid, + auio.uio_resid, loopcount, zzzcount); + } + error = (*fp->f_ops->fo_write)(fp, &fp->f_offset, &auio, fp->f_cred, FOF_UPDATE_OFFSET); switch (error) { case 0: - if (auio.uio_resid > 0) + if (auio.uio_resid > 0) { + loopcount++; goto again; + } if (kte != NULL) goto next; break; case EWOULDBLOCK: kpause("ktrzzz", false, 1, NULL); + zzzcount++; goto again; default: diff --git a/sys/kern/subr_copy.c b/sys/kern/subr_copy.c index cd934032d33c..15e2c4a73e18 100644 --- a/sys/kern/subr_copy.c +++ b/sys/kern/subr_copy.c @@ -110,6 +110,21 @@ uiomove(void *buf, size_t n, struct uio *uio) ASSERT_SLEEPABLE(); + { + size_t resid = uio->uio_resid; + int i; + + for (i = 0; i < uio->uio_iovcnt; i++) { + KASSERTMSG(uio->uio_iov[i].iov_len <= resid, + "uio_iov[%u].iov_len=%zu > resid=%zu;" + " total=%zu n=%zu", + i, uio->uio_iov[i].iov_len, resid, uio->uio_resid, n); + resid -= uio->uio_iov[i].iov_len; + } + KASSERTMSG(resid == 0, "iovcnt=%d resid=%zu; total=%zu n=%zu", + uio->uio_iovcnt, resid, uio->uio_resid, n); + } + KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE); while (n > 0 && uio->uio_resid) { KASSERT(uio->uio_iovcnt > 0);