sync code with last fixes and improvements from OpenBSD
This commit is contained in:
parent
691f97cc10
commit
371ae113c6
175 changed files with 2932 additions and 1512 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kern_clock.c,v 1.109 2023/07/25 18:16:19 cheloha Exp $ */
|
||||
/* $OpenBSD: kern_clock.c,v 1.111 2023/08/05 20:07:55 cheloha Exp $ */
|
||||
/* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -84,7 +84,8 @@ int profhz;
|
|||
int profprocs;
|
||||
int ticks = INT_MAX - (15 * 60 * HZ);
|
||||
|
||||
volatile unsigned long jiffies = ULONG_MAX - (10 * 60 * HZ);
|
||||
/* Don't force early wrap around, triggers bug in inteldrm */
|
||||
volatile unsigned long jiffies;
|
||||
|
||||
/*
|
||||
* Initialize clock frequencies and start both clocks running.
|
||||
|
@ -104,43 +105,14 @@ initclocks(void)
|
|||
inittimecounter();
|
||||
}
|
||||
|
||||
/*
|
||||
* hardclock does the accounting needed for ITIMER_PROF and ITIMER_VIRTUAL.
|
||||
* We don't want to send signals with psignal from hardclock because it makes
|
||||
* MULTIPROCESSOR locking very complicated. Instead, to use an idea from
|
||||
* FreeBSD, we set a flag on the thread and when it goes to return to
|
||||
* userspace it signals itself.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The real-time timer, interrupting hz times per second.
|
||||
*/
|
||||
void
|
||||
hardclock(struct clockframe *frame)
|
||||
{
|
||||
struct proc *p;
|
||||
struct cpu_info *ci = curcpu();
|
||||
|
||||
p = curproc;
|
||||
if (p && ((p->p_flag & (P_SYSTEM | P_WEXIT)) == 0)) {
|
||||
struct process *pr = p->p_p;
|
||||
|
||||
/*
|
||||
* Run current process's virtual and profile time, as needed.
|
||||
*/
|
||||
if (CLKF_USERMODE(frame) &&
|
||||
timespecisset(&pr->ps_timer[ITIMER_VIRTUAL].it_value) &&
|
||||
itimerdecr(&pr->ps_timer[ITIMER_VIRTUAL], tick_nsec) == 0) {
|
||||
atomic_setbits_int(&p->p_flag, P_ALRMPEND);
|
||||
need_proftick(p);
|
||||
}
|
||||
if (timespecisset(&pr->ps_timer[ITIMER_PROF].it_value) &&
|
||||
itimerdecr(&pr->ps_timer[ITIMER_PROF], tick_nsec) == 0) {
|
||||
atomic_setbits_int(&p->p_flag, P_PROFPEND);
|
||||
need_proftick(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (--ci->ci_schedstate.spc_rrticks <= 0)
|
||||
roundrobin(ci);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kern_clockintr.c,v 1.29 2023/07/27 17:52:53 cheloha Exp $ */
|
||||
/* $OpenBSD: kern_clockintr.c,v 1.30 2023/08/05 20:07:55 cheloha Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Dale Rahn <drahn@openbsd.org>
|
||||
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
|
||||
|
@ -196,6 +196,10 @@ clockintr_cpu_init(const struct intrclock *ic)
|
|||
* XXX Need to find a better place to do this. We can't do it in
|
||||
* sched_init_cpu() because initclocks() runs after it.
|
||||
*/
|
||||
if (spc->spc_itimer->cl_expiration == 0) {
|
||||
clockintr_stagger(spc->spc_itimer, hardclock_period,
|
||||
multiplier, MAXCPUS);
|
||||
}
|
||||
if (spc->spc_profclock->cl_expiration == 0) {
|
||||
clockintr_stagger(spc->spc_profclock, profclock_period,
|
||||
multiplier, MAXCPUS);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kern_sched.c,v 1.81 2023/07/27 17:52:53 cheloha Exp $ */
|
||||
/* $OpenBSD: kern_sched.c,v 1.84 2023/08/05 20:07:55 cheloha Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org>
|
||||
*
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include <sys/clockintr.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/task.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/smr.h>
|
||||
#include <sys/tracepoint.h>
|
||||
|
||||
|
@ -87,6 +88,14 @@ sched_init_cpu(struct cpu_info *ci)
|
|||
|
||||
spc->spc_idleproc = NULL;
|
||||
|
||||
if (spc->spc_itimer == NULL) {
|
||||
spc->spc_itimer = clockintr_establish(&ci->ci_queue,
|
||||
itimer_update);
|
||||
if (spc->spc_itimer == NULL) {
|
||||
panic("%s: clockintr_establish itimer_update",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
if (spc->spc_profclock == NULL) {
|
||||
spc->spc_profclock = clockintr_establish(&ci->ci_queue,
|
||||
profclock);
|
||||
|
@ -223,6 +232,10 @@ sched_exit(struct proc *p)
|
|||
timespecsub(&ts, &spc->spc_runtime, &ts);
|
||||
timespecadd(&p->p_rtime, &ts, &p->p_rtime);
|
||||
|
||||
if (ISSET(spc->spc_schedflags, SPCF_ITIMER)) {
|
||||
atomic_clearbits_int(&spc->spc_schedflags, SPCF_ITIMER);
|
||||
clockintr_cancel(spc->spc_itimer);
|
||||
}
|
||||
if (ISSET(spc->spc_schedflags, SPCF_PROFCLOCK)) {
|
||||
atomic_clearbits_int(&spc->spc_schedflags, SPCF_PROFCLOCK);
|
||||
clockintr_cancel(spc->spc_profclock);
|
||||
|
@ -262,7 +275,6 @@ setrunqueue(struct cpu_info *ci, struct proc *p, uint8_t prio)
|
|||
|
||||
KASSERT(ci != NULL);
|
||||
SCHED_ASSERT_LOCKED();
|
||||
KASSERT(!ISSET(p->p_flag, P_WSLEEP) || p->p_stat == SSTOP);
|
||||
|
||||
p->p_cpu = ci;
|
||||
p->p_stat = SRUN;
|
||||
|
@ -373,7 +385,6 @@ sched_choosecpu_fork(struct proc *parent, int flags)
|
|||
{
|
||||
#ifdef MULTIPROCESSOR
|
||||
struct cpu_info *choice = NULL;
|
||||
fixpt_t load, best_load = ~0;
|
||||
int run, best_run = INT_MAX;
|
||||
struct cpu_info *ci;
|
||||
struct cpuset set;
|
||||
|
@ -407,13 +418,10 @@ sched_choosecpu_fork(struct proc *parent, int flags)
|
|||
while ((ci = cpuset_first(&set)) != NULL) {
|
||||
cpuset_del(&set, ci);
|
||||
|
||||
load = ci->ci_schedstate.spc_ldavg;
|
||||
run = ci->ci_schedstate.spc_nrun;
|
||||
|
||||
if (choice == NULL || run < best_run ||
|
||||
(run == best_run &&load < best_load)) {
|
||||
if (choice == NULL || run < best_run) {
|
||||
choice = ci;
|
||||
best_load = load;
|
||||
best_run = run;
|
||||
}
|
||||
}
|
||||
|
@ -606,11 +614,6 @@ sched_proc_to_cpu_cost(struct cpu_info *ci, struct proc *p)
|
|||
if (CPU_IS_PRIMARY(ci))
|
||||
cost += sched_cost_runnable;
|
||||
|
||||
/*
|
||||
* Higher load on the destination means we don't want to go there.
|
||||
*/
|
||||
cost += ((sched_cost_load * spc->spc_ldavg) >> FSHIFT);
|
||||
|
||||
/*
|
||||
* If the proc is on this cpu already, lower the cost by how much
|
||||
* it has been running and an estimate of its footprint.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kern_time.c,v 1.163 2023/02/15 10:07:50 claudio Exp $ */
|
||||
/* $OpenBSD: kern_time.c,v 1.164 2023/08/05 20:07:55 cheloha Exp $ */
|
||||
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -35,6 +35,7 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/clockintr.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -43,6 +44,7 @@
|
|||
#include <sys/stdint.h>
|
||||
#include <sys/pledge.h>
|
||||
#include <sys/task.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeout.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
|
@ -52,6 +54,7 @@
|
|||
#include <dev/clock_subr.h>
|
||||
|
||||
int itimerfix(struct itimerval *);
|
||||
void process_reset_itimer_flag(struct process *);
|
||||
|
||||
/*
|
||||
* Time of day and interval timer support.
|
||||
|
@ -551,6 +554,10 @@ setitimer(int which, const struct itimerval *itv, struct itimerval *olditv)
|
|||
timeout_del(&pr->ps_realit_to);
|
||||
}
|
||||
*itimer = its;
|
||||
if (which == ITIMER_VIRTUAL || which == ITIMER_PROF) {
|
||||
process_reset_itimer_flag(pr);
|
||||
need_resched(curcpu());
|
||||
}
|
||||
}
|
||||
|
||||
if (which == ITIMER_REAL)
|
||||
|
@ -729,49 +736,72 @@ itimerfix(struct itimerval *itv)
|
|||
}
|
||||
|
||||
/*
|
||||
* Decrement an interval timer by the given number of nanoseconds.
|
||||
* Decrement an interval timer by the given duration.
|
||||
* If the timer expires and it is periodic then reload it. When reloading
|
||||
* the timer we subtract any overrun from the next period so that the timer
|
||||
* does not drift.
|
||||
*/
|
||||
int
|
||||
itimerdecr(struct itimerspec *itp, long nsec)
|
||||
itimerdecr(struct itimerspec *itp, const struct timespec *decrement)
|
||||
{
|
||||
struct timespec decrement;
|
||||
|
||||
NSEC_TO_TIMESPEC(nsec, &decrement);
|
||||
|
||||
mtx_enter(&itimer_mtx);
|
||||
|
||||
/*
|
||||
* Double-check that the timer is enabled. A different thread
|
||||
* in setitimer(2) may have disabled it while we were entering
|
||||
* the mutex.
|
||||
*/
|
||||
if (!timespecisset(&itp->it_value)) {
|
||||
mtx_leave(&itimer_mtx);
|
||||
timespecsub(&itp->it_value, decrement, &itp->it_value);
|
||||
if (itp->it_value.tv_sec >= 0 && timespecisset(&itp->it_value))
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The timer is enabled. Update and reload it as needed.
|
||||
*/
|
||||
timespecsub(&itp->it_value, &decrement, &itp->it_value);
|
||||
if (itp->it_value.tv_sec >= 0 && timespecisset(&itp->it_value)) {
|
||||
mtx_leave(&itimer_mtx);
|
||||
return (1);
|
||||
}
|
||||
if (!timespecisset(&itp->it_interval)) {
|
||||
timespecclear(&itp->it_value);
|
||||
mtx_leave(&itimer_mtx);
|
||||
return (0);
|
||||
}
|
||||
while (itp->it_value.tv_sec < 0 || !timespecisset(&itp->it_value))
|
||||
timespecadd(&itp->it_value, &itp->it_interval, &itp->it_value);
|
||||
mtx_leave(&itimer_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
itimer_update(struct clockintr *cl, void *cf)
|
||||
{
|
||||
struct timespec elapsed;
|
||||
uint64_t nsecs;
|
||||
struct clockframe *frame = cf;
|
||||
struct proc *p = curproc;
|
||||
struct process *pr;
|
||||
|
||||
if (p == NULL || ISSET(p->p_flag, P_SYSTEM | P_WEXIT))
|
||||
return;
|
||||
|
||||
pr = p->p_p;
|
||||
if (!ISSET(pr->ps_flags, PS_ITIMER))
|
||||
return;
|
||||
|
||||
nsecs = clockintr_advance(cl, hardclock_period) * hardclock_period;
|
||||
NSEC_TO_TIMESPEC(nsecs, &elapsed);
|
||||
|
||||
mtx_enter(&itimer_mtx);
|
||||
if (CLKF_USERMODE(frame) &&
|
||||
timespecisset(&pr->ps_timer[ITIMER_VIRTUAL].it_value) &&
|
||||
itimerdecr(&pr->ps_timer[ITIMER_VIRTUAL], &elapsed) == 0) {
|
||||
process_reset_itimer_flag(pr);
|
||||
atomic_setbits_int(&p->p_flag, P_ALRMPEND);
|
||||
need_proftick(p);
|
||||
}
|
||||
if (timespecisset(&pr->ps_timer[ITIMER_PROF].it_value) &&
|
||||
itimerdecr(&pr->ps_timer[ITIMER_PROF], &elapsed) == 0) {
|
||||
process_reset_itimer_flag(pr);
|
||||
atomic_setbits_int(&p->p_flag, P_PROFPEND);
|
||||
need_proftick(p);
|
||||
}
|
||||
mtx_leave(&itimer_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
process_reset_itimer_flag(struct process *ps)
|
||||
{
|
||||
if (timespecisset(&ps->ps_timer[ITIMER_VIRTUAL].it_value) ||
|
||||
timespecisset(&ps->ps_timer[ITIMER_PROF].it_value))
|
||||
atomic_setbits_int(&ps->ps_flags, PS_ITIMER);
|
||||
else
|
||||
atomic_clearbits_int(&ps->ps_flags, PS_ITIMER);
|
||||
}
|
||||
|
||||
struct mutex ratecheck_mtx = MUTEX_INITIALIZER(IPL_HIGH);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sched_bsd.c,v 1.78 2023/07/25 18:16:19 cheloha Exp $ */
|
||||
/* $OpenBSD: sched_bsd.c,v 1.79 2023/08/05 20:07:55 cheloha Exp $ */
|
||||
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -350,7 +350,11 @@ mi_switch(void)
|
|||
/* add the time counts for this thread to the process's total */
|
||||
tuagg_unlocked(pr, p);
|
||||
|
||||
/* Stop the profclock if it's running. */
|
||||
/* Stop any optional clock interrupts. */
|
||||
if (ISSET(spc->spc_schedflags, SPCF_ITIMER)) {
|
||||
atomic_clearbits_int(&spc->spc_schedflags, SPCF_ITIMER);
|
||||
clockintr_cancel(spc->spc_itimer);
|
||||
}
|
||||
if (ISSET(spc->spc_schedflags, SPCF_PROFCLOCK)) {
|
||||
atomic_clearbits_int(&spc->spc_schedflags, SPCF_PROFCLOCK);
|
||||
clockintr_cancel(spc->spc_profclock);
|
||||
|
@ -400,7 +404,13 @@ mi_switch(void)
|
|||
*/
|
||||
KASSERT(p->p_cpu == curcpu());
|
||||
|
||||
/* Start the profclock if profil(2) is enabled. */
|
||||
/* Start any optional clock interrupts needed by the thread. */
|
||||
if (ISSET(p->p_p->ps_flags, PS_ITIMER)) {
|
||||
atomic_setbits_int(&p->p_cpu->ci_schedstate.spc_schedflags,
|
||||
SPCF_ITIMER);
|
||||
clockintr_advance(p->p_cpu->ci_schedstate.spc_itimer,
|
||||
hardclock_period);
|
||||
}
|
||||
if (ISSET(p->p_p->ps_flags, PS_PROFIL)) {
|
||||
atomic_setbits_int(&p->p_cpu->ci_schedstate.spc_schedflags,
|
||||
SPCF_PROFCLOCK);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: uipc_socket.c,v 1.306 2023/07/22 14:30:39 mvs Exp $ */
|
||||
/* $OpenBSD: uipc_socket.c,v 1.307 2023/08/03 09:49:08 mvs Exp $ */
|
||||
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -1789,12 +1789,12 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
{
|
||||
int error = 0;
|
||||
|
||||
soassertlocked(so);
|
||||
|
||||
if (level != SOL_SOCKET) {
|
||||
if (so->so_proto->pr_ctloutput) {
|
||||
solock(so);
|
||||
error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
|
||||
level, optname, m);
|
||||
sounlock(so);
|
||||
return (error);
|
||||
}
|
||||
error = ENOPROTOOPT;
|
||||
|
@ -1813,9 +1813,16 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
mtod(m, struct linger *)->l_linger < 0 ||
|
||||
mtod(m, struct linger *)->l_linger > SHRT_MAX)
|
||||
return (EINVAL);
|
||||
so->so_linger = mtod(m, struct linger *)->l_linger;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
solock(so);
|
||||
so->so_linger = mtod(m, struct linger *)->l_linger;
|
||||
if (*mtod(m, int *))
|
||||
so->so_options |= optname;
|
||||
else
|
||||
so->so_options &= ~optname;
|
||||
sounlock(so);
|
||||
|
||||
break;
|
||||
case SO_BINDANY:
|
||||
case SO_DEBUG:
|
||||
case SO_KEEPALIVE:
|
||||
|
@ -1828,12 +1835,15 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
case SO_ZEROIZE:
|
||||
if (m == NULL || m->m_len < sizeof (int))
|
||||
return (EINVAL);
|
||||
|
||||
solock(so);
|
||||
if (*mtod(m, int *))
|
||||
so->so_options |= optname;
|
||||
else
|
||||
so->so_options &= ~optname;
|
||||
break;
|
||||
sounlock(so);
|
||||
|
||||
break;
|
||||
case SO_DONTROUTE:
|
||||
if (m == NULL || m->m_len < sizeof (int))
|
||||
return (EINVAL);
|
||||
|
@ -1853,23 +1863,32 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
cnt = *mtod(m, int *);
|
||||
if ((long)cnt <= 0)
|
||||
cnt = 1;
|
||||
switch (optname) {
|
||||
|
||||
solock(so);
|
||||
switch (optname) {
|
||||
case SO_SNDBUF:
|
||||
if (so->so_snd.sb_state & SS_CANTSENDMORE)
|
||||
return (EINVAL);
|
||||
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (sbcheckreserve(cnt, so->so_snd.sb_wat) ||
|
||||
sbreserve(so, &so->so_snd, cnt))
|
||||
return (ENOBUFS);
|
||||
sbreserve(so, &so->so_snd, cnt)) {
|
||||
error = ENOBUFS;
|
||||
break;
|
||||
}
|
||||
so->so_snd.sb_wat = cnt;
|
||||
break;
|
||||
|
||||
case SO_RCVBUF:
|
||||
if (so->so_rcv.sb_state & SS_CANTRCVMORE)
|
||||
return (EINVAL);
|
||||
if (so->so_rcv.sb_state & SS_CANTRCVMORE) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (sbcheckreserve(cnt, so->so_rcv.sb_wat) ||
|
||||
sbreserve(so, &so->so_rcv, cnt))
|
||||
return (ENOBUFS);
|
||||
sbreserve(so, &so->so_rcv, cnt)) {
|
||||
error = ENOBUFS;
|
||||
break;
|
||||
}
|
||||
so->so_rcv.sb_wat = cnt;
|
||||
break;
|
||||
|
||||
|
@ -1884,6 +1903,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
so->so_rcv.sb_hiwat : cnt;
|
||||
break;
|
||||
}
|
||||
sounlock(so);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1903,8 +1923,9 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
return (EDOM);
|
||||
if (nsecs == 0)
|
||||
nsecs = INFSLP;
|
||||
switch (optname) {
|
||||
|
||||
solock(so);
|
||||
switch (optname) {
|
||||
case SO_SNDTIMEO:
|
||||
so->so_snd.sb_timeo_nsecs = nsecs;
|
||||
break;
|
||||
|
@ -1912,6 +1933,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
so->so_rcv.sb_timeo_nsecs = nsecs;
|
||||
break;
|
||||
}
|
||||
sounlock(so);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1923,19 +1945,20 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
so->so_proto->pr_domain;
|
||||
|
||||
level = dom->dom_protosw->pr_protocol;
|
||||
solock(so);
|
||||
error = (*so->so_proto->pr_ctloutput)
|
||||
(PRCO_SETOPT, so, level, optname, m);
|
||||
return (error);
|
||||
}
|
||||
error = ENOPROTOOPT;
|
||||
sounlock(so);
|
||||
} else
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
|
||||
#ifdef SOCKET_SPLICE
|
||||
case SO_SPLICE:
|
||||
solock(so);
|
||||
if (m == NULL) {
|
||||
error = sosplice(so, -1, 0, NULL);
|
||||
} else if (m->m_len < sizeof(int)) {
|
||||
return (EINVAL);
|
||||
error = EINVAL;
|
||||
} else if (m->m_len < sizeof(struct splice)) {
|
||||
error = sosplice(so, *mtod(m, int *), 0, NULL);
|
||||
} else {
|
||||
|
@ -1944,6 +1967,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
mtod(m, struct splice *)->sp_max,
|
||||
&mtod(m, struct splice *)->sp_idle);
|
||||
}
|
||||
sounlock(so);
|
||||
break;
|
||||
#endif /* SOCKET_SPLICE */
|
||||
|
||||
|
@ -1951,10 +1975,6 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
if (error == 0 && so->so_proto->pr_ctloutput) {
|
||||
(*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
|
||||
level, optname, m);
|
||||
}
|
||||
}
|
||||
|
||||
return (error);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: uipc_syscalls.c,v 1.212 2023/02/10 14:34:17 visa Exp $ */
|
||||
/* $OpenBSD: uipc_syscalls.c,v 1.213 2023/08/03 09:49:08 mvs Exp $ */
|
||||
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -1232,9 +1232,7 @@ sys_setsockopt(struct proc *p, void *v, register_t *retval)
|
|||
m->m_len = SCARG(uap, valsize);
|
||||
}
|
||||
so = fp->f_data;
|
||||
solock(so);
|
||||
error = sosetopt(so, SCARG(uap, level), SCARG(uap, name), m);
|
||||
sounlock(so);
|
||||
bad:
|
||||
m_freem(m);
|
||||
FRELE(fp, p);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue