MLX5DV_DEVX_GENERAL_CMD(3)

Hey bestie, welcome to the mlx5dv_devx_obj_.../query / general(3) manual page β€” yes that's the whole unhinged title, it's giving "six functions, one page, zero chill" πŸ’…. Sit down, grab a πŸ“, and let's get into it.


✨ NAME ✨

Okay so this page is basically a whole friend group of functions, and here's the roster:

  • mlx5dv_devx_obj_create β€” Creates a devx object
  • mlx5dv_devx_obj_destroy β€” Destroys a devx object
  • mlx5dv_devx_obj_modify β€” Modifies a devx object
  • mlx5dv_devx_obj_query β€” Queries a devx object
  • mlx5dv_devx_obj_query_async β€” Queries a devx object in an asynchronous mode
  • mlx5dv_devx_general_cmd β€” Issues a general command over the devx interface

🌸 SYNOPSIS 🌸

Include this and you're in:

#include <infiniband/mlx5dv.h>

struct mlx5dv_devx_obj *
mlx5dv_devx_obj_create(struct ibv_context *context, const void *in, size_t inlen,
               void *out, size_t outlen);
int mlx5dv_devx_obj_query(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen,
              void *out, size_t outlen);
int mlx5dv_devx_obj_query_async(struct mlx5dv_devx_obj *obj, const void *in,
                size_t inlen, size_t outlen,
                uint64_t wr_id,
                struct mlx5dv_devx_cmd_comp *cmd_comp);
int mlx5dv_devx_obj_modify(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen,
               void *out, size_t outlen);
int mlx5dv_devx_obj_destroy(struct mlx5dv_devx_obj *obj);
int mlx5dv_devx_general_cmd(struct ibv_context *context, const void *in, size_t inlen,
                void *out, size_t outlen);

πŸ¦‹ DESCRIPTION πŸ¦‹

So like, the whole vibe: create / destroy / modify / query a devx object, and issue a general command over the devx interface. That's the elevator pitch, periodt.

The DEVX API enables direct access from the user space area to the mlx5 device driver by using the KABI mechanism. The main purpose? Making the user space driver as independent as possible from the kernel so that future device functionality and commands can be activated with minimal to none kernel changes. Lowkey iconic of them.

A DEVX object represents some underlay firmware object, and the input command to create it is some raw data given by the user application β€” and ngl, that raw data should match the device specification. Upon successful creation the output buffer includes the raw data from the device according to its specification, and this data can be used as part of related firmware commands to this object. πŸŽ€

Once the DEVX object is created it can be queried/modified/destroyed by the matching mlx5dv_devx_obj_xxx() API. Both the input and the output for those APIs need to match the device specification as well β€” no improvising, bestie, the spec is the spec.

The mlx5dv_devx_general_cmd() API enables issuing some general command which is not related to an object, such as query device capabilities. Cute, self-contained, no object attached. ✨

The mlx5dv_devx_obj_query_async() API is similar to the query object API, however, it runs asynchronously without blocking. Main character energy: it does NOT wait for you. The input includes an mlx5dv_devx_cmd_comp object and an identifier named wr_id for this command. The response should be read upon success with the mlx5dv_devx_get_async_cmd_comp() API. The wr_id that was supplied as an input is returned as part of the response to let application knows for which command the response is related to β€” like a little name tag at the party so you know who's who 🫢.

An application can gradually migrate to use DEVX according to its needs β€” it is not all or nothing. Fr fr, you can dip a toe. For example it can create an ibv_cq via ibv_create_cq() verb and then use the returned cqn to create a DEVX QP object by the mlx5dv_devx_obj_create() API which needs that cqn.

The above example can enable an application to create a QP with some driver specific attributes that are not exposed in the ibv_create_qp() API β€” and in that case no user or kernel change may be needed at all as the command input reaches directly to the firmware. Direct to firmware. No middleman. Slay.

The expected users for the DEVX APIs are application that use the mlx5 DV APIs and are familiar with the device specification in both control and data path. Iykyk. πŸ’œ

Heads up bestie: to successfully create a DEVX object and work on, a DEVX context must be created, and that's done by the mlx5dv_open_device() API with the MLX5DV_CONTEXT_FLAGS_DEVX flag. Don't skip this step, it's the vibe check of the whole operation.

πŸŽ€ ARGUMENTS πŸŽ€

  • context β€” RDMA device context to create the action on.
  • in β€” A buffer which contains the command's input data provided in a device specification format.
  • inlen β€” The size of in buffer in bytes.
  • out β€” A buffer which contains the command's output data according to the device specification format.
  • outlen β€” The size of out buffer in bytes.
  • obj β€” For query, modify, destroy: the devx object to work on.
  • wr_id β€” The command identifier when working in asynchronous mode.
  • cmd_comp β€” The command completion object to read the response from in asynchronous mode.

⭐ RETURN VALUE ⭐

Upon success mlx5dv_devx_create_obj will return a new struct mlx5dv_devx_obj; on error NULL will be returned and errno will be set. 😭 Sad girl hours.

Upon success query, modify, destroy, general commands, 0 is returned or the value of errno on a failure.

Lowkey important: if the error value is EREMOTEIO, outbox.status and outbox.syndrome will contain the command failure details. That's your receipts, bestie β€” read them.

🌈 SEE ALSO 🌈

Go read these next, they're all linked in the group chat:

  • mlx5dv_open_device
  • mlx5dv_devx_create_cmd_comp
  • mlx5dv_devx_get_async_cmd_comp

πŸ‘‘ AUTHOR πŸ‘‘

Yishai Hadas <yishaih@mellanox.com>


And that's the whole page, bestie 🧚 β€” straight out of the mlx5dv_devx_obj_.../query / general(3) manual, section 3, footer and all. Now go forth and create some objects responsibly. πŸ’–

πŸ“¦ where this page comes from