Changeset View
Changeset View
Standalone View
Standalone View
sys/net/iflib.c
| Show All 23 Lines | |||||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| * POSSIBILITY OF SUCH DAMAGE. | * POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | */ | ||||
| #include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
| #include "opt_inet.h" | #include "opt_inet.h" | ||||
| #include "opt_inet6.h" | #include "opt_inet6.h" | ||||
| #include "opt_acpi.h" | #include "opt_acpi.h" | ||||
| #include "opt_sched.h" | |||||
| #include <sys/param.h> | #include <sys/param.h> | ||||
| #include <sys/types.h> | #include <sys/types.h> | ||||
| #include <sys/bus.h> | #include <sys/bus.h> | ||||
| #include <sys/eventhandler.h> | #include <sys/eventhandler.h> | ||||
| #include <sys/kernel.h> | #include <sys/kernel.h> | ||||
| #include <sys/lock.h> | #include <sys/lock.h> | ||||
| #include <sys/mutex.h> | #include <sys/mutex.h> | ||||
| #include <sys/module.h> | #include <sys/module.h> | ||||
| #include <sys/kobj.h> | #include <sys/kobj.h> | ||||
| #include <sys/proc.h> | |||||
| #include <sys/rman.h> | #include <sys/rman.h> | ||||
| #include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
| #include <sys/sched.h> | |||||
| #include <sys/smp.h> | #include <sys/smp.h> | ||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||
| #include <sys/sockio.h> | #include <sys/sockio.h> | ||||
| #include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
| #include <sys/syslog.h> | #include <sys/syslog.h> | ||||
| #include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
| #include <sys/limits.h> | #include <sys/limits.h> | ||||
| ▲ Show 20 Lines • Show All 4,755 Lines • ▼ Show 20 Lines | do { | ||||
| cpuid = first_valid; | cpuid = first_valid; | ||||
| } while (!CPU_ISSET(cpuid, &ctx->ifc_cpus)); | } while (!CPU_ISSET(cpuid, &ctx->ifc_cpus)); | ||||
| n--; | n--; | ||||
| } | } | ||||
| return (cpuid); | 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 | * CPU mapping behaviors | ||||
| * --------------------- | * --------------------- | ||||
| * 'separate txrx' refers to the separate_txrx sysctl | * 'separate txrx' refers to the separate_txrx sysctl | ||||
| * 'use logical' refers to the use_logical_cores sysctl | * 'use logical' refers to the use_logical_cores sysctl | ||||
| * 'INTR CPUS' indicates whether bus_get_cpus(INTR_CPUS) succeeded | * 'INTR CPUS' indicates whether bus_get_cpus(INTR_CPUS) succeeded | ||||
| * | * | ||||
| * separate use INTR | * separate use INTR | ||||
| * txrx logical CPUS result | * txrx logical CPUS result | ||||
| Show All 35 Lines | if (ctx->ifc_sysctl_separate_txrx) { | ||||
| */ | */ | ||||
| if (ctx->ifc_sysctl_use_logical_cores && | if (ctx->ifc_sysctl_use_logical_cores && | ||||
| ctx->ifc_cpus_are_physical_cores && | ctx->ifc_cpus_are_physical_cores && | ||||
| is_tx && qid < scctx->isc_nrxqsets) { | is_tx && qid < scctx->isc_nrxqsets) { | ||||
| int l2_neighbor; | int l2_neighbor; | ||||
| unsigned int rx_cpuid; | unsigned int rx_cpuid; | ||||
| rx_cpuid = cpuid_advance(ctx, base_cpuid, qid); | 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) { | if (l2_neighbor != -1) { | ||||
| return (l2_neighbor); | return (l2_neighbor); | ||||
| } | } | ||||
| /* | /* | ||||
| * ... else fall through to the normal | * ... else fall through to the normal | ||||
| * consecutive-after-RX assignment scheme. | * consecutive-after-RX assignment scheme. | ||||
| * | * | ||||
| * Note that we are assuming that all RX queue CPUs | * Note that we are assuming that all RX queue CPUs | ||||
| ▲ Show 20 Lines • Show All 2,333 Lines • Show Last 20 Lines | |||||