From 84d7ec4c657f406c6cbd29baf32c8e057b663d17 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Thu, 31 Oct 2024 10:04:11 -0400 Subject: [PATCH 01/20] bnxt: Use IfAPI accessors where able Summary: Don't directly access ifnet members, it's a private structure. Sponsored by: Juniper Networks, Inc. Differential Revision: https://reviews.freebsd.org/D47353 --- sys/dev/bnxt/bnxt_re/bnxt_re.h | 4 ++-- sys/dev/bnxt/bnxt_re/ib_verbs.c | 6 +++--- sys/dev/bnxt/bnxt_re/main.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/dev/bnxt/bnxt_re/bnxt_re.h b/sys/dev/bnxt/bnxt_re/bnxt_re.h index 56b3c8c0488c..fe7a27f4e216 100644 --- a/sys/dev/bnxt/bnxt_re/bnxt_re.h +++ b/sys/dev/bnxt/bnxt_re/bnxt_re.h @@ -946,8 +946,8 @@ int bnxt_re_setup_cnp_cos(struct bnxt_re_dev *rdev, bool reset); static inline enum ib_port_state bnxt_re_get_link_state(struct bnxt_re_dev *rdev) { - if (rdev->netdev->if_drv_flags & IFF_DRV_RUNNING && - rdev->netdev->if_link_state == LINK_STATE_UP) + if (if_getdrvflags(rdev->netdev) & IFF_DRV_RUNNING && + if_getlinkstate(rdev->netdev) == LINK_STATE_UP) return IB_PORT_ACTIVE; return IB_PORT_DOWN; } diff --git a/sys/dev/bnxt/bnxt_re/ib_verbs.c b/sys/dev/bnxt/bnxt_re/ib_verbs.c index 8d43fa96c048..0383a16757aa 100644 --- a/sys/dev/bnxt/bnxt_re/ib_verbs.c +++ b/sys/dev/bnxt/bnxt_re/ib_verbs.c @@ -299,7 +299,7 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num, if (port_attr->state == IB_PORT_ACTIVE) port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP; port_attr->max_mtu = IB_MTU_4096; - port_attr->active_mtu = iboe_get_mtu(rdev->netdev->if_mtu); + port_attr->active_mtu = iboe_get_mtu(if_getmtu(rdev->netdev)); port_attr->gid_tbl_len = dev_attr->max_sgid; port_attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP | IB_PORT_DEVICE_MGMT_SUP | @@ -2118,7 +2118,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom; qplqp->max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; } - qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->if_mtu)); + qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(if_getmtu(rdev->netdev))); qplqp->dpi = &rdev->dpi_privileged; /* Doorbell page */ if (init_attr->create_flags) { dev_dbg(rdev_to_dev(rdev), @@ -2691,7 +2691,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, /* MTU settings allowed only during INIT -> RTR */ if (qp_attr->qp_state == IB_QPS_RTR) { - bnxt_re_init_qpmtu(qp, rdev->netdev->if_mtu, qp_attr_mask, qp_attr, + bnxt_re_init_qpmtu(qp, if_getmtu(rdev->netdev), qp_attr_mask, qp_attr, &is_qpmtu_high); if (udata && !ib_copy_from_udata(&ureq, udata, sizeof(ureq))) { if (ureq.comp_mask & BNXT_RE_COMP_MASK_MQP_EX_PATH_MTU_MASK) { diff --git a/sys/dev/bnxt/bnxt_re/main.c b/sys/dev/bnxt/bnxt_re/main.c index e6c6f754ea47..3d26d21f3fc7 100644 --- a/sys/dev/bnxt/bnxt_re/main.c +++ b/sys/dev/bnxt/bnxt_re/main.c @@ -4168,8 +4168,8 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, dev_info(rdev_to_dev(rdev), "%s: Event = %s (0x%lx), rdev %s (real_dev %s)\n", __func__, bnxt_re_netevent(event), event, - rdev ? rdev->netdev ? rdev->netdev->if_dname : "->netdev = NULL" : "= NULL", - (real_dev == netdev) ? "= netdev" : real_dev->if_dname); + rdev ? rdev->netdev ? if_getdname(rdev->netdev) : "->netdev = NULL" : "= NULL", + (real_dev == netdev) ? "= netdev" : if_getdname(real_dev)); if (!test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) goto exit; From 3f2eb1ac2326826383e919383554d14a69a5321d Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Thu, 31 Oct 2024 10:53:43 -0400 Subject: [PATCH 02/20] dummymbuf: Explicitly include if_private.h struct ifnet is expected to be private for everything outside of the network stack (sys/net*, except netlink. Since dummymbuf is part of the network stack, explicitly include the header to get access to the private members. Sponsored by: Juniper Networks, Inc. --- sys/net/dummymbuf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/net/dummymbuf.c b/sys/net/dummymbuf.c index f7aef562c8d2..d73566759ed3 100644 --- a/sys/net/dummymbuf.c +++ b/sys/net/dummymbuf.c @@ -37,6 +37,7 @@ #include #include +#include #include #include From b224af946a17b8e7a7b4942157556b5bc86dd6fb Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Thu, 31 Oct 2024 11:09:48 -0400 Subject: [PATCH 03/20] netlink: Don't directly access ifnet members Summary: Remove the final direct access of struct ifnet members from netlink. Since only the first address is used, create the iterator and then free, without fully iterating. Reviewed By: kp Sponsored by: Juniper Networks, Inc. Differential Revision: https://reviews.freebsd.org/D42972 --- sys/netlink/route/iface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c index 7d33c89a396a..48fdab6a8475 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -322,11 +322,13 @@ dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr, */ if (if_getaddrlen(ifp) != 0) { struct ifaddr *ifa; + struct ifa_iter it; NET_EPOCH_ENTER(et); - ifa = CK_STAILQ_FIRST(&ifp->if_addrhead); + ifa = ifa_iter_start(ifp, &it); if (ifa != NULL) dump_sa(nw, IFLA_ADDRESS, ifa->ifa_addr); + ifa_iter_finish(&it); NET_EPOCH_EXIT(et); } From 1eaecc214ea2bfde84f4194c1d0e20b18117343f Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 8 Nov 2024 15:22:11 -0500 Subject: [PATCH 04/20] qlnx: Convert recent changes to IfAPI Sponsored by: Juniper Networks, Inc. Reviewed by: zlei Differential Revision: https://reviews.freebsd.org/D47533 --- sys/dev/qlnx/qlnxe/qlnx_os.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/dev/qlnx/qlnxe/qlnx_os.c b/sys/dev/qlnx/qlnxe/qlnx_os.c index 49d3f20aa0c2..a984908abf34 100644 --- a/sys/dev/qlnx/qlnxe/qlnx_os.c +++ b/sys/dev/qlnx/qlnxe/qlnx_os.c @@ -2624,6 +2624,7 @@ static int qlnx_ioctl(if_t ifp, u_long cmd, caddr_t data) { int ret = 0, mask; + int flags; struct ifreq *ifr = (struct ifreq *)data; #ifdef INET struct ifaddr *ifa = (struct ifaddr *)data; @@ -2677,15 +2678,16 @@ qlnx_ioctl(if_t ifp, u_long cmd, caddr_t data) QL_DPRINT4(ha, "SIOCSIFFLAGS (0x%lx)\n", cmd); QLNX_LOCK(ha); + flags = if_getflags(ifp); - if (if_getflags(ifp) & IFF_UP) { + if (flags & IFF_UP) { if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { - if ((if_getflags(ifp) ^ ha->if_flags) & + if ((flags ^ ha->if_flags) & IFF_PROMISC) { - ret = qlnx_set_promisc(ha, ifp->if_flags & IFF_PROMISC); + ret = qlnx_set_promisc(ha, flags & IFF_PROMISC); } else if ((if_getflags(ifp) ^ ha->if_flags) & IFF_ALLMULTI) { - ret = qlnx_set_allmulti(ha, ifp->if_flags & IFF_ALLMULTI); + ret = qlnx_set_allmulti(ha, flags & IFF_ALLMULTI); } } else { ha->max_frame_size = if_getmtu(ifp) + @@ -7055,12 +7057,14 @@ qlnx_set_rx_mode(qlnx_host_t *ha) { int rc = 0; uint8_t filter; - const struct ifnet *ifp = ha->ifp; + const if_t ifp = ha->ifp; + const struct ifaddr *ifa; struct sockaddr_dl *sdl; - if (ifp->if_type == IFT_ETHER && ifp->if_addr != NULL && - ifp->if_addr->ifa_addr != NULL) { - sdl = (struct sockaddr_dl *) ifp->if_addr->ifa_addr; + ifa = if_getifaddr(ifp); + if (if_gettype(ifp) == IFT_ETHER && ifa != NULL && + ifa->ifa_addr != NULL) { + sdl = (struct sockaddr_dl *) ifa->ifa_addr; rc = qlnx_set_ucast_rx_mac(ha, ECORE_FILTER_REPLACE, LLADDR(sdl)); } else { @@ -7077,10 +7081,10 @@ qlnx_set_rx_mode(qlnx_host_t *ha) ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST; - if (qlnx_vf_device(ha) == 0 || (ha->ifp->if_flags & IFF_PROMISC)) { + if (qlnx_vf_device(ha) == 0 || (if_getflags(ha->ifp) & IFF_PROMISC)) { filter |= ECORE_ACCEPT_UCAST_UNMATCHED; filter |= ECORE_ACCEPT_MCAST_UNMATCHED; - } else if (ha->ifp->if_flags & IFF_ALLMULTI) { + } else if (if_getflags(ha->ifp) & IFF_ALLMULTI) { filter |= ECORE_ACCEPT_MCAST_UNMATCHED; } ha->filter = filter; From 4d0c95384f9b2c2691459f22d68f0a2c8b2383c9 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 8 Nov 2024 15:22:49 -0500 Subject: [PATCH 05/20] net: Include private header in more needed places sys/netinet and sys/netipsec are both part of the 'blessed' netstack, so can access struct ifnet directly. With this structure becoming private very soon, the necessary files need to get direct access. Sponsored by: Juniper Networks, Inc. --- sys/netinet/tcp_lro_hpts.c | 1 + sys/netipsec/ipsec_offload.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/netinet/tcp_lro_hpts.c b/sys/netinet/tcp_lro_hpts.c index cd757d5a6164..d56967a12809 100644 --- a/sys/netinet/tcp_lro_hpts.c +++ b/sys/netinet/tcp_lro_hpts.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include diff --git a/sys/netipsec/ipsec_offload.c b/sys/netipsec/ipsec_offload.c index 19719a8f171b..d57ac3826012 100644 --- a/sys/netipsec/ipsec_offload.c +++ b/sys/netipsec/ipsec_offload.c @@ -44,6 +44,7 @@ #include #include +#include #include #include #include From 57609cb2de149a3c99c43e98d37cfa4784958f73 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Tue, 12 Nov 2024 10:01:00 -0500 Subject: [PATCH 06/20] LinuxKPI: Use IfAPI to get LLADDR Reviewed by: bz, emaste Differential Revision: https://reviews.freebsd.org/D47525 --- sys/compat/linuxkpi/common/src/linux_80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 9d0166829d52..543a11b1f729 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -2783,7 +2783,7 @@ lkpi_vif_iflladdr(void *arg, struct ifnet *ifp) } vif = arg; - IEEE80211_ADDR_COPY(vif->bss_conf.addr, IF_LLADDR(ifp)); + IEEE80211_ADDR_COPY(vif->bss_conf.addr, if_getlladdr(ifp)); NET_EPOCH_EXIT(et); } From f6efccaa35fe07f5659dd5d84769f56453f12169 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 8 Nov 2024 14:42:19 -0500 Subject: [PATCH 07/20] IfAPI: Remove temporary inclusion of if_private.h Summary: The kernel is now fully migrated to the IfAPI, so remove the temporary inclusion of the private structure definition. Reviewed By: #network, melifaro Differential Revision: https://reviews.freebsd.org/D39621 --- sys/net/if_var.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/net/if_var.h b/sys/net/if_var.h index cd074e4a8f4e..a0271cfe2a7c 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -753,7 +753,6 @@ int ether_poll_deregister(if_t ifp); #endif /* _KERNEL */ -#include /* XXX: temporary until drivers converted. */ #include /* XXXAO: temporary unconditional include */ #endif /* !_NET_IF_VAR_H_ */ From c1d93f81e49c5c32262eefcd087b9c5582e0f83c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 12 Nov 2024 08:22:06 +0200 Subject: [PATCH 08/20] bufwrite(): style Use bool for vp_md. Compactify the calculation. Explicitly check for non-zero when testing flags. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/kern/vfs_bio.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 7bcc61c27109..3ef715baebfa 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -2304,10 +2304,10 @@ breadn_flags(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, int bufwrite(struct buf *bp) { - int oldflags; struct vnode *vp; long space; - int vp_md; + int oldflags, retval; + bool vp_md; CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags); if ((bp->b_bufobj->bo_flag & BO_DEAD) != 0) { @@ -2316,24 +2316,21 @@ bufwrite(struct buf *bp) brelse(bp); return (ENXIO); } - if (bp->b_flags & B_INVAL) { + if ((bp->b_flags & B_INVAL) != 0) { brelse(bp); return (0); } - if (bp->b_flags & B_BARRIER) + if ((bp->b_flags & B_BARRIER) != 0) atomic_add_long(&barrierwrites, 1); oldflags = bp->b_flags; - KASSERT(!(bp->b_vflags & BV_BKGRDINPROG), + KASSERT((bp->b_vflags & BV_BKGRDINPROG) == 0, ("FFS background buffer should not get here %p", bp)); vp = bp->b_vp; - if (vp) - vp_md = vp->v_vflag & VV_MD; - else - vp_md = 0; + vp_md = vp != NULL && (vp->v_vflag & VV_MD) != 0; /* * Mark the buffer clean. Increment the bufobj write count @@ -2365,19 +2362,19 @@ bufwrite(struct buf *bp) } #endif /* RACCT */ curthread->td_ru.ru_oublock++; - if (oldflags & B_ASYNC) + if ((oldflags & B_ASYNC) != 0) BUF_KERNPROC(bp); bp->b_iooffset = dbtob(bp->b_blkno); buf_track(bp, __func__); bstrategy(bp); if ((oldflags & B_ASYNC) == 0) { - int rtval = bufwait(bp); + retval = bufwait(bp); brelse(bp); - return (rtval); + return (retval); } else if (space > hirunningspace) { /* - * don't allow the async write to saturate the I/O + * Don't allow the async write to saturate the I/O * system. We will not deadlock here because * we are blocking waiting for I/O that is already in-progress * to complete. We do not block here if it is the update From d0b41249bfbe4481baec8f1659468ffbb30388ab Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 12 Nov 2024 08:24:03 +0200 Subject: [PATCH 09/20] bufwrite(): adjust the comment The statement about 'do not deadlock there' is false, since this write might need other writes to finish, which cannot be started due to runningbufspace. PR: 282449 Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/kern/vfs_bio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 3ef715baebfa..62b0567f269a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -2375,11 +2375,9 @@ bufwrite(struct buf *bp) } else if (space > hirunningspace) { /* * Don't allow the async write to saturate the I/O - * system. We will not deadlock here because - * we are blocking waiting for I/O that is already in-progress - * to complete. We do not block here if it is the update - * or syncer daemon trying to clean up as that can lead - * to deadlock. + * system. We do not block here if it is the update + * or syncer daemon trying to clean up as that can + * lead to deadlock. */ if ((curthread->td_pflags & TDP_NORUNNINGBUF) == 0 && !vp_md) waitrunningbufspace(); From 46f02c4282ff76b66579c83be53ef441ea522536 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 12 Nov 2024 08:29:23 +0200 Subject: [PATCH 10/20] SU+J: all writes to SU journal must be exempt from runningbufspace throttling regardless whether they come from the system thread or initiated from a normal thread helping the system. If we block waiting for other writes, that writes might not finish because our journal updates block that. Set TDP_NORUNNINGBUF around softdep_process_journal(). Note: Another solution might be to use bwrite() instead of bawrite() if the current thread is subject to the runningbufspace limit. The exempt approach is used to be same as the bufdaemon. PR: 282449 Noted and reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/ufs/ffs/ffs_softdep.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 97f50867b012..98ad4269b5f2 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -3630,6 +3630,7 @@ softdep_process_journal(struct mount *mp, int cnt; int off; int devbsize; + int savef; ump = VFSTOUFS(mp); if (ump->um_softdep == NULL || ump->um_softdep->sd_jblocks == NULL) @@ -3641,6 +3642,8 @@ softdep_process_journal(struct mount *mp, fs = ump->um_fs; jblocks = ump->softdep_jblocks; devbsize = ump->um_devvp->v_bufobj.bo_bsize; + savef = curthread_pflags_set(TDP_NORUNNINGBUF); + /* * We write anywhere between a disk block and fs block. The upper * bound is picked to prevent buffer cache fragmentation and limit @@ -3859,12 +3862,15 @@ softdep_process_journal(struct mount *mp, */ if (flags == 0 && jblocks->jb_suspended) { if (journal_unsuspend(ump)) - return; + goto out; FREE_LOCK(ump); VFS_SYNC(mp, MNT_NOWAIT); ffs_sbupdate(ump, MNT_WAIT, 0); ACQUIRE_LOCK(ump); } + +out: + curthread_pflags_restore(savef); } /* From ab05a1cf321aca0fe632c1ab40f68630b477422c Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Wed, 13 Nov 2024 11:37:14 -0800 Subject: [PATCH 11/20] Revert commit 8733bc277a383cf59f38a83956f4f523869cfc90 Author: Mateusz Guzik Date: Thu Sep 14 16:13:01 2023 +0000 vfs: don't provoke recycling non-free vnodes without a good reason If the total number of free vnodes is at or above target, there is no point creating more of them. This commit was done as a performance optimization but ends up causing slowdowns when doing operations on many files. Requested by: re (cperciva) MFC after: 1 minute --- sys/kern/vfs_subr.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 3b00fdbe93b4..f9b2a4fb68d1 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1992,25 +1992,11 @@ vn_alloc_hard(struct mount *mp, u_long rnumvnodes, bool bumped) mtx_lock(&vnode_list_mtx); - if (vn_alloc_cyclecount != 0) { - rnumvnodes = atomic_load_long(&numvnodes); - if (rnumvnodes + 1 < desiredvnodes) { - vn_alloc_cyclecount = 0; - mtx_unlock(&vnode_list_mtx); - goto alloc; - } - - rfreevnodes = vnlru_read_freevnodes(); - if (rfreevnodes < wantfreevnodes) { - if (vn_alloc_cyclecount++ >= rfreevnodes) { - vn_alloc_cyclecount = 0; - vstir = true; - } - } else { - vn_alloc_cyclecount = 0; - } + rfreevnodes = vnlru_read_freevnodes(); + if (vn_alloc_cyclecount++ >= rfreevnodes) { + vn_alloc_cyclecount = 0; + vstir = true; } - /* * Grow the vnode cache if it will not be above its target max after * growing. Otherwise, if there is at least one free vnode, try to From 01e186731a141d106ff5bee5a41412e7e2582a78 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 13 Nov 2024 15:07:32 -0500 Subject: [PATCH 12/20] g_eli: update comment for bool return type Fixes: 68eadcec0f7c8 ("Give a couple of predication functions a bool return type.") Sponsored by: The FreeBSD Foundation --- sys/geom/mirror/g_mirror.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index b46296fd211c..25c0490938ef 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -1222,7 +1222,7 @@ g_mirror_start(struct bio *bp) } /* - * Return TRUE if the given request is colliding with a in-progress + * Return true if the given request is colliding with a in-progress * synchronization request. */ static bool @@ -1254,7 +1254,7 @@ g_mirror_sync_collision(struct g_mirror_softc *sc, struct bio *bp) } /* - * Return TRUE if the given sync request is colliding with a in-progress regular + * Return true if the given sync request is colliding with a in-progress regular * request. */ static bool From ac5e30a8073f95a4764c939cde29adae51229bdd Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Wed, 13 Nov 2024 11:26:39 +0100 Subject: [PATCH 13/20] pf: add probe points to pf_route(6)() Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 71 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 691cb697a659..daf3fcf567ad 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -126,6 +126,14 @@ SDT_PROBE_DEFINE5(pf, ip, state, lookup, "struct pfi_kkif *", "struct pf_kstate *"); SDT_PROBE_DEFINE2(pf, ip, , bound_iface, "struct pf_kstate *", "struct pfi_kkif *"); +SDT_PROBE_DEFINE4(pf, ip, route_to, entry, "struct mbuf *", + "struct pf_pdesc *", "struct pf_kstate *", "struct ifnet *"); +SDT_PROBE_DEFINE1(pf, ip, route_to, drop, "int"); +SDT_PROBE_DEFINE2(pf, ip, route_to, output, "struct ifnet *", "int"); +SDT_PROBE_DEFINE4(pf, ip6, route_to, entry, "struct mbuf *", + "struct pf_pdesc *", "struct pf_kstate *", "struct ifnet *"); +SDT_PROBE_DEFINE1(pf, ip6, route_to, drop, "int"); +SDT_PROBE_DEFINE2(pf, ip6, route_to, output, "struct ifnet *", "int"); SDT_PROBE_DEFINE4(pf, sctp, multihome, test, "struct pfi_kkif *", "struct pf_krule *", "struct mbuf *", "int"); SDT_PROBE_DEFINE2(pf, sctp, multihome, add, "uint32_t", @@ -7660,6 +7668,8 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); + SDT_PROBE4(pf, ip, route_to, entry, *m, pd, s, oifp); + if (s) { r_rt = s->rt; r_dir = s->direction; @@ -7677,6 +7687,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, pd->pf_mtag->routed++ > 3) { m0 = *m; *m = NULL; + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad_locked; } @@ -7699,6 +7710,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } else { m0 = *m; *m = NULL; + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad; } } else { @@ -7732,6 +7744,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, if (TAILQ_EMPTY(&r->rpool.list)) { DPFPRINTF(PF_DEBUG_URGENT, ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad_locked; } pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, @@ -7764,18 +7777,24 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, PF_STATE_UNLOCK(s); } - if (ifp == NULL) + if (ifp == NULL) { + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad; + } if (pd->dir == PF_IN) { if (pf_test(AF_INET, PF_OUT, PFIL_FWD, ifp, &m0, inp, - &pd->act) != PF_PASS) + &pd->act) != PF_PASS) { + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad; - else if (m0 == NULL) + } else if (m0 == NULL) { + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto done; + } if (m0->m_len < sizeof(struct ip)) { DPFPRINTF(PF_DEBUG_URGENT, ("%s: m0->m_len < sizeof(struct ip)\n", __func__)); + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad; } ip = mtod(m0, struct ip *); @@ -7834,8 +7853,10 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, md = m0; error = pf_dummynet_route(pd, s, r, ifp, sintosa(&dst), &md); - if (md != NULL) + if (md != NULL) { error = (*ifp->if_output)(ifp, md, sintosa(&dst), NULL); + SDT_PROBE2(pf, ip, route_to, output, ifp, error); + } goto done; } @@ -7851,14 +7872,19 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, ifp->if_mtu); + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto done; - } else + } else { + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad; + } } error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist); - if (error) + if (error) { + SDT_PROBE1(pf, ip, route_to, drop, __LINE__); goto bad; + } for (; m0; m0 = m1) { m1 = m0->m_nextpkt; @@ -7869,9 +7895,11 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, pd->pf_mtag = pf_find_mtag(md); error = pf_dummynet_route(pd, s, r, ifp, sintosa(&dst), &md); - if (md != NULL) + if (md != NULL) { error = (*ifp->if_output)(ifp, md, sintosa(&dst), NULL); + SDT_PROBE2(pf, ip, route_to, output, ifp, error); + } } else m_freem(m0); } @@ -7908,6 +7936,8 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); + SDT_PROBE4(pf, ip6, route_to, entry, *m, pd, s, oifp); + if (s) { r_rt = s->rt; r_dir = s->direction; @@ -7925,6 +7955,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, pd->pf_mtag->routed++ > 3) { m0 = *m; *m = NULL; + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad_locked; } @@ -7947,6 +7978,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } else { m0 = *m; *m = NULL; + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad; } } else { @@ -7980,6 +8012,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, if (TAILQ_EMPTY(&r->rpool.list)) { DPFPRINTF(PF_DEBUG_URGENT, ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad_locked; } pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, @@ -8014,19 +8047,25 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, if (s) PF_STATE_UNLOCK(s); - if (ifp == NULL) + if (ifp == NULL) { + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad; + } if (pd->dir == PF_IN) { if (pf_test(AF_INET6, PF_OUT, PFIL_FWD, ifp, &m0, inp, - &pd->act) != PF_PASS) + &pd->act) != PF_PASS) { + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad; - else if (m0 == NULL) + } else if (m0 == NULL) { + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto done; + } if (m0->m_len < sizeof(struct ip6_hdr)) { DPFPRINTF(PF_DEBUG_URGENT, ("%s: m0->m_len < sizeof(struct ip6_hdr)\n", __func__)); + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad; } ip6 = mtod(m0, struct ip6_hdr *); @@ -8051,8 +8090,11 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { md = m0; pf_dummynet_route(pd, s, r, ifp, sintosa(&dst), &md); - if (md != NULL) - nd6_output_ifp(ifp, ifp, md, &dst, NULL); + if (md != NULL) { + int ret; + ret = nd6_output_ifp(ifp, ifp, md, &dst, NULL); + SDT_PROBE2(pf, ip6, route_to, output, ifp, ret); + } } else { in6_ifstat_inc(ifp, ifs6_in_toobig); @@ -8063,8 +8105,11 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, sizeof(struct ip6_hdr), s); icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); - } else + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); + } else { + SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); goto bad; + } } done: From 1da4954c92ea7585b352ba830d3ee64ca69ada52 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Tue, 12 Nov 2024 23:36:50 +0000 Subject: [PATCH 14/20] Fix failure to add an interface prefix route when route with the same prefix is already presented in the routing table. PR: 277125 Reported by: Oleksandr Ignatyev Reviewed by: ae, jlduran Tested by: jlduran Differential Revision: https://reviews.freebsd.org/D47534 MFC after: 2 weeks --- sys/net/route/route_ctl.c | 13 ++++++++----- sys/net/route/route_ctl.h | 10 +++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index a07a58737c1c..d7756f2a0eb6 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -772,12 +772,15 @@ add_route_byinfo(struct rib_head *rnh, struct rt_addrinfo *info, rnd_add.rnd_weight = get_info_weight(info, RT_DEFAULT_WEIGHT); int op_flags = RTM_F_CREATE; - if (get_prio_from_info(info) == NH_PRIORITY_HIGH) - op_flags |= RTM_F_FORCE; - else - op_flags |= RTM_F_APPEND; - return (add_route_flags(rnh, rt, &rnd_add, op_flags, rc)); + /* + * Set the desired action when the route already exists: + * If RTF_PINNED is present, assume the direct kernel routes that cannot be multipath. + * Otherwise, append the path. + */ + op_flags |= (info->rti_flags & RTF_PINNED) ? RTM_F_REPLACE : RTM_F_APPEND; + + return (add_route_flags(rnh, rt, &rnd_add, op_flags, rc)); } static int diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h index 140f14aa9e4f..845df8ce1fbe 100644 --- a/sys/net/route/route_ctl.h +++ b/sys/net/route/route_ctl.h @@ -61,11 +61,11 @@ int rib_del_route_px_gw(uint32_t fibnum, struct sockaddr *dst, int plen, const struct sockaddr *gw, int op_flags, struct rib_cmd_info *rc); /* operation flags */ -#define RTM_F_CREATE 0x01 -#define RTM_F_EXCL 0x02 -#define RTM_F_REPLACE 0x04 -#define RTM_F_APPEND 0x08 -#define RTM_F_FORCE 0x10 +#define RTM_F_CREATE 0x01 /* Create object if not exists */ +#define RTM_F_EXCL 0x02 /* (Deprecated) Do not replace or append if exists */ +#define RTM_F_REPLACE 0x04 /* Replace if route (even multipath) if exists */ +#define RTM_F_APPEND 0x08 /* Append path to the route */ +#define RTM_F_FORCE 0x10 /* Bump operation priority to highest */ int rib_add_route(uint32_t fibnum, struct rt_addrinfo *info, struct rib_cmd_info *rc); From a4b7367eb027a99b9eb48bf18951049434a9e189 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 13 Nov 2024 16:12:42 -0600 Subject: [PATCH 15/20] timedef: remove redundancy in Catalan date_fmt definitions This is already factored into the month names, resulting in an awkward construction: $ env LC_ALL=ca_ES.UTF-8 date dimecres, 6 de de novembre de 2024, 21:21:18 CST This would now render as: $ env LC_ALL=ca_ES.UTF-8 date dimecres, 6 de novembre de 2024, 21:22:41 CST Reviewed by: bapt, royger Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D47471 --- share/timedef/ca_IT.ISO8859-15.src | 2 +- share/timedef/ca_IT.UTF-8.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/timedef/ca_IT.ISO8859-15.src b/share/timedef/ca_IT.ISO8859-15.src index 669fbab13074..7c625aad19b5 100644 --- a/share/timedef/ca_IT.ISO8859-15.src +++ b/share/timedef/ca_IT.ISO8859-15.src @@ -59,7 +59,7 @@ a. m. p. m. # # date_fmt -%A, %e de %B de %Y, %X %Z +%A, %e %B de %Y, %X %Z # # Long month names (without case ending) de gener diff --git a/share/timedef/ca_IT.UTF-8.src b/share/timedef/ca_IT.UTF-8.src index 5dfd3841d9af..a85dd8c4b942 100644 --- a/share/timedef/ca_IT.UTF-8.src +++ b/share/timedef/ca_IT.UTF-8.src @@ -63,7 +63,7 @@ a. m. p. m. # # date_fmt -%A, %e de %B de %Y, %X %Z +%A, %e %B de %Y, %X %Z # # Long month names (without case ending) de gener From 160c36eae41afa3c4944ed44778c2b48db8fbb77 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 13 Nov 2024 16:12:42 -0600 Subject: [PATCH 16/20] localedata: add some exceptions to utf8proc widths Hangul Jamo medial vowels and final consonants are reportedly combining characters that won't take up any columns on their own and should be reported as zero-width, so add an exception for these as well to reflect how they work in practice. This conforms to how other implementations (e.g., glibc) treat these characters. Reviewed by: bapt (earlier version), jkim Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D47472 --- tools/tools/locale/tools/getwidths.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/tools/locale/tools/getwidths.c b/tools/tools/locale/tools/getwidths.c index 2790b8031912..63c62791253f 100644 --- a/tools/tools/locale/tools/getwidths.c +++ b/tools/tools/locale/tools/getwidths.c @@ -28,6 +28,21 @@ #include +static int +width_of(int32_t wc) +{ + + /* + * Hangul Jamo medial vowels and final consonants are more of + * a combining character, and should be considered zero-width. + */ + if (wc >= 0x1160 && wc <= 0x11ff) + return (0); + + /* No override by default, trust utf8proc's width. */ + return (utf8proc_charwidth(wc)); +} + int main(void) { @@ -43,9 +58,10 @@ main(void) wcc = utf8proc_category(wc); if (wcc == UTF8PROC_CATEGORY_CC) continue; - wcw = utf8proc_charwidth(wc); + wcw = width_of(wc); if (wcw == 1) continue; + printf("%04X %d\n", wc, wcw); } From 0f30aed1056a2e12ca40095debff6735642c4ff4 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 13 Nov 2024 16:12:42 -0600 Subject: [PATCH 17/20] localedata: update widths.txt after recent Hangul exceptions Sponsored by: Klara, Inc. --- tools/tools/locale/etc/final-maps/widths.txt | 160 +++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/tools/tools/locale/etc/final-maps/widths.txt b/tools/tools/locale/etc/final-maps/widths.txt index 93b2e8d7430b..3d0535be3884 100644 --- a/tools/tools/locale/etc/final-maps/widths.txt +++ b/tools/tools/locale/etc/final-maps/widths.txt @@ -859,6 +859,166 @@ WIDTH 2 2 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 0 0 0 From f660777865fcc28e147b51362412e0286e7df78e Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 13 Nov 2024 16:18:40 -0600 Subject: [PATCH 18/20] _utmx_op: don't recurse on chain busy In handling a PP mutex, we'll busy it as soon as we enter the loop and unbusy it either prior to sleeping or at exit time. In this particular case, if we fail to transition the mutex from OWNERDEAD -> owned because of casueword(9) failure and the suspend check fails, we'll start over and attempt to busy an already-busied chain and irrecoverably lock up both this thread and anything else that tries to busy the chain. Unbusy the chain prior to restarting because I couldn't decide if that was a better or worse idea than just keeping track of whether we dirtied it in do_lock_pp() and avoiding re-dirty. This is marginally easier to reason about as it returns us to expected state on entry to the loop. While we're here, simplify the code a bit as `error` will be clobbered right after the branch anyways. Reviewed by: kib, olce (both earlier version) Differential Revision: https://reviews.freebsd.org/D47493 --- sys/kern/kern_umtx.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 705571930d7b..b71fa9a6de24 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2605,11 +2605,9 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, */ if (error == 0) { error = thread_check_susp(td, false); - if (error == 0) { - if (try != 0) - error = EBUSY; - else - continue; + if (error == 0 && try == 0) { + umtxq_unbusy_unlocked(&uq->uq_key); + continue; } error = 0; } From de7a92756f0ab50e5e243ce9ac680e27f5c41370 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 16 Oct 2024 01:34:58 +0300 Subject: [PATCH 19/20] mlx5en: improve reporting of kernel TLS, IPSEC offload, and ratelimit caps Only ever set the capabilities bits if kernel options are enabled. Check for hardware capabilities before setting software bits. Sponsored by: NVidia networking MFC after: 1 week --- sys/dev/mlx5/mlx5_en/mlx5_en_main.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index 5081c1a0b782..ec35d87af962 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -4535,17 +4535,29 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev) if_setcapabilitiesbit(ifp, IFCAP_TSO | IFCAP_VLAN_HWTSO, 0); if_setcapabilitiesbit(ifp, IFCAP_HWSTATS | IFCAP_HWRXTSTMP, 0); if_setcapabilitiesbit(ifp, IFCAP_MEXTPG, 0); - if_setcapabilitiesbit(ifp, IFCAP_TXTLS4 | IFCAP_TXTLS6, 0); +#ifdef KERN_TLS + if (MLX5_CAP_GEN(mdev, tls_tx) != 0 && + MLX5_CAP_GEN(mdev, log_max_dek) != 0) + if_setcapabilitiesbit(ifp, IFCAP_TXTLS4 | IFCAP_TXTLS6, 0); + if (MLX5_CAP_GEN(mdev, tls_rx) != 0 && + MLX5_CAP_GEN(mdev, log_max_dek) != 0 && + MLX5_CAP_FLOWTABLE_NIC_RX(mdev, + ft_field_support.outer_ip_version) != 0) + if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_RXTLS4) | + IFCAP2_BIT(IFCAP2_RXTLS6), 0); +#endif #ifdef RATELIMIT - if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT | IFCAP_TXTLS_RTLMT, 0); + if (MLX5_CAP_GEN(mdev, qos) && + MLX5_CAP_QOS(mdev, packet_pacing)) + if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT | IFCAP_TXTLS_RTLMT, + 0); #endif if_setcapabilitiesbit(ifp, IFCAP_VXLAN_HWCSUM | IFCAP_VXLAN_HWTSO, 0); - if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_RXTLS4) | - IFCAP2_BIT(IFCAP2_RXTLS6), 0); - +#ifdef IPSEC_OFFLOAD if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PACKET_OFFLOAD) if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD), 0); +#endif if_setsndtagallocfn(ifp, mlx5e_snd_tag_alloc); #ifdef RATELIMIT From 36887e04947fedfebb9b648fadd0dd6cc03142ea Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 13 Nov 2024 17:04:06 -0500 Subject: [PATCH 20/20] sched_getcpu: Add man page Reviewed by: kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D47556 --- lib/libsys/Makefile.sys | 1 + lib/libsys/sched_getcpu.3 | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 lib/libsys/sched_getcpu.3 diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys index 87290a17820a..4be64a98bb96 100644 --- a/lib/libsys/Makefile.sys +++ b/lib/libsys/Makefile.sys @@ -299,6 +299,7 @@ MAN+= abort2.2 \ rmdir.2 \ rtprio.2 \ sched_get_priority_max.2 \ + sched_getcpu.3 \ sched_setparam.2 \ sched_setscheduler.2 \ sched_yield.2 \ diff --git a/lib/libsys/sched_getcpu.3 b/lib/libsys/sched_getcpu.3 new file mode 100644 index 000000000000..050a8f3facb4 --- /dev/null +++ b/lib/libsys/sched_getcpu.3 @@ -0,0 +1,51 @@ +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2024 The FreeBSD Foundation +.\" +.\" This documentation was written by Ed Maste +.\" under sponsorship from the FreeBSD Foundation. +.\" +.Dd November 13, 2024 +.Dt SCHED_GETCPU 3 +.Os +.Sh NAME +.Nm sched_getcpu +.Nd get current CPU +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sched.h +.Ft int +.Fn sched_getcpu void +.Sh DESCRIPTION +The +.Fn sched_getcpu +function returns the current CPU on which the calling thread is running. +.Sh RETURN VALUES +.Fn sched_getcpu +returns the 0-based index of the current CPU at the time of the call. +The value may become invalid immediately after return, unless the thread is +pinned to a specific CPU. +CPU numbering is the same as used by +.Xr cpuset 2 +and CPU affinity calls. +.Pp +There are no error values as +.Fn sched_getcpu +does not fail. +.Sh SEE ALSO +.Xr cpuset 2 , +.Xr cpuset_getaffinity 2 , +.Xr cpuset_setaffinity 2 , +.Xr pthread_getaffinity_np 3 , +.Xr pthread_setaffinity_np +.Sh STANDARDS +The +.Nm +function originated in Linux. +This implementation aims to be source-compatible with the Linux implementation. +.Sh HISTORY +The +.Nm +function was introduced in +.Fx 13.1 .