sync with OpenBSD -current

This commit is contained in:
purplerain 2024-05-03 17:35:01 +00:00
parent 7768d1f254
commit c9341f2e4a
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
65 changed files with 2158 additions and 1228 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: subr_hibernate.c,v 1.138 2022/09/03 18:17:15 mlarkin Exp $ */
/* $OpenBSD: subr_hibernate.c,v 1.139 2024/04/30 17:12:19 krw Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@ -1134,7 +1134,7 @@ hibernate_resume(void)
if (hibernate_block_io(&hib,
hib.sig_offset,
DEV_BSIZE, (vaddr_t)&disk_hib, 0)) {
DPRINTF("error in hibernate read");
DPRINTF("error in hibernate read\n");
splx(s);
return;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: subr_witness.c,v 1.50 2023/05/30 08:30:01 jsg Exp $ */
/* $OpenBSD: subr_witness.c,v 1.52 2024/05/03 13:47:31 visa Exp $ */
/*-
* Copyright (c) 2008 Isilon Systems, Inc.
@ -369,6 +369,13 @@ static struct witness_lock_order_data *witness_lock_order_get(
struct witness *child);
static void witness_list_lock(struct lock_instance *instance,
int (*prnt)(const char *fmt, ...));
static void witness_print_cycle(int (*prnt)(const char *fmt, ...),
struct witness *parent, struct witness *child);
static void witness_print_cycle_edge(int (*prnt)(const char *fmt, ...),
struct witness *parent, struct witness *child,
int step, int last);
static int witness_search(struct witness *w, struct witness *target,
struct witness **path, int depth, int *remaining);
static void witness_setflag(struct lock_object *lock, int flag, int set);
/*
@ -652,8 +659,9 @@ witness_ddb_display_descendants(int(*prnt)(const char *fmt, ...),
for (i = 0; i < indent; i++)
prnt(" ");
prnt("%s (type: %s, depth: %d)",
w->w_type->lt_name, w->w_class->lc_name, w->w_ddb_level);
prnt("%s (%s) (type: %s, depth: %d)",
w->w_subtype, w->w_type->lt_name,
w->w_class->lc_name, w->w_ddb_level);
if (w->w_displayed) {
prnt(" -- (already displayed)\n");
return;
@ -719,7 +727,8 @@ witness_ddb_display(int(*prnt)(const char *fmt, ...))
SLIST_FOREACH(w, &w_all, w_list) {
if (w->w_acquired)
continue;
prnt("%s (type: %s, depth: %d)\n", w->w_type->lt_name,
prnt("%s (%s) (type: %s, depth: %d)\n",
w->w_subtype, w->w_type->lt_name,
w->w_class->lc_name, w->w_ddb_level);
}
}
@ -1066,47 +1075,8 @@ witness_checkorder(struct lock_object *lock, int flags,
printf(" 3rd %p %s (%s)\n", lock,
lock->lo_name, w->w_type->lt_name);
}
if (witness_watch > 1) {
struct witness_lock_order_data *wlod1, *wlod2;
mtx_enter(&w_mtx);
wlod1 = witness_lock_order_get(w, w1);
wlod2 = witness_lock_order_get(w1, w);
mtx_leave(&w_mtx);
/*
* It is safe to access saved stack traces,
* w_type, and w_class without the lock.
* Once written, they never change.
*/
if (wlod1 != NULL) {
printf("lock order \"%s\"(%s) -> "
"\"%s\"(%s) first seen at:\n",
w->w_type->lt_name,
w->w_class->lc_name,
w1->w_type->lt_name,
w1->w_class->lc_name);
stacktrace_print(
&wlod1->wlod_stack, printf);
} else {
printf("lock order data "
"w2 -> w1 missing\n");
}
if (wlod2 != NULL) {
printf("lock order \"%s\"(%s) -> "
"\"%s\"(%s) first seen at:\n",
w1->w_type->lt_name,
w1->w_class->lc_name,
w->w_type->lt_name,
w->w_class->lc_name);
stacktrace_print(
&wlod2->wlod_stack, printf);
} else {
printf("lock order data "
"w1 -> w2 missing\n");
}
}
if (witness_watch > 1)
witness_print_cycle(printf, w1, w);
witness_debugger(0);
goto out_splx;
}
@ -1875,6 +1845,92 @@ witness_list_lock(struct lock_instance *instance,
stacktrace_print(&instance->li_stack->ls_stack, prnt);
}
static int
witness_search(struct witness *w, struct witness *target,
struct witness **path, int depth, int *remaining)
{
int i, any_remaining;
if (depth == 0) {
*remaining = 1;
return (w == target);
}
any_remaining = 0;
for (i = 1; i <= w_max_used_index; i++) {
if (w_rmatrix[w->w_index][i] & WITNESS_PARENT) {
if (witness_search(&w_data[i], target, path, depth - 1,
remaining)) {
path[depth - 1] = &w_data[i];
*remaining = 1;
return 1;
}
if (remaining)
any_remaining = 1;
}
}
*remaining = any_remaining;
return 0;
}
static void
witness_print_cycle_edge(int(*prnt)(const char *fmt, ...),
struct witness *parent, struct witness *child, int step, int last)
{
struct witness_lock_order_data *wlod;
int next;
if (last)
next = 1;
else
next = step + 1;
prnt("lock order [%d] %s (%s) -> [%d] %s (%s)\n",
step, parent->w_subtype, parent->w_type->lt_name,
next, child->w_subtype, child->w_type->lt_name);
if (witness_watch > 1) {
mtx_enter(&w_mtx);
wlod = witness_lock_order_get(parent, child);
mtx_leave(&w_mtx);
if (wlod != NULL)
stacktrace_print(&wlod->wlod_stack, printf);
else
prnt("lock order data %p -> %p is missing\n",
parent->w_type->lt_name, child->w_type->lt_name);
}
}
static void
witness_print_cycle(int(*prnt)(const char *fmt, ...),
struct witness *parent, struct witness *child)
{
struct witness *path[4];
struct witness *w;
int depth, remaining;
int step = 0;
/*
* Use depth-limited search to find the shortest path
* from child to parent.
*/
for (depth = 1; depth < nitems(path); depth++) {
if (witness_search(child, parent, path, depth, &remaining))
goto found;
if (!remaining)
break;
}
prnt("witness: incomplete path, depth %d\n", depth);
return;
found:
witness_print_cycle_edge(prnt, parent, child, ++step, 0);
for (w = child; depth > 0; depth--) {
witness_print_cycle_edge(prnt, w, path[depth - 1], ++step,
depth == 1);
w = path[depth - 1];
}
}
#ifdef DDB
static int
witness_thread_has_locks(struct proc *p)
@ -2123,9 +2179,6 @@ db_witness_list_all(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
void
witness_print_badstacks(void)
{
static struct witness tmp_w1, tmp_w2;
static struct witness_lock_order_data tmp_data1, tmp_data2;
struct witness_lock_order_data *data1, *data2;
struct witness *w1, *w2;
int error, generation, i, j;
@ -2139,11 +2192,6 @@ witness_print_badstacks(void)
}
error = 0;
memset(&tmp_w1, 0, sizeof(tmp_w1));
memset(&tmp_w2, 0, sizeof(tmp_w2));
memset(&tmp_data1, 0, sizeof(tmp_data1));
memset(&tmp_data2, 0, sizeof(tmp_data2));
restart:
mtx_enter(&w_mtx);
generation = w_generation;
@ -2165,12 +2213,9 @@ restart:
mtx_leave(&w_mtx);
continue;
}
/* Copy w1 locally so we can release the spin lock. */
tmp_w1 = *w1;
mtx_leave(&w_mtx);
if (tmp_w1.w_reversed == 0)
if (w1->w_reversed == 0)
continue;
for (j = 1; j < w_max_used_index; j++) {
if ((w_rmatrix[i][j] & WITNESS_REVERSAL) == 0 || i > j)
@ -2187,47 +2232,13 @@ restart:
}
w2 = &w_data[j];
data1 = witness_lock_order_get(w1, w2);
data2 = witness_lock_order_get(w2, w1);
/*
* Copy information locally so we can release the
* spin lock.
*/
tmp_w2 = *w2;
if (data1)
tmp_data1.wlod_stack = data1->wlod_stack;
if (data2 && data2 != data1)
tmp_data2.wlod_stack = data2->wlod_stack;
mtx_leave(&w_mtx);
db_printf("\nLock order reversal between \"%s\"(%s) "
"and \"%s\"(%s)!\n",
tmp_w1.w_type->lt_name, tmp_w1.w_class->lc_name,
tmp_w2.w_type->lt_name, tmp_w2.w_class->lc_name);
if (data1) {
db_printf("Lock order \"%s\"(%s) -> \"%s\"(%s) "
"first seen at:\n",
tmp_w1.w_type->lt_name,
tmp_w1.w_class->lc_name,
tmp_w2.w_type->lt_name,
tmp_w2.w_class->lc_name);
stacktrace_print(&tmp_data1.wlod_stack,
db_printf);
db_printf("\n");
}
if (data2 && data2 != data1) {
db_printf("Lock order \"%s\"(%s) -> \"%s\"(%s) "
"first seen at:\n",
tmp_w2.w_type->lt_name,
tmp_w2.w_class->lc_name,
tmp_w1.w_type->lt_name,
tmp_w1.w_class->lc_name);
stacktrace_print(&tmp_data2.wlod_stack,
db_printf);
db_printf("\n");
}
w1->w_type->lt_name, w1->w_class->lc_name,
w2->w_type->lt_name, w2->w_class->lc_name);
witness_print_cycle(db_printf, w1, w2);
}
}
mtx_enter(&w_mtx);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sys_socket.c,v 1.64 2024/04/11 08:33:37 mvs Exp $ */
/* $OpenBSD: sys_socket.c,v 1.65 2024/04/30 17:59:15 mvs Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
@ -92,6 +92,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
case FIOASYNC:
solock(so);
mtx_enter(&so->so_rcv.sb_mtx);
mtx_enter(&so->so_snd.sb_mtx);
if (*(int *)data) {
so->so_rcv.sb_flags |= SB_ASYNC;
so->so_snd.sb_flags |= SB_ASYNC;
@ -99,6 +100,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
so->so_rcv.sb_flags &= ~SB_ASYNC;
so->so_snd.sb_flags &= ~SB_ASYNC;
}
mtx_leave(&so->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
sounlock(so);
break;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket.c,v 1.330 2024/04/15 21:31:29 mvs Exp $ */
/* $OpenBSD: uipc_socket.c,v 1.332 2024/05/02 11:55:31 mvs Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@ -146,8 +146,8 @@ soalloc(const struct protosw *prp, int wait)
refcnt_init(&so->so_refcnt);
rw_init(&so->so_rcv.sb_lock, "sbufrcv");
rw_init(&so->so_snd.sb_lock, "sbufsnd");
mtx_init(&so->so_rcv.sb_mtx, IPL_MPFLOOR);
mtx_init(&so->so_snd.sb_mtx, IPL_MPFLOOR);
mtx_init_flags(&so->so_rcv.sb_mtx, IPL_MPFLOOR, "sbrcv", 0);
mtx_init_flags(&so->so_snd.sb_mtx, IPL_MPFLOOR, "sbsnd", 0);
klist_init_mutex(&so->so_rcv.sb_klist, &so->so_rcv.sb_mtx);
klist_init_mutex(&so->so_snd.sb_klist, &so->so_snd.sb_mtx);
sigio_init(&so->so_sigio);
@ -158,8 +158,10 @@ soalloc(const struct protosw *prp, int wait)
case AF_INET:
case AF_INET6:
switch (prp->pr_type) {
case SOCK_DGRAM:
case SOCK_RAW:
so->so_snd.sb_flags |= SB_MTXLOCK | SB_OWNLOCK;
/* FALLTHROUGH */
case SOCK_DGRAM:
so->so_rcv.sb_flags |= SB_MTXLOCK | SB_OWNLOCK;
break;
}
@ -346,7 +348,10 @@ sofree(struct socket *so, int keep_lock)
sounsplice(so, so->so_sp->ssp_socket, freeing);
}
#endif /* SOCKET_SPLICE */
mtx_enter(&so->so_snd.sb_mtx);
sbrelease(so, &so->so_snd);
mtx_leave(&so->so_snd.sb_mtx);
/*
* Regardless on '_locked' postfix, must release solock() before
@ -569,6 +574,7 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
size_t resid;
int error;
int atomic = sosendallatonce(so) || top;
int dosolock = ((so->so_snd.sb_flags & SB_OWNLOCK) == 0);
if (uio)
resid = uio->uio_resid;
@ -601,16 +607,17 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
#define snderr(errno) { error = errno; goto release; }
solock_shared(so);
if (dosolock)
solock_shared(so);
restart:
if ((error = sblock(so, &so->so_snd, SBLOCKWAIT(flags))) != 0)
goto out;
sb_mtx_lock(&so->so_snd);
so->so_snd.sb_state |= SS_ISSENDING;
do {
if (so->so_snd.sb_state & SS_CANTSENDMORE)
snderr(EPIPE);
if (so->so_error) {
error = so->so_error;
if ((error = READ_ONCE(so->so_error))) {
so->so_error = 0;
snderr(error);
}
@ -638,8 +645,14 @@ restart:
if (flags & MSG_DONTWAIT)
snderr(EWOULDBLOCK);
sbunlock(so, &so->so_snd);
error = sbwait(so, &so->so_snd);
if (so->so_snd.sb_flags & SB_MTXLOCK)
error = sbwait_locked(so, &so->so_snd);
else
error = sbwait(so, &so->so_snd);
so->so_snd.sb_state &= ~SS_ISSENDING;
sb_mtx_unlock(&so->so_snd);
if (error)
goto out;
goto restart;
@ -654,9 +667,13 @@ restart:
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
} else {
sounlock_shared(so);
sb_mtx_unlock(&so->so_snd);
if (dosolock)
sounlock_shared(so);
error = m_getuio(&top, atomic, space, uio);
solock_shared(so);
if (dosolock)
solock_shared(so);
sb_mtx_lock(&so->so_snd);
if (error)
goto release;
space -= top->m_pkthdr.len;
@ -668,10 +685,16 @@ restart:
so->so_snd.sb_state &= ~SS_ISSENDING;
if (top && so->so_options & SO_ZEROIZE)
top->m_flags |= M_ZEROIZE;
sb_mtx_unlock(&so->so_snd);
if (!dosolock)
solock_shared(so);
if (flags & MSG_OOB)
error = pru_sendoob(so, top, addr, control);
else
error = pru_send(so, top, addr, control);
if (!dosolock)
sounlock_shared(so);
sb_mtx_lock(&so->so_snd);
clen = 0;
control = NULL;
top = NULL;
@ -682,9 +705,11 @@ restart:
release:
so->so_snd.sb_state &= ~SS_ISSENDING;
sb_mtx_unlock(&so->so_snd);
sbunlock(so, &so->so_snd);
out:
sounlock_shared(so);
if (dosolock)
sounlock_shared(so);
m_freem(top);
m_freem(control);
return (error);
@ -1401,7 +1426,7 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
if (sosp->so_sp == NULL)
sosp->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO);
if ((error = sblock(so, &sosp->so_snd, SBL_WAIT)) != 0) {
if ((error = sblock(sosp, &sosp->so_snd, SBL_WAIT)) != 0) {
goto out;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket2.c,v 1.150 2024/04/25 17:32:53 bluhm Exp $ */
/* $OpenBSD: uipc_socket2.c,v 1.152 2024/05/02 21:26:52 mvs Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
@ -142,10 +142,15 @@ soisdisconnecting(struct socket *so)
soassertlocked(so);
so->so_state &= ~SS_ISCONNECTING;
so->so_state |= SS_ISDISCONNECTING;
mtx_enter(&so->so_rcv.sb_mtx);
so->so_rcv.sb_state |= SS_CANTRCVMORE;
mtx_leave(&so->so_rcv.sb_mtx);
mtx_enter(&so->so_snd.sb_mtx);
so->so_snd.sb_state |= SS_CANTSENDMORE;
mtx_leave(&so->so_snd.sb_mtx);
wakeup(&so->so_timeo);
sowwakeup(so);
sorwakeup(so);
@ -157,10 +162,15 @@ soisdisconnected(struct socket *so)
soassertlocked(so);
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= SS_ISDISCONNECTED;
mtx_enter(&so->so_rcv.sb_mtx);
so->so_rcv.sb_state |= SS_CANTRCVMORE;
mtx_leave(&so->so_rcv.sb_mtx);
mtx_enter(&so->so_snd.sb_mtx);
so->so_snd.sb_state |= SS_CANTSENDMORE;
mtx_leave(&so->so_snd.sb_mtx);
wakeup(&so->so_timeo);
sowwakeup(so);
sorwakeup(so);
@ -315,14 +325,16 @@ void
socantsendmore(struct socket *so)
{
soassertlocked(so);
mtx_enter(&so->so_snd.sb_mtx);
so->so_snd.sb_state |= SS_CANTSENDMORE;
mtx_leave(&so->so_snd.sb_mtx);
sowwakeup(so);
}
void
socantrcvmore(struct socket *so)
{
if ((so->so_rcv.sb_flags & SB_OWNLOCK) == 0)
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked(so);
mtx_enter(&so->so_rcv.sb_mtx);
@ -666,6 +678,8 @@ soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
{
soassertlocked(so);
mtx_enter(&so->so_rcv.sb_mtx);
mtx_enter(&so->so_snd.sb_mtx);
if (sbreserve(so, &so->so_snd, sndcc))
goto bad;
so->so_snd.sb_wat = sndcc;
@ -673,21 +687,20 @@ soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
so->so_snd.sb_lowat = MCLBYTES;
if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
mtx_enter(&so->so_rcv.sb_mtx);
if (sbreserve(so, &so->so_rcv, rcvcc)) {
mtx_leave(&so->so_rcv.sb_mtx);
if (sbreserve(so, &so->so_rcv, rcvcc))
goto bad2;
}
so->so_rcv.sb_wat = rcvcc;
if (so->so_rcv.sb_lowat == 0)
so->so_rcv.sb_lowat = 1;
mtx_leave(&so->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
return (0);
bad2:
sbrelease(so, &so->so_snd);
bad:
mtx_leave(&so->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
return (ENOBUFS);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_usrreq.c,v 1.204 2024/04/10 12:04:41 mvs Exp $ */
/* $OpenBSD: uipc_usrreq.c,v 1.205 2024/05/02 17:10:55 mvs Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@ -459,9 +459,9 @@ uipc_shutdown(struct socket *so)
socantsendmore(so);
if ((so2 = unp_solock_peer(unp->unp_socket))){
if (unp->unp_conn != NULL) {
so2 = unp->unp_conn->unp_socket;
socantrcvmore(so2);
sounlock(so2);
}
return (0);