diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a95b2763..cefff0018 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ of spdk_idxd_probe_cb function pointer. It should be implemented in idxd_user.c. Added API `spdk_idxd_submit_copy_crc32c` to perform a CRC32C while copying data. +Added API `spdk_idxd_batch_prep_copy_crc32c` to prepare a batch operation to perform +a CRC32C while copying data. + ### util `spdk_crc32c_iov_update` function was added to support calculating the crc32c of the diff --git a/include/spdk/idxd.h b/include/spdk/idxd.h index 4a84f6539..44bc92f88 100644 --- a/include/spdk/idxd.h +++ b/include/spdk/idxd.h @@ -374,6 +374,29 @@ int spdk_idxd_submit_crc32c(struct spdk_idxd_io_channel *chan, uint32_t *dst, vo uint32_t seed, uint64_t nbytes, spdk_idxd_req_cb cb_fn, void *cb_arg); +/** + * Synchronous call to prepare a copy combined with crc32c request into a previously + * initialized batch created with spdk_idxd_batch_create(). The callback will be called + * when the copy + crc32c completes after the batch has been submitted by an asynchronous + * call to spdk_idxd_batch_submit(). + * + * \param chan IDXD channel to submit request. + * \param batch Handle provided when the batch was started with spdk_idxd_batch_create(). + * \param dst Destination virtual address. + * \param src Source virtual address. + * \param crc_dst Resulting calculation. + * \param seed Four byte CRC-32C seed value. + * \param nbytes Number of bytes to calculate on. + * \param cb_fn Callback function which will be called when the request is complete. + * \param cb_arg Opaque value which will be passed back as the arg parameter in + * the completion callback. + * + * \return 0 on success, negative errno on failure. + */ +int spdk_idxd_batch_prep_copy_crc32c(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch, + void *dst, void *src, uint32_t *crc_dst, uint32_t seed, uint64_t nbytes, + spdk_idxd_req_cb cb_fn, void *cb_arg); + /** * Build and submit a copy combined with CRC32-C request. * diff --git a/lib/idxd/idxd.c b/lib/idxd/idxd.c index c27091664..d91933558 100644 --- a/lib/idxd/idxd.c +++ b/lib/idxd/idxd.c @@ -1003,6 +1003,44 @@ spdk_idxd_batch_prep_crc32c(struct spdk_idxd_io_channel *chan, struct idxd_batch return 0; } +int +spdk_idxd_batch_prep_copy_crc32c(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch, + void *dst, void *src, uint32_t *crc_dst, uint32_t seed, uint64_t nbytes, + spdk_idxd_req_cb cb_fn, void *cb_arg) +{ + struct idxd_hw_desc *desc; + struct idxd_comp *comp; + uint64_t src_addr, dst_addr; + int rc; + + /* Common prep. */ + rc = _idxd_prep_batch_cmd(chan, cb_fn, cb_arg, batch, &desc, &comp); + if (rc) { + return rc; + } + + rc = _vtophys(src, &src_addr, nbytes); + if (rc) { + return rc; + } + + rc = _vtophys(dst, &dst_addr, nbytes); + if (rc) { + return rc; + } + + /* Command specific. */ + desc->opcode = IDXD_OPCODE_COPY_CRC; + desc->dst_addr = dst_addr; + desc->src_addr = src_addr; + desc->flags &= IDXD_CLEAR_CRC_FLAGS; + desc->crc32c.seed = seed; + desc->xfer_size = nbytes; + comp->crc_dst = crc_dst; + + return 0; +} + int spdk_idxd_batch_prep_compare(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch, void *src1, void *src2, uint64_t nbytes, spdk_idxd_req_cb cb_fn, diff --git a/lib/idxd/spdk_idxd.map b/lib/idxd/spdk_idxd.map index 1f20f8986..92940d218 100644 --- a/lib/idxd/spdk_idxd.map +++ b/lib/idxd/spdk_idxd.map @@ -11,6 +11,7 @@ spdk_idxd_batch_prep_dualcast; spdk_idxd_batch_prep_fill; spdk_idxd_batch_prep_crc32c; + spdk_idxd_batch_prep_copy_crc32c; spdk_idxd_batch_prep_compare; spdk_idxd_batch_submit; spdk_idxd_batch_create;