Skip to content

Commit 9a4087f

Browse files
brettcreeleyawilliam
authored andcommitted
vfio: Commonize combine_ranges for use in other VFIO drivers
Currently only Mellanox uses the combine_ranges function. The new pds_vfio driver also needs this function. So, move it to a common location for other vendor drivers to use. Also, fix RCT ordering while moving/renaming the function. Cc: Yishai Hadas <[email protected]> Signed-off-by: Brett Creeley <[email protected]> Signed-off-by: Shannon Nelson <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Shameer Kolothum <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 73e2f19 commit 9a4087f

File tree

3 files changed

+51
-47
lines changed

3 files changed

+51
-47
lines changed

drivers/vfio/pci/mlx5/cmd.c

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -732,52 +732,6 @@ void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf)
732732
mlx5vf_cmd_dealloc_pd(migf);
733733
}
734734

735-
static void combine_ranges(struct rb_root_cached *root, u32 cur_nodes,
736-
u32 req_nodes)
737-
{
738-
struct interval_tree_node *prev, *curr, *comb_start, *comb_end;
739-
unsigned long min_gap;
740-
unsigned long curr_gap;
741-
742-
/* Special shortcut when a single range is required */
743-
if (req_nodes == 1) {
744-
unsigned long last;
745-
746-
curr = comb_start = interval_tree_iter_first(root, 0, ULONG_MAX);
747-
while (curr) {
748-
last = curr->last;
749-
prev = curr;
750-
curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
751-
if (prev != comb_start)
752-
interval_tree_remove(prev, root);
753-
}
754-
comb_start->last = last;
755-
return;
756-
}
757-
758-
/* Combine ranges which have the smallest gap */
759-
while (cur_nodes > req_nodes) {
760-
prev = NULL;
761-
min_gap = ULONG_MAX;
762-
curr = interval_tree_iter_first(root, 0, ULONG_MAX);
763-
while (curr) {
764-
if (prev) {
765-
curr_gap = curr->start - prev->last;
766-
if (curr_gap < min_gap) {
767-
min_gap = curr_gap;
768-
comb_start = prev;
769-
comb_end = curr;
770-
}
771-
}
772-
prev = curr;
773-
curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
774-
}
775-
comb_start->last = comb_end->last;
776-
interval_tree_remove(comb_end, root);
777-
cur_nodes--;
778-
}
779-
}
780-
781735
static int mlx5vf_create_tracker(struct mlx5_core_dev *mdev,
782736
struct mlx5vf_pci_core_device *mvdev,
783737
struct rb_root_cached *ranges, u32 nnodes)
@@ -800,7 +754,7 @@ static int mlx5vf_create_tracker(struct mlx5_core_dev *mdev,
800754
int i;
801755

802756
if (num_ranges > max_num_range) {
803-
combine_ranges(ranges, nnodes, max_num_range);
757+
vfio_combine_iova_ranges(ranges, nnodes, max_num_range);
804758
num_ranges = max_num_range;
805759
}
806760

drivers/vfio/vfio_main.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,53 @@ static int vfio_ioctl_device_feature_migration(struct vfio_device *device,
935935
return 0;
936936
}
937937

938+
void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
939+
u32 req_nodes)
940+
{
941+
struct interval_tree_node *prev, *curr, *comb_start, *comb_end;
942+
unsigned long min_gap, curr_gap;
943+
944+
/* Special shortcut when a single range is required */
945+
if (req_nodes == 1) {
946+
unsigned long last;
947+
948+
comb_start = interval_tree_iter_first(root, 0, ULONG_MAX);
949+
curr = comb_start;
950+
while (curr) {
951+
last = curr->last;
952+
prev = curr;
953+
curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
954+
if (prev != comb_start)
955+
interval_tree_remove(prev, root);
956+
}
957+
comb_start->last = last;
958+
return;
959+
}
960+
961+
/* Combine ranges which have the smallest gap */
962+
while (cur_nodes > req_nodes) {
963+
prev = NULL;
964+
min_gap = ULONG_MAX;
965+
curr = interval_tree_iter_first(root, 0, ULONG_MAX);
966+
while (curr) {
967+
if (prev) {
968+
curr_gap = curr->start - prev->last;
969+
if (curr_gap < min_gap) {
970+
min_gap = curr_gap;
971+
comb_start = prev;
972+
comb_end = curr;
973+
}
974+
}
975+
prev = curr;
976+
curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
977+
}
978+
comb_start->last = comb_end->last;
979+
interval_tree_remove(comb_end, root);
980+
cur_nodes--;
981+
}
982+
}
983+
EXPORT_SYMBOL_GPL(vfio_combine_iova_ranges);
984+
938985
/* Ranges should fit into a single kernel page */
939986
#define LOG_MAX_RANGES \
940987
(PAGE_SIZE / sizeof(struct vfio_device_feature_dma_logging_range))

include/linux/vfio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ int vfio_mig_get_next_state(struct vfio_device *device,
283283
enum vfio_device_mig_state new_fsm,
284284
enum vfio_device_mig_state *next_fsm);
285285

286+
void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
287+
u32 req_nodes);
288+
286289
/*
287290
* External user API
288291
*/

0 commit comments

Comments
 (0)