/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.
$ npx -y skills add mohitmishra786/low-level-dev-skills --skill rdma-verbs --agent claude-codeHow 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.mdname: 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_cntUse 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
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_cntUse 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
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.
Repo: mohitmishra786/low-level-dev-skills
Other skills on low-level-dev-skills.
- /custom-allocators
Custom allocator skill for memory allocation strategies. Use when implementing pool/slab/arena allocators, tuning jemalloc/mimalloc, writing Rust GlobalAlloc, or benchmarking allocator performance. Activates on queries about jemalloc, mimalloc, tcmalloc, arena allocator,
Open skill - /numa-programming
NUMA programming skill for multi-socket memory locality. Use when detecting NUMA topology, binding processes with numactl, using libnuma API, building NUMA-aware data structures, or measuring remote access penalties. Activates on queries about numactl, libnuma, NUMA topology,
Open skill - /af-xdp
AF_XDP skill for high-performance XDP sockets. Use when creating AF_XDP sockets, configuring UMEM and XSK rings, XDP_REDIRECT programs, copy vs zero-copy mode, or comparing with DPDK. Activates on queries about AF_XDP, xsk_umem, XDP_REDIRECT, libbpf xsk, or zero-copy XDP.
Open skill - /dpdk
DPDK skill for userspace packet I/O. Use when initializing EAL, configuring PMD drivers, using mbuf pools and rte_ring, setting up huge pages, RSS, or testpmd validation. Activates on queries about DPDK, EAL, rte_eth_rx_burst, hugepages, PMD, or testpmd.
Open skill - /io-uring
io_uring skill for Linux async I/O. Use when building high-performance servers with liburing, multi-shot operations, provided buffers, fixed files, zero-copy send, or tokio-uring. Activates on queries about io_uring, SQE/CQE, liburing, IORING_OP_PROVIDE_BUFFERS, or io_uring vs
Open skill - /adc-dac-baremetal
Bare-metal ADC and DAC skill. Use when configuring analog sampling, DMA-driven ADC, calibration, or DAC output on MCUs. Activates on queries about ADC bare-metal, sampling time, DMA ADC, or DAC channel setup.
Open skill

