]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
vfio: Commonize combine_ranges for use in other VFIO drivers
authorBrett Creeley <brett.creeley@amd.com>
Mon, 7 Aug 2023 20:57:48 +0000 (13:57 -0700)
committerAlex Williamson <alex.williamson@redhat.com>
Wed, 16 Aug 2023 16:52:23 +0000 (10:52 -0600)
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 <yishaih@nvidia.com>
Signed-off-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Link: https://lore.kernel.org/r/20230807205755.29579-2-brett.creeley@amd.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/mlx5/cmd.c
drivers/vfio/vfio_main.c
include/linux/vfio.h

index deed156e61656597415db1abcc68ca3078435b04..7f6c51992a15d95657f9c792280ed535a07bf9b3 100644 (file)
@@ -732,52 +732,6 @@ void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf)
        mlx5vf_cmd_dealloc_pd(migf);
 }
 
-static void combine_ranges(struct rb_root_cached *root, u32 cur_nodes,
-                          u32 req_nodes)
-{
-       struct interval_tree_node *prev, *curr, *comb_start, *comb_end;
-       unsigned long min_gap;
-       unsigned long curr_gap;
-
-       /* Special shortcut when a single range is required */
-       if (req_nodes == 1) {
-               unsigned long last;
-
-               curr = comb_start = interval_tree_iter_first(root, 0, ULONG_MAX);
-               while (curr) {
-                       last = curr->last;
-                       prev = curr;
-                       curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
-                       if (prev != comb_start)
-                               interval_tree_remove(prev, root);
-               }
-               comb_start->last = last;
-               return;
-       }
-
-       /* Combine ranges which have the smallest gap */
-       while (cur_nodes > req_nodes) {
-               prev = NULL;
-               min_gap = ULONG_MAX;
-               curr = interval_tree_iter_first(root, 0, ULONG_MAX);
-               while (curr) {
-                       if (prev) {
-                               curr_gap = curr->start - prev->last;
-                               if (curr_gap < min_gap) {
-                                       min_gap = curr_gap;
-                                       comb_start = prev;
-                                       comb_end = curr;
-                               }
-                       }
-                       prev = curr;
-                       curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
-               }
-               comb_start->last = comb_end->last;
-               interval_tree_remove(comb_end, root);
-               cur_nodes--;
-       }
-}
-
 static int mlx5vf_create_tracker(struct mlx5_core_dev *mdev,
                                 struct mlx5vf_pci_core_device *mvdev,
                                 struct rb_root_cached *ranges, u32 nnodes)
@@ -800,7 +754,7 @@ static int mlx5vf_create_tracker(struct mlx5_core_dev *mdev,
        int i;
 
        if (num_ranges > max_num_range) {
-               combine_ranges(ranges, nnodes, max_num_range);
+               vfio_combine_iova_ranges(ranges, nnodes, max_num_range);
                num_ranges = max_num_range;
        }
 
index 902f06e52c4832f6a63a4a2ecc7b6605fddd8f24..5417778f2b6bb804816554b8d4edaea49d14d6bd 100644 (file)
@@ -935,6 +935,53 @@ static int vfio_ioctl_device_feature_migration(struct vfio_device *device,
        return 0;
 }
 
+void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
+                             u32 req_nodes)
+{
+       struct interval_tree_node *prev, *curr, *comb_start, *comb_end;
+       unsigned long min_gap, curr_gap;
+
+       /* Special shortcut when a single range is required */
+       if (req_nodes == 1) {
+               unsigned long last;
+
+               comb_start = interval_tree_iter_first(root, 0, ULONG_MAX);
+               curr = comb_start;
+               while (curr) {
+                       last = curr->last;
+                       prev = curr;
+                       curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
+                       if (prev != comb_start)
+                               interval_tree_remove(prev, root);
+               }
+               comb_start->last = last;
+               return;
+       }
+
+       /* Combine ranges which have the smallest gap */
+       while (cur_nodes > req_nodes) {
+               prev = NULL;
+               min_gap = ULONG_MAX;
+               curr = interval_tree_iter_first(root, 0, ULONG_MAX);
+               while (curr) {
+                       if (prev) {
+                               curr_gap = curr->start - prev->last;
+                               if (curr_gap < min_gap) {
+                                       min_gap = curr_gap;
+                                       comb_start = prev;
+                                       comb_end = curr;
+                               }
+                       }
+                       prev = curr;
+                       curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
+               }
+               comb_start->last = comb_end->last;
+               interval_tree_remove(comb_end, root);
+               cur_nodes--;
+       }
+}
+EXPORT_SYMBOL_GPL(vfio_combine_iova_ranges);
+
 /* Ranges should fit into a single kernel page */
 #define LOG_MAX_RANGES \
        (PAGE_SIZE / sizeof(struct vfio_device_feature_dma_logging_range))
index 5a1dee983f17f7f9cfa2b8c0d7ac50fa785ac78a..454e9295970c49d8282fe0b23553f36c74dd4928 100644 (file)
@@ -283,6 +283,9 @@ int vfio_mig_get_next_state(struct vfio_device *device,
                            enum vfio_device_mig_state new_fsm,
                            enum vfio_device_mig_state *next_fsm);
 
+void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
+                             u32 req_nodes);
+
 /*
  * External user API
  */