54 lines
1.8 KiB
C
54 lines
1.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
|
|
*/
|
|
#ifndef __IOMMUFD_DOUBLE_SPAN_H
|
|
#define __IOMMUFD_DOUBLE_SPAN_H
|
|
|
|
#include <linux/interval_tree.h>
|
|
|
|
/*
|
|
* This is a variation of the general interval_tree_span_iter that computes the
|
|
* spans over the union of two different interval trees. Used ranges are broken
|
|
* up and reported based on the tree that provides the interval. The first span
|
|
* always takes priority. Like interval_tree_span_iter it is greedy and the same
|
|
* value of is_used will not repeat on two iteration cycles.
|
|
*/
|
|
struct interval_tree_double_span_iter {
|
|
struct rb_root_cached *itrees[2];
|
|
struct interval_tree_span_iter spans[2];
|
|
union {
|
|
unsigned long start_hole;
|
|
unsigned long start_used;
|
|
};
|
|
union {
|
|
unsigned long last_hole;
|
|
unsigned long last_used;
|
|
};
|
|
/* 0 = hole, 1 = used span[0], 2 = used span[1], -1 done iteration */
|
|
int is_used;
|
|
};
|
|
|
|
void interval_tree_double_span_iter_update(
|
|
struct interval_tree_double_span_iter *iter);
|
|
void interval_tree_double_span_iter_first(
|
|
struct interval_tree_double_span_iter *iter,
|
|
struct rb_root_cached *itree1, struct rb_root_cached *itree2,
|
|
unsigned long first_index, unsigned long last_index);
|
|
void interval_tree_double_span_iter_next(
|
|
struct interval_tree_double_span_iter *iter);
|
|
|
|
static inline bool
|
|
interval_tree_double_span_iter_done(struct interval_tree_double_span_iter *state)
|
|
{
|
|
return state->is_used == -1;
|
|
}
|
|
|
|
#define interval_tree_for_each_double_span(span, itree1, itree2, first_index, \
|
|
last_index) \
|
|
for (interval_tree_double_span_iter_first(span, itree1, itree2, \
|
|
first_index, last_index); \
|
|
!interval_tree_double_span_iter_done(span); \
|
|
interval_tree_double_span_iter_next(span))
|
|
|
|
#endif
|