Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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