sync with OpenBSD -current
This commit is contained in:
parent
9d8ac7f158
commit
382ecd9441
108 changed files with 9152 additions and 5077 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: nvme.c,v 1.107 2023/12/20 13:37:25 krw Exp $ */
|
||||
/* $OpenBSD: nvme.c,v 1.109 2024/04/15 14:25:10 krw Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
|
||||
|
@ -60,7 +60,7 @@ void * nvme_ccb_get(void *);
|
|||
void nvme_ccb_put(void *, void *);
|
||||
|
||||
int nvme_poll(struct nvme_softc *, struct nvme_queue *, struct nvme_ccb *,
|
||||
void (*)(struct nvme_softc *, struct nvme_ccb *, void *));
|
||||
void (*)(struct nvme_softc *, struct nvme_ccb *, void *), u_int32_t);
|
||||
void nvme_poll_fill(struct nvme_softc *, struct nvme_ccb *, void *);
|
||||
void nvme_poll_done(struct nvme_softc *, struct nvme_ccb *,
|
||||
struct nvme_cqe *);
|
||||
|
@ -134,6 +134,10 @@ static const struct nvme_ops nvme_ops = {
|
|||
.op_cq_done = nvme_op_cq_done,
|
||||
};
|
||||
|
||||
#define NVME_TIMO_QOP 5000 /* ms to create/delete queue */
|
||||
#define NVME_TIMO_IDENT 10000 /* ms to probe/identify */
|
||||
#define NVME_TIMO_DELAYNS 10 /* ns to delay() in poll loop */
|
||||
|
||||
/*
|
||||
* Some controllers, at least Apple NVMe, always require split
|
||||
* transfers, so don't use bus_space_{read,write}_8() on LP64.
|
||||
|
@ -197,28 +201,46 @@ nvme_dumpregs(struct nvme_softc *sc)
|
|||
int
|
||||
nvme_ready(struct nvme_softc *sc, u_int32_t rdy)
|
||||
{
|
||||
u_int i = 0;
|
||||
u_int32_t csts;
|
||||
u_int i;
|
||||
|
||||
while ((nvme_read4(sc, NVME_CSTS) & NVME_CSTS_RDY) != rdy) {
|
||||
if (i++ > sc->sc_rdy_to)
|
||||
return (1);
|
||||
for (i = 0; i <= sc->sc_rdy_to; i++) {
|
||||
csts = nvme_read4(sc, NVME_CSTS);
|
||||
/* enable fails if fatal error, disable succeeds. */
|
||||
if (csts == 0xffffffff || ISSET(csts, NVME_CSTS_CFS))
|
||||
return (rdy == NVME_CSTS_RDY);
|
||||
|
||||
if ((csts & NVME_CSTS_RDY) == rdy)
|
||||
return (0);
|
||||
|
||||
delay(1000);
|
||||
nvme_barrier(sc, NVME_CSTS, 4, BUS_SPACE_BARRIER_READ);
|
||||
}
|
||||
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
nvme_enable(struct nvme_softc *sc)
|
||||
{
|
||||
u_int32_t cc;
|
||||
u_int32_t cc, csts;
|
||||
|
||||
cc = nvme_read4(sc, NVME_CC);
|
||||
if (ISSET(cc, NVME_CC_EN))
|
||||
if (cc != 0xffffffff && ISSET(cc, NVME_CC_EN))
|
||||
return (nvme_ready(sc, NVME_CSTS_RDY));
|
||||
|
||||
csts = nvme_read4(sc, NVME_CSTS);
|
||||
if (csts != 0xffffffff && ISSET(csts, NVME_CSTS_RDY)) {
|
||||
/*
|
||||
* Ensure CSTS.RDY is 0.
|
||||
*
|
||||
* Transitioning CC.EN from 0 to 1 when CSTS.RDY is 1
|
||||
* "has undefined results" says NVMe.
|
||||
*/
|
||||
if (nvme_ready(sc, 0))
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (sc->sc_ops->op_enable != NULL)
|
||||
sc->sc_ops->op_enable(sc);
|
||||
|
||||
|
@ -254,10 +276,18 @@ nvme_disable(struct nvme_softc *sc)
|
|||
u_int32_t cc, csts;
|
||||
|
||||
cc = nvme_read4(sc, NVME_CC);
|
||||
if (ISSET(cc, NVME_CC_EN)) {
|
||||
csts = nvme_read4(sc, NVME_CSTS);
|
||||
if (!ISSET(csts, NVME_CSTS_CFS) &&
|
||||
nvme_ready(sc, NVME_CSTS_RDY) != 0)
|
||||
if (!ISSET(cc, NVME_CC_EN))
|
||||
return (nvme_ready(sc, 0));
|
||||
|
||||
csts = nvme_read4(sc, NVME_CSTS);
|
||||
if (!ISSET(csts, NVME_CSTS_RDY)) {
|
||||
/*
|
||||
* Ensure CSTS.RDY is 1.
|
||||
*
|
||||
* Transitioning CC.EN from 1 to 0 when CSTS.RDY is 0
|
||||
* "has undefined results" says NVMe.
|
||||
*/
|
||||
if (nvme_ready(sc, NVME_CSTS_RDY))
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -464,7 +494,7 @@ nvme_scsi_probe(struct scsi_link *link)
|
|||
ccb->ccb_cookie = &sqe;
|
||||
|
||||
nvme_dmamem_sync(sc, mem, BUS_DMASYNC_PREREAD);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill, NVME_TIMO_IDENT);
|
||||
nvme_dmamem_sync(sc, mem, BUS_DMASYNC_POSTREAD);
|
||||
|
||||
scsi_io_put(&sc->sc_iopool, ccb);
|
||||
|
@ -509,6 +539,8 @@ nvme_shutdown(struct nvme_softc *sc)
|
|||
nvme_barrier(sc, 0, sc->sc_ios,
|
||||
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
|
||||
csts = nvme_read4(sc, NVME_CSTS);
|
||||
if (csts == 0xffffffff)
|
||||
break;
|
||||
if ((csts & NVME_CSTS_SHST_MASK) == NVME_CSTS_SHST_DONE)
|
||||
return (0);
|
||||
|
||||
|
@ -637,7 +669,7 @@ nvme_scsi_io(struct scsi_xfer *xs, int dir)
|
|||
}
|
||||
|
||||
if (ISSET(xs->flags, SCSI_POLL)) {
|
||||
nvme_poll(sc, sc->sc_q, ccb, nvme_scsi_io_fill);
|
||||
nvme_poll(sc, sc->sc_q, ccb, nvme_scsi_io_fill, xs->timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -724,7 +756,7 @@ nvme_scsi_sync(struct scsi_xfer *xs)
|
|||
ccb->ccb_cookie = xs;
|
||||
|
||||
if (ISSET(xs->flags, SCSI_POLL)) {
|
||||
nvme_poll(sc, sc->sc_q, ccb, nvme_scsi_sync_fill);
|
||||
nvme_poll(sc, sc->sc_q, ccb, nvme_scsi_sync_fill, xs->timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -963,11 +995,13 @@ struct nvme_poll_state {
|
|||
|
||||
int
|
||||
nvme_poll(struct nvme_softc *sc, struct nvme_queue *q, struct nvme_ccb *ccb,
|
||||
void (*fill)(struct nvme_softc *, struct nvme_ccb *, void *))
|
||||
void (*fill)(struct nvme_softc *, struct nvme_ccb *, void *), u_int32_t ms)
|
||||
{
|
||||
struct nvme_poll_state state;
|
||||
void (*done)(struct nvme_softc *, struct nvme_ccb *, struct nvme_cqe *);
|
||||
void *cookie;
|
||||
int64_t us;
|
||||
u_int32_t csts;
|
||||
u_int16_t flags;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
@ -980,11 +1014,17 @@ nvme_poll(struct nvme_softc *sc, struct nvme_queue *q, struct nvme_ccb *ccb,
|
|||
ccb->ccb_cookie = &state;
|
||||
|
||||
nvme_q_submit(sc, q, ccb, nvme_poll_fill);
|
||||
while (!ISSET(state.c.flags, htole16(NVME_CQE_PHASE))) {
|
||||
for (us = ms * 1000; ms == 0 || us > 0; us -= NVME_TIMO_DELAYNS) {
|
||||
if (ISSET(state.c.flags, htole16(NVME_CQE_PHASE)))
|
||||
break;
|
||||
csts = nvme_read4(sc, NVME_CSTS);
|
||||
if (csts == 0xffffffff || ISSET(csts, NVME_CSTS_CFS)) {
|
||||
SET(state.c.flags, htole16(NVME_CQE_SC_INTERNAL_DEV_ERR));
|
||||
break;
|
||||
}
|
||||
if (nvme_q_complete(sc, q) == 0)
|
||||
delay(10);
|
||||
|
||||
/* XXX no timeout? */
|
||||
delay(NVME_TIMO_DELAYNS);
|
||||
nvme_barrier(sc, NVME_CSTS, 4, BUS_SPACE_BARRIER_READ);
|
||||
}
|
||||
|
||||
ccb->ccb_cookie = cookie;
|
||||
|
@ -1100,7 +1140,8 @@ nvme_identify(struct nvme_softc *sc, u_int mpsmin)
|
|||
ccb->ccb_cookie = mem;
|
||||
|
||||
nvme_dmamem_sync(sc, mem, BUS_DMASYNC_PREREAD);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_fill_identify);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_fill_identify,
|
||||
NVME_TIMO_IDENT);
|
||||
nvme_dmamem_sync(sc, mem, BUS_DMASYNC_POSTREAD);
|
||||
|
||||
nvme_ccb_put(sc, ccb);
|
||||
|
@ -1165,7 +1206,7 @@ nvme_q_create(struct nvme_softc *sc, struct nvme_queue *q)
|
|||
htolem16(&sqe.qid, q->q_id);
|
||||
sqe.qflags = NVM_SQE_CQ_IEN | NVM_SQE_Q_PC;
|
||||
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill, NVME_TIMO_QOP);
|
||||
if (rv != 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -1180,7 +1221,7 @@ nvme_q_create(struct nvme_softc *sc, struct nvme_queue *q)
|
|||
htolem16(&sqe.cqid, q->q_id);
|
||||
sqe.qflags = NVM_SQE_Q_PC;
|
||||
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill, NVME_TIMO_QOP);
|
||||
if (rv != 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -1206,7 +1247,7 @@ nvme_q_delete(struct nvme_softc *sc, struct nvme_queue *q)
|
|||
sqe.opcode = NVM_ADMIN_DEL_IOSQ;
|
||||
htolem16(&sqe.qid, q->q_id);
|
||||
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill, NVME_TIMO_QOP);
|
||||
if (rv != 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -1217,7 +1258,7 @@ nvme_q_delete(struct nvme_softc *sc, struct nvme_queue *q)
|
|||
sqe.opcode = NVM_ADMIN_DEL_IOCQ;
|
||||
htolem16(&sqe.qid, q->q_id);
|
||||
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
|
||||
rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill, NVME_TIMO_QOP);
|
||||
if (rv != 0)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* $OpenBSD: init_sysent.c,v 1.277 2024/04/05 14:15:37 deraadt Exp $ */
|
||||
/* $OpenBSD: init_sysent.c,v 1.278 2024/04/15 15:09:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* System call switch table.
|
||||
*
|
||||
* DO NOT EDIT-- this file is automatically generated.
|
||||
* created from; OpenBSD: syscalls.master,v 1.260 2024/04/05 14:15:13 deraadt Exp
|
||||
* created from; OpenBSD: syscalls.master,v 1.261 2024/04/15 15:08:20 claudio Exp
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -254,7 +254,7 @@ const struct sysent sysent[] = {
|
|||
sys_ppoll }, /* 109 = ppoll */
|
||||
{ 6, s(struct sys_pselect_args), SY_NOLOCK | 0,
|
||||
sys_pselect }, /* 110 = pselect */
|
||||
{ 1, s(struct sys_sigsuspend_args), 0,
|
||||
{ 1, s(struct sys_sigsuspend_args), SY_NOLOCK | 0,
|
||||
sys_sigsuspend }, /* 111 = sigsuspend */
|
||||
{ 3, s(struct sys_sendsyslog_args), SY_NOLOCK | 0,
|
||||
sys_sendsyslog }, /* 112 = sendsyslog */
|
||||
|
@ -695,7 +695,7 @@ const struct sysent sysent[] = {
|
|||
sys___thrwakeup }, /* 301 = __thrwakeup */
|
||||
{ 1, s(struct sys___threxit_args), 0,
|
||||
sys___threxit }, /* 302 = __threxit */
|
||||
{ 3, s(struct sys___thrsigdivert_args), 0,
|
||||
{ 3, s(struct sys___thrsigdivert_args), SY_NOLOCK | 0,
|
||||
sys___thrsigdivert }, /* 303 = __thrsigdivert */
|
||||
{ 2, s(struct sys___getcwd_args), 0,
|
||||
sys___getcwd }, /* 304 = __getcwd */
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* $OpenBSD: syscalls.c,v 1.275 2024/04/05 14:15:37 deraadt Exp $ */
|
||||
/* $OpenBSD: syscalls.c,v 1.276 2024/04/15 15:09:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* System call names.
|
||||
*
|
||||
* DO NOT EDIT-- this file is automatically generated.
|
||||
* created from; OpenBSD: syscalls.master,v 1.260 2024/04/05 14:15:13 deraadt Exp
|
||||
* created from; OpenBSD: syscalls.master,v 1.261 2024/04/15 15:08:20 claudio Exp
|
||||
*/
|
||||
|
||||
const char *const syscallnames[] = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $OpenBSD: syscalls.master,v 1.260 2024/04/05 14:15:13 deraadt Exp $
|
||||
; $OpenBSD: syscalls.master,v 1.261 2024/04/15 15:08:20 claudio Exp $
|
||||
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
|
||||
|
||||
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
|
||||
|
@ -234,7 +234,7 @@
|
|||
110 STD NOLOCK { int sys_pselect(int nd, fd_set *in, fd_set *ou, \
|
||||
fd_set *ex, const struct timespec *ts, \
|
||||
const sigset_t *mask); }
|
||||
111 STD { int sys_sigsuspend(int mask); }
|
||||
111 STD NOLOCK { int sys_sigsuspend(int mask); }
|
||||
112 STD NOLOCK { int sys_sendsyslog(const char *buf, size_t nbyte, \
|
||||
int flags); }
|
||||
113 UNIMPL fktrace
|
||||
|
@ -525,7 +525,7 @@
|
|||
301 STD NOLOCK { int sys___thrwakeup(const volatile void *ident, \
|
||||
int n); }
|
||||
302 STD { void sys___threxit(pid_t *notdead); }
|
||||
303 STD { int sys___thrsigdivert(sigset_t sigmask, \
|
||||
303 STD NOLOCK { int sys___thrsigdivert(sigset_t sigmask, \
|
||||
siginfo_t *info, const struct timespec *timeout); }
|
||||
304 STD { int sys___getcwd(char *buf, size_t len); }
|
||||
305 STD NOLOCK { int sys_adjfreq(const int64_t *freq, \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: uipc_socket.c,v 1.329 2024/04/11 13:32:51 mvs Exp $ */
|
||||
/* $OpenBSD: uipc_socket.c,v 1.330 2024/04/15 21:31:29 mvs Exp $ */
|
||||
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -159,8 +159,6 @@ soalloc(const struct protosw *prp, int wait)
|
|||
case AF_INET6:
|
||||
switch (prp->pr_type) {
|
||||
case SOCK_DGRAM:
|
||||
so->so_rcv.sb_flags |= SB_MTXLOCK;
|
||||
break;
|
||||
case SOCK_RAW:
|
||||
so->so_rcv.sb_flags |= SB_MTXLOCK | SB_OWNLOCK;
|
||||
break;
|
||||
|
@ -819,7 +817,7 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
struct mbuf *m, **mp;
|
||||
struct mbuf *cm;
|
||||
u_long len, offset, moff;
|
||||
int flags, error, type, uio_error = 0;
|
||||
int flags, error, error2, type, uio_error = 0;
|
||||
const struct protosw *pr = so->so_proto;
|
||||
struct mbuf *nextrecord;
|
||||
size_t resid, orig_resid = uio->uio_resid;
|
||||
|
@ -889,10 +887,10 @@ restart:
|
|||
panic("receive 1: so %p, so_type %d, sb_cc %lu",
|
||||
so, so->so_type, so->so_rcv.sb_cc);
|
||||
#endif
|
||||
if (so->so_error) {
|
||||
if ((error2 = READ_ONCE(so->so_error))) {
|
||||
if (m)
|
||||
goto dontblock;
|
||||
error = so->so_error;
|
||||
error = error2;
|
||||
if ((flags & MSG_PEEK) == 0)
|
||||
so->so_error = 0;
|
||||
goto release;
|
||||
|
@ -1289,7 +1287,13 @@ sorflush_locked(struct socket *so)
|
|||
error = sblock(so, sb, SBL_WAIT | SBL_NOINTR);
|
||||
/* with SBL_WAIT and SLB_NOINTR sblock() must not fail */
|
||||
KASSERT(error == 0);
|
||||
|
||||
if (sb->sb_flags & SB_OWNLOCK)
|
||||
solock(so);
|
||||
socantrcvmore(so);
|
||||
if (sb->sb_flags & SB_OWNLOCK)
|
||||
sounlock(so);
|
||||
|
||||
mtx_enter(&sb->sb_mtx);
|
||||
m = sb->sb_mb;
|
||||
memset(&sb->sb_startzero, 0,
|
||||
|
@ -1323,13 +1327,17 @@ sorflush(struct socket *so)
|
|||
int
|
||||
sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
|
||||
{
|
||||
struct file *fp;
|
||||
struct file *fp = NULL;
|
||||
struct socket *sosp;
|
||||
struct sosplice *sp;
|
||||
struct taskq *tq;
|
||||
int error = 0;
|
||||
|
||||
soassertlocked(so);
|
||||
if ((so->so_proto->pr_flags & PR_SPLICE) == 0)
|
||||
return (EPROTONOSUPPORT);
|
||||
if (max && max < 0)
|
||||
return (EINVAL);
|
||||
if (tv && (tv->tv_sec < 0 || !timerisvalid(tv)))
|
||||
return (EINVAL);
|
||||
|
||||
if (sosplice_taskq == NULL) {
|
||||
rw_enter_write(&sosplice_lock);
|
||||
|
@ -1350,63 +1358,51 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
|
|||
membar_consumer();
|
||||
}
|
||||
|
||||
if ((so->so_proto->pr_flags & PR_SPLICE) == 0)
|
||||
return (EPROTONOSUPPORT);
|
||||
if (so->so_options & SO_ACCEPTCONN)
|
||||
return (EOPNOTSUPP);
|
||||
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
|
||||
(so->so_proto->pr_flags & PR_CONNREQUIRED))
|
||||
return (ENOTCONN);
|
||||
if (so->so_sp == NULL) {
|
||||
sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO);
|
||||
if (so->so_sp == NULL)
|
||||
so->so_sp = sp;
|
||||
else
|
||||
pool_put(&sosplice_pool, sp);
|
||||
if (so->so_rcv.sb_flags & SB_OWNLOCK) {
|
||||
if ((error = sblock(so, &so->so_rcv, SBL_WAIT)) != 0)
|
||||
return (error);
|
||||
solock(so);
|
||||
} else {
|
||||
solock(so);
|
||||
if ((error = sblock(so, &so->so_rcv, SBL_WAIT)) != 0) {
|
||||
sounlock(so);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
if (so->so_options & SO_ACCEPTCONN) {
|
||||
error = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
|
||||
(so->so_proto->pr_flags & PR_CONNREQUIRED)) {
|
||||
error = ENOTCONN;
|
||||
goto out;
|
||||
}
|
||||
if (so->so_sp == NULL)
|
||||
so->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO);
|
||||
|
||||
/* If no fd is given, unsplice by removing existing link. */
|
||||
if (fd < 0) {
|
||||
/* Lock receive buffer. */
|
||||
if ((error = sblock(so, &so->so_rcv, SBL_WAIT)) != 0) {
|
||||
return (error);
|
||||
}
|
||||
if (so->so_sp->ssp_socket)
|
||||
sounsplice(so, so->so_sp->ssp_socket, 0);
|
||||
sbunlock(so, &so->so_rcv);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (max && max < 0)
|
||||
return (EINVAL);
|
||||
|
||||
if (tv && (tv->tv_sec < 0 || !timerisvalid(tv)))
|
||||
return (EINVAL);
|
||||
|
||||
/* Find sosp, the drain socket where data will be spliced into. */
|
||||
if ((error = getsock(curproc, fd, &fp)) != 0)
|
||||
return (error);
|
||||
goto out;
|
||||
sosp = fp->f_data;
|
||||
if (sosp->so_proto->pr_usrreqs->pru_send !=
|
||||
so->so_proto->pr_usrreqs->pru_send) {
|
||||
error = EPROTONOSUPPORT;
|
||||
goto frele;
|
||||
}
|
||||
if (sosp->so_sp == NULL) {
|
||||
sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO);
|
||||
if (sosp->so_sp == NULL)
|
||||
sosp->so_sp = sp;
|
||||
else
|
||||
pool_put(&sosplice_pool, sp);
|
||||
goto out;
|
||||
}
|
||||
if (sosp->so_sp == NULL)
|
||||
sosp->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO);
|
||||
|
||||
/* Lock both receive and send buffer. */
|
||||
if ((error = sblock(so, &so->so_rcv, SBL_WAIT)) != 0) {
|
||||
goto frele;
|
||||
}
|
||||
if ((error = sblock(so, &sosp->so_snd, SBL_WAIT)) != 0) {
|
||||
sbunlock(so, &so->so_rcv);
|
||||
goto frele;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (so->so_sp->ssp_socket || sosp->so_sp->ssp_soback) {
|
||||
|
@ -1423,8 +1419,10 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
|
|||
}
|
||||
|
||||
/* Splice so and sosp together. */
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
so->so_sp->ssp_socket = sosp;
|
||||
sosp->so_sp->ssp_soback = so;
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
so->so_splicelen = 0;
|
||||
so->so_splicemax = max;
|
||||
if (tv)
|
||||
|
@ -1447,17 +1445,18 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
|
|||
|
||||
release:
|
||||
sbunlock(sosp, &sosp->so_snd);
|
||||
sbunlock(so, &so->so_rcv);
|
||||
frele:
|
||||
/*
|
||||
* FRELE() must not be called with the socket lock held. It is safe to
|
||||
* release the lock here as long as no other operation happen on the
|
||||
* socket when sosplice() returns. The dance could be avoided by
|
||||
* grabbing the socket lock inside this function.
|
||||
*/
|
||||
sounlock(so);
|
||||
FRELE(fp, curproc);
|
||||
solock(so);
|
||||
out:
|
||||
if (so->so_rcv.sb_flags & SB_OWNLOCK) {
|
||||
sounlock(so);
|
||||
sbunlock(so, &so->so_rcv);
|
||||
} else {
|
||||
sbunlock(so, &so->so_rcv);
|
||||
sounlock(so);
|
||||
}
|
||||
|
||||
if (fp)
|
||||
FRELE(fp, curproc);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1469,10 +1468,12 @@ sounsplice(struct socket *so, struct socket *sosp, int freeing)
|
|||
task_del(sosplice_taskq, &so->so_splicetask);
|
||||
timeout_del(&so->so_idleto);
|
||||
sosp->so_snd.sb_flags &= ~SB_SPLICE;
|
||||
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
so->so_rcv.sb_flags &= ~SB_SPLICE;
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
so->so_sp->ssp_socket = sosp->so_sp->ssp_soback = NULL;
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
|
||||
/* Do not wakeup a socket that is about to be freed. */
|
||||
if ((freeing & SOSP_FREEING_READ) == 0 && soreadable(so))
|
||||
sorwakeup(so);
|
||||
|
@ -2025,7 +2026,6 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
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)) {
|
||||
|
@ -2038,7 +2038,6 @@ 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 */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: in_pcb.h,v 1.154 2024/03/22 21:48:38 bluhm Exp $ */
|
||||
/* $OpenBSD: in_pcb.h,v 1.155 2024/04/15 18:31:04 bluhm Exp $ */
|
||||
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -176,9 +176,6 @@ struct inpcb {
|
|||
#define inp_flowinfo inp_hu.hu_ipv6.ip6_flow
|
||||
|
||||
int inp_cksum6;
|
||||
#ifndef _KERNEL
|
||||
#define inp_csumoffset inp_cksum6
|
||||
#endif
|
||||
struct icmp6_filter *inp_icmp6filt;
|
||||
struct pf_state_key *inp_pf_sk; /* [L] */
|
||||
struct mbuf *(*inp_upcall)(void *, struct mbuf *,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* $OpenBSD: syscall.h,v 1.274 2024/04/05 14:15:37 deraadt Exp $ */
|
||||
/* $OpenBSD: syscall.h,v 1.275 2024/04/15 15:09:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* System call numbers.
|
||||
*
|
||||
* DO NOT EDIT-- this file is automatically generated.
|
||||
* created from; OpenBSD: syscalls.master,v 1.260 2024/04/05 14:15:13 deraadt Exp
|
||||
* created from; OpenBSD: syscalls.master,v 1.261 2024/04/15 15:08:20 claudio Exp
|
||||
*/
|
||||
|
||||
/* syscall: "exit" ret: "void" args: "int" */
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* $OpenBSD: syscallargs.h,v 1.277 2024/04/05 14:15:37 deraadt Exp $ */
|
||||
/* $OpenBSD: syscallargs.h,v 1.278 2024/04/15 15:09:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* System call argument lists.
|
||||
*
|
||||
* DO NOT EDIT-- this file is automatically generated.
|
||||
* created from; OpenBSD: syscalls.master,v 1.260 2024/04/05 14:15:13 deraadt Exp
|
||||
* created from; OpenBSD: syscalls.master,v 1.261 2024/04/15 15:08:20 claudio Exp
|
||||
*/
|
||||
|
||||
#ifdef syscallarg
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue