libxnvme_cuda.h#

Structs#

xnvme_cuda_queue#

struct xnvme_cuda_queue#

GPU NVMe IO helpers.

Host-side queue management and device-side helpers for submitting NVMe commands from CUDA kernels using xNVMe’s NVMe spec types.

Instances live in CUDA device memory. Create one via xnvme_cuda_queue_create() and pass the returned pointer as a kernel argument.

With CUDACC (nvcc compiling CUDA kernels): the full definition is provided. This is required for xnvme_cuda_cmd_io().

Note

This API is experimental and may change without notice. GPU-resident NVMe queue pair

Public Members

void *sq#

VA-Pointer to DMA-capable memory backing the Submission Queue (SQ).

void *cq#

VA-Pointer to DMA-capable memory backing the Completion Queue (CQ).

void *sqdb#

Pointer to Submission Queue Doorbell Register in bar0.

void *cqdb#

Pointer to Completion Queue Doorbell Register in bar0.

uint32_t qid#

The admin: queue-id == 0 ; io: queue-id > 0;.

uint16_t depth#

Length of the queue-pair.

uint16_t tail#

Submission Queue Tail Pointer.

uint16_t head#

Completion Queue Head Pointer.

uint8_t phase#

Expected CQ phase bit; flips each time the CQ head wraps to 0.

uint8_t _rsvd[3]#

Padding to align timeout_ms to a 4-byte boundary.

uint32_t timeout_ms#

Command timeout in milliseconds (derived from cap.to).

uint64_t clocks_per_ms#

SM clock cycles per millisecond (set from CU_DEVICE_ATTRIBUTE_CLOCK_RATE).

Functions#

xnvme_cuda_cmd_io#

static inline int xnvme_cuda_cmd_io(struct xnvme_cuda_queue *qp, struct xnvme_spec_cmd *cmd, size_t tid, size_t batch_size)#

Submit an NVMe command and reap its completion from a CUDA kernel.

The intention is to use this in a CUDA kernel where the threadblock size is equal to the queue depth and the number of threadblocks is equal to the number of queues.

The function works as follows: 1) Each active thread (tid < batch_size) enqueues its command with xnvme_cuda_enqueue_at_i() where offset == thread index 2) A threadblock barrier ensures all commands are written before continuing 3) Only the first thread in the block calls xnvme_cuda_sq_update() with increment == batch_size 4) Each active thread reaps a completion with xnvme_cuda_reap_at_i() where offset == thread index 5) A threadblock barrier ensures all completions are reaped before continuing 6) Only the first thread in the block calls xnvme_cuda_cq_update() with increment == batch_size

Inactive threads (tid >= batch_size) participate in the barriers but do not submit or reap commands and return 0. This allows partial rounds where fewer than blockDim.x IOs are needed without breaking the collective barrier contract.

The barriers in steps 2 and 5 are required for correct operation when the threadblock spans multiple warps (i.e. batch_size > 32). Without them, thread 0 may ring the SQ doorbell before other warps have written their commands, or advance the CQ head and flip the phase before other warps have reaped.

Parameters:
  • qp – GPU queue pair (from xnvme_cuda_queue_create())

  • cmd – Command to submit (only read for tid < batch_size)

  • tid – Thread index within the block (threadIdx.x)

  • batch_size – Number of IOs to submit; threads with tid >= batch_size participate in barriers but do not submit or reap

Returns:

0 on success. -EAGAIN on completion timeout. Positive NVMe status code on device error.

xnvme_cuda_cq_update#

static inline void xnvme_cuda_cq_update(struct xnvme_cuda_queue *qp, uint16_t increment)#

Update the completion queue head and head doorbell.

This function updates the head and writes it to the MMIO doorbell register for the given queue pair, notifying the controller that all completions have been reaped.

Parameters:
  • qp – Pointer to the NVMe queue pair whose CQ doorbell should be updated.

  • increment – Number of commands to increment the head by

xnvme_cuda_enqueue_at_i#

static inline void xnvme_cuda_enqueue_at_i(struct xnvme_cuda_queue *qp, struct xnvme_spec_cmd *cmd, uint16_t offset)#

Enqueue a command into an NVMe submission queue at a certain index.

That is, writes it into the submission queue memory. It does not increment the tail-pointer or write the tail to the sq-doorbell.

Parameters:
  • qp – Pointer to the NVMe queue pair to submit command to

  • cmd – Command to submit

  • offset – Where to insert the Command in the queue in relation to the tail

xnvme_cuda_queue_create#

int xnvme_cuda_queue_create(struct xnvme_dev *dev, uint16_t depth, struct xnvme_cuda_queue **queue)#

Create a GPU-resident NVMe IO queue.

Allocates a queue pair in CUDA device memory and registers it with the NVMe controller. The resulting pointer lives in device memory and can be passed directly as a CUDA kernel argument.

Parameters:
  • dev – An xnvme_dev opened on an upcie-cuda device

  • depth – Number of IO slots in the queue

  • queue – On success, set to a device pointer to the GPU queue

Returns:

0 on success, negative error code on failure

xnvme_cuda_queue_destroy#

void xnvme_cuda_queue_destroy(struct xnvme_dev *dev, struct xnvme_cuda_queue *queue)#

Destroy a GPU-resident NVMe IO queue.

Deletes the queue pair from the NVMe controller and frees the device memory.

Parameters:

xnvme_cuda_reap_at_i#

static inline int xnvme_cuda_reap_at_i(struct xnvme_cuda_queue *qp, int timeout_ms, struct xnvme_spec_cpl *cpl, uint16_t offset)#

Reaps the completion queue entry at a certain index if ready before timeout.

This function does not increment the head-pointer or write the head to the cq-doorbell.

Parameters:
  • qp – Pointer to the NVMe queue pair to reap completion from

  • timeout_ms – Timeout in milliseconds

  • cpl – Completion when one is reaped, NULL if timeout

  • offset – Which completion to reap in relation to the head

Returns:

0 on success, -EAGAIN on timeout

xnvme_cuda_sq_update#

static inline void xnvme_cuda_sq_update(struct xnvme_cuda_queue *qp, uint16_t increment)#

Update the submission queue tail and tail doorbell.

This function updates the tail and writes it to the MMIO doorbell register for the given queue pair, notifying the controller of new commands.

Parameters:
  • qp – Pointer to the NVMe queue pair whose SQ doorbell should be updated.

  • increment – Number of commands to increment the tail by