871 lines
31 KiB
Diff
871 lines
31 KiB
Diff
From f0710b6c37214457ab46bd1859f00ec413b01a7f Mon Sep 17 00:00:00 2001
|
|
From: sunshihao <sunshihao@huawei.com>
|
|
Date: Thu, 18 Feb 2021 10:52:24 +0800
|
|
Subject: [PATCH 17/27] add HSAK needed head file and API to spdk
|
|
|
|
Signed-off-by: sunshihao <sunshihao@huawei.com>
|
|
---
|
|
CONFIG | 3 +
|
|
Makefile | 6 +
|
|
configure | 8 ++
|
|
etc/spdk/nvme.conf.in | 88 ++++++++++++
|
|
include/spdk/bdev.h | 85 +++++++++++
|
|
include/spdk/bdev_module.h | 89 ++++++++++++
|
|
include/spdk/log.h | 2 +-
|
|
include/spdk/nvme.h | 230 ++++++++++++++++++++++++++++++
|
|
include/spdk/thread.h | 18 +++
|
|
include/spdk_internal/bdev_stat.h | 63 ++++++++
|
|
include/spdk_internal/debug.h | 43 ++++++
|
|
include/spdk_internal/thread.h | 2 +
|
|
mk/spdk.app_vars.mk | 4 +-
|
|
13 files changed, 639 insertions(+), 2 deletions(-)
|
|
create mode 100644 etc/spdk/nvme.conf.in
|
|
create mode 100644 include/spdk_internal/bdev_stat.h
|
|
create mode 100644 include/spdk_internal/debug.h
|
|
|
|
diff --git a/CONFIG b/CONFIG
|
|
index b5fffae..214e59e 100644
|
|
--- a/CONFIG
|
|
+++ b/CONFIG
|
|
@@ -43,6 +43,9 @@ CONFIG_CROSS_PREFIX=
|
|
# Build with debug logging. Turn off for performance testing and normal usage
|
|
CONFIG_DEBUG=n
|
|
|
|
+# Enable read and write NVMe for application
|
|
+CONFIG_APP_RW=n
|
|
+
|
|
# Treat warnings as errors (fail the build on any warning).
|
|
CONFIG_WERROR=n
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index a50fa94..1c98268 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -37,6 +37,12 @@ S :=
|
|
SPDK_ROOT_DIR := $(CURDIR)
|
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
|
|
|
+ifeq ($(CONFIG_APP_RW),y)
|
|
+# secure compile option
|
|
+CFLAGS += -fPIE -pie -fPIC -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -Wall -Werror
|
|
+CFLAGS += -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines
|
|
+endif
|
|
+
|
|
DIRS-y += lib
|
|
DIRS-y += module
|
|
DIRS-$(CONFIG_SHARED) += shared_lib
|
|
diff --git a/configure b/configure
|
|
index 5b48696..964322e 100644
|
|
--- a/configure
|
|
+++ b/configure
|
|
@@ -25,6 +25,8 @@ function usage()
|
|
echo " example: aarch64-linux-gnu"
|
|
echo ""
|
|
echo " --enable-debug Configure for debug builds"
|
|
+ echo " --enable-err-injc Enable error injection feature"
|
|
+ echo " --enable-raw Enable read and write NVMe disk feature."
|
|
echo " --enable-werror Treat compiler warnings as errors"
|
|
echo " --enable-asan Enable address sanitizer"
|
|
echo " --enable-ubsan Enable undefined behavior sanitizer"
|
|
@@ -204,6 +206,12 @@ for i in "$@"; do
|
|
--disable-debug)
|
|
CONFIG[DEBUG]=n
|
|
;;
|
|
+ --enable-raw)
|
|
+ CONFIG[APP_RW]=y
|
|
+ ;;
|
|
+ --enable-err-injc)
|
|
+ CONFIG[ERR_INJC]=y
|
|
+ ;;
|
|
--enable-asan)
|
|
CONFIG[ASAN]=y
|
|
;;
|
|
diff --git a/etc/spdk/nvme.conf.in b/etc/spdk/nvme.conf.in
|
|
new file mode 100644
|
|
index 0000000..a3df92b
|
|
--- /dev/null
|
|
+++ b/etc/spdk/nvme.conf.in
|
|
@@ -0,0 +1,88 @@
|
|
+#NVME configuration file
|
|
+#
|
|
+# Please write all parameters using ASCII.
|
|
+# The parameter must be quoted if it includes whitespace.
|
|
+#
|
|
+# Configuration syntax:
|
|
+# Leading whitespace is ignored.
|
|
+# Lines starting with '#' are comments.
|
|
+# Lines ending with '\' are concatenated with the next line.
|
|
+# Bracketed ([]) names define sections
|
|
+
|
|
+[Global]
|
|
+ # Users can restrict work items to only run on certain cores by specifying a ReactorMask.
|
|
+ # Can not specify the NO. 0 core.
|
|
+ ReactorMask 0x2
|
|
+
|
|
+ # The print level of log.
|
|
+ # 0: Print ERROR log only; 1: Print WARNING and ERROR log; and so on, 4: Print all level log
|
|
+ LogLevel 1
|
|
+
|
|
+ # The sizes of Memory for Libstorge(Unit: MB). The minimum value is 300MB.
|
|
+ # If parameter "SocketMem" was set corrected, MemSize was useless
|
|
+ MemSize 300
|
|
+
|
|
+ # The same block device supports multiple queues.
|
|
+ MultiQ No
|
|
+
|
|
+ # End-to-end data protection. This item is only used if the namespace is formatted to use end-to-end protection information.
|
|
+ # if the value is set to '1', then the protection information are generated by controller, and the logical block data and protection information are written to NVM.
|
|
+ # if the value is set to '2', then the protection information are transferred from the host buffer to NVM.
|
|
+ E2eDif 2
|
|
+
|
|
+ # Open IOstat or not
|
|
+ IoStat No
|
|
+
|
|
+ # Poll time threshold in millisecond, It will count exceptional polling thread call which duration exceed the value and display in stat report.
|
|
+ # This item is only used when UseReactor = No, Set to 0 means disable this measurement.
|
|
+ PollTime 0
|
|
+
|
|
+ # Preallocate specified amounts of memory(Unit: MB) per socket.
|
|
+ # The parameter is a comma-sprated list of values, For example:
|
|
+ # SocketMem 1024,2048
|
|
+ # This will allocate 1 gigabyte of memory on socket 0, and 2048 megabytes of memory on socket 1.
|
|
+ # The sum of socket memory must be greater than 300MB.
|
|
+ # if SocketMem was set corrected, The parameter "MemSize" was useless
|
|
+ # SocketMem 300
|
|
+
|
|
+ # Place a per-socket upper limit on memory use (non-legacy memory mode only).
|
|
+ # 0 will disable the limit for a particular socket.
|
|
+ # SocketLimit 1024,1
|
|
+ # This will set upper limit of 1 gigabyte on socket 0, and 1 megabytes of memory on socket 1.
|
|
+ # if the value is set to empty, means disable the limit per socket.
|
|
+ # if SocketMem was empty, the parameter was useless.
|
|
+ # SocketLimit 300
|
|
+
|
|
+ #Decide whether to start rpc server or not
|
|
+ RpcServer Yes
|
|
+
|
|
+# NVMe configuration options
|
|
+[Nvme]
|
|
+ # NVMe Device Whitelist
|
|
+ # Users may specify which NVMe devices to claim by their transport id.
|
|
+ # See spdk_nvme_transport_id_parse() in spdk/nvme.h for the correct format.
|
|
+ # The second argument is the assigned name, which can be referenced from
|
|
+ # other sections in the configuration file. For NVMe devices, a namespace
|
|
+ # is automatically appended to each name in the format <YourName>nY, where
|
|
+ # Y is the NSID (starts at 1).
|
|
+ #TransportID "trtype:PCIe traddr:0000:81:00.0" nvme0
|
|
+ #TransportID "trtype:PCIe traddr:0000:01:00.0" nvme1
|
|
+
|
|
+ # The number of attempts per I/O when an I/O fails. Do not include
|
|
+ # this key to get the default behavior.
|
|
+ RetryCount 4
|
|
+ # Timeout for each command, in microseconds. If 0, don't track timeouts.
|
|
+ TimeoutUsec 0
|
|
+ # Action to take on command time out. Only valid when Timeout is greater
|
|
+ # than 0. This may be 'Reset' to reset the controller, 'Abort' to abort
|
|
+ # the command, or 'None' to just print a message but do nothing.
|
|
+ # Admin command timeouts will always result in a reset.
|
|
+ ActionOnTimeout None
|
|
+ # Set how often the admin queue is polled for asynchronous events.
|
|
+ # Units in microseconds.
|
|
+ AdminPollRate 100000
|
|
+
|
|
+[Reactor]
|
|
+ # Batch size of IO for one-time release by reactor.
|
|
+ # The maximum value is 32.
|
|
+ BatchSize 8
|
|
diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h
|
|
index d894646..2951660 100644
|
|
--- a/include/spdk/bdev.h
|
|
+++ b/include/spdk/bdev.h
|
|
@@ -53,6 +53,8 @@ extern "C" {
|
|
|
|
#define SPDK_BDEV_SMALL_BUF_MAX_SIZE 8192
|
|
#define SPDK_BDEV_LARGE_BUF_MAX_SIZE (64 * 1024)
|
|
+#define SPDK_BDEV_SMALL_BUF_WITH_MAX_MD 512
|
|
+#define SPDK_BDEV_LARGE_BUF_WITH_MAX_MD 1024
|
|
|
|
/* Increase the buffer size to store interleaved metadata. Increment is the
|
|
* amount necessary to store metadata per data block. 16 byte metadata per
|
|
@@ -116,6 +118,42 @@ enum spdk_bdev_status {
|
|
SPDK_BDEV_STATUS_REMOVING,
|
|
};
|
|
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+/** ns status */
|
|
+enum spdk_bdev_ns_status {
|
|
+ SPDK_BDEV_NS_STATUS_INVALID,
|
|
+ SPDK_BDEV_NS_STATUS_READY,
|
|
+ SPDK_BDEV_NS_STATUS_REMOVING,
|
|
+ SPDK_BDEV_NS_STATUS_UNREGISTER,
|
|
+};
|
|
+
|
|
+typedef void (*LIBSTORAGE_CALLBACK_FUNC)(int32_t cb_status, int32_t sct_code, void *cb_arg);
|
|
+
|
|
+typedef struct libstorage_io {
|
|
+ uint8_t *buf;
|
|
+ struct iovec *iovs; /* array of iovecs to transfer */
|
|
+ int iovcnt; /* Number of iovecs in iovs array */
|
|
+ int32_t fd; /* File Descriptor */
|
|
+ uint16_t opcode; /* r/w */
|
|
+ uint16_t streamId; /* Stream ID for IO */
|
|
+ uint8_t pi_action;
|
|
+ uint8_t fua;
|
|
+ uint8_t location;
|
|
+ bool inSubmit; /* In the I/0 phase or not. Use in nopoll model */
|
|
+ uint32_t count;
|
|
+ uint32_t nbytes;
|
|
+ uint64_t offset;
|
|
+ uint8_t *md_buf;
|
|
+ uint32_t md_len;
|
|
+ uint32_t magic;
|
|
+ /*Save the error code returned by the callback */
|
|
+ int32_t err;
|
|
+ int32_t reserved;
|
|
+ LIBSTORAGE_CALLBACK_FUNC cb;
|
|
+ void *cb_arg;
|
|
+} LIBSTORAGE_IO_T;
|
|
+#endif
|
|
+
|
|
/**
|
|
* \brief Handle to an opened SPDK block device.
|
|
*/
|
|
@@ -140,6 +178,13 @@ enum spdk_bdev_io_type {
|
|
SPDK_BDEV_IO_TYPE_COMPARE,
|
|
SPDK_BDEV_IO_TYPE_COMPARE_AND_WRITE,
|
|
SPDK_BDEV_IO_TYPE_ABORT,
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+ SPDK_BDEV_IO_TYPE_READ_NVME,
|
|
+ SPDK_BDEV_IO_TYPE_WRITE_NVME,
|
|
+ SPDK_BDEV_IO_TYPE_READV_NVME,
|
|
+ SPDK_BDEV_IO_TYPE_WRITEV_NVME,
|
|
+ SPDK_BDEV_IO_TYPE_UNMAP_BLOCKS,
|
|
+#endif
|
|
SPDK_BDEV_NUM_IO_TYPES /* Keep last */
|
|
};
|
|
|
|
@@ -181,6 +226,14 @@ struct spdk_bdev_io_stat {
|
|
uint64_t write_latency_ticks;
|
|
uint64_t unmap_latency_ticks;
|
|
uint64_t ticks_rate;
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+ int io_stat_id;
|
|
+ uint64_t io_ticks;
|
|
+ uint64_t pre_ticks;
|
|
+ uint64_t cur_ticks;
|
|
+ uint64_t start_tsc;
|
|
+ uint64_t interval_tsc;
|
|
+#endif
|
|
};
|
|
|
|
struct spdk_bdev_opts {
|
|
@@ -1342,6 +1395,38 @@ int spdk_bdev_unmap(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
uint64_t offset, uint64_t nbytes,
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg);
|
|
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+/**
|
|
+ * Submit an unmap request to the block device. Unmap is sometimes also called trim or
|
|
+ * deallocate. This notifies the device that the data in the blocks described is no
|
|
+ * longer valid. Reading blocks that have been unmapped results in indeterminate data.
|
|
+ *
|
|
+ * \param bdev Block device description
|
|
+ * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel().
|
|
+ * \param unmap_d An array of unmap descriptors.
|
|
+ * \param bdesc_count The number of elements in unmap_d.
|
|
+ * \param cb Called when the request is complete.
|
|
+ * \param cb_arg Argument passed to cb.
|
|
+ *
|
|
+ * \return 0 on success. On success, the callback will always
|
|
+ * be called (even if the request ultimately failed). Return
|
|
+ * negated errno on failure, in which case the callback will not be called.
|
|
+ */
|
|
+int
|
|
+spdk_bdev_unmap_multiblocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
+ void *unmap_d, uint16_t unmap_count,
|
|
+ spdk_bdev_io_completion_cb cb, void *cb_arg);
|
|
+
|
|
+void*
|
|
+spdk_bdev_get_channel_group(struct spdk_io_channel *io_ch);
|
|
+
|
|
+void*
|
|
+spdk_bdev_io_get_pool(size_t nbytes);
|
|
+
|
|
+bool
|
|
+spdk_bdev_have_io_in_channel(struct spdk_io_channel *bdevIoCh);
|
|
+#endif
|
|
+
|
|
/**
|
|
* Submit an unmap request to the block device. Unmap is sometimes also called trim or
|
|
* deallocate. This notifies the device that the data in the blocks described is no
|
|
diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h
|
|
index bbb9f94..c2fd81d 100644
|
|
--- a/include/spdk/bdev_module.h
|
|
+++ b/include/spdk/bdev_module.h
|
|
@@ -222,8 +222,67 @@ struct spdk_bdev_fn_table {
|
|
|
|
/** Get bdev module context. */
|
|
void *(*get_module_ctx)(void *ctx);
|
|
+
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+ uint16_t (*get_io_channel_id)(struct spdk_io_channel *ch);
|
|
+
|
|
+ int (*bdev_poll_rsp)(void *pollCh);
|
|
+
|
|
+ uint64_t (*get_timeout_count)(struct spdk_io_channel *ch);
|
|
+#endif
|
|
+};
|
|
+
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+static inline void spdk_bdev_set_io_location(void *bdev_ctx, uint8_t location)
|
|
+{
|
|
+ struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(bdev_ctx);
|
|
+ uint8_t *ioLoc = (uint8_t *)bdev_io->internal.caller_ctx;
|
|
+ *ioLoc = location;
|
|
+}
|
|
+
|
|
+enum spdk_bdev_driver_ctx {
|
|
+ SPDK_BDEV_IO_ACTION_PI,
|
|
+ SPDK_BDEV_IO_ACTION_FUA,
|
|
+ SPDK_BDEV_IO_STREAM_ID_0,
|
|
+ SPDK_BDEV_IO_STREAM_ID_1,
|
|
+};
|
|
+
|
|
+enum spdk_bdev_io_e2e_pi_action{
|
|
+ IO_NO_PROTECTION = 0,
|
|
+ IO_HALF_WAY_PROTECTION = 1,
|
|
+ IO_E2E_PROTECTION = 2
|
|
};
|
|
|
|
+#define FLAG_NO_REF 0x10//bit 4 : 1, disable ctrl ref tag check; 0, enable check
|
|
+#define FLAG_CALCRC 0x08//bit 3 : 1, libstorage calculate crc; 0, app calculate crc
|
|
+#define FLAG_PRCHK 0x04//bit 2 : 1, enable ctrl guard crc check; 0, disable check
|
|
+
|
|
+enum spdk_bdev_io_fua{
|
|
+ IO_FUA_NO = 0,
|
|
+ IO_FUA_YES = 1
|
|
+};
|
|
+
|
|
+void spdk_bdev_nvme_remove_cb(void *cb_ctx, void *ctrlr);
|
|
+
|
|
+void spdk_bdev_fail_ctrlr(const char* traddr);
|
|
+
|
|
+void *nvme_channel_get_group(void *io_ch);
|
|
+
|
|
+enum reqLocation_E
|
|
+{
|
|
+ LOCAL_RECEIVE_APP = 1,
|
|
+ LOCAL_LIBSTORAGE_SUBMIT = 2,
|
|
+ LOCAL_LIBSTORAGE_ASYNC_REQ = 3,
|
|
+ LOCAL_LIBSTORAGE_BDEV_NVME = 4,
|
|
+ LOCAL_LIBSTORAGE_HUNG_REQ = 5,
|
|
+ LOCAL_LIBSTORAGE_TO_DISK = 6,
|
|
+ LOCAL_LIBSTORAGE_FROM_DISK = 7,
|
|
+ LOCAL_LIBSTORAGE_CALLBACK = 8,
|
|
+ LOCAL_LIBSTORAGE_SUBMIT_RETRY = 9,
|
|
+ LOCAL_LIBSTORAGE_BDEV_NOMEM = 10,
|
|
+};
|
|
+#endif
|
|
+
|
|
/** bdev I/O completion status */
|
|
enum spdk_bdev_io_status {
|
|
SPDK_BDEV_IO_STATUS_AIO_ERROR = -8,
|
|
@@ -407,6 +466,10 @@ struct spdk_bdev {
|
|
/** The bdev status */
|
|
enum spdk_bdev_status status;
|
|
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+ enum spdk_bdev_ns_status ns_status;
|
|
+#endif
|
|
+
|
|
/**
|
|
* Pointer to the module that has claimed this bdev for purposes of creating virtual
|
|
* bdevs on top of it. Set to NULL if the bdev has not been claimed.
|
|
@@ -528,6 +591,11 @@ struct spdk_bdev_io {
|
|
/** Starting offset (in blocks) of the bdev for this I/O. */
|
|
uint64_t offset_blocks;
|
|
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+ /* The number of bytes to transfer */
|
|
+ size_t nbytes;
|
|
+#endif
|
|
+
|
|
/** stored user callback in case we split the I/O and use a temporary callback */
|
|
spdk_bdev_io_completion_cb stored_user_cb;
|
|
|
|
@@ -595,6 +663,27 @@ struct spdk_bdev_io {
|
|
/* The data buffer */
|
|
void *buf;
|
|
} zone_mgmt;
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+ struct {
|
|
+ /* The data buffer to transfer */
|
|
+ void *buf;
|
|
+
|
|
+ /* The meta data buffer to transfer */
|
|
+ void *md_buf;
|
|
+
|
|
+ /** Total size of data(in blocks) to be transferred. */
|
|
+ uint64_t num_blocks;
|
|
+
|
|
+ /* The number of bytes to transfer */
|
|
+ size_t nbytes;
|
|
+
|
|
+ /** Starting offset (in blocks) of the bdev for this I/O. */
|
|
+ size_t offset_blocks;
|
|
+
|
|
+ /* meta data buffer size to transfer */
|
|
+ size_t md_len;
|
|
+ } contig;
|
|
+#endif
|
|
} u;
|
|
|
|
/** It may be used by modules to put the bdev_io into its own list. */
|
|
diff --git a/include/spdk/log.h b/include/spdk/log.h
|
|
index ad850ab..e16035c 100644
|
|
--- a/include/spdk/log.h
|
|
+++ b/include/spdk/log.h
|
|
@@ -173,7 +173,7 @@ enum spdk_log_level spdk_log_get_print_level(void);
|
|
* \param format Format string to the message.
|
|
*/
|
|
void spdk_log(enum spdk_log_level level, const char *file, const int line, const char *func,
|
|
- const char *format, ...) __attribute__((__format__(__printf__, 5, 6)));
|
|
+ const char *format, ...) __attribute__((weak)) __attribute__((__format__(__printf__, 5, 6)));
|
|
|
|
/**
|
|
* Same as spdk_log except that instead of being called with variable number of
|
|
diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h
|
|
index 45b9f94..8e05139 100644
|
|
--- a/include/spdk/nvme.h
|
|
+++ b/include/spdk/nvme.h
|
|
@@ -2465,6 +2465,7 @@ enum spdk_nvme_ns_flags {
|
|
part of the logical block that it is associated with */
|
|
SPDK_NVME_NS_WRITE_UNCORRECTABLE_SUPPORTED = 0x40, /**< The write uncorrectable command is supported */
|
|
SPDK_NVME_NS_COMPARE_SUPPORTED = 0x80, /**< The compare command is supported */
|
|
+ SPDK_NVME_NS_DPS_PI_MDSTART = 0x100 /**< protection info transferred at start of metadata */
|
|
};
|
|
|
|
/**
|
|
@@ -3434,6 +3435,235 @@ struct spdk_nvme_transport_ops {
|
|
*/
|
|
void spdk_nvme_transport_register(const struct spdk_nvme_transport_ops *ops);
|
|
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+struct nvme_ctrlr_info {
|
|
+ char ctrlName[16];
|
|
+ char pciAddr[24];
|
|
+ uint64_t tnvmcap; /* Total NVM Capacity in bytes */
|
|
+ uint64_t unvmcap; /* Unallocated NVM Capacity in bytes */
|
|
+ int8_t sn[20]; /* Serial number */
|
|
+ int8_t mn[40]; /* Model number */
|
|
+ uint8_t fr[8]; /* Firmware revision */
|
|
+ uint32_t max_num_ns; /* Number of namespaces */
|
|
+ uint32_t version; /* Version of the NVM Express specification that the controller implementation supports */
|
|
+ uint16_t num_io_queues; /* num of io queues */
|
|
+ uint16_t io_queue_size; /* io queue size */
|
|
+ uint16_t device_id; /* Device id */
|
|
+ uint16_t subdevice_id; /* Subsystem device id */
|
|
+ uint16_t vid; /* Vendor id */
|
|
+ uint16_t ssvid; /* Subsystem vendor id */
|
|
+ uint16_t ctrlid; /* Controller id */
|
|
+ uint16_t trtype; /* Transport type */
|
|
+ uint16_t support_ns :1; /* Supports the Namespace Management and Namespace Attachment commands */
|
|
+ uint16_t directives :1; /* Supports Directives */
|
|
+ uint16_t streams :1; /* Supports Streams Directives */
|
|
+ uint16_t dsm :1; /* Supports the controller supports the Dataset Management command */
|
|
+ uint16_t reserved :12;
|
|
+ uint16_t reserved2[3];
|
|
+};
|
|
+
|
|
+struct nvme_ctrlr;
|
|
+struct nvme_bdev_ctrlr;
|
|
+struct spdk_bdev;
|
|
+struct nvme_bdev;
|
|
+struct spdk_nvme_ns;
|
|
+struct spdk_nvme_qpair;
|
|
+int32_t nvme_ctrlr_get_info(const char* ctrlName, struct nvme_ctrlr_info** ppCtrlr);
|
|
+struct spdk_nvme_ctrlr* spdk_nvme_ctrlr_get_by_name(const char* ctrlname);
|
|
+struct spdk_nvme_ctrlr* spdk_nvme_ctrlr_get_by_ctrlr(const struct nvme_bdev_ctrlr *nvme_bdev_ctrlr);
|
|
+struct nvme_bdev_ctrlr* nvme_ctrlr_get_by_name(const char* ctrlname);
|
|
+void nvme_ctrlr_clear_iostat_by_name(const char* ctrlname);
|
|
+void nvme_ctrlr_clear_iostat_all(void);
|
|
+struct nvme_bdev_ctrlr* bdev_nvme_get_ctrlr_by_bdev_desc(void *bdev);
|
|
+struct spdk_nvme_ns* bdev_nvme_get_ns(struct nvme_bdev *nbdev);
|
|
+void bdev_nvme_update_block_by_nvme_ctrlr(struct spdk_nvme_ctrlr *ctrlr);
|
|
+int bdev_nvme_update_ns(struct nvme_bdev_ctrlr *nvme_ctrlr, uint32_t nsid);
|
|
+bool spdk_bdev_can_remove(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, uint32_t nsid);
|
|
+void spdk_bdev_set_ns_normal(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, uint32_t nsid);
|
|
+void spdk_nvme_ctrlr_set_shutdown(struct spdk_nvme_ctrlr *ctrlr, bool is_shutdown);
|
|
+bool spdk_nvme_ctrlr_is_smart_per_namespace_supported(struct spdk_nvme_ctrlr *ctrlr);
|
|
+int spdk_nvme_ctrlr_get_smart_info(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, struct spdk_nvme_health_information_page *health_payload);
|
|
+int spdk_nvme_ctrlr_get_error_info(struct spdk_nvme_ctrlr *ctrlr, uint32_t err_entries, struct spdk_nvme_error_information_entry *error_info);
|
|
+struct spdk_nvme_ctrlr_opts* spdk_nvme_ctrlr_get_opts(struct spdk_nvme_ctrlr *ctrlr);
|
|
+int nvme_ns_get_common_data(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns_data *nsdata);
|
|
+bool spdk_nvme_ns_is_allocated(struct spdk_nvme_ctrlr *ctrlr, uint16_t nsid);
|
|
+bool spdk_nvme_ctrlr_is_ns_manage_supported(struct spdk_nvme_ctrlr *ctrlr);
|
|
+bool spdk_nvme_ctrlr_is_format_supported(struct spdk_nvme_ctrlr *ctrlr);
|
|
+bool spdk_nvme_ctrlr_is_format_all_ns(struct spdk_nvme_ctrlr *ctrlr);
|
|
+bool spdk_nvme_ctrlr_is_directive_supported(struct spdk_nvme_ctrlr *ctrlr);
|
|
+bool spdk_nvme_ctrlr_is_streams_supported(struct spdk_nvme_ctrlr *ctrlr);
|
|
+int32_t spdk_nvme_ctrlr_identify_directives(struct spdk_nvme_ctrlr *ctrlr, uint16_t nsid, void *payload);
|
|
+int32_t spdk_nvme_ctrlr_enable_streams(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid);
|
|
+int32_t spdk_nvme_ctrlr_ret_streams_param(struct spdk_nvme_ctrlr *ctrlr, void *payload);
|
|
+int32_t spdk_nvme_ns_ret_streams_param(struct spdk_nvme_ns *ns, void *payload);
|
|
+int32_t spdk_nvme_ns_get_streams_status(struct spdk_nvme_ns *ns, void *payload);
|
|
+int32_t spdk_nvme_ns_alloc_streams_res(struct spdk_nvme_ns *ns, uint16_t nsr);
|
|
+int32_t spdk_nvme_ns_release_streams_id(struct spdk_nvme_ns *ns, uint16_t streamsId);
|
|
+int32_t spdk_nvme_ns_release_streams_res(struct spdk_nvme_ns *ns);
|
|
+void spdk_nvme_use_streams(bool use);
|
|
+
|
|
+/**
|
|
+ * \brief Get the ctrlr is_failed state, for an I/O sent to the given namespace.
|
|
+ *
|
|
+ * This function is thread safe and can be called at any point while the controller is attached to
|
|
+ * the SPDK NVMe driver.
|
|
+ */
|
|
+bool spdk_nvme_ns_ctrl_is_failed(struct spdk_nvme_ns *ns);
|
|
+#define NVME_MAX_CONTROLLERS 1024
|
|
+
|
|
+/* check nvme whether exist by access cc register */
|
|
+bool nvme_ctrlr_is_exist(struct spdk_nvme_ctrlr *ctrlr);
|
|
+
|
|
+/* create ctrlr for new added device */
|
|
+int spdk_bdev_nvme_create_self(struct spdk_nvme_transport_id *trid, const char *base_name,
|
|
+ const char **names, size_t *count, const char *hostnqn);
|
|
+
|
|
+int spdk_nvme_detach_ublock(struct spdk_nvme_ctrlr *ctrlr);
|
|
+void spdk_nvme_ctrlr_update_unvmcap(struct spdk_nvme_ctrlr *ctrlr);
|
|
+
|
|
+#define SPDK_NVME_UEVENT_SUBSYSTEM_UIO 1
|
|
+#define SPDK_NVME_UEVENT_SUBSYSTEM_NVME 2
|
|
+
|
|
+enum spdk_nvme_uevent_action {
|
|
+ SPDK_NVME_UEVENT_ADD = 0,
|
|
+ SPDK_NVME_UEVENT_REMOVE = 1,
|
|
+};
|
|
+
|
|
+struct spdk_uevent {
|
|
+ /* remove or add */
|
|
+ enum spdk_nvme_uevent_action action;
|
|
+ int subsystem;
|
|
+ /* pci address of device */
|
|
+ char traddr[SPDK_NVMF_TRADDR_MAX_LEN + 1];
|
|
+};
|
|
+
|
|
+/* make a socket to get uevent */
|
|
+int nvme_uevent_connect(void);
|
|
+
|
|
+/* get uevent from socket fd */
|
|
+int nvme_get_uevent(int fd, struct spdk_uevent *uevent);
|
|
+
|
|
+/* blocked to get uevent from socket fd */
|
|
+int nvme_get_uevent_block(int fd, struct spdk_uevent *uevent);
|
|
+
|
|
+/**
|
|
+ * @Description: bind device with pci_addr to driver
|
|
+ * @param pci_addr: device's pci_addr,like "0000:08:00.0"
|
|
+ * @param driver: driver name which device bind to
|
|
+ */
|
|
+int32_t spdk_rebind_driver(char *pci_addr, char *driver_name);
|
|
+
|
|
+/**
|
|
+ * \brief True if the protection information transferred at the start of metadata
|
|
+ * when end-to-end data protection enabled.
|
|
+ *
|
|
+ * This function is thread safe and can be called at any point while the controller is attached to
|
|
+ * the SPDK NVMe driver.
|
|
+ */
|
|
+bool spdk_nvme_ns_pi_md_start(struct spdk_nvme_ns *ns);
|
|
+
|
|
+/**
|
|
+ * \brief True if the namespace supports Dataset Management command.
|
|
+ *
|
|
+ * This function is thread safe and can be called at any point while the controller is attached to
|
|
+ * the SPDK NVMe driver.
|
|
+ */
|
|
+bool spdk_nvme_ns_is_dataset_mng_supported(struct spdk_nvme_ns *ns);
|
|
+
|
|
+/**
|
|
+ * Submit a data set management request to the specified NVMe namespace. Data set
|
|
+ * management operations are designed to optimize interaction with the block
|
|
+ * translation layer inside the device. The most common type of operation is
|
|
+ * deallocate, which is often referred to as TRIM or UNMAP.
|
|
+ *
|
|
+ * The command is submitted to a qpair allocated by spdk_nvme_ctrlr_alloc_io_qpair().
|
|
+ * The user must ensure that only one thread submits I/O on a given qpair at any
|
|
+ * given time.
|
|
+ *
|
|
+ * This is a convenience wrapper that will automatically allocate and construct
|
|
+ * the correct data buffers. Therefore, ranges does not need to be allocated from
|
|
+ * pinned memory and can be placed on the stack. If a higher performance, zero-copy
|
|
+ * version of DSM is required, simply build and submit a raw command using
|
|
+ * spdk_nvme_ctrlr_cmd_io_raw().
|
|
+ *
|
|
+ * \param ns NVMe namespace to submit the DSM request
|
|
+ * \param type A bit field constructed from \ref spdk_nvme_dsm_attribute.
|
|
+ * \param qpair I/O queue pair to submit the request
|
|
+ * \param ranges An array of \ref spdk_nvme_dsm_range elements describing the LBAs
|
|
+ * to operate on.
|
|
+ * \param num_ranges The number of elements in the ranges array.
|
|
+ * \param cb_fn Callback function to invoke when the I/O is completed
|
|
+ * \param cb_arg Argument to pass to the callback function
|
|
+ *
|
|
+ * \return 0 if successfully submitted, negated POSIX errno values otherwise.
|
|
+ */
|
|
+int spdk_nvme_ns_cmd_unmap_blocks(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
|
|
+ uint32_t type,
|
|
+ const struct spdk_nvme_dsm_range *ranges,
|
|
+ uint16_t num_ranges,
|
|
+ spdk_nvme_cmd_cb cb_fn,
|
|
+ void *cb_arg);
|
|
+/**
|
|
+ * \brief Submits a write I/O to the specified NVMe namespace.
|
|
+ *
|
|
+ * \param ns NVMe namespace to submit the write I/O
|
|
+ * \param qpair I/O queue pair to submit the request
|
|
+ * \param lba starting LBA to write the data
|
|
+ * \param lba_count length (in sectors) for the write operation
|
|
+ * \param streamId The stream id for write I/O
|
|
+ * \param cb_fn callback function to invoke when the I/O is completed
|
|
+ * \param cb_arg argument to pass to the callback function
|
|
+ * \param io_flags set flags, defined in nvme_spec.h, for this I/O
|
|
+ * \param reset_sgl_fn callback function to reset scattered payload
|
|
+ * \param next_sge_fn callback function to iterate each scattered
|
|
+ * payload memory segment
|
|
+ *
|
|
+ * \return 0 if successfully submitted, ENOMEM if an nvme_request
|
|
+ * structure cannot be allocated for the I/O request
|
|
+ *
|
|
+ * The command is submitted to a qpair allocated by spdk_nvme_ctrlr_alloc_io_qpair().
|
|
+ * The user must ensure that only one thread submits I/O on a given qpair at any given time.
|
|
+ */
|
|
+int spdk_nvme_ns_cmd_writev_stream(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
|
|
+ uint64_t lba, uint32_t lba_count, uint16_t streamId,
|
|
+ spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
|
|
+ spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
|
|
+ spdk_nvme_req_next_sge_cb next_sge_fn);
|
|
+
|
|
+/**
|
|
+ * \brief Send comman to NVMe controller to start or abort a self-test operation.
|
|
+ *
|
|
+ * \param ctrlr NVMe controller to operate self-test command.
|
|
+ * \param nsid Depending on the log page, this may be 0, a namespace identifier, or SPDK_NVME_GLOBAL_NS_TAG.
|
|
+ * \param stc self-test code, which specifies the action taken by the Device Self-test command.
|
|
+ * \param payload The pointer to the payload buffer. it doesn't work actually.
|
|
+ * \param payload_size The size of payload buffer. it doesn't work actually.
|
|
+ * \param cb_fn Callback function to invoke when the feature has been retrieved.
|
|
+ * \param cb_arg Argument to pass to the callback function.
|
|
+ *
|
|
+ * \return 0 if successfully submitted, ENOMEM if resources could not be allocated for this request
|
|
+ *
|
|
+ * This function is thread safe and can be called at any point while the controller is attached to
|
|
+ * the SPDK NVMe driver.
|
|
+ *
|
|
+ * Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
|
|
+ * of commands submitted through this function.
|
|
+ *
|
|
+ * \sa spdk_nvme_ctrlr_cmd_self_test_operation()
|
|
+ */
|
|
+int spdk_nvme_ctrlr_cmd_self_test_operation(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, uint32_t stc,
|
|
+ void *payload, uint32_t payload_size,
|
|
+ spdk_nvme_cmd_cb cb_fn, void *cb_arg);
|
|
+
|
|
+/**
|
|
+ *\get I/O queue pair id
|
|
+ *\param qpair I/O queue pair to submit the request
|
|
+ *\
|
|
+ *\return I/O queue pair id
|
|
+ */
|
|
+uint16_t spdk_nvme_get_qpair_id(struct spdk_nvme_qpair *qpair);
|
|
+#endif
|
|
+
|
|
/*
|
|
* Macro used to register new transports.
|
|
*/
|
|
diff --git a/include/spdk/thread.h b/include/spdk/thread.h
|
|
index 4b7e650..7c52433 100644
|
|
--- a/include/spdk/thread.h
|
|
+++ b/include/spdk/thread.h
|
|
@@ -42,6 +42,9 @@
|
|
|
|
#include "spdk/cpuset.h"
|
|
#include "spdk/queue.h"
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+#include "rte_config.h"
|
|
+#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
@@ -57,6 +60,21 @@ enum spdk_thread_poller_rc {
|
|
*/
|
|
struct spdk_thread;
|
|
|
|
+#ifdef SPDK_CONFIG_APP_RW
|
|
+struct spdk_iodev_thread_info {
|
|
+ struct spdk_thread *thread;
|
|
+ volatile int32_t state;
|
|
+ uint32_t bdevnum;
|
|
+};
|
|
+extern struct spdk_iodev_thread_info lcore_thread_info[RTE_MAX_LCORE];
|
|
+
|
|
+void spdk_reactors_use(bool useOrNot);
|
|
+
|
|
+bool spdk_get_reactor_type(void);
|
|
+
|
|
+void spdk_set_thread_exited(struct spdk_thread *thread);
|
|
+#endif
|
|
+
|
|
/**
|
|
* A function repeatedly called on the same spdk_thread.
|
|
*/
|
|
diff --git a/include/spdk_internal/bdev_stat.h b/include/spdk_internal/bdev_stat.h
|
|
new file mode 100644
|
|
index 0000000..f1ba1df
|
|
--- /dev/null
|
|
+++ b/include/spdk_internal/bdev_stat.h
|
|
@@ -0,0 +1,63 @@
|
|
+/*
|
|
+ * Copyright (C) 2021. Huawei Technologies Co., Ltd. All rights reserved.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 and
|
|
+ * only version 2 as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+*/
|
|
+
|
|
+#ifndef LIBSTORAGE_STAT_H
|
|
+#define LIBSTORAGE_STAT_H
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdbool.h>
|
|
+#include <inttypes.h>
|
|
+
|
|
+//share memory file name
|
|
+#define LIBSTORAGE_STAT_SHM_FILE_NAME "libstorage_stat.shm.\
|
|
+49ce4ec241e017c65812b71b9832a50865f0b7d9b4d5f18d3d03283b"
|
|
+
|
|
+//max number of channel+bdev
|
|
+#define STAT_MAX_NUM 8192
|
|
+
|
|
+extern int32_t g_libstorage_iostat;
|
|
+extern int32_t g_polltime_threshold;
|
|
+
|
|
+extern pthread_mutex_t *g_io_stat_map_mutex;
|
|
+
|
|
+/* libstorage iostat status */
|
|
+enum libstorage_iostat_status {
|
|
+ LIBSTORAGE_IOSTAT_DISABLE = 0,
|
|
+ LIBSTORAGE_IOSTAT_ENABLE = 1,
|
|
+ LIBSTORAGE_IOSTAT_QUERY = 2,
|
|
+};
|
|
+
|
|
+struct libstorage_bdev_io_stat
|
|
+{
|
|
+ bool used;
|
|
+ uint16_t channel_id;
|
|
+ char bdev_name[24];
|
|
+ uint64_t num_read_ops;
|
|
+ uint64_t num_write_ops;
|
|
+ uint64_t bytes_read;
|
|
+ uint64_t bytes_written;
|
|
+ uint64_t io_outstanding;
|
|
+ uint64_t read_latency_ticks;
|
|
+ uint64_t write_latency_ticks;
|
|
+ uint64_t io_ticks;
|
|
+ bool poll_time_used;
|
|
+ uint64_t num_poll_timeout;
|
|
+};
|
|
+
|
|
+extern struct libstorage_bdev_io_stat *g_io_stat_map;
|
|
+
|
|
+int libstorage_stat_init(void);
|
|
+
|
|
+int libstorage_stat_exit(void);
|
|
+#endif
|
|
diff --git a/include/spdk_internal/debug.h b/include/spdk_internal/debug.h
|
|
new file mode 100644
|
|
index 0000000..5d6e623
|
|
--- /dev/null
|
|
+++ b/include/spdk_internal/debug.h
|
|
@@ -0,0 +1,43 @@
|
|
+/*
|
|
+ * Copyright (C) 2021. Huawei Technologies Co., Ltd. All rights reserved.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 and
|
|
+ * only version 2 as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+*/
|
|
+
|
|
+#ifndef LIBSTORAGE_INTERNAL_DEBUG_H
|
|
+#define LIBSTORAGE_INTERNAL_DEBUG_H
|
|
+#include "spdk/stdinc.h"
|
|
+
|
|
+struct spdk_debug_subsystem
|
|
+{
|
|
+ const char *name;
|
|
+ void (*output)(FILE *file);
|
|
+ TAILQ_ENTRY(spdk_debug_subsystem) tailq;
|
|
+};
|
|
+
|
|
+void spdk_add_debug_subsystem(struct spdk_debug_subsystem *subsystem);
|
|
+
|
|
+/**
|
|
+ * \brief Register a new subsystem
|
|
+ */
|
|
+#define SPDK_DEBUG_REGISTER(_name, _output) \
|
|
+ struct spdk_debug_subsystem __spdk_debug_subsystem_ ## _name = \
|
|
+ { \
|
|
+ .name = #_name, \
|
|
+ .output = _output, \
|
|
+ }; \
|
|
+ __attribute__((constructor)) static void _name ## _debug_register(void) \
|
|
+ { \
|
|
+ spdk_add_debug_subsystem(&__spdk_debug_subsystem_ ## _name); \
|
|
+ }
|
|
+
|
|
+void spdk_output_debug_info(void);
|
|
+
|
|
+#endif
|
|
diff --git a/include/spdk_internal/thread.h b/include/spdk_internal/thread.h
|
|
index 5bab452..7d1811b 100644
|
|
--- a/include/spdk_internal/thread.h
|
|
+++ b/include/spdk_internal/thread.h
|
|
@@ -80,6 +80,8 @@ struct spdk_poller {
|
|
};
|
|
|
|
enum spdk_thread_state {
|
|
+ SPDK_THREAD_STATE_INITIALIZED,
|
|
+
|
|
/* The thread is pocessing poller and message by spdk_thread_poll(). */
|
|
SPDK_THREAD_STATE_RUNNING,
|
|
|
|
diff --git a/mk/spdk.app_vars.mk b/mk/spdk.app_vars.mk
|
|
index 059a56e..ff8fad5 100644
|
|
--- a/mk/spdk.app_vars.mk
|
|
+++ b/mk/spdk.app_vars.mk
|
|
@@ -57,8 +57,10 @@ SPDK_LIB_LINKER_ARGS = \
|
|
-L$(SPDK_ROOT_DIR)/build/lib \
|
|
-Wl,--whole-archive \
|
|
-Wl,--no-as-needed \
|
|
+ -Wl,-Bstatic \
|
|
$(SPDK_DEPLIB_LIST:%=-lspdk_%) \
|
|
- -Wl,--no-whole-archive
|
|
+ -Wl,--no-whole-archive \
|
|
+ -Wl,-Bdynamic
|
|
|
|
# This is primarily used for unit tests to ensure they link when shared library
|
|
# build is enabled. Shared libraries can't get their mock implementation from
|
|
--
|
|
2.33.0
|
|
|