Ejemplo n.º 1
0
static u64 compute_subtree_max_end(struct memtype *data)
{
	u64 max_end = data->end, child_max_end;

	child_max_end = get_subtree_max_end(data->rb.rb_right);
	if (child_max_end > max_end)
		max_end = child_max_end;

	child_max_end = get_subtree_max_end(data->rb.rb_left);
	if (child_max_end > max_end)
		max_end = child_max_end;

	return max_end;
}
Ejemplo n.º 2
0
/* Update 'subtree_max_end' for a node, based on node and its children */
static void memtype_rb_augment_cb(struct rb_node *node, void *__unused)
{
	struct memtype *data;
	u64 max_end, child_max_end;

	if (!node)
		return;

	data = container_of(node, struct memtype, rb);
	max_end = data->end;

	child_max_end = get_subtree_max_end(node->rb_right);
	if (child_max_end > max_end)
		max_end = child_max_end;

	child_max_end = get_subtree_max_end(node->rb_left);
	if (child_max_end > max_end)
		max_end = child_max_end;

	data->subtree_max_end = max_end;
}
/* Update 'subtree_max_end' for a node, based on node and its children */
static void update_node_max_end(struct rb_node *node)
{
	struct memtype *data;
	u64 max_end, child_max_end;

	if (!node)
		return;

	data = container_of(node, struct memtype, rb);
	max_end = data->end;

	child_max_end = get_subtree_max_end(node->rb_right);
	if (child_max_end > max_end)
		max_end = child_max_end;

	child_max_end = get_subtree_max_end(node->rb_left);
	if (child_max_end > max_end)
		max_end = child_max_end;

	data->subtree_max_end = max_end;
}
Ejemplo n.º 4
0
/* Find the first (lowest start addr) overlapping range from rb tree */
static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
				u64 start, u64 end)
{
	struct rb_node *node = root->rb_node;
	struct memtype *last_lower = NULL;

	while (node) {
		struct memtype *data = container_of(node, struct memtype, rb);

		if (get_subtree_max_end(node->rb_left) > start) {
			/* Lowest overlap if any must be on left side */
			node = node->rb_left;
		} else if (is_node_overlap(data, start, end)) {
			last_lower = data;
			break;
		} else if (start >= data->start) {
			/* Lowest overlap if any must be on right side */
			node = node->rb_right;
		} else {
			break;
		}
	}
	return last_lower; /* Returns NULL if there is no overlap */
}