Add experimental Computational Storage Drive mode#188
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an experimental Computational Storage Drive (CSD) mode (femu_mode=4) to FEMU, including host-side computational program lifecycle handling and guest-side passthrough tooling to exercise the new vendor/admin commands without requiring a CEMU-specific kernel/FDMFS setup.
Changes:
- Add a new FEMU controller mode (
femu_mode=4) with CSD-specific NVMe admin/I/O command handling underhw/femu/csd/. - Add build/config plumbing for optional uBPF support (Meson option +
femu-compile.shflag) and arun-csd.shlauncher script. - Add guest-side passthrough tests and sample kernels under
tests/femu-csd/, plus README documentation updates.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
tests/femu-csd/README.md |
Documents guest-side passthrough tests and how to run CSD validations. |
tests/femu-csd/Makefile |
Builds passthrough tool and sample shared-library/BPF kernels. |
tests/femu-csd/femu-csd-kernel.h |
Defines the shared CSD kernel ABI struct used by sample kernels. |
tests/femu-csd/csd-vadd.c |
Sample shared-library kernels (direct + indirect vadd). |
tests/femu-csd/csd-vadd.bpf.c |
Sample uBPF kernel. |
tests/femu-csd/csd-passthru.c |
Guest-side NVMe passthrough tool exercising CSD admin/I/O commands. |
tests/femu-csd/csd-original-kernels.cc |
Ports of selected original CEMU kernels into a shared library. |
scripts/meson-buildoptions.sh |
Adds configure-wrapper options for enabling/disabling FEMU CSD uBPF. |
README.md |
Adds CSD mode documentation and updates the feature table and tree. |
meson.build |
Adds Meson options/deps wiring for optional uBPF support. |
meson_options.txt |
Introduces femu_csd_ubpf and femu_csd_ubpf_path options. |
hw/femu/nvme.h |
Adds CSD controller params, mode constant, and admin_cmd_cqe hook. |
hw/femu/nvme-io.c |
Treats CSD like BBSSD/ZNSSD in CQ completion processing path selection. |
hw/femu/nvme-admin.c |
Routes unknown admin opcodes to ext_ops.admin_cmd_cqe() when present. |
hw/femu/meson.build |
Builds and links csd/csd.c and wires in optional uBPF dep. |
hw/femu/femu.c |
Registers the CSD extension and adds QOM properties for CSD params. |
hw/femu/csd/csd.h |
Adds CSD command structs and private definitions. |
hw/femu/csd/csd.c |
Implements CSD mode: AFDM, MRS, program load/activate, exec, QoS groups, optional uBPF. |
hw/femu/backend/dram.c |
Treats CSD like BBSSD/ZNSSD/NoSSD for DRAM backend addressing logic. |
femu-scripts/run-csd.sh |
New script to run a CSD-configured VM. |
femu-scripts/femu-copy-scripts.sh |
Copies run-csd.sh alongside other FEMU helper scripts. |
femu-scripts/femu-compile.sh |
Adds --enable-csd-ubpf[...] configuration support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+533
to
+538
| FemuCsdState *csd = csd_state(n); | ||
| NvmeCsdProgramActivationCmd *activation = | ||
| (NvmeCsdProgramActivationCmd *)cmd; | ||
| uint16_t pind = activation->pind; | ||
| uint8_t sel = activation->sel; | ||
| FemuCsdProgram *program; |
Comment on lines
+596
to
+608
| qemu_mutex_lock(&csd->lock); | ||
| id = csd->next_rsid++; | ||
| if (id == 0) { | ||
| csd->next_rsid = 1; | ||
| id = csd->next_rsid++; | ||
| } | ||
| while (g_hash_table_contains(csd->mrs, GUINT_TO_POINTER(id))) { | ||
| id = csd->next_rsid++; | ||
| if (id == 0) { | ||
| csd->next_rsid = 1; | ||
| id = csd->next_rsid++; | ||
| } | ||
| } |
Comment on lines
+883
to
+891
| qemu_mutex_lock(&csd->lock); | ||
| id = csd->next_group_id++; | ||
| if (id == 0) { | ||
| csd->next_group_id = 1; | ||
| id = csd->next_group_id++; | ||
| } | ||
| group->id = id; | ||
| g_hash_table_insert(csd->groups, GUINT_TO_POINTER(id), group); | ||
| qemu_mutex_unlock(&csd->lock); |
Comment on lines
+840
to
+843
| if (runtime) { | ||
| req->reqlat += runtime; | ||
| req->expire_time += runtime; | ||
| } |
Comment on lines
+829
to
+831
| if (!status) { | ||
| req->cqe.n.result = result > UINT32_MAX ? UINT32_MAX : result; | ||
| } |
Comment on lines
+365
to
+380
| program->module = g_module_open(path, G_MODULE_BIND_LOCAL); | ||
| if (!program->module) { | ||
| femu_err("CSD: failed to load shared library %s: %s\n", path, | ||
| g_module_error()); | ||
| return NVME_INVALID_FIELD | NVME_DNR; | ||
| } | ||
|
|
||
| if (!g_module_symbol(program->module, symbol, &fn) || !fn) { | ||
| femu_err("CSD: failed to find shared library symbol %s: %s\n", symbol, | ||
| g_module_error()); | ||
| csd_program_unload(program); | ||
| return NVME_INVALID_FIELD | NVME_DNR; | ||
| } | ||
|
|
||
| program->shared_lib_fn = (FemuCsdSharedLibFn)fn; | ||
| return NVME_SUCCESS; |
Comment on lines
+463
to
+466
| if (pind == 0 || psize > UINT32_MAX || loff > psize || | ||
| numb > psize - loff) { | ||
| return NVME_INVALID_FIELD | NVME_DNR; | ||
| } |
Comment on lines
+2296
to
+2305
| if femu_csd_ubpf_path != '' | ||
| femu_csd_ubpf_lib_path = femu_csd_ubpf_path / 'build/lib/libubpf.a' | ||
| femu_csd_ubpf_lib = cc.find_library('ubpf', | ||
| dirs: femu_csd_ubpf_path / 'build/lib', | ||
| required: get_option('femu_csd_ubpf')) | ||
| femu_csd_ubpf = declare_dependency( | ||
| include_directories: include_directories(femu_csd_ubpf_path / 'vm/inc', | ||
| femu_csd_ubpf_path / 'build/vm'), | ||
| dependencies: femu_csd_ubpf_lib) | ||
| emulator_link_args += femu_csd_ubpf_lib_path |
| 'bbssd/bb.c', 'bbssd/ftl.c', 'csd/csd.c', | ||
| 'lib/pqueue.c', 'lib/rte_ring.c', | ||
| 'backend/dram.c')) | ||
| system_ss.add(when: 'CONFIG_FEMU_CSD_UBPF', if_true: femu_csd_ubpf) |
Comment on lines
+11
to
+14
| --enable-csd-ubpf=*) | ||
| UBPF_PATH="${arg#*=}" | ||
| FEMU_CONFIGURE_OPTS="${FEMU_CONFIGURE_OPTS} --enable-femu-csd-ubpf -Dfemu_csd_ubpf_path=${UBPF_PATH}" | ||
| ;; |
Contributor
|
CSD emulation is a great addition to FEMU, and CEMU is a very nice work, thank you for upstreaming it! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds an experimental Computational Storage Drive (CSD) mode to FEMU as
femu_mode=4.The implementation is derived from CEMU, but adapted to FEMU's current codebase and configuration model. CSD-specific logic is kept under
hw/femu/csd/where possible, with only small hooks in common FEMU/NVMe paths.This PR intentionally avoids requiring a CEMU-specific Linux kernel, FDMFS, or a fixed VM image.
What is included
femu_mode=4for CSD modefdm_sizenr_cunr_threadtime_slicecontext_switch_timecsf_runtime_scale./femu-compile.sh --enable-csd-ubpf./femu-compile.sh --enable-csd-ubpf=/path/to/ubpf-cemutests/femu-csd/run-csd.shfollowing FEMU script styleWhat is intentionally not included
Validation
Build/static checks:
Manual KVM guest end-to-end validation can be reproduced with a normal Linux guest image. No CEMU-specific kernel, FDMFS, or fixed VM image is required.
Start a CSD VM:
cd build-femu ./run-csd.shCopy the passthrough tests into the guest and build them there:
Run the core CSD command smoke tests:
Optional uBPF validation requires building FEMU with uBPF support:
./femu-compile.sh --enable-csd-ubpf=/path/to/ubpf-cemu cd tests/femu-csd make bpfThen, inside the guest:
The KVM guest end-to-end validation covered: