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) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * call-path.h: Manipulate a tree data structure containing function call paths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2014, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "call-path.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) static void call_path__init(struct call_path *cp, struct call_path *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 			    struct symbol *sym, u64 ip, bool in_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	cp->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	cp->sym = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	cp->ip = sym ? 0 : ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	cp->db_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	cp->in_kernel = in_kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	RB_CLEAR_NODE(&cp->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	cp->children = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct call_path_root *call_path_root__new(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct call_path_root *cpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	cpr = zalloc(sizeof(struct call_path_root));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (!cpr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	call_path__init(&cpr->call_path, NULL, NULL, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	INIT_LIST_HEAD(&cpr->blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return cpr;
^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) void call_path_root__free(struct call_path_root *cpr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	struct call_path_block *pos, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		list_del_init(&pos->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		free(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	free(cpr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static struct call_path *call_path__new(struct call_path_root *cpr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 					struct call_path *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 					struct symbol *sym, u64 ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 					bool in_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct call_path_block *cpb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct call_path *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	size_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (cpr->next < cpr->sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		cpb = list_last_entry(&cpr->blocks, struct call_path_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 				      node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		cpb = zalloc(sizeof(struct call_path_block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		if (!cpb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		list_add_tail(&cpb->node, &cpr->blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		cpr->sz += CALL_PATH_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	n = cpr->next++ & CALL_PATH_BLOCK_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	cp = &cpb->cp[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	call_path__init(cp, parent, sym, ip, in_kernel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	return cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) struct call_path *call_path__findnew(struct call_path_root *cpr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				     struct call_path *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 				     struct symbol *sym, u64 ip, u64 ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct rb_node **p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct rb_node *node_parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct call_path *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	bool in_kernel = ip >= ks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		ip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return call_path__new(cpr, parent, sym, ip, in_kernel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	p = &parent->children.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		node_parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		cp = rb_entry(node_parent, struct call_path, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		if (cp->sym == sym && cp->ip == ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			return cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if (sym < cp->sym || (sym == cp->sym && ip < cp->ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	cp = call_path__new(cpr, parent, sym, ip, in_kernel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (!cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	rb_link_node(&cp->rb_node, node_parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	rb_insert_color(&cp->rb_node, &parent->children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	return cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }