git: b602ba1b5fd9 - main - net/iflib.c: move out scheduler-depended code into the hook
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 29 Jan 2026 18:12:35 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=b602ba1b5fd92bb226e32f5720885f856a5cb0bb
commit b602ba1b5fd92bb226e32f5720885f856a5cb0bb
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-01-22 13:38:20 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-01-29 18:11:56 +0000
net/iflib.c: move out scheduler-depended code into the hook
Add sched_find_l2_neighbor(). This really should be not
scheduler-depended, in does not have anything to do with scheduler at
all. But for now keep the same code structure.
Reviewed by: olce
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54831
---
sys/kern/sched_4bsd.c | 7 +++++
sys/kern/sched_shim.c | 1 +
sys/kern/sched_ule.c | 68 ++++++++++++++++++++++++++++++++++++++++++
sys/net/iflib.c | 82 ++-------------------------------------------------
sys/sys/sched.h | 8 +++++
5 files changed, 87 insertions(+), 79 deletions(-)
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 03e7b71d3fe6..11baf9d2bdfa 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -1854,6 +1854,12 @@ sched_4bsd_do_timer_accounting(void)
#endif
}
+static int
+sched_4bsd_find_l2_neighbor(int cpu)
+{
+ return (-1);
+}
+
struct sched_instance sched_4bsd_instance = {
#define SLOT(name) .name = sched_4bsd_##name
SLOT(load),
@@ -1897,6 +1903,7 @@ struct sched_instance sched_4bsd_instance = {
SLOT(tdname),
SLOT(clear_tdname),
SLOT(do_timer_accounting),
+ SLOT(find_l2_neighbor),
SLOT(init),
SLOT(init_ap),
SLOT(setup),
diff --git a/sys/kern/sched_shim.c b/sys/kern/sched_shim.c
index d2f0b5749752..816d0b44bb52 100644
--- a/sys/kern/sched_shim.c
+++ b/sys/kern/sched_shim.c
@@ -94,6 +94,7 @@ DEFINE_SHIM0(sizeof_thread, int, sched_sizeof_thread)
DEFINE_SHIM1(tdname, char *, sched_tdname, struct thread *, td)
DEFINE_SHIM1(clear_tdname, void, sched_clear_tdname, struct thread *, td)
DEFINE_SHIM0(do_timer_accounting, bool, sched_do_timer_accounting)
+DEFINE_SHIM1(find_l2_neighbor, int, sched_find_l2_neighbor, int, cpu)
DEFINE_SHIM0(init_ap, void, schedinit_ap)
static char sched_name[32] = "ULE";
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 22257b2c0d7a..7a745619480d 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -3360,6 +3360,73 @@ sched_ule_do_timer_accounting(void)
return (true);
}
+#ifdef SMP
+static int
+sched_ule_find_child_with_core(int cpu, struct cpu_group *grp)
+{
+ int i;
+
+ if (grp->cg_children == 0)
+ return (-1);
+
+ MPASS(grp->cg_child);
+ for (i = 0; i < grp->cg_children; i++) {
+ if (CPU_ISSET(cpu, &grp->cg_child[i].cg_mask))
+ return (i);
+ }
+
+ return (-1);
+}
+
+static int
+sched_ule_find_l2_neighbor(int cpu)
+{
+ struct cpu_group *grp;
+ int i;
+
+ grp = cpu_top;
+ if (grp == NULL)
+ return (-1);
+
+ /*
+ * Find the smallest CPU group that contains the given core.
+ */
+ i = 0;
+ while ((i = sched_ule_find_child_with_core(cpu, grp)) != -1) {
+ /*
+ * If the smallest group containing the given CPU has less
+ * than two members, we conclude the given CPU has no
+ * L2 neighbor.
+ */
+ if (grp->cg_child[i].cg_count <= 1)
+ return (-1);
+ grp = &grp->cg_child[i];
+ }
+
+ /* Must share L2. */
+ if (grp->cg_level > CG_SHARE_L2 || grp->cg_level == CG_SHARE_NONE)
+ return (-1);
+
+ /*
+ * Select the first member of the set that isn't the reference
+ * CPU, which at this point is guaranteed to exist.
+ */
+ for (i = 0; i < CPU_SETSIZE; i++) {
+ if (CPU_ISSET(i, &grp->cg_mask) && i != cpu)
+ return (i);
+ }
+
+ /* Should never be reached */
+ return (-1);
+}
+#else
+static int
+sched_ule_find_l2_neighbor(int cpu)
+{
+ return (-1);
+}
+#endif
+
struct sched_instance sched_ule_instance = {
#define SLOT(name) .name = sched_ule_##name
SLOT(load),
@@ -3403,6 +3470,7 @@ struct sched_instance sched_ule_instance = {
SLOT(tdname),
SLOT(clear_tdname),
SLOT(do_timer_accounting),
+ SLOT(find_l2_neighbor),
SLOT(init),
SLOT(init_ap),
SLOT(setup),
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index b0e4bb9470c9..8e2fd257ca74 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -29,7 +29,6 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_acpi.h"
-#include "opt_sched.h"
#include <sys/param.h>
#include <sys/types.h>
@@ -40,8 +39,10 @@
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/kobj.h>
+#include <sys/proc.h>
#include <sys/rman.h>
#include <sys/sbuf.h>
+#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@@ -4813,83 +4814,6 @@ cpuid_advance(if_ctx_t ctx, unsigned int cpuid, unsigned int n)
return (cpuid);
}
-#if defined(SMP) && defined(SCHED_ULE)
-extern struct cpu_group *cpu_top; /* CPU topology */
-
-static int
-find_child_with_core(int cpu, struct cpu_group *grp)
-{
- int i;
-
- if (grp->cg_children == 0)
- return (-1);
-
- MPASS(grp->cg_child);
- for (i = 0; i < grp->cg_children; i++) {
- if (CPU_ISSET(cpu, &grp->cg_child[i].cg_mask))
- return (i);
- }
-
- return (-1);
-}
-
-
-/*
- * Find an L2 neighbor of the given CPU or return -1 if none found. This
- * does not distinguish among multiple L2 neighbors if the given CPU has
- * more than one (it will always return the same result in that case).
- */
-static int
-find_l2_neighbor(int cpu)
-{
- struct cpu_group *grp;
- int i;
-
- grp = cpu_top;
- if (grp == NULL)
- return (-1);
-
- /*
- * Find the smallest CPU group that contains the given core.
- */
- i = 0;
- while ((i = find_child_with_core(cpu, grp)) != -1) {
- /*
- * If the smallest group containing the given CPU has less
- * than two members, we conclude the given CPU has no
- * L2 neighbor.
- */
- if (grp->cg_child[i].cg_count <= 1)
- return (-1);
- grp = &grp->cg_child[i];
- }
-
- /* Must share L2. */
- if (grp->cg_level > CG_SHARE_L2 || grp->cg_level == CG_SHARE_NONE)
- return (-1);
-
- /*
- * Select the first member of the set that isn't the reference
- * CPU, which at this point is guaranteed to exist.
- */
- for (i = 0; i < CPU_SETSIZE; i++) {
- if (CPU_ISSET(i, &grp->cg_mask) && i != cpu)
- return (i);
- }
-
- /* Should never be reached */
- return (-1);
-}
-
-#else
-static int
-find_l2_neighbor(int cpu)
-{
-
- return (-1);
-}
-#endif
-
/*
* CPU mapping behaviors
* ---------------------
@@ -4942,7 +4866,7 @@ get_cpuid_for_queue(if_ctx_t ctx, unsigned int base_cpuid, unsigned int qid,
unsigned int rx_cpuid;
rx_cpuid = cpuid_advance(ctx, base_cpuid, qid);
- l2_neighbor = find_l2_neighbor(rx_cpuid);
+ l2_neighbor = sched_find_l2_neighbor(rx_cpuid);
if (l2_neighbor != -1) {
return (l2_neighbor);
}
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index 9c78452432b4..3ba40fb191d3 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -243,6 +243,13 @@ void schedinit_ap(void);
bool sched_do_timer_accounting(void);
+/*
+ * Find an L2 neighbor of the given CPU or return -1 if none found. This
+ * does not distinguish among multiple L2 neighbors if the given CPU has
+ * more than one (it will always return the same result in that case).
+ */
+int sched_find_l2_neighbor(int cpu);
+
struct sched_instance {
int (*load)(void);
int (*rr_interval)(void);
@@ -285,6 +292,7 @@ struct sched_instance {
char *(*tdname)(struct thread *td);
void (*clear_tdname)(struct thread *td);
bool (*do_timer_accounting)(void);
+ int (*find_l2_neighbor)(int cpuid);
void (*init)(void);
void (*init_ap)(void);
void (*setup)(void);