Skip to content

Commit f886473

Browse files
Yishai Hadasawilliam
authored andcommitted
vfio/mlx5: Add support for tracker object change event
Add support for tracker object change event by referring to its MLX5_EVENT_TYPE_OBJECT_CHANGE event when occurs. This lets the driver recognize whether the firmware moved the tracker object to an error state. In that case, the driver will skip/block any usage of that object including an early exit in case the object was previously marked with an error. This functionality also covers the case when no CQE is delivered as of the error state. The driver was adapted to the device specification to handle the above. Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Acked-by: Leon Romanovsky <leon@kernel.org> Link: https://lore.kernel.org/r/20240205124828.232701-3-yishaih@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 1cbcb56 commit f886473

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

drivers/vfio/pci/mlx5/cmd.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev,
149149
return 0;
150150
}
151151

152+
static void set_tracker_change_event(struct mlx5vf_pci_core_device *mvdev)
153+
{
154+
mvdev->tracker.object_changed = true;
155+
complete(&mvdev->tracker_comp);
156+
}
157+
152158
static void set_tracker_error(struct mlx5vf_pci_core_device *mvdev)
153159
{
154160
/* Mark the tracker under an error and wake it up if it's running */
@@ -900,6 +906,29 @@ static int mlx5vf_cmd_modify_tracker(struct mlx5_core_dev *mdev,
900906
return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
901907
}
902908

909+
static int mlx5vf_cmd_query_tracker(struct mlx5_core_dev *mdev,
910+
struct mlx5_vhca_page_tracker *tracker)
911+
{
912+
u32 out[MLX5_ST_SZ_DW(query_page_track_obj_out)] = {};
913+
u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
914+
void *obj_context;
915+
void *cmd_hdr;
916+
int err;
917+
918+
cmd_hdr = MLX5_ADDR_OF(modify_page_track_obj_in, in, general_obj_in_cmd_hdr);
919+
MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
920+
MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_PAGE_TRACK);
921+
MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, tracker->id);
922+
923+
err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
924+
if (err)
925+
return err;
926+
927+
obj_context = MLX5_ADDR_OF(query_page_track_obj_out, out, obj_context);
928+
tracker->status = MLX5_GET(page_track, obj_context, state);
929+
return 0;
930+
}
931+
903932
static int alloc_cq_frag_buf(struct mlx5_core_dev *mdev,
904933
struct mlx5_vhca_cq_buf *buf, int nent,
905934
int cqe_size)
@@ -957,9 +986,11 @@ static int mlx5vf_event_notifier(struct notifier_block *nb, unsigned long type,
957986
mlx5_nb_cof(nb, struct mlx5_vhca_page_tracker, nb);
958987
struct mlx5vf_pci_core_device *mvdev = container_of(
959988
tracker, struct mlx5vf_pci_core_device, tracker);
989+
struct mlx5_eqe_obj_change *object;
960990
struct mlx5_eqe *eqe = data;
961991
u8 event_type = (u8)type;
962992
u8 queue_type;
993+
u32 obj_id;
963994
int qp_num;
964995

965996
switch (event_type) {
@@ -975,6 +1006,12 @@ static int mlx5vf_event_notifier(struct notifier_block *nb, unsigned long type,
9751006
break;
9761007
set_tracker_error(mvdev);
9771008
break;
1009+
case MLX5_EVENT_TYPE_OBJECT_CHANGE:
1010+
object = &eqe->data.obj_change;
1011+
obj_id = be32_to_cpu(object->obj_id);
1012+
if (obj_id == tracker->id)
1013+
set_tracker_change_event(mvdev);
1014+
break;
9781015
default:
9791016
break;
9801017
}
@@ -1634,6 +1671,11 @@ int mlx5vf_tracker_read_and_clear(struct vfio_device *vdev, unsigned long iova,
16341671
goto end;
16351672
}
16361673

1674+
if (tracker->is_err) {
1675+
err = -EIO;
1676+
goto end;
1677+
}
1678+
16371679
mdev = mvdev->mdev;
16381680
err = mlx5vf_cmd_modify_tracker(mdev, tracker->id, iova, length,
16391681
MLX5_PAGE_TRACK_STATE_REPORTING);
@@ -1652,6 +1694,12 @@ int mlx5vf_tracker_read_and_clear(struct vfio_device *vdev, unsigned long iova,
16521694
dirty, &tracker->status);
16531695
if (poll_err == CQ_EMPTY) {
16541696
wait_for_completion(&mvdev->tracker_comp);
1697+
if (tracker->object_changed) {
1698+
tracker->object_changed = false;
1699+
err = mlx5vf_cmd_query_tracker(mdev, tracker);
1700+
if (err)
1701+
goto end;
1702+
}
16551703
continue;
16561704
}
16571705
}

drivers/vfio/pci/mlx5/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct mlx5_vhca_page_tracker {
162162
u32 id;
163163
u32 pdn;
164164
u8 is_err:1;
165+
u8 object_changed:1;
165166
struct mlx5_uars_page *uar;
166167
struct mlx5_vhca_cq cq;
167168
struct mlx5_vhca_qp *host_qp;

0 commit comments

Comments
 (0)