DF-0941 / fix.diff
diff --git a/sys/kern/subr_cpu_topology.c b/sys/kern/subr_cpu_topology.c --- a/sys/kern/subr_cpu_topology.c +++ b/sys/kern/subr_cpu_topology.c @@ -78,11 +78,11 @@ MALLOC_DEFINE(M_PCPUSYS, "pcpusys", "pcpu sysctl topology"); -SYSCTL_INT(_hw, OID_AUTO, cpu_topology_ht_ids, CTLFLAG_RW, +SYSCTL_INT(_hw, OID_AUTO, cpu_topology_ht_ids, CTLFLAG_RD, &cpu_topology_ht_ids, 0, "# of logical cores per real core"); -SYSCTL_INT(_hw, OID_AUTO, cpu_topology_core_ids, CTLFLAG_RW, +SYSCTL_INT(_hw, OID_AUTO, cpu_topology_core_ids, CTLFLAG_RD, &cpu_topology_core_ids, 0, "# of real cores per package"); -SYSCTL_INT(_hw, OID_AUTO, cpu_topology_phys_ids, CTLFLAG_RW, +SYSCTL_INT(_hw, OID_AUTO, cpu_topology_phys_ids, CTLFLAG_RD, &cpu_topology_phys_ids, 0, "# of physical packages"); /* Get the next valid apicid starting diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1192,7 +1192,9 @@ */ object_pg_color = object ? object->pg_color : 0; - if (cpu_topology_ht_ids) { + if (cpu_topology_ht_ids > 0 && + cpu_topology_core_ids > 0 && + cpu_topology_phys_ids > 0) { int phys_id; int core_id; int ht_id; @@ -1226,6 +1228,14 @@ grpscale = physcale / cpu_topology_core_ids; cpuscale = grpscale / cpu_topology_ht_ids; + /* + * If the topology is too wide for PQ_L2_SIZE cpuscale + * collapses to zero and the modulo below would divide by + * zero. Fall back to the simple distribution. + */ + if (cpuscale == 0) + goto simple; + pg_color = phys_id * physcale; pg_color += core_id * grpscale; pg_color += ht_id * cpuscale; @@ -1247,6 +1257,8 @@ } #endif } else { + simple: + ; /* * Unknown topology, distribute things evenly. * |