Skip to content
Development
Skill

/rdma-verbs

RDMA verbs skill for InfiniBand and RoCE programming. Use when using libibverbs API, creating queue pairs, RDMA read/write operations, or benchmarking with perftest. Activates on queries about libibverbs, ibv_reg_mr, ibv_create_qp, RDMA, RoCE, ib_send_bw, or rdma-sys.

From plugin
low-level-dev-skills
159142 skills
Install
$ npx -y skills add mohitmishra786/low-level-dev-skills --skill rdma-verbs --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/rdma-verbs

Context preview

The summary Claude sees to decide when to auto-load this skill.

RDMA verbs skill for InfiniBand and RoCE programming. Use when using libibverbs API, creating queue pairs, RDMA read/write operations, or benchmarking with perftest. Activates on queries about libibverbs, ibv_reg_mr, ibv_create_qp, RDMA, RoCE, ib_send_bw, or rdma-sys.

SKILL.md

rdma-verbs.SKILL.md
name: rdma-verbs
description: RDMA verbs skill for InfiniBand and RoCE programming. Use when using libibverbs API, creating queue pairs, RDMA read/write operations, or benchmarking with perftest. Activates on queries about libibverbs, ibv_reg_mr, ibv_create_qp, RDMA, RoCE, ib_send_bw, or rdma-sys.

RDMA Verbs

Purpose

Guide agents through RDMA programming with libibverbs: one-sided vs two-sided operations, RC/UC/UD transports, device setup (`ibv_get_device_list`, protection domains, memory registration, completion queues, queue pairs), work requests and completions, RoCE vs InfiniBand, perftest benchmarking, and Rust `rdma-sys` bindings.

When to Use

  • Building ultra-low-latency storage or database networking
  • Bypassing CPU for remote memory access (one-sided RDMA)
  • Setting up RoCE on Ethernet fabrics
  • Benchmarking network fabric with perftest tools
  • Integrating RDMA into MPI or custom RPC systems
  • Debugging RDMA connection and completion errors

Workflow

1. RDMA concepts

RDMA stack
├── Application (libibverbs)
├── Kernel RDMA driver (mlx5, rdma_rxe)
├── NIC/HCA hardware
└── Fabric (InfiniBand or RoCE/Ethernet)

Operation types
├── Two-sided: Send/Recv (both sides participate)
└── One-sided: RDMA Read/Write (remote CPU not involved)

Transports:

| Type | Reliable | Connection | Use | |------|----------|------------|-----| | RC (Reliable Connected) | Yes | 1:1 QP pair | General purpose | | UC (Unreliable Connected) | No | 1:1 | Multicast-like | | UD (Unreliable Datagram) | No | Many:Many | MPI, discovery |

2. Device discovery

# List RDMA devices
ibv_devices
ibv_devinfo

# RoCE link status
rdma link show
ibstat

# Perftest prerequisites
modprobe ib_umad

3. Minimal libibverbs setup

#include <infiniband/verbs.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int num_devices;
    struct ibv_device **dev_list = ibv_get_device_list(&num_devices);
    if (!dev_list || num_devices == 0) {
        fprintf(stderr, "No RDMA devices\n");
        return 1;
    }

    struct ibv_context *ctx = ibv_open_device(dev_list[0]);
    struct ibv_pd *pd = ibv_alloc_pd(ctx);

    char buf[4096];
    struct ibv_mr *mr = ibv_reg_mr(pd, buf, sizeof(buf),
        IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE);

    struct ibv_cq *cq = ibv_create_cq(ctx, 10, NULL, NULL, 0);

    struct ibv_qp_init_attr qp_attr = {
        .send_cq = cq,
        .recv_cq = cq,
        .cap = { .max_send_wr = 10, .max_recv_wr = 10,
                 .max_send_sge = 1, .max_recv_sge = 1 },
        .qp_type = IBV_QPT_RC,
    };
    struct ibv_qp *qp = ibv_create_qp(pd, &qp_attr);

    printf("QP num %u, MR lkey %u rkey %u\n",
           qp->qp_num, mr->lkey, mr->rkey);

    ibv_destroy_qp(qp);
    ibv_dereg_mr(mr);
    ibv_destroy_cq(cq);
    ibv_dealloc_pd(pd);
    ibv_close_device(ctx);
    ibv_free_device_list(dev_list);
    return 0;
}
gcc -o rdma_setup rdma_setup.c -libverbs

4. Connection setup (RC)

RC requires exchanging QP info (lid, gid, qp_num, psn) out-of-band:

// Simplified: exchange via TCP socket before RDMA
struct qp_info {
    uint16_t lid;
    uint32_t qpn;
    uint32_t psn;
    union ibv_gid gid;
};

// Modify QP to INIT → RTR → RTS states
struct ibv_qp_attr attr = { .qp_state = IBV_QPS_INIT, ... };
ibv_modify_qp(qp, &attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | ...);
// RTR: set path_mtu, dest_qp_num, rq_psn, ah_attr
// RTS: set sq_psn, timeout, retry_cnt

Use rdmacm (`librdmacm`) for simplified connection management:

#include <rdma/rdma_cma.h>
// rdma_create_event_channel, rdma_connect, rdma_accept

5. Send/Recv (two-sided)

// Post receive
struct ibv_recv_wr recv_wr = {}, *bad_wr;
struct ibv_sge recv_sge = { .addr = (uint64_t)recv_buf, .length = 4096, .lkey = mr->lkey };
recv_wr.wr_id = 1;
recv_wr.sg_list = &recv_sge;
recv_wr.num_sge = 1;
ibv_post_recv(qp, &recv_wr, &bad_wr);

// Post send
struct ibv_send_wr send_wr = {}, *bad_send;
struct ibv_sge send_sge = { .addr = (uint64_t)send_buf, .length = msg_len, .lkey = mr->lkey };
send_wr.wr_id = 2;
send_wr.opcode = IBV_WR_SEND;
send_wr.sg_list = &send_sge;
send_wr.num_sge = 1;
ibv_post_send(qp, &send_wr, &bad_send);

// Poll completion
struct ibv_wc wc;
while (ibv_poll_cq(cq, 1, &wc) == 0);
if (wc.status != IBV_WC_SUCCESS)
    fprintf(stderr, "WC error: %s\n", ibv_wc_status_str(wc.status));

6. RDMA Write (one-sided)

struct ibv_send_wr wr = {}, *bad;
struct ibv_sge sge = { .addr = (uint64_t)local_buf, .length = len, .lkey = local_mr->lkey };

wr.wr_id = 3;
wr.opcode = IBV_WR_RDMA_WRITE;
wr.send_flags = IBV_SEND_SIGNALED;
wr.sg_list = &sge;
wr.num_sge = 1;
wr.wr.rdma.remote_addr = remote_addr;  // from peer exchange
wr.wr.rdma.rkey = remote_rkey;

ibv_post_send(qp, &wr, &bad);

Remote CPU is not interrupted — data appears in remote memory directly.

7. RoCE vs InfiniBand

| | InfiniBand | RoCE | |---|------------|------| | Physical | Dedicated IB fabric | Ethernet (lossless DCB/PFC) | | LID/GID | Both | Primarily GID (IPv6-like) | | Setup | Subnet manager | DCB config, PFC, ECN |

# RoCEv2 GID
cat /sys/class/infiniband/mlx5_0/ports/1/gids/3

8. perftest benchmarking

# Server
ib_send_bw -d mlx5_0 -x 3

# Client
ib_send_bw -d mlx5_0 -x 3 <server_ip>

# Latency
ib_send_lat -d mlx5_0 <server_ip>

# RDMA write bandwidth
ib_write_bw -d mlx5_0 <server_ip>

9. Rust rdma-sys

# Cargo.toml
rdma-sys = "0.1"

Wrap libibverbs with safe abstractions or use `async-rdma` crate for higher-level API.

Common Problems

| Symptom | Cause | Fix | |---------|-------|-----| | `ibv_reg_mr` fails | Memory limit or wrong permissions | Check `ulimit -l`; set access flags | | WC status `rem_inv_req` | Bad rkey/addr | Re-exchange MR info after reconnect | | QP RTS failure | Wrong PSN or path | Verify lid/gid match; subnet manager | | RoCE packet loss | No PFC on switches | Enable lossless Ethernet; DC

Read more
Ships withlow-level-dev-skills

A curated suite of AI agent skills for systems and low-level programming — C/C++, Rust, Zig, GPU, bare-metal firmware, Linux kernel/driver development, computer architecture, compiler internals, HPC, and more.

Get the whole plugin
Stats
172
Stars
24
Forks
Maintained
Maintenance
JavaScript
Language
MIT
License
1mo ago
Last commit
5mo ago
Created

Repo: mohitmishra786/low-level-dev-skills

Other skills on low-level-dev-skills.