The balloon nodes used to fill areas of GGTT inaccessible for a specific VF, were allocaten and inserted into GGTT within one function. This disallowed re-using the insertion part during VF migration recovery.
This patch separates allocation (init/fini functs) from the insertion of balloons (balloon/deballoon functs). Locks are also moved to ensure calls from post-migration recovery worker will not cause a deadlock. Signed-off-by: Tomasz Lis <tomasz....@intel.com> --- drivers/gpu/drm/xe/xe_ggtt.c | 9 +--- drivers/gpu/drm/xe/xe_ggtt.h | 2 + drivers/gpu/drm/xe/xe_gt_sriov_vf.c | 64 ++++++++++++++++++++++------- 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index 5fcb2b4c2c13..2d7456e37ef4 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -452,9 +452,7 @@ int xe_ggtt_node_insert_balloon(struct xe_ggtt_node *node, u64 start, u64 end) node->base.start = start; node->base.size = end - start; - mutex_lock(&ggtt->lock); err = drm_mm_reserve_node(&ggtt->mm, &node->base); - mutex_unlock(&ggtt->lock); if (xe_gt_WARN(ggtt->tile->primary_gt, err, "Failed to balloon GGTT %#llx-%#llx (%pe)\n", @@ -477,16 +475,11 @@ void xe_ggtt_node_remove_balloon(struct xe_ggtt_node *node) return; if (!drm_mm_node_allocated(&node->base)) - goto free_node; + return; xe_ggtt_dump_node(node->ggtt, &node->base, "remove-balloon"); - mutex_lock(&node->ggtt->lock); drm_mm_remove_node(&node->base); - mutex_unlock(&node->ggtt->lock); - -free_node: - xe_ggtt_node_fini(node); } /** diff --git a/drivers/gpu/drm/xe/xe_ggtt.h b/drivers/gpu/drm/xe/xe_ggtt.h index 27e7d67de004..fddb68f309d9 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.h +++ b/drivers/gpu/drm/xe/xe_ggtt.h @@ -18,6 +18,8 @@ void xe_ggtt_node_fini(struct xe_ggtt_node *node); int xe_ggtt_node_insert_balloon(struct xe_ggtt_node *node, u64 start, u64 size); void xe_ggtt_node_remove_balloon(struct xe_ggtt_node *node); +int xe_gt_sriov_vf_balloon_ggtt(struct xe_gt *gt); +void xe_gt_sriov_vf_deballoon_ggtt(struct xe_gt *gt); int xe_ggtt_node_insert(struct xe_ggtt_node *node, u32 size, u32 align); int xe_ggtt_node_insert_locked(struct xe_ggtt_node *node, diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c index a439261bf4d7..9edbe34f45f4 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c @@ -560,26 +560,33 @@ u64 xe_gt_sriov_vf_lmem(struct xe_gt *gt) return gt->sriov.vf.self_config.lmem_size; } -static struct xe_ggtt_node * -vf_balloon_ggtt_node(struct xe_ggtt *ggtt, u64 start, u64 end) +static int +vf_balloon_ggtt_node(struct xe_ggtt *ggtt, struct xe_ggtt_node *node, + u64 start, u64 end) { - struct xe_ggtt_node *node; int err; - node = xe_ggtt_node_init(ggtt); if (IS_ERR(node)) - return node; + return PTR_ERR(node); err = xe_ggtt_node_insert_balloon(node, start, end); if (err) { - xe_ggtt_node_fini(node); - return ERR_PTR(err); + return err; } - return node; + return 0; } -static int vf_balloon_ggtt(struct xe_gt *gt) +static void xe_gt_sriov_vf_balloon_init(struct xe_gt *gt) +{ + struct xe_tile *tile = gt_to_tile(gt); + struct xe_ggtt *ggtt = tile->mem.ggtt; + + tile->sriov.vf.ggtt_balloon[0] = xe_ggtt_node_init(ggtt); + tile->sriov.vf.ggtt_balloon[1] = xe_ggtt_node_init(ggtt); +} + +int xe_gt_sriov_vf_balloon_ggtt(struct xe_gt *gt) { struct xe_gt_sriov_vf_selfconfig *config = >->sriov.vf.self_config; struct xe_tile *tile = gt_to_tile(gt); @@ -589,6 +596,7 @@ static int vf_balloon_ggtt(struct xe_gt *gt) xe_gt_assert(gt, IS_SRIOV_VF(xe)); xe_gt_assert(gt, !xe_gt_is_media_type(gt)); + lockdep_assert_held(&tile->mem.ggtt->lock); if (!config->ggtt_size) return -ENODATA; @@ -611,7 +619,7 @@ static int vf_balloon_ggtt(struct xe_gt *gt) start = xe_wopcm_size(xe); end = config->ggtt_base; if (end != start) { - tile->sriov.vf.ggtt_balloon[0] = vf_balloon_ggtt_node(ggtt, start, end); + vf_balloon_ggtt_node(ggtt, tile->sriov.vf.ggtt_balloon[0], start, end); if (IS_ERR(tile->sriov.vf.ggtt_balloon[0])) return PTR_ERR(tile->sriov.vf.ggtt_balloon[0]); } @@ -619,7 +627,7 @@ static int vf_balloon_ggtt(struct xe_gt *gt) start = config->ggtt_base + config->ggtt_size; end = GUC_GGTT_TOP; if (end != start) { - tile->sriov.vf.ggtt_balloon[1] = vf_balloon_ggtt_node(ggtt, start, end); + vf_balloon_ggtt_node(ggtt, tile->sriov.vf.ggtt_balloon[1], start, end); if (IS_ERR(tile->sriov.vf.ggtt_balloon[1])) { xe_ggtt_node_remove_balloon(tile->sriov.vf.ggtt_balloon[0]); return PTR_ERR(tile->sriov.vf.ggtt_balloon[1]); @@ -629,15 +637,34 @@ static int vf_balloon_ggtt(struct xe_gt *gt) return 0; } -static void deballoon_ggtt(struct drm_device *drm, void *arg) +void xe_gt_sriov_vf_deballoon_ggtt(struct xe_gt *gt) { - struct xe_tile *tile = arg; + struct xe_tile *tile = gt_to_tile(gt); xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile))); + lockdep_assert_held(&tile->mem.ggtt->lock); xe_ggtt_node_remove_balloon(tile->sriov.vf.ggtt_balloon[1]); xe_ggtt_node_remove_balloon(tile->sriov.vf.ggtt_balloon[0]); } +static void xe_gt_sriov_vf_balloon_fini(struct xe_gt *gt) +{ + struct xe_tile *tile = gt_to_tile(gt); + + xe_ggtt_node_fini(tile->sriov.vf.ggtt_balloon[1]); + xe_ggtt_node_fini(tile->sriov.vf.ggtt_balloon[0]); +} + +static void deballoon_ggtt(struct drm_device *drm, void *arg) +{ + struct xe_tile *tile = arg; + + mutex_lock(&tile->mem.ggtt->lock); + xe_gt_sriov_vf_deballoon_ggtt(tile->primary_gt); + mutex_unlock(&tile->mem.ggtt->lock); + xe_gt_sriov_vf_balloon_fini(tile->primary_gt); +} + /** * xe_gt_sriov_vf_prepare_ggtt - Prepare a VF's GGTT configuration. * @gt: the &xe_gt @@ -650,14 +677,21 @@ int xe_gt_sriov_vf_prepare_ggtt(struct xe_gt *gt) { struct xe_tile *tile = gt_to_tile(gt); struct xe_device *xe = tile_to_xe(tile); + struct xe_ggtt *ggtt = tile->mem.ggtt; int err; if (xe_gt_is_media_type(gt)) return 0; - err = vf_balloon_ggtt(gt); - if (err) + xe_gt_sriov_vf_balloon_init(gt); + + mutex_lock(&ggtt->lock); + err = xe_gt_sriov_vf_balloon_ggtt(gt); + mutex_unlock(&ggtt->lock); + if (err) { + xe_gt_sriov_vf_balloon_fini(gt); return err; + } return drmm_add_action_or_reset(&xe->drm, deballoon_ggtt, tile); } -- 2.25.1