sync with OpenBSD -current

This commit is contained in:
purplerain 2025-01-15 01:19:55 +00:00
parent 39858ff105
commit f11f16fb18
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
19 changed files with 713 additions and 177 deletions

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.26 2025/01/13 14:18:07 claudio Exp $
# $OpenBSD: Makefile,v 1.27 2025/01/14 13:15:18 claudio Exp $
REGRESS_TARGETS = network_statement md5 ovs capa policy pftable \
mrt maxprefix maxprefixout maxcomm maxattr \
@ -51,6 +51,9 @@ l3vpn:
ixp:
${SUDO} ksh ${.CURDIR}/$@.sh ${BGPD} ${.CURDIR} 11 12 pair11 pair12
addpath:
${SUDO} ksh ${.CURDIR}/$@.sh ${BGPD} ${.CURDIR} 11 12 pair11 pair12
lladdr:
${SUDO} ksh ${.CURDIR}/$@.sh ${BGPD} ${.CURDIR} 11 12 pair11 pair12

View file

@ -0,0 +1,31 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete
flags vs destination gateway lpref med aspath origin
*> N-? 2.0.1.0/24 192.0.2.21 100 2 2 i
*> N-? 2.0.2.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.2.0/24 192.0.2.31 100 3 3 i
*> N-? 2.0.3.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.3.0/24 192.0.2.31 100 3 3 i
* N-? 2.0.3.0/24 192.0.2.41 100 4 4 i
*> N-? 2.0.4.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.4.0/24 192.0.2.31 100 3 3 i
* N-? 2.0.4.0/24 192.0.2.41 100 4 4 i
*> N-? 2.0.5.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.5.0/24 192.0.2.31 100 3 3 i
* N-? 2.0.5.0/24 192.0.2.41 100 4 4 i
*> N-? 2.0.6.0/24 192.0.2.31 100 3 3 i
* N-? 2.0.6.0/24 192.0.2.41 100 4 4 i
* N-? 2.0.6.0/24 192.0.2.51 100 5 5 i
*> N-? 2.0.7.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.7.0/24 192.0.2.41 100 4 4 i
* N-? 2.0.7.0/24 192.0.2.51 100 5 5 i
*> N-? 2.0.8.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.8.0/24 192.0.2.31 100 3 3 i
* N-? 2.0.8.0/24 192.0.2.51 100 5 5 i
*> N-? 2.0.9.0/24 192.0.2.21 100 2 2 i
* N-? 2.0.9.0/24 192.0.2.31 100 3 3 i
* N-? 2.0.9.0/24 192.0.2.41 100 4 4 i

View file

@ -0,0 +1,100 @@
#!/bin/ksh
# $OpenBSD: addpath.sh,v 1.1 2025/01/14 13:15:18 claudio Exp $
set -e
BGPD=$1
BGPDCONFIGDIR=$2
RDOMAIN1=$3
RDOMAIN2=$4
PAIR1=$5
PAIR2=$6
RDOMAINS="${RDOMAIN1} ${RDOMAIN2}"
PAIRS="${PAIR1} ${PAIR2}"
PAIR1IP=192.0.2.2
PAIR2IP=192.0.2.11
PAIR2IP2=192.0.2.21
PAIR2IP3=192.0.2.31
PAIR2IP4=192.0.2.41
PAIR2IP5=192.0.2.51
error_notify() {
echo cleanup
pkill -T ${RDOMAIN1} bgpd || true
pkill -T ${RDOMAIN2} bgpd || true
sleep 1
ifconfig ${PAIR2} destroy || true
ifconfig ${PAIR1} destroy || true
route -qn -T ${RDOMAIN1} flush || true
route -qn -T ${RDOMAIN2} flush || true
ifconfig lo${RDOMAIN1} destroy || true
ifconfig lo${RDOMAIN2} destroy || true
if [ $1 -ne 0 ]; then
echo FAILED
exit 1
else
echo SUCCESS
fi
}
if [ "$(id -u)" -ne 0 ]; then
echo need root privileges >&2
exit 1
fi
. "${BGPDCONFIGDIR}/util.sh"
trap 'error_notify $?' EXIT
echo check if rdomains are busy
for n in ${RDOMAINS}; do
if /sbin/ifconfig | grep -v "^lo${n}:" | grep " rdomain ${n} "; then
echo routing domain ${n} is already used >&2
exit 1
fi
done
echo check if interfaces are busy
for n in ${PAIRS}; do
/sbin/ifconfig "${n}" >/dev/null 2>&1 && \
( echo interface ${n} is already used >&2; exit 1 )
done
set -x
echo setup
ifconfig ${PAIR1} rdomain ${RDOMAIN1} ${PAIR1IP}/24 up
ifconfig ${PAIR2} rdomain ${RDOMAIN2} ${PAIR2IP}/24 up
ifconfig ${PAIR2} alias ${PAIR2IP2}/32
ifconfig ${PAIR2} alias ${PAIR2IP3}/32
ifconfig ${PAIR2} alias ${PAIR2IP4}/32
ifconfig ${PAIR2} alias ${PAIR2IP5}/32
ifconfig ${PAIR1} patch ${PAIR2}
ifconfig lo${RDOMAIN1} inet 127.0.0.1/8
ifconfig lo${RDOMAIN2} inet 127.0.0.1/8
echo run bgpds
route -T ${RDOMAIN1} exec ${BGPD} \
-v -f ${BGPDCONFIGDIR}/bgpd.addpath.rdomain1.conf
sleep 2
route -T ${RDOMAIN2} exec ${BGPD} \
-v -f ${BGPDCONFIGDIR}/bgpd.addpath.rdomain2_1.conf
route -T ${RDOMAIN2} exec ${BGPD} \
-v -f ${BGPDCONFIGDIR}/bgpd.addpath.rdomain2_2.conf
route -T ${RDOMAIN2} exec ${BGPD} \
-v -f ${BGPDCONFIGDIR}/bgpd.addpath.rdomain2_3.conf
route -T ${RDOMAIN2} exec ${BGPD} \
-v -f ${BGPDCONFIGDIR}/bgpd.addpath.rdomain2_4.conf
route -T ${RDOMAIN2} exec ${BGPD} \
-v -f ${BGPDCONFIGDIR}/bgpd.addpath.rdomain2_5.conf
sleep 7
route -T ${RDOMAIN1} exec bgpctl show
route -T ${RDOMAIN2} exec bgpctl show rib | tee addpath.rdomain2.out
diff -u ${BGPDCONFIGDIR}/addpath.rdomain2.ok addpath.rdomain2.out
echo OK
exit 0

View file

@ -0,0 +1,51 @@
# built by ARouteServer
AS 999
router-id 192.0.2.2
fib-update no
log updates
nexthop qualify via default
rde evaluate all
# ---------------------------------------------------------
# MEMBERS
group "clients" {
transparent-as yes
neighbor 192.0.2.11 {
remote-as 1
descr "AS1_1 client"
announce add-path send best plus 2
}
neighbor 192.0.2.21 {
remote-as 2
descr "AS2_1 client"
set med +2
}
neighbor 192.0.2.31 {
remote-as 3
descr "AS3_1 client"
set med +3
}
neighbor 192.0.2.41 {
remote-as 4
descr "AS4_1 client"
set med +4
}
neighbor 192.0.2.51 {
remote-as 5
descr "AS5_1 client"
set med +5
}
}
allow from any
allow to any

View file

@ -0,0 +1,17 @@
AS 1
router-id 192.0.2.11
listen on 192.0.2.11
fib-update no
rde med compare always
neighbor 192.0.2.2 {
remote-as 999
local-address 192.0.2.11
enforce neighbor-as no
announce add-path recv yes
}
allow from any
allow to any

View file

@ -0,0 +1,24 @@
AS 2
router-id 192.0.2.21
listen on 192.0.2.21
fib-update no
socket "/var/run/bgpd.sock.12_2"
network 2.0.1.0/24
network 2.0.2.0/24
network 2.0.3.0/24
network 2.0.4.0/24
network 2.0.5.0/24
network 2.0.6.0/24 set prepend-self 2
network 2.0.7.0/24
network 2.0.8.0/24
network 2.0.9.0/24
neighbor 192.0.2.2 {
remote-as 999
local-address 192.0.2.21
enforce neighbor-as no
}
deny from any
allow to any

View file

@ -0,0 +1,23 @@
AS 3
router-id 192.0.2.31
listen on 192.0.2.31
fib-update no
socket "/var/run/bgpd.sock.12_3"
network 2.0.2.0/24
network 2.0.3.0/24
network 2.0.4.0/24
network 2.0.5.0/24
network 2.0.6.0/24
network 2.0.7.0/24 set prepend-self 2
network 2.0.8.0/24
network 2.0.9.0/24
neighbor 192.0.2.2 {
remote-as 999
local-address 192.0.2.31
enforce neighbor-as no
}
deny from any
allow to any

View file

@ -0,0 +1,22 @@
AS 4
router-id 192.0.2.41
listen on 192.0.2.41
fib-update no
socket "/var/run/bgpd.sock.12_4"
network 2.0.3.0/24
network 2.0.4.0/24
network 2.0.5.0/24
network 2.0.6.0/24
network 2.0.7.0/24
network 2.0.8.0/24 set prepend-self 2
network 2.0.9.0/24
neighbor 192.0.2.2 {
remote-as 999
local-address 192.0.2.41
enforce neighbor-as no
}
deny from any
allow to any

View file

@ -0,0 +1,21 @@
AS 5
router-id 192.0.2.51
listen on 192.0.2.51
fib-update no
socket "/var/run/bgpd.sock.12_5"
network 2.0.4.0/24
network 2.0.5.0/24
network 2.0.6.0/24
network 2.0.7.0/24
network 2.0.8.0/24
network 2.0.9.0/24 set prepend-self 2
neighbor 192.0.2.2 {
remote-as 999
local-address 192.0.2.51
enforce neighbor-as no
}
deny from any
allow to any

View file

@ -1,4 +1,4 @@
/* $OpenBSD: virtio_mmio.c,v 1.21 2024/12/20 22:18:27 sf Exp $ */
/* $OpenBSD: virtio_mmio.c,v 1.23 2025/01/14 14:28:38 sf Exp $ */
/* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
/*
@ -105,6 +105,8 @@ int virtio_mmio_negotiate_features(struct virtio_softc *,
const struct virtio_feature_name *);
int virtio_mmio_intr(void *);
void virtio_mmio_intr_barrier(struct virtio_softc *);
int virtio_mmio_intr_establish(struct virtio_softc *, struct virtio_attach_args *,
int, struct cpu_info *, int (*)(void *), void *);
struct virtio_mmio_softc {
struct virtio_softc sc_sc;
@ -122,7 +124,7 @@ struct virtio_mmio_softc {
struct virtio_mmio_attach_args {
struct virtio_attach_args vma_va;
struct fdt_attach_args *vma_fa;
struct fdt_attach_args *vma_fa;
};
const struct cfattach virtio_mmio_ca = {
@ -160,6 +162,7 @@ const struct virtio_ops virtio_mmio_ops = {
virtio_mmio_attach_finish,
virtio_mmio_intr,
virtio_mmio_intr_barrier,
virtio_mmio_intr_establish,
};
uint16_t
@ -234,7 +237,7 @@ virtio_mmio_set_status(struct virtio_softc *vsc, int status)
VIRTIO_MMIO_STATUS) != 0) {
CPU_BUSY_CYCLE();
}
} else {
} else {
old = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_MMIO_STATUS);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_STATUS,
@ -546,3 +549,11 @@ virtio_mmio_intr_barrier(struct virtio_softc *vsc)
if (sc->sc_ih)
intr_barrier(sc->sc_ih);
}
int
virtio_mmio_intr_establish(struct virtio_softc *vsc,
struct virtio_attach_args *va, int vec, struct cpu_info *ci,
int (*func)(void *), void *arg)
{
return ENXIO;
}

View file

@ -404,7 +404,7 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine)
rw_init(&ce->pin_mutex, "cepin");
mtx_init(&ce->guc_state.lock, IPL_NONE);
mtx_init(&ce->guc_state.lock, IPL_TTY);
INIT_LIST_HEAD(&ce->guc_state.fences);
INIT_LIST_HEAD(&ce->guc_state.requests);

View file

@ -165,7 +165,7 @@ static void set_scheduler_caps(struct drm_i915_private *i915)
disabled |= (I915_SCHEDULER_CAP_ENABLED |
I915_SCHEDULER_CAP_PRIORITY);
if (intel_uc_uses_guc_submission(&to_gt(i915)->uc))
if (intel_uc_uses_guc_submission(&engine->gt->uc))
enabled |= I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP;
for (i = 0; i < ARRAY_SIZE(map); i++) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: virtio_pci.c,v 1.48 2024/12/20 22:18:27 sf Exp $ */
/* $OpenBSD: virtio_pci.c,v 1.50 2025/01/14 14:28:38 sf Exp $ */
/* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
/*
@ -50,7 +50,7 @@
* XXX: PCI-endian while the device specific registers are native endian.
*/
#define MAX_MSIX_VECS 8
#define MAX_MSIX_VECS 16
struct virtio_pci_softc;
struct virtio_pci_attach_args;
@ -62,7 +62,7 @@ int virtio_pci_attach_10(struct virtio_pci_softc *sc, struct pci_attach_args *p
int virtio_pci_detach(struct device *, int);
void virtio_pci_kick(struct virtio_softc *, uint16_t);
int virtio_pci_adjust_config_region(struct virtio_pci_softc *);
int virtio_pci_adjust_config_region(struct virtio_pci_softc *, int offset);
uint8_t virtio_pci_read_device_config_1(struct virtio_softc *, int);
uint16_t virtio_pci_read_device_config_2(struct virtio_softc *, int);
uint32_t virtio_pci_read_device_config_4(struct virtio_softc *, int);
@ -81,9 +81,10 @@ int virtio_pci_negotiate_features(struct virtio_softc *, const struct virtio_fe
int virtio_pci_negotiate_features_10(struct virtio_softc *, const struct virtio_feature_name *);
void virtio_pci_set_msix_queue_vector(struct virtio_pci_softc *, uint32_t, uint16_t);
void virtio_pci_set_msix_config_vector(struct virtio_pci_softc *, uint16_t);
int virtio_pci_msix_establish(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int, int (*)(void *), void *);
int virtio_pci_msix_establish(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int, struct cpu_info *, int (*)(void *), void *);
int virtio_pci_setup_msix(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int);
void virtio_pci_intr_barrier(struct virtio_softc *);
int virtio_pci_intr_establish(struct virtio_softc *, struct virtio_attach_args *, int, struct cpu_info *, int (*)(void *), void *);
void virtio_pci_free_irqs(struct virtio_pci_softc *);
int virtio_pci_poll_intr(void *);
int virtio_pci_legacy_intr(void *);
@ -100,6 +101,7 @@ enum irq_type {
IRQ_NO_MSIX,
IRQ_MSIX_SHARED, /* vec 0: config irq, vec 1 shared by all vqs */
IRQ_MSIX_PER_VQ, /* vec 0: config irq, vec n: irq of vq[n-1] */
IRQ_MSIX_CHILD, /* assigned by child driver */
};
struct virtio_pci_intr {
@ -179,6 +181,7 @@ const struct virtio_ops virtio_pci_ops = {
virtio_pci_attach_finish,
virtio_pci_poll_intr,
virtio_pci_intr_barrier,
virtio_pci_intr_establish,
};
static inline uint64_t
@ -426,7 +429,7 @@ virtio_pci_find_cap(struct virtio_pci_softc *sc, int cfg_type, void *buf, int bu
printf("%s: cap too large\n", __func__);
return ERANGE;
}
for (i = 4; i < len / sizeof(pcireg_t); i++)
for (i = 4; i < len / sizeof(pcireg_t); i++)
v->reg[i] = pci_conf_read(pc, tag, offset + i * 4);
}
@ -648,10 +651,12 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
goto free;
}
sc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;
sc->sc_irq_type = IRQ_NO_MSIX;
if (virtio_pci_adjust_config_region(sc) != 0)
goto err;
if (virtio_pci_adjust_config_region(sc,
VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI) != 0)
{
goto free;
}
virtio_device_reset(vsc);
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
@ -692,7 +697,9 @@ virtio_pci_attach_finish(struct virtio_softc *vsc,
pci_chipset_tag_t pc = vpa->vpa_pa->pa_pc;
char const *intrstr;
if (virtio_pci_setup_msix(sc, vpa, 0) == 0) {
if (sc->sc_irq_type == IRQ_MSIX_CHILD) {
intrstr = "msix";
} else if (virtio_pci_setup_msix(sc, vpa, 0) == 0) {
sc->sc_irq_type = IRQ_MSIX_PER_VQ;
intrstr = "msix per-VQ";
} else if (virtio_pci_setup_msix(sc, vpa, 1) == 0) {
@ -754,11 +761,14 @@ virtio_pci_detach(struct device *self, int flags)
}
int
virtio_pci_adjust_config_region(struct virtio_pci_softc *sc)
virtio_pci_adjust_config_region(struct virtio_pci_softc *sc, int offset)
{
if (sc->sc_sc.sc_version_1)
return 0;
sc->sc_devcfg_iosize = sc->sc_iosize - sc->sc_devcfg_offset;
if (sc->sc_devcfg_offset == offset)
return 0;
sc->sc_devcfg_offset = offset;
sc->sc_devcfg_iosize = sc->sc_iosize - offset;
sc->sc_devcfg_iot = sc->sc_iot;
if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, sc->sc_devcfg_offset,
sc->sc_devcfg_iosize, &sc->sc_devcfg_ioh) != 0) {
@ -958,30 +968,33 @@ virtio_pci_write_device_config_8(struct virtio_softc *vsc,
int
virtio_pci_msix_establish(struct virtio_pci_softc *sc,
struct virtio_pci_attach_args *vpa, int idx,
struct virtio_pci_attach_args *vpa, int idx, struct cpu_info *ci,
int (*handler)(void *), void *ih_arg)
{
struct virtio_softc *vsc = &sc->sc_sc;
pci_intr_handle_t ih;
int r;
KASSERT(idx < sc->sc_nintr);
if (pci_intr_map_msix(vpa->vpa_pa, idx, &ih) != 0) {
r = pci_intr_map_msix(vpa->vpa_pa, idx, &ih);
if (r != 0) {
#if VIRTIO_DEBUG
printf("%s[%d]: pci_intr_map_msix failed\n",
vsc->sc_dev.dv_xname, idx);
#endif
return 1;
return r;
}
snprintf(sc->sc_intr[idx].name, sizeof(sc->sc_intr[idx].name), "%s:%d",
vsc->sc_child->dv_xname, idx);
sc->sc_intr[idx].ih = pci_intr_establish(sc->sc_pc, ih, vsc->sc_ipl,
handler, ih_arg, sc->sc_intr[idx].name);
sc->sc_intr[idx].ih = pci_intr_establish_cpu(sc->sc_pc, ih, vsc->sc_ipl,
ci, handler, ih_arg, sc->sc_intr[idx].name);
if (sc->sc_intr[idx].ih == NULL) {
printf("%s[%d]: couldn't establish msix interrupt\n",
vsc->sc_dev.dv_xname, idx);
return 1;
vsc->sc_child->dv_xname, idx);
return ENOMEM;
}
virtio_pci_adjust_config_region(sc, VIRTIO_CONFIG_DEVICE_CONFIG_MSI);
return 0;
}
@ -1031,8 +1044,8 @@ virtio_pci_free_irqs(struct virtio_pci_softc *sc)
}
}
sc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;
virtio_pci_adjust_config_region(sc);
/* XXX msix_delroute does not unset PCI_MSIX_MC_MSIXE -> leave alone? */
virtio_pci_adjust_config_region(sc, VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI);
}
int
@ -1040,34 +1053,33 @@ virtio_pci_setup_msix(struct virtio_pci_softc *sc,
struct virtio_pci_attach_args *vpa, int shared)
{
struct virtio_softc *vsc = &sc->sc_sc;
int i;
int i, r = 0;
/* Shared needs config + queue */
if (shared && vpa->vpa_va.va_nintr < 1 + 1)
return 1;
return ERANGE;
/* Per VQ needs config + N * queue */
if (!shared && vpa->vpa_va.va_nintr < 1 + vsc->sc_nvqs)
return 1;
return ERANGE;
if (virtio_pci_msix_establish(sc, vpa, 0, virtio_pci_config_intr, vsc))
return 1;
sc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI;
virtio_pci_adjust_config_region(sc);
r = virtio_pci_msix_establish(sc, vpa, 0, NULL, virtio_pci_config_intr, vsc);
if (r != 0)
return r;
if (shared) {
if (virtio_pci_msix_establish(sc, vpa, 1,
virtio_pci_shared_queue_intr, vsc)) {
r = virtio_pci_msix_establish(sc, vpa, 1, NULL,
virtio_pci_shared_queue_intr, vsc);
if (r != 0)
goto fail;
}
for (i = 0; i < vsc->sc_nvqs; i++)
vsc->sc_vqs[i].vq_intr_vec = 1;
} else {
for (i = 0; i < vsc->sc_nvqs; i++) {
if (virtio_pci_msix_establish(sc, vpa, i + 1,
virtio_pci_queue_intr, &vsc->sc_vqs[i])) {
r = virtio_pci_msix_establish(sc, vpa, i + 1, NULL,
virtio_pci_queue_intr, &vsc->sc_vqs[i]);
if (r != 0)
goto fail;
}
vsc->sc_vqs[i].vq_intr_vec = i + 1;
}
}
@ -1075,7 +1087,28 @@ virtio_pci_setup_msix(struct virtio_pci_softc *sc,
return 0;
fail:
virtio_pci_free_irqs(sc);
return 1;
return r;
}
int
virtio_pci_intr_establish(struct virtio_softc *vsc,
struct virtio_attach_args *va, int vec, struct cpu_info *ci,
int (*func)(void *), void *arg)
{
struct virtio_pci_attach_args *vpa;
struct virtio_pci_softc *sc;
if (vsc->sc_ops != &virtio_pci_ops)
return ENXIO;
vpa = (struct virtio_pci_attach_args *)va;
sc = (struct virtio_pci_softc *)vsc;
if (vec >= sc->sc_nintr || sc->sc_nintr <= 1)
return ERANGE;
sc->sc_irq_type = IRQ_MSIX_CHILD;
return virtio_pci_msix_establish(sc, vpa, vec, ci, func, arg);
}
void

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_vio.c,v 1.63 2025/01/06 14:23:52 sf Exp $ */
/* $OpenBSD: if_vio.c,v 1.66 2025/01/14 14:32:32 sf Exp $ */
/*
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@ -32,8 +32,10 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/intrmap.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/percpu.h> /* for CACHELINESIZE */
#include <sys/sockio.h>
#include <sys/timeout.h>
@ -64,14 +66,21 @@
* if_vioreg.h:
*/
/* Configuration registers */
#define VIRTIO_NET_CONFIG_MAC 0 /* 8bit x 6byte */
#define VIRTIO_NET_CONFIG_STATUS 6 /* 16bit */
#define VIRTIO_NET_CONFIG_MAC 0 /* 8 bit x 6 byte */
#define VIRTIO_NET_CONFIG_STATUS 6 /* 16 bit */
#define VIRTIO_NET_CONFIG_MAX_QUEUES 8 /* 16 bit */
#define VIRTIO_NET_CONFIG_MTU 10 /* 16 bit */
#define VIRTIO_NET_CONFIG_SPEED 12 /* 32 bit */
#define VIRTIO_NET_CONFIG_DUPLEX 16 /* 8 bit */
#define VIRTIO_NET_CONFIG_RSS_SIZE 17 /* 8 bit */
#define VIRTIO_NET_CONFIG_RSS_LEN 18 /* 16 bit */
#define VIRTIO_NET_CONFIG_HASH_TYPES 20 /* 16 bit */
/* Feature bits */
#define VIRTIO_NET_F_CSUM (1ULL<<0)
#define VIRTIO_NET_F_GUEST_CSUM (1ULL<<1)
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS (1ULL<<2)
#define VIRTIO_NET_F_MTU (1ULL<<3)
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS (1ULL<<2)
#define VIRTIO_NET_F_MTU (1ULL<<3)
#define VIRTIO_NET_F_MAC (1ULL<<5)
#define VIRTIO_NET_F_GSO (1ULL<<6)
#define VIRTIO_NET_F_GUEST_TSO4 (1ULL<<7)
@ -183,6 +192,11 @@ struct virtio_net_ctrl_cmd {
# define VIRTIO_NET_CTRL_VLAN_ADD 0
# define VIRTIO_NET_CTRL_VLAN_DEL 1
#define VIRTIO_NET_CTRL_MQ 4
# define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0
# define VIRTIO_NET_CTRL_MQ_RSS_CONFIG 1
# define VIRTIO_NET_CTRL_MQ_HASH_CONFIG 2
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
# define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
@ -196,6 +210,12 @@ struct virtio_net_ctrl_rx {
uint8_t onoff;
} __packed;
struct virtio_net_ctrl_mq_pairs_set {
uint16_t virtqueue_pairs;
};
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
struct virtio_net_ctrl_guest_offloads {
uint64_t offloads;
} __packed;
@ -231,7 +251,7 @@ struct vio_queue {
struct virtqueue *viq_txvq;
struct mutex viq_txmtx, viq_rxmtx;
int viq_txfree_slots;
};
} __aligned(CACHELINESIZE);
struct vio_softc {
struct device sc_dev;
@ -251,14 +271,16 @@ struct vio_softc {
caddr_t sc_dma_kva;
int sc_hdr_size;
struct virtio_net_ctrl_cmd *sc_ctrl_cmd;
struct virtio_net_ctrl_status *sc_ctrl_status;
struct virtio_net_ctrl_rx *sc_ctrl_rx;
struct virtio_net_ctrl_guest_offloads *sc_ctrl_guest_offloads;
struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_uc;
struct virtio_net_ctrl_cmd *sc_ctrl_cmd;
struct virtio_net_ctrl_status *sc_ctrl_status;
struct virtio_net_ctrl_rx *sc_ctrl_rx;
struct virtio_net_ctrl_mq_pairs_set *sc_ctrl_mq_pairs;
struct virtio_net_ctrl_guest_offloads *sc_ctrl_guest_offloads;
struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_uc;
#define sc_ctrl_mac_info sc_ctrl_mac_tbl_uc
struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_mc;
struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_mc;
struct intrmap *sc_intrmap;
struct vio_queue *sc_q;
uint16_t sc_nqueues;
int sc_tx_slots_per_req;
@ -317,10 +339,15 @@ void vio_tx_drain(struct vio_softc *);
int vio_encap(struct vio_queue *, int, struct mbuf *);
void vio_txtick(void *);
int vio_queue_intr(void *);
int vio_config_intr(void *);
int vio_ctrl_intr(void *);
/* other control */
void vio_link_state(struct ifnet *);
int vio_config_change(struct virtio_softc *);
int vio_ctrl_rx(struct vio_softc *, int, int);
int vio_ctrl_mq(struct vio_softc *);
int vio_ctrl_guest_offloads(struct vio_softc *, uint64_t);
int vio_set_rx_filter(struct vio_softc *);
void vio_iff(struct vio_softc *);
@ -408,6 +435,8 @@ vio_free_dmamem(struct vio_softc *sc)
* sc_ctrl_status: return value for a command via ctrl vq (READ)
* sc_ctrl_rx: parameter for a VIRTIO_NET_CTRL_RX class command
* (WRITE)
* sc_ctrl_mq_pairs_set: set number of rx/tx queue pais (WRITE)
* sc_ctrl_guest_offloads: configure offload features (WRITE)
* sc_ctrl_mac_tbl_uc: unicast MAC address filter for a VIRTIO_NET_CTRL_MAC
* class command (WRITE)
* sc_ctrl_mac_tbl_mc: multicast MAC address filter for a VIRTIO_NET_CTRL_MAC
@ -449,6 +478,7 @@ vio_alloc_mem(struct vio_softc *sc, int tx_max_segments)
allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1;
allocsize += sizeof(struct virtio_net_ctrl_status) * 1;
allocsize += sizeof(struct virtio_net_ctrl_rx) * 1;
allocsize += sizeof(struct virtio_net_ctrl_mq_pairs_set) * 1;
allocsize += sizeof(struct virtio_net_ctrl_guest_offloads) * 1;
allocsize += VIO_CTRL_MAC_INFO_SIZE;
}
@ -474,6 +504,8 @@ vio_alloc_mem(struct vio_softc *sc, int tx_max_segments)
offset += sizeof(*sc->sc_ctrl_status);
sc->sc_ctrl_rx = (void *)(kva + offset);
offset += sizeof(*sc->sc_ctrl_rx);
sc->sc_ctrl_mq_pairs = (void *)(kva + offset);
offset += sizeof(*sc->sc_ctrl_mq_pairs);
sc->sc_ctrl_guest_offloads = (void *)(kva + offset);
offset += sizeof(*sc->sc_ctrl_guest_offloads);
sc->sc_ctrl_mac_tbl_uc = (void *)(kva + offset);
@ -598,7 +630,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
struct vio_softc *sc = (struct vio_softc *)self;
struct virtio_softc *vsc = (struct virtio_softc *)parent;
struct virtio_attach_args *va = aux;
int i, tx_max_segments;
int i, r, tx_max_segments;
struct ifnet *ifp = &sc->sc_ac.ac_if;
if (vsc->sc_child != NULL) {
@ -616,6 +648,9 @@ vio_attach(struct device *parent, struct device *self, void *aux)
VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_CSUM |
VIRTIO_F_RING_EVENT_IDX | VIRTIO_NET_F_GUEST_CSUM;
if (va->va_nintr > 3 && ncpus > 1)
vsc->sc_driver_features |= VIRTIO_NET_F_MQ;
vsc->sc_driver_features |= VIRTIO_NET_F_HOST_TSO4;
vsc->sc_driver_features |= VIRTIO_NET_F_HOST_TSO6;
@ -626,10 +661,23 @@ vio_attach(struct device *parent, struct device *self, void *aux)
if (virtio_negotiate_features(vsc, virtio_net_feature_names) != 0)
goto err;
sc->sc_nqueues = 1;
vsc->sc_nvqs = 2 * sc->sc_nqueues;
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
vsc->sc_nvqs++;
if (virtio_has_feature(vsc, VIRTIO_NET_F_MQ)) {
i = virtio_read_device_config_2(vsc,
VIRTIO_NET_CONFIG_MAX_QUEUES);
vsc->sc_nvqs = 2 * i + 1;
i = MIN(i, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX);
sc->sc_intrmap = intrmap_create(&sc->sc_dev, i,
va->va_nintr - 2, 0);
sc->sc_nqueues = intrmap_count(sc->sc_intrmap);
printf(": %u queue%s", sc->sc_nqueues,
sc->sc_nqueues > 1 ? "s" : "");
} else {
sc->sc_nqueues = 1;
printf(": 1 queue");
vsc->sc_nvqs = 2;
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
vsc->sc_nvqs++;
}
vsc->sc_vqs = mallocarray(vsc->sc_nvqs, sizeof(*vsc->sc_vqs), M_DEVBUF,
M_WAITOK|M_ZERO);
@ -729,18 +777,66 @@ vio_attach(struct device *parent, struct device *self, void *aux)
else
virtio_stop_vq_intr(vsc, vioq->viq_txvq);
vioq->viq_txfree_slots = vioq->viq_txvq->vq_num - 1;
KASSERT(vioq->viq_txfree_slots > sc->sc_tx_slots_per_req);
if (vioq->viq_txvq->vq_num != sc->sc_q[0].viq_txvq->vq_num) {
printf("inequal tx queue size %d: %d != %d\n", i,
vioq->viq_txvq->vq_num,
sc->sc_q[0].viq_txvq->vq_num);
goto err;
}
DPRINTF("%d: q %p rx %p tx %p\n", i, vioq, vioq->viq_rxvq,
vioq->viq_txvq);
if (sc->sc_intrmap != NULL) {
vioq->viq_rxvq->vq_intr_vec = i + 2;
vioq->viq_txvq->vq_intr_vec = i + 2;
}
}
/* control queue */
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ)) {
sc->sc_ctl_vq = &vsc->sc_vqs[2];
if (virtio_alloc_vq(vsc, sc->sc_ctl_vq, 2, 1,
"control") != 0)
i = 2;
if (virtio_has_feature(vsc, VIRTIO_NET_F_MQ)) {
i = 2 * virtio_read_device_config_2(vsc,
VIRTIO_NET_CONFIG_MAX_QUEUES);
}
sc->sc_ctl_vq = &vsc->sc_vqs[i];
if (virtio_alloc_vq(vsc, sc->sc_ctl_vq, i, 1, "control") != 0)
goto err;
sc->sc_ctl_vq->vq_done = vio_ctrleof;
if (sc->sc_intrmap != NULL)
sc->sc_ctl_vq->vq_intr_vec = 1;
virtio_start_vq_intr(vsc, sc->sc_ctl_vq);
}
if (sc->sc_intrmap) {
r = virtio_intr_establish(vsc, va, 0, NULL, vio_config_intr,
vsc);
if (r != 0) {
printf("%s: cannot alloc config intr: %d\n",
sc->sc_dev.dv_xname, r);
goto err;
}
r = virtio_intr_establish(vsc, va, 1, NULL, vio_ctrl_intr,
sc->sc_ctl_vq);
if (r != 0) {
printf("%s: cannot alloc ctrl intr: %d\n",
sc->sc_dev.dv_xname, r);
goto err;
}
for (i = 0; i < sc->sc_nqueues; i++) {
struct cpu_info *ci = NULL;
ci = intrmap_cpu(sc->sc_intrmap, i);
r = virtio_intr_establish(vsc, va, i + 2, ci,
vio_queue_intr, &sc->sc_q[i]);
if (r != 0) {
printf("%s: cannot alloc q%d intr: %d\n",
sc->sc_dev.dv_xname, i, r);
goto err;
}
}
}
if (vio_alloc_mem(sc, tx_max_segments) < 0)
goto err;
@ -760,6 +856,11 @@ vio_attach(struct device *parent, struct device *self, void *aux)
if (virtio_attach_finish(vsc, va) != 0)
goto err;
if (virtio_has_feature(vsc, VIRTIO_NET_F_MQ)) {
/* ctrl queue works only after DRIVER_OK */
vio_ctrl_mq(sc);
}
if_attach(ifp);
ether_ifattach(ifp);
vio_link_state(ifp);
@ -805,6 +906,33 @@ vio_link_state(struct ifnet *ifp)
}
}
/* interrupt handlers for multi-queue */
int
vio_queue_intr(void *arg)
{
struct vio_queue *vioq = arg;
struct virtio_softc *vsc = vioq->viq_sc->sc_virtio;
int r;
r = virtio_check_vq(vsc, vioq->viq_txvq);
r |= virtio_check_vq(vsc, vioq->viq_rxvq);
return r;
}
int
vio_config_intr(void *arg)
{
struct virtio_softc *vsc = arg;
return vio_config_change(vsc);
}
int
vio_ctrl_intr(void *arg)
{
struct virtqueue *vq = arg;
return virtio_check_vq(vq->vq_owner, vq);
}
int
vio_config_change(struct virtio_softc *vsc)
{
@ -913,6 +1041,8 @@ vio_stop(struct ifnet *ifp, int disable)
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
virtio_start_vq_intr(vsc, sc->sc_ctl_vq);
virtio_reinit_end(vsc);
if (virtio_has_feature(vsc, VIRTIO_NET_F_MQ))
vio_ctrl_mq(sc);
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
vio_ctrl_wakeup(sc, FREE);
}
@ -1137,6 +1267,33 @@ vio_dump(struct vio_softc *sc)
}
#endif
static int
vio_rxr_info(struct vio_softc *sc, struct if_rxrinfo *ifri)
{
struct if_rxring_info *ifrs, *ifr;
int error;
unsigned int i;
ifrs = mallocarray(sc->sc_nqueues, sizeof(*ifrs),
M_TEMP, M_WAITOK|M_ZERO|M_CANFAIL);
if (ifrs == NULL)
return (ENOMEM);
for (i = 0; i < sc->sc_nqueues; i++) {
ifr = &ifrs[i];
ifr->ifr_size = sc->sc_rx_mbuf_size;
snprintf(ifr->ifr_name, sizeof(ifr->ifr_name), "%u", i);
ifr->ifr_info = sc->sc_q[i].viq_rxring;
}
error = if_rxr_info_ioctl(ifri, i, ifrs);
free(ifrs, M_TEMP, i * sizeof(*ifrs));
return (error);
}
int
vio_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
@ -1171,8 +1328,7 @@ vio_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
r = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
break;
case SIOCGIFRXR:
r = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
NULL, sc->sc_rx_mbuf_size, &sc->sc_q[0].viq_rxring);
r = vio_rxr_info(sc, (struct if_rxrinfo *)ifr->ifr_data);
break;
default:
r = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
@ -1666,6 +1822,8 @@ vio_ctrl_submit(struct vio_softc *sc, int slot)
vio_ctrl_wakeup(sc, RESET);
return ENXIO;
}
if (cold)
virtio_check_vq(sc->sc_virtio, sc->sc_ctl_vq);
}
VIO_DMAMEM_SYNC(vsc, sc, sc->sc_ctrl_cmd,
@ -1723,6 +1881,41 @@ vio_ctrl_rx(struct vio_softc *sc, int cmd, int onoff)
return r;
}
/* issue a VIRTIO_NET_CTRL_MQ class command and wait for completion */
int
vio_ctrl_mq(struct vio_softc *sc)
{
struct virtio_softc *vsc = sc->sc_virtio;
struct virtqueue *vq = sc->sc_ctl_vq;
int r, slot;
r = vio_ctrl_start(sc, VIRTIO_NET_CTRL_MQ,
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, 1, &slot);
if (r != 0)
return r;
sc->sc_ctrl_mq_pairs->virtqueue_pairs = sc->sc_nqueues;
vio_dmamem_enqueue(vsc, sc, vq, slot, sc->sc_ctrl_mq_pairs,
sizeof(*sc->sc_ctrl_mq_pairs), 1);
r = vio_ctrl_submit(sc, slot);
VIO_DMAMEM_SYNC(vsc, sc, sc->sc_ctrl_mq_pairs,
sizeof(*sc->sc_ctrl_mq_pairs), BUS_DMASYNC_POSTWRITE);
if (r != 0)
printf("%s: ctrl cmd %d failed\n", sc->sc_dev.dv_xname,
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET);
DPRINTF("%s: cmd %d %d: %d\n", __func__,
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, sc->sc_nqueues, r);
vio_ctrl_finish(sc);
return r;
}
int
vio_ctrl_guest_offloads(struct vio_softc *sc, uint64_t features)
{
@ -1745,7 +1938,7 @@ vio_ctrl_guest_offloads(struct vio_softc *sc, uint64_t features)
VIO_DMAMEM_SYNC(vsc, sc, sc->sc_ctrl_guest_offloads,
sizeof(*sc->sc_ctrl_guest_offloads), BUS_DMASYNC_POSTWRITE);
if (r != 0) {
if (r != 0 && features != 0) {
printf("%s: offload features 0x%llx failed\n",
sc->sc_dev.dv_xname, features);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: virtiovar.h,v 1.27 2025/01/09 10:55:22 sf Exp $ */
/* $OpenBSD: virtiovar.h,v 1.28 2025/01/14 12:30:57 sf Exp $ */
/* $NetBSD: virtiovar.h,v 1.1 2011/10/30 12:12:21 hannken Exp $ */
/*
@ -165,6 +165,8 @@ struct virtio_ops {
int (*attach_finish)(struct virtio_softc *, struct virtio_attach_args *);
int (*poll_intr)(void *);
void (*intr_barrier)(struct virtio_softc *);
int (*intr_establish)(struct virtio_softc *, struct virtio_attach_args *,
int, struct cpu_info *, int (*)(void *), void *);
};
#define VIRTIO_CHILD_ERROR ((void*)1)
@ -208,6 +210,14 @@ struct virtio_softc {
#define virtio_set_status(sc, i) (sc)->sc_ops->set_status(sc, i)
#define virtio_intr_barrier(sc) (sc)->sc_ops->intr_barrier(sc)
/*
* virtio_intr_establish() only works if va_nintr > 1. If it is called by a
* child driver, the transport driver will skip automatic intr allocation and
* the child driver must allocate all required interrupts itself. Vector 0 is
* always used for the config change interrupt.
*/
#define virtio_intr_establish(sc, va, v, ci, fn, a) (sc)->sc_ops->intr_establish(sc, va, v, ci, fn, a)
/* only for transport drivers */
#define virtio_device_reset(sc) virtio_set_status((sc), 0)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_malloc.c,v 1.152 2024/06/26 01:40:49 jsg Exp $ */
/* $OpenBSD: kern_malloc.c,v 1.153 2025/01/14 18:37:51 mvs Exp $ */
/* $NetBSD: kern_malloc.c,v 1.15.4.2 1996/06/13 17:10:56 cgd Exp $ */
/*
@ -50,6 +50,11 @@
#include <ddb/db_output.h>
#endif
/*
* Locks used to protect data:
* I Immutable data
*/
static
#ifndef SMALL_KERNEL
__inline__
@ -95,12 +100,11 @@ struct kmemstats kmemstats[M_LAST];
#endif
struct kmemusage *kmemusage;
char *kmembase, *kmemlimit;
char buckstring[16 * sizeof("123456,")];
char buckstring[16 * sizeof("123456,")]; /* [I] */
int buckstring_init = 0;
#if defined(KMEMSTATS) || defined(DIAGNOSTIC)
char *memname[] = INITKMEMNAMES;
char *memall = NULL;
struct rwlock sysctl_kmemlock = RWLOCK_INITIALIZER("sysctlklk");
char *memall; /* [I] */
#endif
/*
@ -540,6 +544,10 @@ kmeminit(void)
vaddr_t base, limit;
long indx;
#if defined(KMEMSTATS) || defined(DIAGNOSTIC)
int i, siz, totlen;
#endif
#ifdef DIAGNOSTIC
if (sizeof(struct kmem_freelist) > (1 << MINBUCKET))
panic("kmeminit: minbucket too small/struct freelist too big");
@ -577,6 +585,38 @@ kmeminit(void)
for (indx = 0; indx < M_LAST; indx++)
kmemstats[indx].ks_limit =
(long)nkmempages * PAGE_SIZE * 6 / 10;
memset(buckstring, 0, sizeof(buckstring));
for (siz = 0, i = MINBUCKET; i < MINBUCKET + 16; i++) {
snprintf(buckstring + siz, sizeof buckstring - siz,
"%d,", (u_int)(1<<i));
siz += strlen(buckstring + siz);
}
/* Remove trailing comma */
if (siz)
buckstring[siz - 1] = '\0';
#endif
#if defined(KMEMSTATS) || defined(DIAGNOSTIC)
/* Figure out how large a buffer we need */
for (totlen = 0, i = 0; i < M_LAST; i++) {
if (memname[i])
totlen += strlen(memname[i]);
totlen++;
}
memall = malloc(totlen + M_LAST, M_SYSCTL, M_WAITOK|M_ZERO);
for (siz = 0, i = 0; i < M_LAST; i++) {
snprintf(memall + siz, totlen + M_LAST - siz, "%s,",
memname[i] ? memname[i] : "");
siz += strlen(memall + siz);
}
/* Remove trailing comma */
if (siz)
memall[siz - 1] = '\0';
/* Now, convert all spaces to underscores */
for (i = 0; i < totlen; i++) {
if (memall[i] == ' ')
memall[i] = '_';
}
#endif
}
@ -591,10 +631,6 @@ sysctl_malloc(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
#ifdef KMEMSTATS
struct kmemstats km;
#endif
#if defined(KMEMSTATS) || defined(DIAGNOSTIC)
int error;
#endif
int i, siz;
if (namelen != 2 && name[0] != KERN_MALLOC_BUCKETS &&
name[0] != KERN_MALLOC_KMEMNAMES)
@ -602,20 +638,6 @@ sysctl_malloc(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
switch (name[0]) {
case KERN_MALLOC_BUCKETS:
/* Initialize the first time */
if (buckstring_init == 0) {
buckstring_init = 1;
memset(buckstring, 0, sizeof(buckstring));
for (siz = 0, i = MINBUCKET; i < MINBUCKET + 16; i++) {
snprintf(buckstring + siz,
sizeof buckstring - siz,
"%d,", (u_int)(1<<i));
siz += strlen(buckstring + siz);
}
/* Remove trailing comma */
if (siz)
buckstring[siz - 1] = '\0';
}
return (sysctl_rdstring(oldp, oldlenp, newp, buckstring));
case KERN_MALLOC_BUCKET:
@ -635,41 +657,9 @@ sysctl_malloc(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
#else
return (EOPNOTSUPP);
#endif
case KERN_MALLOC_KMEMNAMES:
#if defined(KMEMSTATS) || defined(DIAGNOSTIC)
error = rw_enter(&sysctl_kmemlock, RW_WRITE|RW_INTR);
if (error)
return (error);
if (memall == NULL) {
int totlen;
/* Figure out how large a buffer we need */
for (totlen = 0, i = 0; i < M_LAST; i++) {
if (memname[i])
totlen += strlen(memname[i]);
totlen++;
}
memall = malloc(totlen + M_LAST, M_SYSCTL,
M_WAITOK|M_ZERO);
for (siz = 0, i = 0; i < M_LAST; i++) {
snprintf(memall + siz,
totlen + M_LAST - siz,
"%s,", memname[i] ? memname[i] : "");
siz += strlen(memall + siz);
}
/* Remove trailing comma */
if (siz)
memall[siz - 1] = '\0';
/* Now, convert all spaces to underscores */
for (i = 0; i < totlen; i++)
if (memall[i] == ' ')
memall[i] = '_';
}
rw_exit_write(&sysctl_kmemlock);
case KERN_MALLOC_KMEMNAMES:
return (sysctl_rdstring(oldp, oldlenp, newp, memall));
#else
return (EOPNOTSUPP);
#endif
default:
return (EOPNOTSUPP);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_sysctl.c,v 1.461 2025/01/13 18:09:24 mvs Exp $ */
/* $OpenBSD: kern_sysctl.c,v 1.462 2025/01/14 18:37:51 mvs Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@ -403,6 +403,9 @@ kern_sysctl_dirs(int top_name, int *name, u_int namelen,
int error;
switch (top_name) {
case KERN_MALLOCSTATS:
return (sysctl_malloc(name, namelen, oldp, oldlenp,
newp, newlen, p));
case KERN_POOL:
return (sysctl_dopool(name, namelen, oldp, oldlenp));
#if NAUDIO > 0
@ -454,9 +457,6 @@ kern_sysctl_dirs_locked(int top_name, int *name, u_int namelen,
return (sysctl_doprof(name, namelen, oldp, oldlenp,
newp, newlen));
#endif
case KERN_MALLOCSTATS:
return (sysctl_malloc(name, namelen, oldp, oldlenp,
newp, newlen, p));
case KERN_TTY:
return (sysctl_tty(name, namelen, oldp, oldlenp,
newp, newlen));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_timer.c,v 1.80 2025/01/05 12:18:48 bluhm Exp $ */
/* $OpenBSD: tcp_timer.c,v 1.81 2025/01/14 13:49:44 bluhm Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
@ -106,6 +106,36 @@ tcp_timer_init(void)
tcp_delack_msecs = TCP_DELACK_MSECS;
}
static inline int
tcp_timer_enter(struct inpcb *inp, struct socket **so, struct tcpcb **tp,
u_int timer)
{
KASSERT(timer < TCPT_NTIMERS);
NET_LOCK_SHARED();
*so = in_pcbsolock_ref(inp);
if (*so == NULL) {
*tp = NULL;
return -1;
}
*tp = intotcpcb(inp);
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
if (*tp == NULL || !ISSET((*tp)->t_flags, TF_TIMER << timer) ||
timeout_pending(&(*tp)->t_timer[timer]))
return -1;
CLR((*tp)->t_flags, TF_TIMER << timer);
return 0;
}
static inline void
tcp_timer_leave(struct inpcb *inp, struct socket *so)
{
in_pcbsounlock_rele(inp, so);
NET_UNLOCK_SHARED();
in_pcbunref(inp);
}
/*
* Callout to process delayed ACKs for a TCPCB.
*/
@ -113,6 +143,7 @@ void
tcp_timer_delack(void *arg)
{
struct inpcb *inp = arg;
struct socket *so;
struct tcpcb *otp = NULL, *tp;
short ostate;
@ -121,15 +152,10 @@ tcp_timer_delack(void *arg)
* for whatever reason, it will restart the delayed
* ACK callout.
*/
NET_LOCK();
tp = intotcpcb(inp);
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_DELACK) ||
timeout_pending(&tp->t_timer[TCPT_DELACK]))
if (tcp_timer_enter(inp, &so, &tp, TCPT_DELACK))
goto out;
CLR(tp->t_flags, TF_TMR_DELACK);
if (inp->inp_socket->so_options & SO_DEBUG) {
if (so->so_options & SO_DEBUG) {
otp = tp;
ostate = tp->t_state;
}
@ -138,8 +164,7 @@ tcp_timer_delack(void *arg)
if (otp)
tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_DELACK, 0);
out:
NET_UNLOCK();
in_pcbunref(inp);
tcp_timer_leave(inp, so);
}
/*
@ -199,19 +224,15 @@ void
tcp_timer_rexmt(void *arg)
{
struct inpcb *inp = arg;
struct socket *so;
struct tcpcb *otp = NULL, *tp;
uint32_t rto;
short ostate;
uint32_t rto;
NET_LOCK();
tp = intotcpcb(inp);
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_REXMT) ||
timeout_pending(&tp->t_timer[TCPT_REXMT]))
if (tcp_timer_enter(inp, &so, &tp, TCPT_REXMT))
goto out;
CLR(tp->t_flags, TF_TMR_REXMT);
if ((tp->t_flags & TF_PMTUD_PEND) && inp &&
if ((tp->t_flags & TF_PMTUD_PEND) &&
SEQ_GEQ(tp->t_pmtud_th_seq, tp->snd_una) &&
SEQ_LT(tp->t_pmtud_th_seq, (int)(tp->snd_una + tp->t_maxseg))) {
struct sockaddr_in sin;
@ -249,7 +270,7 @@ tcp_timer_rexmt(void *arg)
tp->t_softerror : ETIMEDOUT);
goto out;
}
if (inp->inp_socket->so_options & SO_DEBUG) {
if (so->so_options & SO_DEBUG) {
otp = tp;
ostate = tp->t_state;
}
@ -270,13 +291,13 @@ tcp_timer_rexmt(void *arg)
* lots more sophisticated searching to find the right
* value here...
*/
if (ip_mtudisc && inp &&
if (ip_mtudisc &&
TCPS_HAVEESTABLISHED(tp->t_state) &&
tp->t_rxtshift > TCP_MAXRXTSHIFT / 6) {
struct rtentry *rt = NULL;
/* No data to send means path mtu is not a problem */
if (!inp->inp_socket->so_snd.sb_cc)
if (!READ_ONCE(so->so_snd.sb_cc))
goto leave;
rt = in_pcbrtentry(inp);
@ -391,31 +412,26 @@ tcp_timer_rexmt(void *arg)
if (otp)
tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_REXMT, 0);
out:
NET_UNLOCK();
in_pcbunref(inp);
tcp_timer_leave(inp, so);
}
void
tcp_timer_persist(void *arg)
{
struct inpcb *inp = arg;
struct socket *so;
struct tcpcb *otp = NULL, *tp;
uint32_t rto;
short ostate;
uint64_t now;
uint32_t rto;
NET_LOCK();
tp = intotcpcb(inp);
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_PERSIST) ||
timeout_pending(&tp->t_timer[TCPT_PERSIST]))
if (tcp_timer_enter(inp, &so, &tp, TCPT_PERSIST))
goto out;
CLR(tp->t_flags, TF_TMR_PERSIST);
if (TCP_TIMER_ISARMED(tp, TCPT_REXMT))
goto out;
if (inp->inp_socket->so_options & SO_DEBUG) {
if (so->so_options & SO_DEBUG) {
otp = tp;
ostate = tp->t_state;
}
@ -445,26 +461,21 @@ tcp_timer_persist(void *arg)
if (otp)
tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_PERSIST, 0);
out:
NET_UNLOCK();
in_pcbunref(inp);
tcp_timer_leave(inp, so);
}
void
tcp_timer_keep(void *arg)
{
struct inpcb *inp = arg;
struct socket *so;
struct tcpcb *otp = NULL, *tp;
short ostate;
NET_LOCK();
tp = intotcpcb(inp);
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_KEEP) ||
timeout_pending(&tp->t_timer[TCPT_KEEP]))
if (tcp_timer_enter(inp, &so, &tp, TCPT_KEEP))
goto out;
CLR(tp->t_flags, TF_TMR_KEEP);
if (inp->inp_socket->so_options & SO_DEBUG) {
if (so->so_options & SO_DEBUG) {
otp = tp;
ostate = tp->t_state;
}
@ -475,7 +486,7 @@ tcp_timer_keep(void *arg)
goto out;
}
if ((atomic_load_int(&tcp_always_keepalive) ||
inp->inp_socket->so_options & SO_KEEPALIVE) &&
so->so_options & SO_KEEPALIVE) &&
tp->t_state <= TCPS_CLOSING) {
int maxidle;
uint64_t now;
@ -509,28 +520,23 @@ tcp_timer_keep(void *arg)
if (otp)
tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_KEEP, 0);
out:
NET_UNLOCK();
in_pcbunref(inp);
tcp_timer_leave(inp, so);
}
void
tcp_timer_2msl(void *arg)
{
struct inpcb *inp = arg;
struct socket *so;
struct tcpcb *otp = NULL, *tp;
short ostate;
int maxidle;
uint64_t now;
int maxidle;
NET_LOCK();
tp = intotcpcb(inp);
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_2MSL) ||
timeout_pending(&tp->t_timer[TCPT_2MSL]))
if (tcp_timer_enter(inp, &so, &tp, TCPT_2MSL))
goto out;
CLR(tp->t_flags, TF_TMR_2MSL);
if (inp->inp_socket->so_options & SO_DEBUG) {
if (so->so_options & SO_DEBUG) {
otp = tp;
ostate = tp->t_state;
}
@ -546,8 +552,7 @@ tcp_timer_2msl(void *arg)
if (otp)
tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_2MSL, 0);
out:
NET_UNLOCK();
in_pcbunref(inp);
tcp_timer_leave(inp, so);
}
void

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rde_rib.c,v 1.266 2024/12/12 20:19:03 claudio Exp $ */
/* $OpenBSD: rde_rib.c,v 1.267 2025/01/14 12:24:23 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@ -1273,6 +1273,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
/* nothing changed */
p->validation_state = state->vstate;
p->lastchange = getmonotime();
p->flags &= ~PREFIX_FLAG_STALE;
return;
}
@ -1343,6 +1344,7 @@ prefix_adjout_withdraw(struct prefix *p)
/* already a withdraw, shortcut */
if (p->flags & PREFIX_FLAG_WITHDRAW) {
p->lastchange = getmonotime();
p->flags &= ~PREFIX_FLAG_STALE;
return;
}
/* pending update just got withdrawn */