Skip to content

Commit d89d58f

Browse files
dtatuleamstsirkin
authored andcommitted
vdpa/mlx5: Introduce async fw command wrapper
Introduce a new function mlx5_vdpa_exec_async_cmds() which wraps the mlx5_core async firmware command API in a way that will be used to parallelize certain operation in this driver. The wrapper deals with the case when mlx5_cmd_exec_cb() returns EBUSY due to the command being throttled. Signed-off-by: Dragos Tatulea <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Acked-by: Eugenio Pérez <[email protected]> Tested-by: Lei Yang <[email protected]>
1 parent de2cd39 commit d89d58f

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

drivers/vdpa/mlx5/core/mlx5_vdpa.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ struct mlx5_vdpa_dev {
105105
bool suspended;
106106
};
107107

108+
struct mlx5_vdpa_async_cmd {
109+
int err;
110+
struct mlx5_async_work cb_work;
111+
struct completion cmd_done;
112+
113+
void *in;
114+
size_t inlen;
115+
116+
void *out;
117+
size_t outlen;
118+
};
119+
108120
int mlx5_vdpa_create_tis(struct mlx5_vdpa_dev *mvdev, void *in, u32 *tisn);
109121
void mlx5_vdpa_destroy_tis(struct mlx5_vdpa_dev *mvdev, u32 tisn);
110122
int mlx5_vdpa_create_rqt(struct mlx5_vdpa_dev *mvdev, void *in, int inlen, u32 *rqtn);
@@ -134,6 +146,9 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
134146
unsigned int asid);
135147
int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
136148
int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
149+
int mlx5_vdpa_exec_async_cmds(struct mlx5_vdpa_dev *mvdev,
150+
struct mlx5_vdpa_async_cmd *cmds,
151+
int num_cmds);
137152

138153
#define mlx5_vdpa_err(__dev, format, ...) \
139154
dev_err((__dev)->mdev->device, "%s:%d:(pid %d) error: " format, __func__, __LINE__, \

drivers/vdpa/mlx5/core/resources.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,76 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev)
321321
mutex_destroy(&mvdev->mr_mtx);
322322
res->valid = false;
323323
}
324+
325+
static void virtqueue_cmd_callback(int status, struct mlx5_async_work *context)
326+
{
327+
struct mlx5_vdpa_async_cmd *cmd =
328+
container_of(context, struct mlx5_vdpa_async_cmd, cb_work);
329+
330+
cmd->err = mlx5_cmd_check(context->ctx->dev, status, cmd->in, cmd->out);
331+
complete(&cmd->cmd_done);
332+
}
333+
334+
static int issue_async_cmd(struct mlx5_vdpa_dev *mvdev,
335+
struct mlx5_vdpa_async_cmd *cmds,
336+
int issued,
337+
int *completed)
338+
339+
{
340+
struct mlx5_vdpa_async_cmd *cmd = &cmds[issued];
341+
int err;
342+
343+
retry:
344+
err = mlx5_cmd_exec_cb(&mvdev->async_ctx,
345+
cmd->in, cmd->inlen,
346+
cmd->out, cmd->outlen,
347+
virtqueue_cmd_callback,
348+
&cmd->cb_work);
349+
if (err == -EBUSY) {
350+
if (*completed < issued) {
351+
/* Throttled by own commands: wait for oldest completion. */
352+
wait_for_completion(&cmds[*completed].cmd_done);
353+
(*completed)++;
354+
355+
goto retry;
356+
} else {
357+
/* Throttled by external commands: switch to sync api. */
358+
err = mlx5_cmd_exec(mvdev->mdev,
359+
cmd->in, cmd->inlen,
360+
cmd->out, cmd->outlen);
361+
if (!err)
362+
(*completed)++;
363+
}
364+
}
365+
366+
return err;
367+
}
368+
369+
int mlx5_vdpa_exec_async_cmds(struct mlx5_vdpa_dev *mvdev,
370+
struct mlx5_vdpa_async_cmd *cmds,
371+
int num_cmds)
372+
{
373+
int completed = 0;
374+
int issued = 0;
375+
int err = 0;
376+
377+
for (int i = 0; i < num_cmds; i++)
378+
init_completion(&cmds[i].cmd_done);
379+
380+
while (issued < num_cmds) {
381+
382+
err = issue_async_cmd(mvdev, cmds, issued, &completed);
383+
if (err) {
384+
mlx5_vdpa_err(mvdev, "error issuing command %d of %d: %d\n",
385+
issued, num_cmds, err);
386+
break;
387+
}
388+
389+
issued++;
390+
}
391+
392+
while (completed < issued)
393+
wait_for_completion(&cmds[completed++].cmd_done);
394+
395+
return err;
396+
}

0 commit comments

Comments
 (0)