summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
committerRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
commit4a05f5440acda223e6a0ec5157bc32ecc0f09ff9 (patch)
tree4c2ece480e5d4155ed35bec62996de40eb179f18 /sys/kern
parent681a482d8fc4bfc14a24f7a9d75cca6337f2a520 (diff)
parenta1e52233c91fd46e666297270ab655f1abff8535 (diff)
downloadFreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.zip
FreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_elf.c33
-rw-r--r--sys/kern/kern_procctl.c2
-rw-r--r--sys/kern/kern_switch.c15
-rw-r--r--sys/kern/sched_4bsd.c4
-rw-r--r--sys/kern/sched_ule.c4
-rw-r--r--sys/kern/subr_unit.c12
-rw-r--r--sys/kern/uipc_mbuf2.c2
-rw-r--r--sys/kern/vfs_syscalls.c4
8 files changed, 61 insertions, 15 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 293a65d..bdf709f 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1176,9 +1176,31 @@ core_output(struct vnode *vp, void *base, size_t len, off_t offset,
panic("shouldn't be here");
#endif
} else {
+ /*
+ * EFAULT is a non-fatal error that we can get, for example,
+ * if the segment is backed by a file but extends beyond its
+ * end.
+ */
error = vn_rdwr_inchunks(UIO_WRITE, vp, base, len, offset,
UIO_USERSPACE, IO_UNIT | IO_DIRECT, active_cred, file_cred,
NULL, td);
+ if (error == EFAULT) {
+ log(LOG_WARNING, "Failed to fully fault in a core file "
+ "segment at VA %p with size 0x%zx to be written at "
+ "offset 0x%jx for process %s\n", base, len, offset,
+ curproc->p_comm);
+
+ /*
+ * Write a "real" zero byte at the end of the target
+ * region in the case this is the last segment.
+ * The intermediate space will be implicitly
+ * zero-filled.
+ */
+ error = vn_rdwr_inchunks(UIO_WRITE, vp,
+ __DECONST(void *, zero_region), 1, offset + len - 1,
+ UIO_SYSSPACE, IO_UNIT | IO_DIRECT, active_cred,
+ file_cred, NULL, td);
+ }
}
return (error);
}
@@ -2309,7 +2331,16 @@ compress_core (gzFile file, char *inbuf, char *dest_buf, unsigned int len,
while (len) {
if (inbuf != NULL) {
chunk_len = (len > CORE_BUF_SIZE) ? CORE_BUF_SIZE : len;
- copyin(inbuf, dest_buf, chunk_len);
+
+ /*
+ * We can get EFAULT error here. In that case zero out
+ * the current chunk of the segment.
+ */
+ error = copyin(inbuf, dest_buf, chunk_len);
+ if (error != 0) {
+ bzero(dest_buf, chunk_len);
+ error = 0;
+ }
inbuf += chunk_len;
} else {
chunk_len = len;
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index e6e432e..4ccf646 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -243,7 +243,7 @@ reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk)
return (ECAPMODE);
if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG)
return (EINVAL);
- if ((rk->rk_flags & ~REAPER_KILL_CHILDREN) != 0)
+ if ((rk->rk_flags & ~(REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) != 0)
return (EINVAL);
PROC_UNLOCK(p);
reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p;
diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c
index d0009b1..f58acd5 100644
--- a/sys/kern/kern_switch.c
+++ b/sys/kern/kern_switch.c
@@ -206,7 +206,22 @@ critical_exit(void)
if (td->td_critnest == 1) {
td->td_critnest = 0;
+
+ /*
+ * Interrupt handlers execute critical_exit() on
+ * leave, and td_owepreempt may be left set by an
+ * interrupt handler only when td_critnest > 0. If we
+ * are decrementing td_critnest from 1 to 0, read
+ * td_owepreempt after decrementing, to not miss the
+ * preempt. Disallow compiler to reorder operations.
+ */
+ __compiler_membar();
if (td->td_owepreempt && !kdb_active) {
+ /*
+ * Microoptimization: we committed to switch,
+ * disable preemption in interrupt handlers
+ * while spinning for the thread lock.
+ */
td->td_critnest = 1;
thread_lock(td);
td->td_critnest--;
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index db23e1d..7309ae3 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -963,8 +963,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
sched_load_rem();
td->td_lastcpu = td->td_oncpu;
- preempted = !((td->td_flags & TDF_SLICEEND) ||
- (flags & SWT_RELINQUISH));
+ preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
+ (flags & SW_PREEMPT) != 0;
td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
td->td_owepreempt = 0;
td->td_oncpu = NOCPU;
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 30aad12..53a46c9 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1870,8 +1870,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
ts->ts_rltick = ticks;
td->td_lastcpu = td->td_oncpu;
td->td_oncpu = NOCPU;
- preempted = !((td->td_flags & TDF_SLICEEND) ||
- (flags & SWT_RELINQUISH));
+ preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
+ (flags & SW_PREEMPT) != 0;
td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
td->td_owepreempt = 0;
if (!TD_IS_IDLETHREAD(td))
diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c
index 3bf7aaf..d53ec1e 100644
--- a/sys/kern/subr_unit.c
+++ b/sys/kern/subr_unit.c
@@ -192,7 +192,7 @@ CTASSERT(sizeof(struct unr) == sizeof(struct unrb));
* Consistency check function.
*
* Checks the internal consistency as well as we can.
- *
+ *
* Called at all boundaries of this API.
*/
static void
@@ -220,7 +220,7 @@ check_unrhdr(struct unrhdr *uh, int line)
("UNR inconsistency: busy %u found %u (line %d)\n",
ub->busy, w, line));
y += w;
- } else if (up->ptr != NULL)
+ } else if (up->ptr != NULL)
y += up->len;
}
KASSERT (y == uh->busy,
@@ -355,7 +355,7 @@ is_bitmap(struct unrhdr *uh, struct unr *up)
/*
* Look for sequence of items which can be combined into a bitmap, if
* multiple are present, take the one which saves most memory.
- *
+ *
* Return (1) if a sequence was found to indicate that another call
* might be able to do more. Return (0) if we found no suitable sequence.
*
@@ -582,7 +582,7 @@ alloc_unrl(struct unrhdr *uh)
}
/*
- * We can always allocate from the first list element, so if we have
+ * We can always allocate from the first list element, so if we have
* nothing on the list, we must have run out of unit numbers.
*/
if (up == NULL)
@@ -797,7 +797,7 @@ free_unrl(struct unrhdr *uh, u_int item, void **p1, void **p2)
/* Handle bitmap items */
if (is_bitmap(uh, up)) {
ub = up->ptr;
-
+
KASSERT(bit_test(ub->map, item) != 0,
("UNR: Freeing free item %d (bitmap)\n", item));
bit_clear(ub->map, item);
@@ -900,7 +900,7 @@ print_unr(struct unrhdr *uh, struct unr *up)
for (x = 0; x < up->len; x++) {
if (bit_test(ub->map, x))
printf("#");
- else
+ else
printf(" ");
}
printf("]\n");
diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c
index 00472d3..f69b47e 100644
--- a/sys/kern/uipc_mbuf2.c
+++ b/sys/kern/uipc_mbuf2.c
@@ -161,7 +161,7 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
* the target data is on <n, off>.
* if we got enough data on the mbuf "n", we're done.
*/
- if ((off == 0 || offp) && len <= n->m_len - off && writable)
+ if ((off == 0 || offp) && len <= n->m_len - off)
goto ok;
/*
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9f922db..5701e5a 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -464,7 +464,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
- if (sfsp && count < maxcount) {
+ if (sfsp != NULL && count < maxcount) {
sp = &mp->mnt_stat;
/*
* Set these in case the underlying filesystem
@@ -509,7 +509,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
vfs_unbusy(mp);
}
mtx_unlock(&mountlist_mtx);
- if (sfsp && count > maxcount)
+ if (sfsp != NULL && count > maxcount)
td->td_retval[0] = maxcount;
else
td->td_retval[0] = count;
OpenPOWER on IntegriCloud