KVSSD & uNVMe
KVSSD总体结构:
- application
- kvbench
- PDK
- core/src/api:应用程序使用的接口
- core/src/device_abstract_layer:设备抽象层,kernel和仿真器共用
- emulator
- kernel_driver_adapter
- driver/PCIe:PCIe驱动,包括kernel和userspace
- kernel_driver
- user_driver:Samsung的uNVMe
- spec
-
pdf,SNIA出版的KV存储API标准v1.1
1. SNIA API
-
init、process_completions、store_tuple、retrieve_tuple、delete_tuple、exist_tuple、create_iterator、delete_iterator、delete_iterator_all、iterator_next、get_waf、get_used_size、get_total_size、get_device_info
2. 函数调用路径
一般的,应用程序下发的命令会经过API接口、设备抽象层、设备驱动、设备内部处理。
2.1 put
kvs_store_kvp
:KVSSD/PDK/core/include/kvs_api.h line.546store_tuple
:KVSSD/PDK/core/src/api/include/private/kvkdd.hpp、udd.hpp、kvemul.hpp
接下来有三条路径,分别对应kernel device driver、userspace device driver和emulator。
2.1.1 kdd->put
kv_store
:KVSSD/PDK/core/src/device_abstract_layer/include/kvs_adi.h line.1491KADI::kv_store
:KVSSD/PDK/core/src/device_abstract_layer/kernel_driver_adapter/kadi.h line.256ioctl
2.1.2 udd->put
两种写路径(同步与异步),以同步为例。
kv_nvme_write
:声明位于KVSSD/PDK/core/src/api/include/udd/kvnvme.h line.235,定义位于uNVMe/driver/core/kv_interface.c line.254(注意到该函数定义在uNVMe目录下,属于用户空间驱动给上层的接口)nvme_dev_operations::write
:uNVMe/driver/core/kv_driver.h line.62(函数指针,指向实际的设备操作函数)_kv_nvme_store
:uNVMe/driver/core/kv_cmd.h line.37(上述函数指针指向的实际调用函数,赋值位于uNVMe/driver/core/kv_driver.c的kv_nvme_init函数559行)spdk_nvme_kv_cmd_store
:KVSSD/PDK/core/src/api/include/udd/spdk/kvnvme_spdk.h line.90(再次回到KVSSD目录下)
后续是SPDK内部命令请求的转换处理等。
// To add
2.1.3 emul->put
kv_store
:KVSSD/PDK/core/src/device_abstract_layer/include/kvs_adi.h line.1491kv_device_internal::kv_store
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_device.hpp line.177(cmd添加opcode:KV_OPC_STORE)kv_device_internal::submit_io
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_device.hpp line.94emul_ioqueue::enqueue
:KVSSD/PDK/core/src/device_abstract_layer/include/private/queue.hpp line.113(设备IO队列)- 经过队列的等待。
io_cmd::execute_cmd
:KVSSD/PDK/core/src/device_abstract_layer/include/private/io_cmd.hpp line.68(根据cmd的opcode进行函数处理)kv_namespace_internal::kv_store
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_namespace.hpp line.70kv_emulator::kv_store
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_emulator.hpp line.118(到达emulator内部)- emulator通过两个kv_key*映射到string的unordered_map来存储KV pair。store语句:m_map[ks_id].emplace(std::make_pair(new_key, std::move(valstr)));
2.2 get
kvs_retrieve_kvp
:KVSSD/PDK/core/include/kvs_api.h line.476retrieve_tuple
:KVSSD/PDK/core/src/api/include/private/kvkdd.hpp、udd.hpp、kvemul.hpp
接下来有三条路径,分别对应kdd、udd和emulator。
2.2.1 kdd->get
kv_retrieve
:KVSSD/PDK/core/src/device_abstract_layer/include/kvs_adi.h line.1438KADI::kv_retrieve
:KVSSD/PDK/core/src/device_abstract_layer/kernel_driver_adapter/kadi.h line.257ioctl
2.2.2 udd->get
两种读路径(同步与异步),以同步为例。
kv_nvme_read
:声明位于KVSSD/PDK/core/src/api/include/udd/kvnvme.h line.265,定义位于uNVMe/driver/core/kv_interface.c line.340(注意到该函数定义在uNVMe目录下,属于用户空间驱动给上层的接口)nvme_dev_operations::read
:uNVMe/driver/core/kv_driver.h line.66(函数指针)_kv_nvme_retrieve
:uNVMe/driver/core/kv_cmd.h line.39(上述函数指针指向的实际调用函数,赋值位于uNVMe/driver/core/kv_driver.c的kv_nvme_init函数560行)spdk_nvme_kv_cmd_retrieve
:KVSSD/PDK/core/src/api/include/udd/spdk/kvnvme_spdk.h line.124(再次回到KVSSD目录下)
后续是SPDK内部命令请求的转换处理等。
// To add
2.2.3 emul->get
kv_retrieve
:KVSSD/PDK/core/src/device_abstract_layer/include/kvs_adi.h line.1438kv_device_internal::kv_retrieve
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_device.hpp line.176(给cmd加上opcode:KV_OPC_GET)kv_device_internal::submit_io
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_device.hpp line.94emul_ioqueue::enqueue
:KVSSD/PDK/core/src/device_abstract_layer/include/private/queue.hpp line.113(设备IO队列)- 经过队列的等待。
io_cmd::execute_cmd
:KVSSD/PDK/core/src/device_abstract_layer/include/private/io_cmd.hpp line.68(根据cmd的opcode进行函数处理)kv_namespace_internal::kv_retrieve
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_namespace.hpp line.69kv_emulator::kv_retrieve
:KVSSD/PDK/core/src/device_abstract_layer/include/private/kv_emulator.hpp line.119(到达emulator内部)- emulator内部查找key对应的value,emulator通过两个kv_key* 映射到string的unordered_map来存储KV pair。查询语句:auto it = m_map[ks_id].find((kv_key*)key);
2.3 delete
// To add
附录
KVSSD下载:https://github.com/OpenMPDK/KVSSD
uNVMe下载:https://github.com/OpenMPDK/uNVMe
KVS API规范:https://www.snia.org/keyvalue