Spdk/test/nvme/fused_ordering/fused_ordering.c
Jim Harris 488570ebd4 Replace most BSD 3-clause license text with SPDX identifier.
Many open source projects have moved to using SPDX identifiers
to specify license information, reducing the amount of
boilerplate code in every source file.  This patch replaces
the bulk of SPDK .c, .cpp and Makefiles with the BSD-3-Clause
identifier.

Almost all of these files share the exact same license text,
and this patch only modifies the files that contain the
most common license text.  There can be slight variations
because the third clause contains company names - most say
"Intel Corporation", but there are instances for Nvidia,
Samsung, Eideticom and even "the copyright holder".

Used a bash script to automate replacement of the license text
with SPDX identifier which is checked into scripts/spdx.sh.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Iaa88ab5e92ea471691dc298cfe41ebfb5d169780
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12904
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Dong Yi <dongx.yi@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: <qun.wan@intel.com>
2022-06-09 07:35:12 +00:00

204 lines
4.9 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) Intel Corporation.
* All rights reserved.
*/
#include "spdk/stdinc.h"
#include "spdk/nvme.h"
#include "spdk/env.h"
#include "spdk/string.h"
#include "spdk/log.h"
static struct spdk_nvme_ctrlr *g_ctrlr;
static struct spdk_nvme_ns *g_ns;
static struct spdk_nvme_qpair *g_qpair;
static struct spdk_nvme_transport_id g_trid = {};
static uint32_t g_outstanding;
static void
io_complete(void *arg, const struct spdk_nvme_cpl *cpl)
{
if (spdk_nvme_cpl_is_error(cpl)) {
spdk_nvme_print_completion(spdk_nvme_qpair_get_id(g_qpair),
(struct spdk_nvme_cpl *)cpl);
exit(1);
}
g_outstanding--;
}
#define WRITE_BLOCKS 128
#define FUSED_BLOCKS 1
static void
fused_ordering(uint32_t poll_count)
{
void *cw_buf, *large_buf;
int rc;
int i;
g_qpair = spdk_nvme_ctrlr_alloc_io_qpair(g_ctrlr, NULL, 0);
if (g_qpair == NULL) {
printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n");
exit(1);
}
cw_buf = spdk_zmalloc(FUSED_BLOCKS * 4096, 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
if (cw_buf == NULL) {
printf("ERROR: buffer allocation failed\n");
return;
}
large_buf = spdk_zmalloc(WRITE_BLOCKS * 4096, 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY,
SPDK_MALLOC_DMA);
if (large_buf == NULL) {
printf("ERROR: buffer allocation failed\n");
return;
}
/* Issue a bunch of relatively large writes - big enough that the data will not fit
* in-capsule - followed by the compare command. Then poll the completion queue a number of
* times matching the poll_count variable. This adds a variable amount of delay between
* the compare and the subsequent fused write submission.
*
* GitHub issue #2428 showed a problem where once the non-in-capsule data had been fetched from
* the host, that request could get sent to the target layer between the two fused commands. This
* variable delay would eventually induce this condition before the fix.
*/
for (i = 0; i < 8; i++) {
rc = spdk_nvme_ns_cmd_write(g_ns, g_qpair, large_buf, 0, WRITE_BLOCKS, io_complete, NULL, 0);
if (rc != 0) {
fprintf(stderr, "starting write I/O failed\n");
exit(1);
}
g_outstanding++;
}
rc = spdk_nvme_ns_cmd_compare(g_ns, g_qpair, cw_buf, 0, FUSED_BLOCKS, io_complete, NULL,
SPDK_NVME_IO_FLAGS_FUSE_FIRST);
if (rc != 0) {
fprintf(stderr, "starting compare I/O failed\n");
exit(1);
}
g_outstanding++;
while (poll_count--) {
spdk_nvme_qpair_process_completions(g_qpair, 0);
}
rc = spdk_nvme_ns_cmd_write(g_ns, g_qpair, cw_buf, 0, FUSED_BLOCKS, io_complete, NULL,
SPDK_NVME_IO_FLAGS_FUSE_SECOND);
if (rc != 0) {
fprintf(stderr, "starting write I/O failed\n");
exit(1);
}
g_outstanding++;
while (g_outstanding) {
spdk_nvme_qpair_process_completions(g_qpair, 0);
}
spdk_nvme_ctrlr_free_io_qpair(g_qpair);
spdk_free(cw_buf);
spdk_free(large_buf);
}
static void
usage(const char *program_name)
{
printf("%s [options]", program_name);
printf("\t\n");
printf("options:\n");
printf("\t[-r remote NVMe over Fabrics target address]\n");
#ifdef DEBUG
printf("\t[-L enable debug logging]\n");
#else
printf("\t[-L enable debug logging (flag disabled, must reconfigure with --enable-debug)\n");
#endif
}
static int
parse_args(int argc, char **argv, struct spdk_env_opts *env_opts)
{
int op, rc;
while ((op = getopt(argc, argv, "r:L:")) != -1) {
switch (op) {
case 'r':
if (spdk_nvme_transport_id_parse(&g_trid, optarg) != 0) {
fprintf(stderr, "Error parsing transport address\n");
return 1;
}
break;
case 'L':
rc = spdk_log_set_flag(optarg);
if (rc < 0) {
fprintf(stderr, "unknown flag\n");
usage(argv[0]);
exit(EXIT_FAILURE);
}
#ifdef DEBUG
spdk_log_set_print_level(SPDK_LOG_DEBUG);
#endif
break;
default:
usage(argv[0]);
return 1;
}
}
return 0;
}
int main(int argc, char **argv)
{
int rc, i;
struct spdk_env_opts opts;
struct spdk_nvme_ctrlr_opts ctrlr_opts;
int nsid;
spdk_env_opts_init(&opts);
spdk_log_set_print_level(SPDK_LOG_NOTICE);
rc = parse_args(argc, argv, &opts);
if (rc != 0) {
return rc;
}
opts.name = "fused_ordering";
if (spdk_env_init(&opts) < 0) {
fprintf(stderr, "Unable to initialize SPDK env\n");
return 1;
}
spdk_nvme_ctrlr_get_default_ctrlr_opts(&ctrlr_opts, sizeof(ctrlr_opts));
ctrlr_opts.keep_alive_timeout_ms = 60 * 1000;
g_ctrlr = spdk_nvme_connect(&g_trid, &ctrlr_opts, sizeof(ctrlr_opts));
if (g_ctrlr == NULL) {
fprintf(stderr, "spdk_nvme_connect() failed\n");
rc = 1;
goto exit;
}
printf("Attached to %s\n", g_trid.subnqn);
nsid = spdk_nvme_ctrlr_get_first_active_ns(g_ctrlr);
if (nsid == 0) {
perror("No active namespaces");
exit(1);
}
g_ns = spdk_nvme_ctrlr_get_ns(g_ctrlr, nsid);
printf(" Namespace ID: %d size: %juGB\n", spdk_nvme_ns_get_id(g_ns),
spdk_nvme_ns_get_size(g_ns) / 1000000000);
for (i = 0; i < 1024; i++) {
printf("fused_ordering(%d)\n", i);
fused_ordering(i);
}
exit:
spdk_nvme_detach(g_ctrlr);
spdk_env_fini();
return rc;
}