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: paul luse <paul.e.luse@intel.com>
Change-Id: I99fc62d6bfd6ec97985a86fc1ae5454a21679684
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11482
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: GangCao <gang.cao@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
paul luse 2022-02-09 14:00:49 -07:00 committed by Jim Harris
parent 37ae5a2fb9
commit 0d5ce8c2cf
2 changed files with 24 additions and 7 deletions

View File

@ -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.
*/

View File

@ -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 {