summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-07 12:12:37 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:36 +0200
commitde261e0404e1fe54544275fc57d5b982df4f42b4 (patch)
tree856cbdf23d6809b99c4d642d066bc45cd67c26e6 /freebsd/sys/kern
parentlibbsd.txt: Use rtems_bsd_ifconfig_lo0() (diff)
downloadrtems-libbsd-de261e0404e1fe54544275fc57d5b982df4f42b4.tar.bz2
Update to FreeBSD head 2017-06-01
Git mirror commit dfb26efac4ce9101dda240e94d9ab53f80a9e131. Update #3472.
Diffstat (limited to 'freebsd/sys/kern')
-rw-r--r--freebsd/sys/kern/kern_intr.c136
-rw-r--r--freebsd/sys/kern/kern_mib.c1
-rw-r--r--freebsd/sys/kern/kern_synch.c2
-rw-r--r--freebsd/sys/kern/kern_timeout.c2
-rw-r--r--freebsd/sys/kern/subr_kobj.c12
-rw-r--r--freebsd/sys/kern/subr_prf.c7
-rw-r--r--freebsd/sys/kern/sys_socket.c29
-rw-r--r--freebsd/sys/kern/tty.c2
-rw-r--r--freebsd/sys/kern/uipc_sockbuf.c14
-rw-r--r--freebsd/sys/kern/uipc_socket.c27
10 files changed, 172 insertions, 60 deletions
diff --git a/freebsd/sys/kern/kern_intr.c b/freebsd/sys/kern/kern_intr.c
index c3d30c31..fbb5a1e9 100644
--- a/freebsd/sys/kern/kern_intr.c
+++ b/freebsd/sys/kern/kern_intr.c
@@ -314,13 +314,11 @@ intr_event_create(struct intr_event **event, void *source, int flags, int irq,
/*
* Bind an interrupt event to the specified CPU. Note that not all
* platforms support binding an interrupt to a CPU. For those
- * platforms this request will fail. For supported platforms, any
- * associated ithreads as well as the primary interrupt context will
- * be bound to the specificed CPU. Using a cpu id of NOCPU unbinds
+ * platforms this request will fail. Using a cpu id of NOCPU unbinds
* the interrupt event.
*/
-int
-intr_event_bind(struct intr_event *ie, int cpu)
+static int
+_intr_event_bind(struct intr_event *ie, int cpu, bool bindirq, bool bindithread)
{
lwpid_t id;
int error;
@@ -340,35 +338,75 @@ intr_event_bind(struct intr_event *ie, int cpu)
* If we have any ithreads try to set their mask first to verify
* permissions, etc.
*/
- mtx_lock(&ie->ie_lock);
- if (ie->ie_thread != NULL) {
- id = ie->ie_thread->it_thread->td_tid;
- mtx_unlock(&ie->ie_lock);
- error = cpuset_setithread(id, cpu);
- if (error)
- return (error);
- } else
- mtx_unlock(&ie->ie_lock);
- error = ie->ie_assign_cpu(ie->ie_source, cpu);
- if (error) {
+ if (bindithread) {
mtx_lock(&ie->ie_lock);
if (ie->ie_thread != NULL) {
- cpu = ie->ie_cpu;
id = ie->ie_thread->it_thread->td_tid;
mtx_unlock(&ie->ie_lock);
- (void)cpuset_setithread(id, cpu);
+ error = cpuset_setithread(id, cpu);
+ if (error)
+ return (error);
} else
mtx_unlock(&ie->ie_lock);
+ }
+ if (bindirq)
+ error = ie->ie_assign_cpu(ie->ie_source, cpu);
+ if (error) {
+ if (bindithread) {
+ mtx_lock(&ie->ie_lock);
+ if (ie->ie_thread != NULL) {
+ cpu = ie->ie_cpu;
+ id = ie->ie_thread->it_thread->td_tid;
+ mtx_unlock(&ie->ie_lock);
+ (void)cpuset_setithread(id, cpu);
+ } else
+ mtx_unlock(&ie->ie_lock);
+ }
return (error);
}
- mtx_lock(&ie->ie_lock);
- ie->ie_cpu = cpu;
- mtx_unlock(&ie->ie_lock);
+ if (bindirq) {
+ mtx_lock(&ie->ie_lock);
+ ie->ie_cpu = cpu;
+ mtx_unlock(&ie->ie_lock);
+ }
return (error);
}
+/*
+ * Bind an interrupt event to the specified CPU. For supported platforms, any
+ * associated ithreads as well as the primary interrupt context will be bound
+ * to the specificed CPU.
+ */
+int
+intr_event_bind(struct intr_event *ie, int cpu)
+{
+
+ return (_intr_event_bind(ie, cpu, true, true));
+}
+
+/*
+ * Bind an interrupt event to the specified CPU, but do not bind associated
+ * ithreads.
+ */
+int
+intr_event_bind_irqonly(struct intr_event *ie, int cpu)
+{
+
+ return (_intr_event_bind(ie, cpu, true, false));
+}
+
+/*
+ * Bind an interrupt event's ithread to the specified CPU.
+ */
+int
+intr_event_bind_ithread(struct intr_event *ie, int cpu)
+{
+
+ return (_intr_event_bind(ie, cpu, false, true));
+}
+
static struct intr_event *
intr_lookup(int irq)
{
@@ -385,7 +423,7 @@ intr_lookup(int irq)
}
int
-intr_setaffinity(int irq, void *m)
+intr_setaffinity(int irq, int mode, void *m)
{
struct intr_event *ie;
cpuset_t *mask;
@@ -409,26 +447,62 @@ intr_setaffinity(int irq, void *m)
ie = intr_lookup(irq);
if (ie == NULL)
return (ESRCH);
- return (intr_event_bind(ie, cpu));
+ switch (mode) {
+ case CPU_WHICH_IRQ:
+ return (intr_event_bind(ie, cpu));
+ case CPU_WHICH_INTRHANDLER:
+ return (intr_event_bind_irqonly(ie, cpu));
+ case CPU_WHICH_ITHREAD:
+ return (intr_event_bind_ithread(ie, cpu));
+ default:
+ return (EINVAL);
+ }
}
int
-intr_getaffinity(int irq, void *m)
+intr_getaffinity(int irq, int mode, void *m)
{
struct intr_event *ie;
+ struct thread *td;
+ struct proc *p;
cpuset_t *mask;
+ lwpid_t id;
+ int error;
mask = m;
ie = intr_lookup(irq);
if (ie == NULL)
return (ESRCH);
+
+ error = 0;
CPU_ZERO(mask);
- mtx_lock(&ie->ie_lock);
- if (ie->ie_cpu == NOCPU)
- CPU_COPY(cpuset_root, mask);
- else
- CPU_SET(ie->ie_cpu, mask);
- mtx_unlock(&ie->ie_lock);
+ switch (mode) {
+ case CPU_WHICH_IRQ:
+ case CPU_WHICH_INTRHANDLER:
+ mtx_lock(&ie->ie_lock);
+ if (ie->ie_cpu == NOCPU)
+ CPU_COPY(cpuset_root, mask);
+ else
+ CPU_SET(ie->ie_cpu, mask);
+ mtx_unlock(&ie->ie_lock);
+ break;
+ case CPU_WHICH_ITHREAD:
+ mtx_lock(&ie->ie_lock);
+ if (ie->ie_thread == NULL) {
+ mtx_unlock(&ie->ie_lock);
+ CPU_COPY(cpuset_root, mask);
+ } else {
+ id = ie->ie_thread->it_thread->td_tid;
+ mtx_unlock(&ie->ie_lock);
+ error = cpuset_which(CPU_WHICH_TID, id, &p, &td, NULL);
+ if (error != 0)
+ return (error);
+ CPU_COPY(&td->td_cpuset->cs_mask, mask);
+ PROC_UNLOCK(p);
+ }
+ default:
+ return (EINVAL);
+ }
return (0);
}
@@ -1225,7 +1299,7 @@ swi_sched(void *cookie, int flags)
if (!(flags & SWI_DELAY)) {
#ifndef __rtems__
- PCPU_INC(cnt.v_soft);
+ VM_CNT_INC(v_soft);
#endif /* __rtems__ */
#ifdef INTR_FILTER
error = intr_event_schedule_thread(ie, ie->ie_thread);
diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c
index 6dc8a200..1f867dd4 100644
--- a/freebsd/sys/kern/kern_mib.c
+++ b/freebsd/sys/kern/kern_mib.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sbuf.h>
#include <sys/smp.h>
#include <sys/sx.h>
+#include <sys/vmmeter.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <rtems/bsd/sys/unistd.h>
diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c
index 8b7b9afa..3dfa4164 100644
--- a/freebsd/sys/kern/kern_synch.c
+++ b/freebsd/sys/kern/kern_synch.c
@@ -460,7 +460,7 @@ mi_switch(int flags, struct thread *newtd)
td->td_incruntime += runtime;
PCPU_SET(switchtime, new_switchtime);
td->td_generation++; /* bump preempt-detect counter */
- PCPU_INC(cnt.v_swtch);
+ VM_CNT_INC(v_swtch);
PCPU_SET(switchticks, ticks);
CTR4(KTR_PROC, "mi_switch: old thread %ld (td_sched %p, pid %ld, %s)",
td->td_tid, td_get_sched(td), td->td_proc->p_pid, td->td_name);
diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c
index 5427defa..e1f6209d 100644
--- a/freebsd/sys/kern/kern_timeout.c
+++ b/freebsd/sys/kern/kern_timeout.c
@@ -1670,7 +1670,7 @@ _callout_init_lock(struct callout *c, struct lock_object *lock, int flags)
void
adjust_timeout_calltodo(struct timeval *time_change)
{
- register struct callout *p;
+ struct callout *p;
unsigned long delta_ticks;
/*
diff --git a/freebsd/sys/kern/subr_kobj.c b/freebsd/sys/kern/subr_kobj.c
index 519630fb..7436535e 100644
--- a/freebsd/sys/kern/subr_kobj.c
+++ b/freebsd/sys/kern/subr_kobj.c
@@ -215,19 +215,11 @@ kobj_lookup_method(kobj_class_t cls,
{
kobj_method_t *ce;
-#ifdef KOBJ_STATS
- /*
- * Correct for the 'hit' assumption in KOBJOPLOOKUP and record
- * a 'miss'.
- */
- kobj_lookup_hits--;
- kobj_lookup_misses++;
-#endif
-
ce = kobj_lookup_method_mi(cls, desc);
if (!ce)
ce = &desc->deflt;
- *cep = ce;
+ if (cep)
+ *cep = ce;
return ce;
}
diff --git a/freebsd/sys/kern/subr_prf.c b/freebsd/sys/kern/subr_prf.c
index 2f3efe49..39f5826d 100644
--- a/freebsd/sys/kern/subr_prf.c
+++ b/freebsd/sys/kern/subr_prf.c
@@ -1289,4 +1289,11 @@ sbuf_putbuf(struct sbuf *sb)
printf("%s", sbuf_data(sb));
}
#endif
+#else /* __rtems__ */
+void
+sbuf_putbuf(struct sbuf *sb)
+{
+
+ printf("%s", sbuf_data(sb));
+}
#endif /* __rtems__ */
diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c
index 3ffb1839..8d87c51b 100644
--- a/freebsd/sys/kern/sys_socket.c
+++ b/freebsd/sys/kern/sys_socket.c
@@ -576,18 +576,23 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
kif->kf_type = KF_TYPE_SOCKET;
so = fp->f_data;
- kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
- kif->kf_sock_type = so->so_type;
- kif->kf_sock_protocol = so->so_proto->pr_protocol;
+ kif->kf_un.kf_sock.kf_sock_domain0 =
+ so->so_proto->pr_domain->dom_family;
+ kif->kf_un.kf_sock.kf_sock_type0 = so->so_type;
+ kif->kf_un.kf_sock.kf_sock_protocol0 = so->so_proto->pr_protocol;
kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
- switch (kif->kf_sock_domain) {
+ switch (kif->kf_un.kf_sock.kf_sock_domain0) {
case AF_INET:
case AF_INET6:
- if (kif->kf_sock_protocol == IPPROTO_TCP) {
+ if (kif->kf_un.kf_sock.kf_sock_protocol0 == IPPROTO_TCP) {
if (so->so_pcb != NULL) {
inpcb = (struct inpcb *)(so->so_pcb);
kif->kf_un.kf_sock.kf_sock_inpcb =
(uintptr_t)inpcb->inp_ppcb;
+ kif->kf_un.kf_sock.kf_sock_sendq =
+ sbused(&so->so_snd);
+ kif->kf_un.kf_sock.kf_sock_recvq =
+ sbused(&so->so_rcv);
}
}
break;
@@ -601,18 +606,24 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
so->so_rcv.sb_state;
kif->kf_un.kf_sock.kf_sock_snd_sb_state =
so->so_snd.sb_state;
+ kif->kf_un.kf_sock.kf_sock_sendq =
+ sbused(&so->so_snd);
+ kif->kf_un.kf_sock.kf_sock_recvq =
+ sbused(&so->so_rcv);
}
}
break;
}
error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
- if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
- bcopy(sa, &kif->kf_sa_local, sa->sa_len);
+ if (error == 0 &&
+ sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) {
+ bcopy(sa, &kif->kf_un.kf_sock.kf_sa_local, sa->sa_len);
free(sa, M_SONAME);
}
error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
- if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
- bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
+ if (error == 0 &&
+ sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) {
+ bcopy(sa, &kif->kf_un.kf_sock.kf_sa_peer, sa->sa_len);
free(sa, M_SONAME);
}
strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
diff --git a/freebsd/sys/kern/tty.c b/freebsd/sys/kern/tty.c
index 6e4246b6..7d8400c7 100644
--- a/freebsd/sys/kern/tty.c
+++ b/freebsd/sys/kern/tty.c
@@ -1220,7 +1220,7 @@ tty_to_xtty(struct tty *tp, struct xtty *xt)
xt->xt_pgid = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
xt->xt_sid = tp->t_session ? tp->t_session->s_sid : 0;
xt->xt_flags = tp->t_flags;
- xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : NODEV;
+ xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : (uint32_t)NODEV;
}
static int
diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c
index d6c3b04b..04193c29 100644
--- a/freebsd/sys/kern/uipc_sockbuf.c
+++ b/freebsd/sys/kern/uipc_sockbuf.c
@@ -800,8 +800,20 @@ sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa,
return (0);
m->m_len = asa->sa_len;
bcopy(asa, mtod(m, caddr_t), asa->sa_len);
- if (m0)
+ if (m0) {
m_clrprotoflags(m0);
+ m_tag_delete_chain(m0, NULL);
+ /*
+ * Clear some persistent info from pkthdr.
+ * We don't use m_demote(), because some netgraph consumers
+ * expect M_PKTHDR presence.
+ */
+ m0->m_pkthdr.rcvif = NULL;
+ m0->m_pkthdr.flowid = 0;
+ m0->m_pkthdr.csum_flags = 0;
+ m0->m_pkthdr.fibnum = 0;
+ m0->m_pkthdr.rsstype = 0;
+ }
if (ctrl_last)
ctrl_last->m_next = m0; /* concatenate data to control */
else
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index d64f9ed2..c52a543c 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -1797,7 +1797,7 @@ dontblock:
* requires MT_SONAME mbufs at the head of
* each record.
*/
- if (m && pr->pr_flags & PR_ATOMIC &&
+ if (pr->pr_flags & PR_ATOMIC &&
((flags & MSG_PEEK) == 0))
(void)sbdroprecord_locked(&so->so_rcv);
SOCKBUF_UNLOCK(&so->so_rcv);
@@ -2378,13 +2378,27 @@ int
soshutdown(struct socket *so, int how)
{
struct protosw *pr = so->so_proto;
- int error;
+ int error, soerror_enotconn;
if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
return (EINVAL);
+
+ soerror_enotconn = 0;
if ((so->so_state &
- (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0)
- return (ENOTCONN);
+ (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) {
+ /*
+ * POSIX mandates us to return ENOTCONN when shutdown(2) is
+ * invoked on a datagram sockets, however historically we would
+ * actually tear socket down. This is known to be leveraged by
+ * some applications to unblock process waiting in recvXXX(2)
+ * by other process that it shares that socket with. Try to meet
+ * both backward-compatibility and POSIX requirements by forcing
+ * ENOTCONN but still asking protocol to perform pru_shutdown().
+ */
+ if (so->so_type != SOCK_DGRAM)
+ return (ENOTCONN);
+ soerror_enotconn = 1;
+ }
CURVNET_SET(so->so_vnet);
if (pr->pr_usrreqs->pru_flush != NULL)
@@ -2395,11 +2409,12 @@ soshutdown(struct socket *so, int how)
error = (*pr->pr_usrreqs->pru_shutdown)(so);
wakeup(&so->so_timeo);
CURVNET_RESTORE();
- return (error);
+ return ((error == 0 && soerror_enotconn) ? ENOTCONN : error);
}
wakeup(&so->so_timeo);
CURVNET_RESTORE();
- return (0);
+
+ return (soerror_enotconn ? ENOTCONN : 0);
}
void