3 #include <linux/bitmap.h>
4 #include <linux/kernel.h>
5 #include <linux/zalloc.h>
11 struct rb_node rb_node
;
17 static void phys_entry__insert(struct phys_entry
*entry
, struct rb_root
*root
)
19 struct rb_node
**p
= &root
->rb_node
;
20 struct rb_node
*parent
= NULL
;
25 e
= rb_entry(parent
, struct phys_entry
, rb_node
);
27 if (entry
->start
< e
->start
)
33 rb_link_node(&entry
->rb_node
, parent
, p
);
34 rb_insert_color(&entry
->rb_node
, root
);
38 phys_entry__init(struct phys_entry
*entry
, u64 start
, u64 bsize
, u64 node
)
41 entry
->end
= start
+ bsize
;
43 RB_CLEAR_NODE(&entry
->rb_node
);
46 int mem2node__init(struct mem2node
*map
, struct perf_env
*env
)
48 struct memory_node
*n
, *nodes
= &env
->memory_nodes
[0];
49 struct phys_entry
*entries
, *tmp_entries
;
50 u64 bsize
= env
->memory_bsize
;
51 int i
, j
= 0, max
= 0;
53 memset(map
, 0x0, sizeof(*map
));
56 for (i
= 0; i
< env
->nr_memory_nodes
; i
++) {
58 max
+= bitmap_weight(n
->set
, n
->size
);
61 entries
= zalloc(sizeof(*entries
) * max
);
65 for (i
= 0; i
< env
->nr_memory_nodes
; i
++) {
70 for (bit
= 0; bit
< n
->size
; bit
++) {
73 if (!test_bit(bit
, n
->set
))
79 * Merge nearby areas, we walk in order
80 * through the bitmap, so no need to sort.
83 struct phys_entry
*prev
= &entries
[j
- 1];
85 if ((prev
->end
== start
) &&
86 (prev
->node
== n
->node
)) {
92 phys_entry__init(&entries
[j
++], start
, bsize
, n
->node
);
96 /* Cut unused entries, due to merging. */
97 tmp_entries
= realloc(entries
, sizeof(*entries
) * j
);
99 entries
= tmp_entries
;
101 for (i
= 0; i
< j
; i
++) {
102 pr_debug("mem2node %03" PRIu64
" [0x%016" PRIx64
"-0x%016" PRIx64
"]\n",
103 entries
[i
].node
, entries
[i
].start
, entries
[i
].end
);
105 phys_entry__insert(&entries
[i
], &map
->root
);
108 map
->entries
= entries
;
112 void mem2node__exit(struct mem2node
*map
)
114 zfree(&map
->entries
);
117 int mem2node__node(struct mem2node
*map
, u64 addr
)
119 struct rb_node
**p
, *parent
= NULL
;
120 struct phys_entry
*entry
;
122 p
= &map
->root
.rb_node
;
125 entry
= rb_entry(parent
, struct phys_entry
, rb_node
);
126 if (addr
< entry
->start
)
128 else if (addr
>= entry
->end
)
136 return entry
? (int) entry
->node
: -1;