~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/mem2node.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <errno.h>
  2 #include <inttypes.h>
  3 #include <asm/bug.h>
  4 #include <linux/bitmap.h>
  5 #include <linux/kernel.h>
  6 #include <linux/zalloc.h>
  7 #include "debug.h"
  8 #include "env.h"
  9 #include "mem2node.h"
 10 
 11 struct phys_entry {
 12         struct rb_node  rb_node;
 13         u64     start;
 14         u64     end;
 15         u64     node;
 16 };
 17 
 18 static void phys_entry__insert(struct phys_entry *entry, struct rb_root *root)
 19 {
 20         struct rb_node **p = &root->rb_node;
 21         struct rb_node *parent = NULL;
 22         struct phys_entry *e;
 23 
 24         while (*p != NULL) {
 25                 parent = *p;
 26                 e = rb_entry(parent, struct phys_entry, rb_node);
 27 
 28                 if (entry->start < e->start)
 29                         p = &(*p)->rb_left;
 30                 else
 31                         p = &(*p)->rb_right;
 32         }
 33 
 34         rb_link_node(&entry->rb_node, parent, p);
 35         rb_insert_color(&entry->rb_node, root);
 36 }
 37 
 38 static void
 39 phys_entry__init(struct phys_entry *entry, u64 start, u64 bsize, u64 node)
 40 {
 41         entry->start = start;
 42         entry->end   = start + bsize;
 43         entry->node  = node;
 44         RB_CLEAR_NODE(&entry->rb_node);
 45 }
 46 
 47 int mem2node__init(struct mem2node *map, struct perf_env *env)
 48 {
 49         struct memory_node *n, *nodes = &env->memory_nodes[0];
 50         struct phys_entry *entries, *tmp_entries;
 51         u64 bsize = env->memory_bsize;
 52         int i, j = 0, max = 0;
 53 
 54         memset(map, 0x0, sizeof(*map));
 55         map->root = RB_ROOT;
 56 
 57         for (i = 0; i < env->nr_memory_nodes; i++) {
 58                 n = &nodes[i];
 59                 max += bitmap_weight(n->set, n->size);
 60         }
 61 
 62         entries = zalloc(sizeof(*entries) * max);
 63         if (!entries)
 64                 return -ENOMEM;
 65 
 66         for (i = 0; i < env->nr_memory_nodes; i++) {
 67                 u64 bit;
 68 
 69                 n = &nodes[i];
 70 
 71                 for (bit = 0; bit < n->size; bit++) {
 72                         u64 start;
 73 
 74                         if (!test_bit(bit, n->set))
 75                                 continue;
 76 
 77                         start = bit * bsize;
 78 
 79                         /*
 80                          * Merge nearby areas, we walk in order
 81                          * through the bitmap, so no need to sort.
 82                          */
 83                         if (j > 0) {
 84                                 struct phys_entry *prev = &entries[j - 1];
 85 
 86                                 if ((prev->end == start) &&
 87                                     (prev->node == n->node)) {
 88                                         prev->end += bsize;
 89                                         continue;
 90                                 }
 91                         }
 92 
 93                         phys_entry__init(&entries[j++], start, bsize, n->node);
 94                 }
 95         }
 96 
 97         /* Cut unused entries, due to merging. */
 98         tmp_entries = realloc(entries, sizeof(*entries) * j);
 99         if (tmp_entries ||
100             WARN_ONCE(j == 0, "No memory nodes, is CONFIG_MEMORY_HOTPLUG enabled?\n"))
101                 entries = tmp_entries;
102 
103         for (i = 0; i < j; i++) {
104                 pr_debug("mem2node %03" PRIu64 " [0x%016" PRIx64 "-0x%016" PRIx64 "]\n",
105                          entries[i].node, entries[i].start, entries[i].end);
106 
107                 phys_entry__insert(&entries[i], &map->root);
108         }
109 
110         map->entries = entries;
111         return 0;
112 }
113 
114 void mem2node__exit(struct mem2node *map)
115 {
116         zfree(&map->entries);
117 }
118 
119 int mem2node__node(struct mem2node *map, u64 addr)
120 {
121         struct rb_node **p, *parent = NULL;
122         struct phys_entry *entry;
123 
124         p = &map->root.rb_node;
125         while (*p != NULL) {
126                 parent = *p;
127                 entry = rb_entry(parent, struct phys_entry, rb_node);
128                 if (addr < entry->start)
129                         p = &(*p)->rb_left;
130                 else if (addr >= entry->end)
131                         p = &(*p)->rb_right;
132                 else
133                         goto out;
134         }
135 
136         entry = NULL;
137 out:
138         return entry ? (int) entry->node : -1;
139 }
140 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php