Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6acb9a5875 | ||
|
5882a3621b | ||
|
c5f0959de6 | ||
|
1a970987df | ||
|
78554349e7 | ||
|
9da2afe938 | ||
|
c4e28a51a6 | ||
|
f7f016d5ef | ||
|
c2e522ec9e | ||
|
58a35d24d5 | ||
|
d7b0ae8913 | ||
|
bb9348e736 | ||
|
a10baa808e | ||
|
15edc31247 | ||
|
9d04c1d2f7 | ||
|
3f2d3a6ff2 | ||
|
d831e63353 | ||
|
fca143dcb0 | ||
|
10adee24ff | ||
|
0afad8dd11 | ||
|
d8f54aed9a | ||
|
b47e2267cf | ||
|
c0bf57f87d |
176
CHANGELOG.md
176
CHANGELOG.md
@ -1,6 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v20.04: (Upcoming Release)
|
## v20.04.2: (Upcoming Release)
|
||||||
|
|
||||||
|
## v20.04.1:
|
||||||
|
|
||||||
|
### dpdk
|
||||||
|
|
||||||
|
Updated DPDK submodule to DPDK 19.11.2, which includes fixes for DPDK vulnerabilities:
|
||||||
|
CVE-2020-10722, CVE-2020-10723, CVE-2020-10724, CVE-2020-10725, CVE-2020-10724.
|
||||||
|
|
||||||
|
## v20.04:
|
||||||
|
|
||||||
### configuration
|
### configuration
|
||||||
|
|
||||||
@ -8,6 +17,24 @@ Legacy INI style configuration for SPDK applications has been deprecated and wil
|
|||||||
removed in future release.
|
removed in future release.
|
||||||
Please switch to JSON-RPC configuration files and/or RPC driven run-time configuration.
|
Please switch to JSON-RPC configuration files and/or RPC driven run-time configuration.
|
||||||
|
|
||||||
|
### copy
|
||||||
|
|
||||||
|
The copy engine library, modules and public APIs have been renamed. Use of the word `copy`
|
||||||
|
has been replaced with the word `accel` short for accelerator in preparation for adding new
|
||||||
|
capabilities in the future. Additionally, APIs for what was previously called the `memcpy`
|
||||||
|
engine have been renamed to identify the engine as a software accelerator.
|
||||||
|
|
||||||
|
### crypto
|
||||||
|
|
||||||
|
Support for AES_XTS was added for the QAT polled mode driver (pmd). The create RPC
|
||||||
|
`bdev_crypto_create` has 2 new optional parameters: cipher and key2. Cipher can be either
|
||||||
|
AES_CBC (default) or AES_XTS. AES_XTS is only valid when using the QAT polled mode driver.
|
||||||
|
The key2 parameter is the second key required for AES_XTS.
|
||||||
|
|
||||||
|
### event
|
||||||
|
|
||||||
|
Reactors now accumulate CPU stats and they are retrieved by the RPC `framework_get_reactors`.
|
||||||
|
|
||||||
### idxd
|
### idxd
|
||||||
|
|
||||||
IDXD support was added in the form of a low level library that can directly
|
IDXD support was added in the form of a low level library that can directly
|
||||||
@ -16,51 +43,77 @@ with the generic accel framework API. IDXD is the first in a family of offload
|
|||||||
engines that share the same interface, specifically DSA is added here. More info
|
engines that share the same interface, specifically DSA is added here. More info
|
||||||
can be found here: https://01.org/blogs/2019/introducing-intel-data-streaming-accelerator
|
can be found here: https://01.org/blogs/2019/introducing-intel-data-streaming-accelerator
|
||||||
|
|
||||||
Much of the implementation models IOAT, however their low level interfaces are very
|
Much of the implementation models IOAT, however the low level interfaces are very
|
||||||
different. The RPC to enable IDXD requires a configuration number as well. The
|
different. The RPC to enable IDXD requires a configuration number as well. The
|
||||||
code includes 2 pre-defined configurations of IDXD groups/work queues/engines. A future
|
code includes two pre-defined configurations of IDXD groups/work queues/engines. A future
|
||||||
version will provide an interface to allow for setting of individual configuration
|
version will provide an interface to allow for setting of individual configuration
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
IDXD is not yet available so this feature should be considered experimental. It will
|
IDXD is not yet available so this feature should be considered experimental. It will
|
||||||
be built up with additional documentation as an ongoing activity.
|
be built up with additional documentation as an ongoing activity.
|
||||||
|
|
||||||
### ocf
|
### iscsi
|
||||||
|
|
||||||
Update OCF submodule to OCF v20.03
|
|
||||||
|
|
||||||
New version of OCF comes with API changes and bug fixes
|
|
||||||
|
|
||||||
### nvme
|
|
||||||
|
|
||||||
Export internal nvme_ctrlr_cmd_security_receive/send() APIs as public APIs with "spdk_"
|
|
||||||
prefix.
|
|
||||||
|
|
||||||
Added `priority` field in `spdk_nvme_transport_id`, this field is used to specify the priority
|
|
||||||
of the NVMe-oF connection, and currently it is used for NVMe-oF tcp connection.
|
|
||||||
|
|
||||||
### copy
|
|
||||||
|
|
||||||
The copy engine library, modules and public APIs have been renamed. Use of the word `copy`
|
|
||||||
has been replaced with the word `accel` short for accelerator in preparation for adding new
|
|
||||||
capabilities in the future. Additionally, APIs for what was previously called the `memcpy`
|
|
||||||
engine have been renamed to identify the engine as a software accelerator.
|
|
||||||
|
|
||||||
### event
|
|
||||||
|
|
||||||
Reactor now accumulates CPU stats and they are retrieved by the RPC `framework_get_reactors`.
|
|
||||||
|
|
||||||
### iSCSI
|
|
||||||
|
|
||||||
The iSCSI target now creates a lightweight thread per poll group instead of assuming a pool
|
The iSCSI target now creates a lightweight thread per poll group instead of assuming a pool
|
||||||
of lightweight threads already exist at start up time. A poll group is a collection of
|
of lightweight threads already exist at start up time. A poll group is a collection of
|
||||||
unrelated iSCSI connections. Each poll group is only accessed from the associated
|
unrelated iSCSI connections. Each poll group is only accessed from the associated
|
||||||
lightweight thread.
|
lightweight thread.
|
||||||
|
|
||||||
### vmd
|
### ftl
|
||||||
|
|
||||||
A new function, `spdk_vmd_fini`, has been added. It releases all resources acquired by the VMD
|
Several changes have been made to the `spdk_ftl_conf`, `spdk_ftl_dev_init_ops`, and
|
||||||
library through the `spdk_vmd_init` call.
|
`spdk_ftl_attrs` structs. Please see `include/spdk/ftl.h` for more details.
|
||||||
|
|
||||||
|
### miscellaneous
|
||||||
|
|
||||||
|
The `--json-ignore-init-errors` command line parameter has been added to ignore
|
||||||
|
initialization errors on JSON config load.
|
||||||
|
|
||||||
|
The public header file io_channel.h has been removed. Please use thread.h which has the
|
||||||
|
exact same API.
|
||||||
|
|
||||||
|
### nvme
|
||||||
|
|
||||||
|
Exported internal nvme_ctrlr_cmd_security_receive/send() APIs as public APIs with "the spdk_"
|
||||||
|
prefix.
|
||||||
|
|
||||||
|
Added `priority` field in `spdk_nvme_transport_id`, this field is used to specify the priority
|
||||||
|
of the NVMe-oF connection, and currently it is used for NVMe-oF tcp connection.
|
||||||
|
|
||||||
|
A new poll group API has been added to allow for pooling of nvme qpairs across a single
|
||||||
|
entity which can be polled for completions. This new API consists of the `spdk_nvme_poll_group`
|
||||||
|
family of functions. As a result of this new API, all NVMe transports are expected to implement
|
||||||
|
several poll group related functions.
|
||||||
|
|
||||||
|
A new flag, `create_only`, has been added to the `spdk_nvme_io_qpair_opts` structure. This flag
|
||||||
|
allows a user to call `spdk_nvme_ctrlr_get_default_io_qpair` without also connecting the qpair
|
||||||
|
within the context of that call.
|
||||||
|
|
||||||
|
As a result of the `create_only` flag, two new API functions, `spdk_nvme_ctrlr_connect_io_qpair`
|
||||||
|
and `spdk_nvme_ctrlr_disconnect_io_qpair`, have been added to facilitate connecting newly created
|
||||||
|
qpairs (for example, after they have been added to a poll group) and disconnecting qpairs without
|
||||||
|
destroying them (for example to disconnect a qpair before migrating it to a new poll group and
|
||||||
|
reconnecting it).
|
||||||
|
|
||||||
|
The functions `spdk_nvme_ctrlr_alloc_cmb_io_buffer` and `spdk_nvme_ctrlr_free_cmb_io_buffer`
|
||||||
|
have been changed to `spdk_nvme_ctrlr_map_cmb` and `spdk_nvme_ctrlr_unmap_cmb` respectively.
|
||||||
|
|
||||||
|
An additional function, `spdk_nvme_ctrlr_reserve_cmb`, has been added to facilitate reserving
|
||||||
|
the entire size of the controller memory buffer for data transfer.
|
||||||
|
|
||||||
|
### nvme_cuse
|
||||||
|
|
||||||
|
`spdk_nvme_cuse_get_ctrlr_name` now takes two additional parameters, `char *name` which
|
||||||
|
stores the pointer to the controller name, and `size_t *size` which stores the length of
|
||||||
|
the name. The return type has also been changed from char * to int.
|
||||||
|
|
||||||
|
`spdk_nvme_cuse_get_ns_name` now takes two additional parameters, `char *name` which
|
||||||
|
stores the pointer to the namespace name, and `size_t *size` which stores the length of
|
||||||
|
the name. The return type has also been changed from char * to int.
|
||||||
|
|
||||||
|
### nvme_opal
|
||||||
|
|
||||||
|
Several public OPAL structure definitions have been changed since the last release.
|
||||||
|
|
||||||
### nvmf
|
### nvmf
|
||||||
|
|
||||||
@ -71,36 +124,49 @@ of lightweight threads already exist at start up time. A poll group is a collect
|
|||||||
unrelated NVMe-oF connections. Each poll group is only accessed from the associated
|
unrelated NVMe-oF connections. Each poll group is only accessed from the associated
|
||||||
lightweight thread.
|
lightweight thread.
|
||||||
|
|
||||||
### Miscellaneous
|
A new struct, `spdk_nvmf_subsystem_listener`, has been added to encapsulate the subsystem specific
|
||||||
|
nature of a listener object.
|
||||||
|
|
||||||
`--json-ignore-init-errors` command line param has been added to ignore initialization errors
|
`spdk_nvmf_tgt_listen` no longer accepts a callback function or argument. It also returns an
|
||||||
on JSON config load.
|
int to indicate the status of the listen call.
|
||||||
|
|
||||||
The public header file io_channel.h has been removed. Please use thread.h which has the
|
The execution of `spdk_nvme_poll_group_destroy` is now asynchronous and the function accepts
|
||||||
exact same API.
|
a cb_fn and cb_arg to call upon completion.
|
||||||
|
|
||||||
### crypto
|
The execution of `spdk_nvmf_subsystem_add_listener` is now asynchronous and the function accepts
|
||||||
|
a cb_fn and cb_arg to call upon completion.
|
||||||
|
|
||||||
Support for AES_XTS was added for the QAT polled mode driver (pmd). The create RPC
|
The `nvmf_transport.h` header has been made public to allow custom NVMe-oF transports to integrate
|
||||||
`bdev_crypto_create` has 2 new optional parameters: cipher and key2. Cipher can be either
|
with NVMe-oF libraries without using internal APIs.
|
||||||
AES_CBC (default) or AES_XTS. AES_XTS is only valid when using the QAT polled mode driver.
|
|
||||||
The key2 parameter is the second key required for AES_XTS.
|
|
||||||
|
|
||||||
### util
|
### ocf
|
||||||
|
|
||||||
New functions `spdk_sn32_lt` and `spdk_sn32_gt` have been added. They compare two sequence
|
Updated the OCF submodule to OCF v20.03
|
||||||
numbers based on serial number arithmetic.
|
|
||||||
|
New version of OCF comes with API changes and bug fixes
|
||||||
|
|
||||||
### rpc
|
### rpc
|
||||||
|
|
||||||
A new RPC `thread_set_cpumask` has been added to set the cpumask of the thread
|
A new RPC `thread_set_cpumask` has been added to set the cpumask of the thread
|
||||||
to the specified value.
|
to the specified value.
|
||||||
|
|
||||||
A new RPC `thread_get_pollers` has been added to retrieve pollers of SPDK threads.
|
A new RPC `thread_get_pollers` has been added to retrieve pollers from SPDK threads.
|
||||||
|
|
||||||
A new RPC `thread_get_io_channels` has been added to retrieve I/O channels of SPDK threads.
|
A new RPC `thread_get_io_channels` has been added to retrieve I/O channels from SPDK threads.
|
||||||
|
|
||||||
A new RPC `bdev_rbd_resize` has been added to resize the Ceph RBD bdev.
|
A new RPC `bdev_rbd_resize` has been added to resize Ceph RBD bdevs.
|
||||||
|
|
||||||
|
### sock
|
||||||
|
|
||||||
|
The `spdk_sock_set_priority` function has been removed since the feature to set the sock priority
|
||||||
|
will be contained in two new functions, i.e., `spdk_sock_listen_ext` and `spdk_sock_connect_ext`.
|
||||||
|
Users may now specify the priority of the socket in the opts that they want to use.
|
||||||
|
|
||||||
|
### spdk_top
|
||||||
|
|
||||||
|
A new application, `spdk_top`, has been added which allows users to monitor resource consumption
|
||||||
|
by a running SPDK application. More information on this application can be found in
|
||||||
|
`app/spdk_top/README`.
|
||||||
|
|
||||||
### thread
|
### thread
|
||||||
|
|
||||||
@ -113,7 +179,7 @@ Current SPDK operation types are `SPDK_THREAD_OP_NEW` and `SPDK_THREAD_OP_RESCHE
|
|||||||
The operation `SPDK_THREAD_OP_NEW` is called each time a new thread is created.
|
The operation `SPDK_THREAD_OP_NEW` is called each time a new thread is created.
|
||||||
The operation `SPDK_THREAD_OP_RESCHED` is called when SPDK thread needs to be rescheduled.
|
The operation `SPDK_THREAD_OP_RESCHED` is called when SPDK thread needs to be rescheduled.
|
||||||
|
|
||||||
An unique ID has been added for each created SPDK thread, it is retrieved by a new function
|
A unique ID has been added for each created SPDK thread, it is retrieved by a new function
|
||||||
`spdk_thread_get_id`, and the SPDK thread which has the specific ID is got by
|
`spdk_thread_get_id`, and the SPDK thread which has the specific ID is got by
|
||||||
a new function `spdk_thread_get_by_id`.
|
a new function `spdk_thread_get_by_id`.
|
||||||
|
|
||||||
@ -130,15 +196,19 @@ threads configuration, and a new function `spdk_thread_get_last_tsc` has been ad
|
|||||||
Voluntary termination of SPDK thread has been supported by refining the functions `spdk_thread_exit`
|
Voluntary termination of SPDK thread has been supported by refining the functions `spdk_thread_exit`
|
||||||
and `spdk_thread_poll`.
|
and `spdk_thread_poll`.
|
||||||
|
|
||||||
|
### util
|
||||||
|
|
||||||
|
New functions `spdk_sn32_lt` and `spdk_sn32_gt` have been added. They compare two sequence
|
||||||
|
numbers based on serial number arithmetic.
|
||||||
|
|
||||||
### vhost
|
### vhost
|
||||||
|
|
||||||
Poll groups per session have been replaced by SPDK threads per vhost controller.
|
Poll groups per session have been replaced by SPDK threads per vhost controller.
|
||||||
|
|
||||||
### sock
|
### vmd
|
||||||
|
|
||||||
Remove `spdk_sock_set_priority` function since the feature to set the sock priority will be
|
A new function, `spdk_vmd_fini`, has been added. It releases all resources acquired by the VMD
|
||||||
contained in two new functions, i.e., `spdk_sock_listen_ext` and `spdk_sock_connect_ext`.
|
library through the `spdk_vmd_init` call.
|
||||||
Users may now specify the priority of the socket in the opts that they want to use.
|
|
||||||
|
|
||||||
## v20.01
|
## v20.01
|
||||||
|
|
||||||
|
@ -944,6 +944,10 @@ store_last_run_counter(const char *poller_name, uint64_t thread_id, uint64_t las
|
|||||||
}
|
}
|
||||||
|
|
||||||
history = calloc(1, sizeof(*history));
|
history = calloc(1, sizeof(*history));
|
||||||
|
if (history == NULL) {
|
||||||
|
fprintf(stderr, "Unable to allocate a history object in store_last_run_counter.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
history->poller_name = strdup(poller_name);
|
history->poller_name = strdup(poller_name);
|
||||||
history->thread_id = thread_id;
|
history->thread_id = thread_id;
|
||||||
history->last_run_counter = last_run_counter;
|
history->last_run_counter = last_run_counter;
|
||||||
@ -983,8 +987,10 @@ sort_pollers(const void *p1, const void *p2, void *arg)
|
|||||||
return strcmp(poller1->thread_name, poller2->thread_name);
|
return strcmp(poller1->thread_name, poller2->thread_name);
|
||||||
case 3: /* Sort by run counter */
|
case 3: /* Sort by run counter */
|
||||||
last_run_counter = get_last_run_counter(poller1->name, poller1->thread_id);
|
last_run_counter = get_last_run_counter(poller1->name, poller1->thread_id);
|
||||||
|
assert(last_run_counter != NULL);
|
||||||
count1 = poller1->run_count - *last_run_counter;
|
count1 = poller1->run_count - *last_run_counter;
|
||||||
last_run_counter = get_last_run_counter(poller2->name, poller2->thread_id);
|
last_run_counter = get_last_run_counter(poller2->name, poller2->thread_id);
|
||||||
|
assert(last_run_counter != NULL);
|
||||||
count2 = poller2->run_count - *last_run_counter;
|
count2 = poller2->run_count - *last_run_counter;
|
||||||
break;
|
break;
|
||||||
case 4: /* Sort by period */
|
case 4: /* Sort by period */
|
||||||
@ -1021,6 +1027,7 @@ copy_pollers(struct rpc_pollers *pollers, uint64_t pollers_count, enum spdk_poll
|
|||||||
last_run_counter = get_last_run_counter(pollers->pollers[i].name, thread->id);
|
last_run_counter = get_last_run_counter(pollers->pollers[i].name, thread->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(last_run_counter != NULL);
|
||||||
*last_run_counter = pollers->pollers[i].run_count;
|
*last_run_counter = pollers->pollers[i].run_count;
|
||||||
}
|
}
|
||||||
pollers_info[*current_count] = &pollers->pollers[i];
|
pollers_info[*current_count] = &pollers->pollers[i];
|
||||||
@ -1113,6 +1120,7 @@ refresh_pollers_tab(uint8_t current_page)
|
|||||||
|
|
||||||
if (!col_desc[3].disabled) {
|
if (!col_desc[3].disabled) {
|
||||||
last_run_counter = get_last_run_counter(pollers[i]->name, pollers[i]->thread_id);
|
last_run_counter = get_last_run_counter(pollers[i]->name, pollers[i]->thread_id);
|
||||||
|
assert(last_run_counter != NULL);
|
||||||
|
|
||||||
snprintf(run_count, MAX_TIME_STR_LEN, "%" PRIu64, pollers[i]->run_count - *last_run_counter);
|
snprintf(run_count, MAX_TIME_STR_LEN, "%" PRIu64, pollers[i]->run_count - *last_run_counter);
|
||||||
print_max_len(g_tabs[POLLERS_TAB], TABS_DATA_START_ROW + item_index, col,
|
print_max_len(g_tabs[POLLERS_TAB], TABS_DATA_START_ROW + item_index, col,
|
||||||
@ -1377,6 +1385,10 @@ draw_filtering_menu(uint8_t position, WINDOW *filter_win, uint8_t tab, MENU **my
|
|||||||
elements = i;
|
elements = i;
|
||||||
|
|
||||||
my_items = (ITEM **)calloc(elements * WINDOW_COLUMNS + ADDITIONAL_ELEMENTS, sizeof(ITEM *));
|
my_items = (ITEM **)calloc(elements * WINDOW_COLUMNS + ADDITIONAL_ELEMENTS, sizeof(ITEM *));
|
||||||
|
if (my_items == NULL) {
|
||||||
|
fprintf(stderr, "Unable to allocate an item list in draw_filtering_menu.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < elements * 2; i++) {
|
for (i = 0; i < elements * 2; i++) {
|
||||||
my_items[i] = new_item(col_desc[i / WINDOW_COLUMNS].name, NULL);
|
my_items[i] = new_item(col_desc[i / WINDOW_COLUMNS].name, NULL);
|
||||||
@ -1441,7 +1453,7 @@ filter_columns(uint8_t tab)
|
|||||||
PANEL *filter_panel;
|
PANEL *filter_panel;
|
||||||
WINDOW *filter_win;
|
WINDOW *filter_win;
|
||||||
ITEM **my_items;
|
ITEM **my_items;
|
||||||
MENU *my_menu;
|
MENU *my_menu = NULL;
|
||||||
int i, c, elements;
|
int i, c, elements;
|
||||||
bool stop_loop = false;
|
bool stop_loop = false;
|
||||||
ITEM *cur;
|
ITEM *cur;
|
||||||
@ -1552,6 +1564,10 @@ change_sorting(uint8_t tab)
|
|||||||
elements = i;
|
elements = i;
|
||||||
|
|
||||||
my_items = (ITEM **)calloc(elements + 1, sizeof(ITEM *));
|
my_items = (ITEM **)calloc(elements + 1, sizeof(ITEM *));
|
||||||
|
if (my_items == NULL) {
|
||||||
|
fprintf(stderr, "Unable to allocate an item list in change_sorting.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < elements; ++i) {
|
for (i = 0; i < elements; ++i) {
|
||||||
my_items[i] = new_item(g_col_desc[tab][i].name, NULL);
|
my_items[i] = new_item(g_col_desc[tab][i].name, NULL);
|
||||||
|
@ -35,7 +35,12 @@ fi
|
|||||||
|
|
||||||
timing_enter build_release
|
timing_enter build_release
|
||||||
|
|
||||||
./configure $(get_config_params) --disable-debug --enable-lto
|
if [ $(uname -s) = Linux ]; then
|
||||||
|
./configure $(get_config_params) --disable-debug --enable-lto --disable-unit-tests
|
||||||
|
else
|
||||||
|
# LTO needs a special compiler to work on BSD.
|
||||||
|
./configure $(get_config_params) --disable-debug
|
||||||
|
fi
|
||||||
$MAKE ${MAKEFLAGS}
|
$MAKE ${MAKEFLAGS}
|
||||||
$MAKE ${MAKEFLAGS} clean
|
$MAKE ${MAKEFLAGS} clean
|
||||||
|
|
||||||
|
5
configure
vendored
5
configure
vendored
@ -494,6 +494,11 @@ if [[ "${CONFIG[ISAL]}" = "n" ]] && [[ "${CONFIG[REDUCE]}" = "y" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${CONFIG[LTO]}" = "y" ]] && [[ "${CONFIG[UNIT_TESTS]}" = "y" ]]; then
|
||||||
|
echo "ERROR Conflicting options: --enable-lto is not compatible with --enable-unit-tests."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "${CONFIG[ENV]}" ]; then
|
if [ -z "${CONFIG[ENV]}" ]; then
|
||||||
CONFIG[ENV]=$rootdir/lib/env_dpdk
|
CONFIG[ENV]=$rootdir/lib/env_dpdk
|
||||||
echo "Using default SPDK env in ${CONFIG[ENV]}"
|
echo "Using default SPDK env in ${CONFIG[ENV]}"
|
||||||
|
2
dpdk
2
dpdk
@ -1 +1 @@
|
|||||||
Subproject commit 76f9669b1f4cdd52bae2c3408ad129272bf99d1f
|
Subproject commit ef71bfaface10cc19b75e45d3158ab71a788e3a9
|
@ -54,7 +54,7 @@
|
|||||||
* Patch level is incremented on maintenance branch releases and reset to 0 for each
|
* Patch level is incremented on maintenance branch releases and reset to 0 for each
|
||||||
* new major.minor release.
|
* new major.minor release.
|
||||||
*/
|
*/
|
||||||
#define SPDK_VERSION_PATCH 0
|
#define SPDK_VERSION_PATCH 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version string suffix.
|
* Version string suffix.
|
||||||
|
@ -71,7 +71,6 @@ static struct spdk_conf *default_config = NULL;
|
|||||||
struct spdk_conf *
|
struct spdk_conf *
|
||||||
spdk_conf_allocate(void)
|
spdk_conf_allocate(void)
|
||||||
{
|
{
|
||||||
SPDK_ERRLOG("INI configuration has been deprecated and will be removed in a future release. Please switch to JSON-RPC.\n");
|
|
||||||
return calloc(1, sizeof(struct spdk_conf));
|
return calloc(1, sizeof(struct spdk_conf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,6 +610,7 @@ spdk_conf_read(struct spdk_conf *cp, const char *file)
|
|||||||
if (file == NULL || file[0] == '\0') {
|
if (file == NULL || file[0] == '\0') {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
SPDK_ERRLOG("INI configuration has been deprecated and will be removed in a future release. Please switch to JSON-RPC.\n");
|
||||||
|
|
||||||
fp = fopen(file, "r");
|
fp = fopen(file, "r");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
|
@ -78,6 +78,11 @@ ifneq (, $(wildcard $(DPDK_ABS_DIR)/lib/librte_bus_pci.*))
|
|||||||
DPDK_LIB_LIST += rte_bus_pci
|
DPDK_LIB_LIST += rte_bus_pci
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# DPDK 20.05 eal dependency
|
||||||
|
ifneq (, $(wildcard $(DPDK_ABS_DIR)/lib/librte_telemetry.*))
|
||||||
|
DPDK_LIB_LIST += rte_telemetry
|
||||||
|
endif
|
||||||
|
|
||||||
# There are some complex dependencies when using crypto, reduce or both so
|
# There are some complex dependencies when using crypto, reduce or both so
|
||||||
# here we add the feature specific ones and set a flag to add the common
|
# here we add the feature specific ones and set a flag to add the common
|
||||||
# ones after that.
|
# ones after that.
|
||||||
|
@ -77,8 +77,8 @@ void pci_driver_register(struct spdk_pci_driver *driver);
|
|||||||
int pci_device_init(struct rte_pci_driver *driver, struct rte_pci_device *device);
|
int pci_device_init(struct rte_pci_driver *driver, struct rte_pci_device *device);
|
||||||
int pci_device_fini(struct rte_pci_device *device);
|
int pci_device_fini(struct rte_pci_device *device);
|
||||||
|
|
||||||
void pci_init(void);
|
void pci_env_init(void);
|
||||||
void pci_fini(void);
|
void pci_env_fini(void);
|
||||||
int mem_map_init(bool legacy_mem);
|
int mem_map_init(bool legacy_mem);
|
||||||
int vtophys_init(void);
|
int vtophys_init(void);
|
||||||
|
|
||||||
|
@ -499,7 +499,7 @@ spdk_env_dpdk_post_init(bool legacy_mem)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
pci_init();
|
pci_env_init();
|
||||||
|
|
||||||
rc = mem_map_init(legacy_mem);
|
rc = mem_map_init(legacy_mem);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@ -519,7 +519,7 @@ spdk_env_dpdk_post_init(bool legacy_mem)
|
|||||||
void
|
void
|
||||||
spdk_env_dpdk_post_fini(void)
|
spdk_env_dpdk_post_fini(void)
|
||||||
{
|
{
|
||||||
pci_fini();
|
pci_env_fini();
|
||||||
|
|
||||||
spdk_free_args(g_eal_cmdline, g_eal_cmdline_argcount);
|
spdk_free_args(g_eal_cmdline, g_eal_cmdline_argcount);
|
||||||
}
|
}
|
||||||
|
@ -259,7 +259,7 @@ _get_alarm_thread_cb(void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pci_init(void)
|
pci_env_init(void)
|
||||||
{
|
{
|
||||||
#if RTE_VERSION >= RTE_VERSION_NUM(18, 11, 0, 0)
|
#if RTE_VERSION >= RTE_VERSION_NUM(18, 11, 0, 0)
|
||||||
struct spdk_pci_driver *driver;
|
struct spdk_pci_driver *driver;
|
||||||
@ -298,7 +298,7 @@ pci_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pci_fini(void)
|
pci_env_fini(void)
|
||||||
{
|
{
|
||||||
struct spdk_pci_device *dev;
|
struct spdk_pci_device *dev;
|
||||||
char bdf[32];
|
char bdf[32];
|
||||||
|
@ -1611,6 +1611,7 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry,
|
|||||||
struct ftl_wbuf_entry *prev;
|
struct ftl_wbuf_entry *prev;
|
||||||
struct ftl_band *band;
|
struct ftl_band *band;
|
||||||
int valid;
|
int valid;
|
||||||
|
bool io_weak = entry->io_flags & FTL_IO_WEAK;
|
||||||
|
|
||||||
prev_addr = ftl_l2p_get(dev, entry->lba);
|
prev_addr = ftl_l2p_get(dev, entry->lba);
|
||||||
if (ftl_addr_invalid(prev_addr)) {
|
if (ftl_addr_invalid(prev_addr)) {
|
||||||
@ -1618,14 +1619,7 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the L2P's physical address is different than what we expected we don't need to */
|
|
||||||
/* do anything (someone's already overwritten our data). */
|
|
||||||
if ((entry->io_flags & FTL_IO_WEAK) && !ftl_addr_cmp(prev_addr, entry->addr)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ftl_addr_cached(prev_addr)) {
|
if (ftl_addr_cached(prev_addr)) {
|
||||||
assert(!(entry->io_flags & FTL_IO_WEAK));
|
|
||||||
prev = ftl_get_entry_from_addr(dev, prev_addr);
|
prev = ftl_get_entry_from_addr(dev, prev_addr);
|
||||||
pthread_spin_lock(&prev->lock);
|
pthread_spin_lock(&prev->lock);
|
||||||
|
|
||||||
@ -1634,12 +1628,33 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry,
|
|||||||
prev_addr = ftl_l2p_get(dev, entry->lba);
|
prev_addr = ftl_l2p_get(dev, entry->lba);
|
||||||
|
|
||||||
/* If the entry is no longer in cache, another write has been */
|
/* If the entry is no longer in cache, another write has been */
|
||||||
/* scheduled in the meantime, so we have to invalidate its LBA */
|
/* scheduled in the meantime, so we can return to evicted path */
|
||||||
if (!ftl_addr_cached(prev_addr)) {
|
if (!ftl_addr_cached(prev_addr)) {
|
||||||
ftl_invalidate_addr(dev, prev_addr);
|
pthread_spin_unlock(&prev->lock);
|
||||||
|
goto evicted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If previous entry is part of cache, remove and invalidate it */
|
/*
|
||||||
|
* Relocating block could still reside in cache due to fact that write
|
||||||
|
* buffers are independent for each IO channel and enough amount of data
|
||||||
|
* (write unit size) must be collected before it will be submitted to lower
|
||||||
|
* layer.
|
||||||
|
* When previous entry wasn't overwritten invalidate old address and entry.
|
||||||
|
* Otherwise skip relocating block.
|
||||||
|
*/
|
||||||
|
if (io_weak &&
|
||||||
|
/* Check if prev_addr was updated in meantime */
|
||||||
|
!(ftl_addr_cmp(prev_addr, ftl_get_addr_from_entry(prev)) &&
|
||||||
|
/* Check if relocating address it the same as in previous entry */
|
||||||
|
ftl_addr_cmp(prev->addr, entry->addr))) {
|
||||||
|
pthread_spin_unlock(&prev->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If previous entry is part of cache and was written into disk remove
|
||||||
|
* and invalidate it
|
||||||
|
*/
|
||||||
if (prev->valid) {
|
if (prev->valid) {
|
||||||
ftl_invalidate_addr(dev, prev->addr);
|
ftl_invalidate_addr(dev, prev->addr);
|
||||||
prev->valid = false;
|
prev->valid = false;
|
||||||
@ -1650,6 +1665,15 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evicted:
|
||||||
|
/*
|
||||||
|
* If the L2P's physical address is different than what we expected we don't need to
|
||||||
|
* do anything (someone's already overwritten our data).
|
||||||
|
*/
|
||||||
|
if (io_weak && !ftl_addr_cmp(prev_addr, entry->addr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Lock the band containing previous physical address. This assures atomic changes to */
|
/* Lock the band containing previous physical address. This assures atomic changes to */
|
||||||
/* the L2P as wall as metadata. The valid bits in metadata are used to */
|
/* the L2P as wall as metadata. The valid bits in metadata are used to */
|
||||||
/* check weak writes validity. */
|
/* check weak writes validity. */
|
||||||
@ -1660,7 +1684,7 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry,
|
|||||||
|
|
||||||
/* If the address has been invalidated already, we don't want to update */
|
/* If the address has been invalidated already, we don't want to update */
|
||||||
/* the L2P for weak writes, as it means the write is no longer valid. */
|
/* the L2P for weak writes, as it means the write is no longer valid. */
|
||||||
if (!(entry->io_flags & FTL_IO_WEAK) || valid) {
|
if (!io_weak || valid) {
|
||||||
ftl_l2p_set(dev, entry->lba, addr);
|
ftl_l2p_set(dev, entry->lba, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,6 +923,11 @@ ftl_dev_get_zone_info_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_ar
|
|||||||
"zone id: %"PRIu64"\n", init_ctx->zone_id);
|
"zone id: %"PRIu64"\n", init_ctx->zone_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set write pointer to the last block plus one for zone in full state */
|
||||||
|
if (zone->info.state == SPDK_BDEV_ZONE_STATE_FULL) {
|
||||||
|
zone->info.write_pointer = zone->info.zone_id + zone->info.capacity;
|
||||||
|
}
|
||||||
|
|
||||||
if (zone->info.state != SPDK_BDEV_ZONE_STATE_OFFLINE) {
|
if (zone->info.state != SPDK_BDEV_ZONE_STATE_OFFLINE) {
|
||||||
band->num_zones++;
|
band->num_zones++;
|
||||||
CIRCLEQ_INSERT_TAIL(&band->zones, zone, circleq);
|
CIRCLEQ_INSERT_TAIL(&band->zones, zone, circleq);
|
||||||
|
@ -1629,7 +1629,7 @@ static void
|
|||||||
nvme_rdma_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
|
nvme_rdma_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
|
||||||
{
|
{
|
||||||
struct nvme_rdma_qpair *rqpair = nvme_rdma_qpair(qpair);
|
struct nvme_rdma_qpair *rqpair = nvme_rdma_qpair(qpair);
|
||||||
struct nvme_rdma_ctrlr *rctrlr;
|
struct nvme_rdma_ctrlr *rctrlr = NULL;
|
||||||
struct nvme_rdma_cm_event_entry *entry, *tmp;
|
struct nvme_rdma_cm_event_entry *entry, *tmp;
|
||||||
|
|
||||||
nvme_rdma_unregister_mem(rqpair);
|
nvme_rdma_unregister_mem(rqpair);
|
||||||
@ -1658,8 +1658,7 @@ nvme_rdma_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme
|
|||||||
|
|
||||||
if (rqpair->cm_id) {
|
if (rqpair->cm_id) {
|
||||||
rdma_disconnect(rqpair->cm_id);
|
rdma_disconnect(rqpair->cm_id);
|
||||||
if (qpair->ctrlr != NULL) {
|
if (rctrlr != NULL) {
|
||||||
|
|
||||||
if (nvme_rdma_process_event(rqpair, rctrlr->cm_channel, RDMA_CM_EVENT_DISCONNECTED)) {
|
if (nvme_rdma_process_event(rqpair, rctrlr->cm_channel, RDMA_CM_EVENT_DISCONNECTED)) {
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_NVME, "Target did not respond to qpair disconnect.\n");
|
SPDK_DEBUGLOG(SPDK_LOG_NVME, "Target did not respond to qpair disconnect.\n");
|
||||||
}
|
}
|
||||||
|
@ -1121,18 +1121,17 @@ spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_nu
|
|||||||
svdev = to_scsi_dev(vdev);
|
svdev = to_scsi_dev(vdev);
|
||||||
assert(svdev != NULL);
|
assert(svdev != NULL);
|
||||||
scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
|
scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
|
||||||
|
|
||||||
|
if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
|
if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
|
||||||
SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
|
SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
|
assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
|
||||||
if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
|
|
||||||
SPDK_WARNLOG("%s: SCSI target %u has been already marked for hotremoval.\n",
|
|
||||||
vdev->name, scsi_tgt_num);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = calloc(1, sizeof(*ctx));
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
SPDK_ERRLOG("calloc failed\n");
|
SPDK_ERRLOG("calloc failed\n");
|
||||||
|
@ -1204,9 +1204,18 @@ _device_unregister_cb(void *io_device)
|
|||||||
rte_cryptodev_sym_session_free(crypto_bdev->session_decrypt);
|
rte_cryptodev_sym_session_free(crypto_bdev->session_decrypt);
|
||||||
rte_cryptodev_sym_session_free(crypto_bdev->session_encrypt);
|
rte_cryptodev_sym_session_free(crypto_bdev->session_encrypt);
|
||||||
free(crypto_bdev->drv_name);
|
free(crypto_bdev->drv_name);
|
||||||
|
if (crypto_bdev->key) {
|
||||||
|
memset(crypto_bdev->key, 0, strnlen(crypto_bdev->key, (AES_CBC_KEY_LENGTH + 1)));
|
||||||
free(crypto_bdev->key);
|
free(crypto_bdev->key);
|
||||||
|
}
|
||||||
|
if (crypto_bdev->key2) {
|
||||||
|
memset(crypto_bdev->key2, 0, strnlen(crypto_bdev->key2, (AES_XTS_KEY_LENGTH + 1)));
|
||||||
free(crypto_bdev->key2);
|
free(crypto_bdev->key2);
|
||||||
|
}
|
||||||
|
if (crypto_bdev->xts_key) {
|
||||||
|
memset(crypto_bdev->xts_key, 0, strnlen(crypto_bdev->xts_key, (AES_XTS_KEY_LENGTH * 2) + 1));
|
||||||
free(crypto_bdev->xts_key);
|
free(crypto_bdev->xts_key);
|
||||||
|
}
|
||||||
free(crypto_bdev->crypto_bdev.name);
|
free(crypto_bdev->crypto_bdev.name);
|
||||||
free(crypto_bdev);
|
free(crypto_bdev);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
enum spdk_sock_task_type {
|
enum spdk_sock_task_type {
|
||||||
SPDK_SOCK_TASK_POLLIN = 0,
|
SPDK_SOCK_TASK_POLLIN = 0,
|
||||||
SPDK_SOCK_TASK_WRITE,
|
SPDK_SOCK_TASK_WRITE,
|
||||||
|
SPDK_SOCK_TASK_CANCEL,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum spdk_uring_sock_task_status {
|
enum spdk_uring_sock_task_status {
|
||||||
@ -82,6 +83,7 @@ struct spdk_uring_sock {
|
|||||||
struct spdk_uring_sock_group_impl *group;
|
struct spdk_uring_sock_group_impl *group;
|
||||||
struct spdk_uring_task write_task;
|
struct spdk_uring_task write_task;
|
||||||
struct spdk_uring_task pollin_task;
|
struct spdk_uring_task pollin_task;
|
||||||
|
struct spdk_uring_task cancel_task;
|
||||||
int outstanding_io;
|
int outstanding_io;
|
||||||
struct spdk_pipe *recv_pipe;
|
struct spdk_pipe *recv_pipe;
|
||||||
void *recv_buf;
|
void *recv_buf;
|
||||||
@ -858,6 +860,26 @@ _sock_prep_pollin(struct spdk_sock *_sock)
|
|||||||
task->status = SPDK_URING_SOCK_TASK_IN_PROCESS;
|
task->status = SPDK_URING_SOCK_TASK_IN_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_sock_prep_cancel_task(struct spdk_sock *_sock, void *user_data)
|
||||||
|
{
|
||||||
|
struct spdk_uring_sock *sock = __uring_sock(_sock);
|
||||||
|
struct spdk_uring_task *task = &sock->cancel_task;
|
||||||
|
struct io_uring_sqe *sqe;
|
||||||
|
|
||||||
|
if (task->status == SPDK_URING_SOCK_TASK_IN_PROCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(sock->group != NULL);
|
||||||
|
sock->group->io_queued++;
|
||||||
|
|
||||||
|
sqe = io_uring_get_sqe(&sock->group->uring);
|
||||||
|
io_uring_prep_cancel(sqe, user_data, 0);
|
||||||
|
io_uring_sqe_set_data(sqe, task);
|
||||||
|
task->status = SPDK_URING_SOCK_TASK_IN_PROCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, int max_read_events,
|
spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, int max_read_events,
|
||||||
struct spdk_sock **socks)
|
struct spdk_sock **socks)
|
||||||
@ -919,7 +941,6 @@ spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, in
|
|||||||
if (spdk_unlikely(task->sock->outstanding_io > 0 &&
|
if (spdk_unlikely(task->sock->outstanding_io > 0 &&
|
||||||
TAILQ_EMPTY(&sock->base.pending_reqs))) {
|
TAILQ_EMPTY(&sock->base.pending_reqs))) {
|
||||||
if (--sock->outstanding_io == 0) {
|
if (--sock->outstanding_io == 0) {
|
||||||
sock->group = NULL;
|
|
||||||
/* Just for sock close case */
|
/* Just for sock close case */
|
||||||
if (sock->base.flags.closed) {
|
if (sock->base.flags.closed) {
|
||||||
spdk_uring_sock_close(&sock->base);
|
spdk_uring_sock_close(&sock->base);
|
||||||
@ -927,6 +948,11 @@ spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SPDK_SOCK_TASK_CANCEL:
|
||||||
|
if ((status == 0) && (sock->outstanding_io > 0)) {
|
||||||
|
sock->outstanding_io--;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SPDK_UNREACHABLE();
|
SPDK_UNREACHABLE();
|
||||||
@ -1151,32 +1177,15 @@ spdk_uring_sock_group_impl_add_sock(struct spdk_sock_group_impl *_group,
|
|||||||
sock->pollin_task.sock = sock;
|
sock->pollin_task.sock = sock;
|
||||||
sock->pollin_task.type = SPDK_SOCK_TASK_POLLIN;
|
sock->pollin_task.type = SPDK_SOCK_TASK_POLLIN;
|
||||||
|
|
||||||
return 0;
|
sock->cancel_task.sock = sock;
|
||||||
}
|
sock->cancel_task.type = SPDK_SOCK_TASK_CANCEL;
|
||||||
|
|
||||||
static int
|
/* switched from another polling group due to scheduling */
|
||||||
spdk_uring_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group,
|
if (spdk_unlikely(sock->recv_pipe != NULL &&
|
||||||
struct spdk_sock *_sock)
|
(spdk_pipe_reader_bytes_available(sock->recv_pipe) > 0))) {
|
||||||
{
|
assert(sock->pending_recv == false);
|
||||||
struct spdk_uring_sock *sock = __uring_sock(_sock);
|
sock->pending_recv = true;
|
||||||
struct spdk_uring_sock_group_impl *group = __uring_group_impl(_group);
|
TAILQ_INSERT_TAIL(&group->pending_recv, sock, link);
|
||||||
|
|
||||||
if (sock->write_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
|
|
||||||
sock->outstanding_io++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
|
|
||||||
sock->outstanding_io++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((sock->recv_pipe != NULL) &&
|
|
||||||
spdk_pipe_reader_bytes_available(sock->recv_pipe) > 0) {
|
|
||||||
TAILQ_REMOVE(&group->pending_recv, sock, link);
|
|
||||||
sock->pending_recv = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sock->outstanding_io) {
|
|
||||||
sock->group = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1220,6 +1229,41 @@ spdk_uring_sock_group_impl_poll(struct spdk_sock_group_impl *_group, int max_eve
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spdk_uring_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group,
|
||||||
|
struct spdk_sock *_sock)
|
||||||
|
{
|
||||||
|
struct spdk_uring_sock *sock = __uring_sock(_sock);
|
||||||
|
struct spdk_uring_sock_group_impl *group = __uring_group_impl(_group);
|
||||||
|
|
||||||
|
if (sock->write_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
|
||||||
|
/* For write, we do not need to cancel it */
|
||||||
|
sock->outstanding_io++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
|
||||||
|
sock->outstanding_io++;
|
||||||
|
_sock_prep_cancel_task(_sock, &sock->pollin_task);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Since spdk_sock_group_remove_sock is not asynchronous interface, so
|
||||||
|
* currently can use a while loop here. */
|
||||||
|
while (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
|
||||||
|
spdk_uring_sock_group_impl_poll(_group, 32, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->recv_pipe != NULL) {
|
||||||
|
if (spdk_pipe_reader_bytes_available(sock->recv_pipe) > 0) {
|
||||||
|
TAILQ_REMOVE(&group->pending_recv, sock, link);
|
||||||
|
sock->pending_recv = false;
|
||||||
|
}
|
||||||
|
assert(sock->pending_recv == false);
|
||||||
|
}
|
||||||
|
sock->group = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_uring_sock_group_impl_close(struct spdk_sock_group_impl *_group)
|
spdk_uring_sock_group_impl_close(struct spdk_sock_group_impl *_group)
|
||||||
{
|
{
|
||||||
@ -1242,7 +1286,13 @@ spdk_uring_sock_group_impl_close(struct spdk_sock_group_impl *_group)
|
|||||||
static int
|
static int
|
||||||
spdk_uring_sock_flush(struct spdk_sock *_sock)
|
spdk_uring_sock_flush(struct spdk_sock *_sock)
|
||||||
{
|
{
|
||||||
|
struct spdk_uring_sock *sock = __uring_sock(_sock);
|
||||||
|
|
||||||
|
if (!sock->group) {
|
||||||
return _sock_flush_client(_sock);
|
return _sock_flush_client(_sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spdk_net_impl g_uring_net_impl = {
|
static struct spdk_net_impl g_uring_net_impl = {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
%bcond_with doc
|
%bcond_with doc
|
||||||
|
|
||||||
Name: spdk
|
Name: spdk
|
||||||
Version: master
|
Version: 20.04.x
|
||||||
Release: 0%{?dist}
|
Release: 0%{?dist}
|
||||||
Epoch: 0
|
Epoch: 0
|
||||||
URL: http://spdk.io
|
URL: http://spdk.io
|
||||||
|
|
||||||
Source: https://github.com/spdk/spdk/archive/master.tar.gz
|
Source: https://github.com/spdk/spdk/archive/v20.04.x.tar.gz
|
||||||
Summary: Set of libraries and utilities for high performance user-mode storage
|
Summary: Set of libraries and utilities for high performance user-mode storage
|
||||||
|
|
||||||
%define package_version %{epoch}:%{version}-%{release}
|
%define package_version %{epoch}:%{version}-%{release}
|
||||||
|
@ -827,7 +827,9 @@ function discover_bdevs()
|
|||||||
local rootdir=$1
|
local rootdir=$1
|
||||||
local config_file=$2
|
local config_file=$2
|
||||||
local cfg_type=$3
|
local cfg_type=$3
|
||||||
local wait_for_spdk_bdev=${4:-30}
|
shift 3
|
||||||
|
local bdev_svc_opts=("$@")
|
||||||
|
local wait_for_spdk_bdev=30
|
||||||
local rpc_server=/var/tmp/spdk-discover-bdevs.sock
|
local rpc_server=/var/tmp/spdk-discover-bdevs.sock
|
||||||
|
|
||||||
if [ ! -e $config_file ]; then
|
if [ ! -e $config_file ]; then
|
||||||
@ -841,7 +843,7 @@ function discover_bdevs()
|
|||||||
|
|
||||||
# Start the bdev service to query for the list of available
|
# Start the bdev service to query for the list of available
|
||||||
# bdevs.
|
# bdevs.
|
||||||
$rootdir/test/app/bdev_svc/bdev_svc -r $rpc_server -i 0 \
|
$rootdir/test/app/bdev_svc/bdev_svc -r $rpc_server -i 0 "${bdev_svc_opts[@]}" \
|
||||||
$cfg_type $config_file &>/dev/null &
|
$cfg_type $config_file &>/dev/null &
|
||||||
stubpid=$!
|
stubpid=$!
|
||||||
while ! [ -e /var/run/spdk_bdev0 ]; do
|
while ! [ -e /var/run/spdk_bdev0 ]; do
|
||||||
|
@ -22,11 +22,11 @@ $spdkcli_job "'/bdevs/malloc create 32 512 Malloc0' 'Malloc0' True
|
|||||||
'/bdevs/malloc create 32 512 Malloc1' 'Malloc1' True
|
'/bdevs/malloc create 32 512 Malloc1' 'Malloc1' True
|
||||||
"
|
"
|
||||||
pci_blk=$(lspci -nn -D | grep '1af4:1001' | head -1 | awk '{print $1;}')
|
pci_blk=$(lspci -nn -D | grep '1af4:1001' | head -1 | awk '{print $1;}')
|
||||||
if [ -n "$pci_blk" ]; then
|
if [ -n "$pci_blk" ] && grep -Eq "DRIVER=(uio|vfio)" "/sys/bus/pci/devices/$pci_blk/uevent"; then
|
||||||
$spdkcli_job "'/bdevs/virtioblk_disk create virtioblk_pci pci $pci_blk' 'virtioblk_pci' True"
|
$spdkcli_job "'/bdevs/virtioblk_disk create virtioblk_pci pci $pci_blk' 'virtioblk_pci' True"
|
||||||
fi
|
fi
|
||||||
pci_scsi=$(lspci -nn -D | grep '1af4:1004' | head -1 | awk '{print $1;}')
|
pci_scsi=$(lspci -nn -D | grep '1af4:1004' | head -1 | awk '{print $1;}')
|
||||||
if [ -n "$pci_scsi" ]; then
|
if [ -n "$pci_scsi" ] && grep -Eq "DRIVER=(uio|vfio)" "/sys/bus/pci/devices/$pci_scsi/uevent"; then
|
||||||
$spdkcli_job "'/bdevs/virtioscsi_disk create virtioscsi_pci pci $pci_scsi' 'virtioscsi_pci' True"
|
$spdkcli_job "'/bdevs/virtioscsi_disk create virtioscsi_pci pci $pci_scsi' 'virtioscsi_pci' True"
|
||||||
fi
|
fi
|
||||||
$spdkcli_job "'/vhost/scsi create sample_scsi' 'sample_scsi' True
|
$spdkcli_job "'/vhost/scsi create sample_scsi' 'sample_scsi' True
|
||||||
@ -63,10 +63,10 @@ $spdkcli_job "'/vhost/block delete sample_block' 'sample_block'
|
|||||||
'/vhost/scsi/sample_scsi remove_target 0' 'Malloc0'
|
'/vhost/scsi/sample_scsi remove_target 0' 'Malloc0'
|
||||||
'/vhost/scsi delete sample_scsi' 'sample_scsi'
|
'/vhost/scsi delete sample_scsi' 'sample_scsi'
|
||||||
"
|
"
|
||||||
if [ -n "$pci_blk" ]; then
|
if [ -n "$pci_blk" ] && grep -Eq "DRIVER=(uio|vfio)" "/sys/bus/pci/devices/$pci_blk/uevent"; then
|
||||||
$spdkcli_job "'/bdevs/virtioblk_disk delete virtioblk_pci' 'virtioblk_pci'"
|
$spdkcli_job "'/bdevs/virtioblk_disk delete virtioblk_pci' 'virtioblk_pci'"
|
||||||
fi
|
fi
|
||||||
if [ -n "$pci_scsi" ]; then
|
if [ -n "$pci_scsi" ] && grep -Eq "DRIVER=(uio|vfio)" "/sys/bus/pci/devices/$pci_scsi/uevent"; then
|
||||||
$spdkcli_job "'/bdevs/virtioscsi_disk delete virtioscsi_pci' 'virtioscsi_pci'"
|
$spdkcli_job "'/bdevs/virtioscsi_disk delete virtioscsi_pci' 'virtioscsi_pci'"
|
||||||
fi
|
fi
|
||||||
$spdkcli_job "'/bdevs/malloc delete Malloc0' 'Malloc0'
|
$spdkcli_job "'/bdevs/malloc delete Malloc0' 'Malloc0'
|
||||||
|
@ -58,6 +58,7 @@ function run_spdk_fio() {
|
|||||||
function create_bdev_config()
|
function create_bdev_config()
|
||||||
{
|
{
|
||||||
local vbdevs
|
local vbdevs
|
||||||
|
local g_opt
|
||||||
|
|
||||||
if [ -z "$($RPC_PY bdev_get_bdevs | jq '.[] | select(.name=="Nvme0n1")')" ]; then
|
if [ -z "$($RPC_PY bdev_get_bdevs | jq '.[] | select(.name=="Nvme0n1")')" ]; then
|
||||||
error "Nvme0n1 bdev not found!"
|
error "Nvme0n1 bdev not found!"
|
||||||
@ -82,7 +83,13 @@ function create_bdev_config()
|
|||||||
$RPC_PY vhost_create_scsi_controller naa.Malloc1.0
|
$RPC_PY vhost_create_scsi_controller naa.Malloc1.0
|
||||||
$RPC_PY vhost_scsi_controller_add_target naa.Malloc1.0 0 Malloc1
|
$RPC_PY vhost_scsi_controller_add_target naa.Malloc1.0 0 Malloc1
|
||||||
|
|
||||||
vbdevs=$(discover_bdevs $rootdir $testdir/bdev.json "--json")
|
# Check default size of host hugepages. If it's 2MB then we have to use
|
||||||
|
# bdev_svc "-g" option for virtio devices.
|
||||||
|
if (( $(grep "Hugepagesize" /proc/meminfo | grep -Eo "[[:digit:]]+") == 2048 )); then
|
||||||
|
g_opt="-g"
|
||||||
|
fi
|
||||||
|
|
||||||
|
vbdevs=$(discover_bdevs $rootdir $testdir/bdev.json "--json" $g_opt)
|
||||||
virtio_bdevs=$(jq -r '[.[].name] | join(":")' <<< $vbdevs)
|
virtio_bdevs=$(jq -r '[.[].name] | join(":")' <<< $vbdevs)
|
||||||
virtio_with_unmap=$(jq -r '[.[] | select(.supported_io_types.unmap==true).name]
|
virtio_with_unmap=$(jq -r '[.[] | select(.supported_io_types.unmap==true).name]
|
||||||
| join(":")' <<< $vbdevs)
|
| join(":")' <<< $vbdevs)
|
||||||
|
Loading…
Reference in New Issue
Block a user