The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b602ba1b5fd92bb226e32f5720885f856a5cb0bb

commit b602ba1b5fd92bb226e32f5720885f856a5cb0bb
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-01-22 13:38:20 +0000
Commit:     Konstantin Belousov <[email protected]>
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);

Reply via email to