linux/include/linux/topology.h
<<
>>
Prefs
   1/*
   2 * include/linux/topology.h
   3 *
   4 * Written by: Matthew Dobson, IBM Corporation
   5 *
   6 * Copyright (C) 2002, IBM Corp.
   7 *
   8 * All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful, but
  16 * WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  18 * NON INFRINGEMENT.  See the GNU General Public License for more
  19 * details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 * Send feedback to <colpatch@us.ibm.com>
  26 */
  27#ifndef _LINUX_TOPOLOGY_H
  28#define _LINUX_TOPOLOGY_H
  29
  30#include <linux/arch_topology.h>
  31#include <linux/cpumask.h>
  32#include <linux/bitops.h>
  33#include <linux/mmzone.h>
  34#include <linux/smp.h>
  35#include <linux/percpu.h>
  36#include <asm/topology.h>
  37
  38#ifndef nr_cpus_node
  39#define nr_cpus_node(node) cpumask_weight(cpumask_of_node(node))
  40#endif
  41
  42#define for_each_node_with_cpus(node)                   \
  43        for_each_online_node(node)                      \
  44                if (nr_cpus_node(node))
  45
  46int arch_update_cpu_topology(void);
  47
  48/* Conform to ACPI 2.0 SLIT distance definitions */
  49#define LOCAL_DISTANCE          10
  50#define REMOTE_DISTANCE         20
  51#define DISTANCE_BITS           8
  52#ifndef node_distance
  53#define node_distance(from,to)  ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE)
  54#endif
  55#ifndef RECLAIM_DISTANCE
  56/*
  57 * If the distance between nodes in a system is larger than RECLAIM_DISTANCE
  58 * (in whatever arch specific measurement units returned by node_distance())
  59 * and node_reclaim_mode is enabled then the VM will only call node_reclaim()
  60 * on nodes within this distance.
  61 */
  62#define RECLAIM_DISTANCE 30
  63#endif
  64
  65/*
  66 * The following tunable allows platforms to override the default node
  67 * reclaim distance (RECLAIM_DISTANCE) if remote memory accesses are
  68 * sufficiently fast that the default value actually hurts
  69 * performance.
  70 *
  71 * AMD EPYC machines use this because even though the 2-hop distance
  72 * is 32 (3.2x slower than a local memory access) performance actually
  73 * *improves* if allowed to reclaim memory and load balance tasks
  74 * between NUMA nodes 2-hops apart.
  75 */
  76extern int __read_mostly node_reclaim_distance;
  77
  78#ifndef PENALTY_FOR_NODE_WITH_CPUS
  79#define PENALTY_FOR_NODE_WITH_CPUS      (1)
  80#endif
  81
  82#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
  83DECLARE_PER_CPU(int, numa_node);
  84
  85#ifndef numa_node_id
  86/* Returns the number of the current Node. */
  87static inline int numa_node_id(void)
  88{
  89        return raw_cpu_read(numa_node);
  90}
  91#endif
  92
  93#ifndef cpu_to_node
  94static inline int cpu_to_node(int cpu)
  95{
  96        return per_cpu(numa_node, cpu);
  97}
  98#endif
  99
 100#ifndef set_numa_node
 101static inline void set_numa_node(int node)
 102{
 103        this_cpu_write(numa_node, node);
 104}
 105#endif
 106
 107#ifndef set_cpu_numa_node
 108static inline void set_cpu_numa_node(int cpu, int node)
 109{
 110        per_cpu(numa_node, cpu) = node;
 111}
 112#endif
 113
 114#else   /* !CONFIG_USE_PERCPU_NUMA_NODE_ID */
 115
 116/* Returns the number of the current Node. */
 117#ifndef numa_node_id
 118static inline int numa_node_id(void)
 119{
 120        return cpu_to_node(raw_smp_processor_id());
 121}
 122#endif
 123
 124#endif  /* [!]CONFIG_USE_PERCPU_NUMA_NODE_ID */
 125
 126#ifdef CONFIG_HAVE_MEMORYLESS_NODES
 127
 128/*
 129 * N.B., Do NOT reference the '_numa_mem_' per cpu variable directly.
 130 * It will not be defined when CONFIG_HAVE_MEMORYLESS_NODES is not defined.
 131 * Use the accessor functions set_numa_mem(), numa_mem_id() and cpu_to_mem().
 132 */
 133DECLARE_PER_CPU(int, _numa_mem_);
 134
 135#ifndef set_numa_mem
 136static inline void set_numa_mem(int node)
 137{
 138        this_cpu_write(_numa_mem_, node);
 139}
 140#endif
 141
 142#ifndef numa_mem_id
 143/* Returns the number of the nearest Node with memory */
 144static inline int numa_mem_id(void)
 145{
 146        return raw_cpu_read(_numa_mem_);
 147}
 148#endif
 149
 150#ifndef cpu_to_mem
 151static inline int cpu_to_mem(int cpu)
 152{
 153        return per_cpu(_numa_mem_, cpu);
 154}
 155#endif
 156
 157#ifndef set_cpu_numa_mem
 158static inline void set_cpu_numa_mem(int cpu, int node)
 159{
 160        per_cpu(_numa_mem_, cpu) = node;
 161}
 162#endif
 163
 164#else   /* !CONFIG_HAVE_MEMORYLESS_NODES */
 165
 166#ifndef numa_mem_id
 167/* Returns the number of the nearest Node with memory */
 168static inline int numa_mem_id(void)
 169{
 170        return numa_node_id();
 171}
 172#endif
 173
 174#ifndef cpu_to_mem
 175static inline int cpu_to_mem(int cpu)
 176{
 177        return cpu_to_node(cpu);
 178}
 179#endif
 180
 181#endif  /* [!]CONFIG_HAVE_MEMORYLESS_NODES */
 182
 183#ifndef topology_physical_package_id
 184#define topology_physical_package_id(cpu)       ((void)(cpu), -1)
 185#endif
 186#ifndef topology_die_id
 187#define topology_die_id(cpu)                    ((void)(cpu), -1)
 188#endif
 189#ifndef topology_core_id
 190#define topology_core_id(cpu)                   ((void)(cpu), 0)
 191#endif
 192#ifndef topology_sibling_cpumask
 193#define topology_sibling_cpumask(cpu)           cpumask_of(cpu)
 194#endif
 195#ifndef topology_core_cpumask
 196#define topology_core_cpumask(cpu)              cpumask_of(cpu)
 197#endif
 198#ifndef topology_die_cpumask
 199#define topology_die_cpumask(cpu)               cpumask_of(cpu)
 200#endif
 201
 202#if defined(CONFIG_SCHED_SMT) && !defined(cpu_smt_mask)
 203static inline const struct cpumask *cpu_smt_mask(int cpu)
 204{
 205        return topology_sibling_cpumask(cpu);
 206}
 207#endif
 208
 209static inline const struct cpumask *cpu_cpu_mask(int cpu)
 210{
 211        return cpumask_of_node(cpu_to_node(cpu));
 212}
 213
 214
 215#endif /* _LINUX_TOPOLOGY_H */
 216