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#ifndef node_distance
  52#define node_distance(from,to)  ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE)
  53#endif
  54#ifndef RECLAIM_DISTANCE
  55/*
  56 * If the distance between nodes in a system is larger than RECLAIM_DISTANCE
  57 * (in whatever arch specific measurement units returned by node_distance())
  58 * and node_reclaim_mode is enabled then the VM will only call node_reclaim()
  59 * on nodes within this distance.
  60 */
  61#define RECLAIM_DISTANCE 30
  62#endif
  63
  64/*
  65 * The following tunable allows platforms to override the default node
  66 * reclaim distance (RECLAIM_DISTANCE) if remote memory accesses are
  67 * sufficiently fast that the default value actually hurts
  68 * performance.
  69 *
  70 * AMD EPYC machines use this because even though the 2-hop distance
  71 * is 32 (3.2x slower than a local memory access) performance actually
  72 * *improves* if allowed to reclaim memory and load balance tasks
  73 * between NUMA nodes 2-hops apart.
  74 */
  75extern int __read_mostly node_reclaim_distance;
  76
  77#ifndef PENALTY_FOR_NODE_WITH_CPUS
  78#define PENALTY_FOR_NODE_WITH_CPUS      (1)
  79#endif
  80
  81#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
  82DECLARE_PER_CPU(int, numa_node);
  83
  84#ifndef numa_node_id
  85/* Returns the number of the current Node. */
  86static inline int numa_node_id(void)
  87{
  88        return raw_cpu_read(numa_node);
  89}
  90#endif
  91
  92#ifndef cpu_to_node
  93static inline int cpu_to_node(int cpu)
  94{
  95        return per_cpu(numa_node, cpu);
  96}
  97#endif
  98
  99#ifndef set_numa_node
 100static inline void set_numa_node(int node)
 101{
 102        this_cpu_write(numa_node, node);
 103}
 104#endif
 105
 106#ifndef set_cpu_numa_node
 107static inline void set_cpu_numa_node(int cpu, int node)
 108{
 109        per_cpu(numa_node, cpu) = node;
 110}
 111#endif
 112
 113#else   /* !CONFIG_USE_PERCPU_NUMA_NODE_ID */
 114
 115/* Returns the number of the current Node. */
 116#ifndef numa_node_id
 117static inline int numa_node_id(void)
 118{
 119        return cpu_to_node(raw_smp_processor_id());
 120}
 121#endif
 122
 123#endif  /* [!]CONFIG_USE_PERCPU_NUMA_NODE_ID */
 124
 125#ifdef CONFIG_HAVE_MEMORYLESS_NODES
 126
 127/*
 128 * N.B., Do NOT reference the '_numa_mem_' per cpu variable directly.
 129 * It will not be defined when CONFIG_HAVE_MEMORYLESS_NODES is not defined.
 130 * Use the accessor functions set_numa_mem(), numa_mem_id() and cpu_to_mem().
 131 */
 132DECLARE_PER_CPU(int, _numa_mem_);
 133extern int _node_numa_mem_[MAX_NUMNODES];
 134
 135#ifndef set_numa_mem
 136static inline void set_numa_mem(int node)
 137{
 138        this_cpu_write(_numa_mem_, node);
 139        _node_numa_mem_[numa_node_id()] = node;
 140}
 141#endif
 142
 143#ifndef node_to_mem_node
 144static inline int node_to_mem_node(int node)
 145{
 146        return _node_numa_mem_[node];
 147}
 148#endif
 149
 150#ifndef numa_mem_id
 151/* Returns the number of the nearest Node with memory */
 152static inline int numa_mem_id(void)
 153{
 154        return raw_cpu_read(_numa_mem_);
 155}
 156#endif
 157
 158#ifndef cpu_to_mem
 159static inline int cpu_to_mem(int cpu)
 160{
 161        return per_cpu(_numa_mem_, cpu);
 162}
 163#endif
 164
 165#ifndef set_cpu_numa_mem
 166static inline void set_cpu_numa_mem(int cpu, int node)
 167{
 168        per_cpu(_numa_mem_, cpu) = node;
 169        _node_numa_mem_[cpu_to_node(cpu)] = node;
 170}
 171#endif
 172
 173#else   /* !CONFIG_HAVE_MEMORYLESS_NODES */
 174
 175#ifndef numa_mem_id
 176/* Returns the number of the nearest Node with memory */
 177static inline int numa_mem_id(void)
 178{
 179        return numa_node_id();
 180}
 181#endif
 182
 183#ifndef node_to_mem_node
 184static inline int node_to_mem_node(int node)
 185{
 186        return node;
 187}
 188#endif
 189
 190#ifndef cpu_to_mem
 191static inline int cpu_to_mem(int cpu)
 192{
 193        return cpu_to_node(cpu);
 194}
 195#endif
 196
 197#endif  /* [!]CONFIG_HAVE_MEMORYLESS_NODES */
 198
 199#ifndef topology_physical_package_id
 200#define topology_physical_package_id(cpu)       ((void)(cpu), -1)
 201#endif
 202#ifndef topology_die_id
 203#define topology_die_id(cpu)                    ((void)(cpu), -1)
 204#endif
 205#ifndef topology_core_id
 206#define topology_core_id(cpu)                   ((void)(cpu), 0)
 207#endif
 208#ifndef topology_sibling_cpumask
 209#define topology_sibling_cpumask(cpu)           cpumask_of(cpu)
 210#endif
 211#ifndef topology_core_cpumask
 212#define topology_core_cpumask(cpu)              cpumask_of(cpu)
 213#endif
 214#ifndef topology_die_cpumask
 215#define topology_die_cpumask(cpu)               cpumask_of(cpu)
 216#endif
 217
 218#ifdef CONFIG_SCHED_SMT
 219static inline const struct cpumask *cpu_smt_mask(int cpu)
 220{
 221        return topology_sibling_cpumask(cpu);
 222}
 223#endif
 224
 225static inline const struct cpumask *cpu_cpu_mask(int cpu)
 226{
 227        return cpumask_of_node(cpu_to_node(cpu));
 228}
 229
 230
 231#endif /* _LINUX_TOPOLOGY_H */
 232