Commit 0d5ce8c2 authored by paul luse's avatar paul luse Committed by Jim Harris
Browse files

idxd: introduce new IDXD flag for cache control



A new public flag, SPDK_IDXD_FLAG_NONTEMPORAL, is introduced
that hints to DSA that it should bypass CPU cache. An example
use case of this would be where the target is PMEM. This flag
is not set by the low level library (so default is that CPU
cache is the target).

Signed-off-by: default avatarpaul luse <paul.e.luse@intel.com>
Change-Id: I99fc62d6bfd6ec97985a86fc1ae5454a21679684
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11482


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 37ae5a2f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#define SPDK_IDXD_H

#include "spdk/stdinc.h"
#include "spdk/idxd_spec.h"

#ifdef __cplusplus
extern "C" {
@@ -46,6 +47,22 @@ extern "C" {

#include "spdk/env.h"

/* The following flags control the behavior of I/O operations to IDXD. These flags
 * are often mapped to DSA specification values to ensure they have a unique value,
 * but do not necessarily correspond 1:1 with the hardware-defined flags.
 */

/* This flag indicates that IDXD should bypass the CPU cache for write operations,
 * landing the output directly into main memory. This is considered a hint, rather
 * than a guarantee.
 *
 * Note: While the value here is defined to be IDXD_FLAG_CACHE_CONTROL, this is only
 * to ensure that the flag has a unique value. The meaning here is the reverse of
 * IDXD_FLAG_CACHE_CONTROL - i.e. not specifying a flag writes data into CPU cache
 * because writing to cache is a more sensible default behavior.
 */
#define SPDK_IDXD_FLAG_NONTEMPORAL IDXD_FLAG_CACHE_CONTROL

/**
 * Opaque handle for a single IDXD channel.
 */
+7 −7
Original line number Diff line number Diff line
@@ -641,7 +641,7 @@ _idxd_submit_copy_single(struct spdk_idxd_io_channel *chan, void *dst, const voi
	desc->src_addr = src_addr;
	desc->dst_addr = dst_addr;
	desc->xfer_size = nbytes;
	desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
	desc->flags ^= IDXD_FLAG_CACHE_CONTROL;

	return _idxd_flush_batch(chan);

@@ -719,7 +719,7 @@ spdk_idxd_submit_copy(struct spdk_idxd_io_channel *chan,
		desc->src_addr = src_addr;
		desc->dst_addr = dst_addr;
		desc->xfer_size = len;
		desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
		desc->flags ^= IDXD_FLAG_CACHE_CONTROL;
	}

	rc = idxd_batch_submit(chan, batch, cb_fn, cb_arg);
@@ -782,7 +782,7 @@ spdk_idxd_submit_dualcast(struct spdk_idxd_io_channel *chan, void *dst1, void *d
	desc->dst_addr = dst1_addr;
	desc->dest2 = dst2_addr;
	desc->xfer_size = nbytes;
	desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
	desc->flags ^= IDXD_FLAG_CACHE_CONTROL;

	/* Submit operation. */
	_submit_to_hw(chan, op);
@@ -951,7 +951,7 @@ _idxd_submit_fill_single(struct spdk_idxd_io_channel *chan, void *dst, uint64_t
	desc->pattern = fill_pattern;
	desc->dst_addr = dst_addr;
	desc->xfer_size = nbytes;
	desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
	desc->flags ^= IDXD_FLAG_CACHE_CONTROL;

	return _idxd_flush_batch(chan);

@@ -1011,7 +1011,7 @@ spdk_idxd_submit_fill(struct spdk_idxd_io_channel *chan,
		desc->pattern = fill_pattern;
		desc->dst_addr = dst_addr;
		desc->xfer_size = diov[i].iov_len;
		desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
		desc->flags ^= IDXD_FLAG_CACHE_CONTROL;
	}

	rc = idxd_batch_submit(chan, batch, cb_fn, cb_arg);
@@ -1190,7 +1190,7 @@ _idxd_submit_copy_crc32c_single(struct spdk_idxd_io_channel *chan, void *dst, vo
	desc->opcode = IDXD_OPCODE_COPY_CRC;
	desc->dst_addr = dst_addr;
	desc->src_addr = src_addr;
	desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
	desc->flags ^= IDXD_FLAG_CACHE_CONTROL;
	desc->flags &= IDXD_CLEAR_CRC_FLAGS;
	desc->crc32c.seed = seed;
	desc->xfer_size = nbytes;
@@ -1269,7 +1269,7 @@ spdk_idxd_submit_copy_crc32c(struct spdk_idxd_io_channel *chan,
		desc->opcode = IDXD_OPCODE_COPY_CRC;
		desc->dst_addr = dst_addr;
		desc->src_addr = src_addr;
		desc->flags |= IDXD_FLAG_CACHE_CONTROL; /* direct IO to CPU cache instead of mem */
		desc->flags ^= IDXD_FLAG_CACHE_CONTROL;
		if (prev_crc == NULL) {
			desc->crc32c.seed = seed;
		} else {