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_);
 133
 134#ifndef set_numa_mem
 135static inline void set_numa_mem(int node)
 136{
 137        this_cpu_write(_numa_mem_, node);
 138}
 139#endif
 140
 141#ifndef numa_mem_id
 142/* Returns the number of the nearest Node with memory */
 143static inline int numa_mem_id(void)
 144{
 145        return raw_cpu_read(_numa_mem_);
 146}
 147#endif
 148
 149#ifndef cpu_to_mem
 150static inline int cpu_to_mem(int cpu)
 151{
 152        return per_cpu(_numa_mem_, cpu);
 153}
 154#endif
 155
 156#ifndef set_cpu_numa_mem
 157static inline void set_cpu_numa_mem(int cpu, int node)
 158{
 159        per_cpu(_numa_mem_, cpu) = node;
 160}
 161#endif
 162
 163#else   /* !CONFIG_HAVE_MEMORYLESS_NODES */
 164
 165#ifndef numa_mem_id
 166/* Returns the number of the nearest Node with memory */
 167static inline int numa_mem_id(void)
 168{
 169        return numa_node_id();
 170}
 171#endif
 172
 173#ifndef cpu_to_mem
 174static inline int cpu_to_mem(int cpu)
 175{
 176        return cpu_to_node(cpu);
 177}
 178#endif
 179
 180#endif  /* [!]CONFIG_HAVE_MEMORYLESS_NODES */
 181
 182#ifndef topology_physical_package_id
 183#define topology_physical_package_id(cpu)       ((void)(cpu), -1)
 184#endif
 185#ifndef topology_die_id
 186#define topology_die_id(cpu)                    ((void)(cpu), -1)
 187#endif
 188#ifndef topology_core_id
 189#define topology_core_id(cpu)                   ((void)(cpu), 0)
 190#endif
 191#ifndef topology_sibling_cpumask
 192#define topology_sibling_cpumask(cpu)           cpumask_of(cpu)
 193#endif
 194#ifndef topology_core_cpumask
 195#define topology_core_cpumask(cpu)              cpumask_of(cpu)
 196#endif
 197#ifndef topology_die_cpumask
 198#define topology_die_cpumask(cpu)               cpumask_of(cpu)
 199#endif
 200
 201#ifdef CONFIG_SCHED_SMT
 202static inline const struct cpumask *cpu_smt_mask(int cpu)
 203{
 204        return topology_sibling_cpumask(cpu);
 205}
 206#endif
 207
 208static inline const struct cpumask *cpu_cpu_mask(int cpu)
 209{
 210        return cpumask_of_node(cpu_to_node(cpu));
 211}
 212
 213
 214#endif /* _LINUX_TOPOLOGY_H */
 215