Commit ee8f6dd1 authored by Ziye Yang's avatar Ziye Yang Committed by Tomasz Zawadzki
Browse files

sgl.h: Add a new internal header file.



The purpose is to reduce the duplicated code in nvmf and iscsi
layer.

Change-Id: I7e96f0d5bb1ba4b81378addca3cdd929056384e9
Signed-off-by: default avatarZiye Yang <ziye.yang@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8132


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatar <dongx.yi@intel.com>
parent 6a49507c
Loading
Loading
Loading
Loading
+21 −72
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#include "spdk/sock.h"
#include "spdk/dif.h"

#include "sgl.h"

#define SPDK_CRC32C_XOR				0xffffffffUL
#define SPDK_NVME_TCP_DIGEST_LEN		4
#define SPDK_NVME_TCP_DIGEST_ALIGNMENT		4
@@ -76,13 +78,6 @@

typedef void (*nvme_tcp_qpair_xfer_complete_cb)(void *cb_arg);

struct _nvme_tcp_sgl {
	struct iovec	*iov;
	int		iovcnt;
	uint32_t	iov_offset;
	uint32_t	total_size;
};

struct nvme_tcp_pdu {
	union {
		/* to hold error pdu data */
@@ -125,7 +120,7 @@ struct nvme_tcp_pdu {
	TAILQ_ENTRY(nvme_tcp_pdu)			tailq;
	uint32_t					remaining;
	uint32_t					padding_len;
	struct _nvme_tcp_sgl				sgl;
	struct spdk_iov_sgl				sgl;

	struct spdk_dif_ctx				*dif_ctx;

@@ -248,32 +243,7 @@ nvme_tcp_pdu_calc_data_digest(struct nvme_tcp_pdu *pdu)
}

static inline void
_nvme_tcp_sgl_init(struct _nvme_tcp_sgl *s, struct iovec *iov, int iovcnt,
		   uint32_t iov_offset)
{
	s->iov = iov;
	s->iovcnt = iovcnt;
	s->iov_offset = iov_offset;
	s->total_size = 0;
}

static inline void
_nvme_tcp_sgl_advance(struct _nvme_tcp_sgl *s, uint32_t step)
{
	s->iov_offset += step;
	while (s->iovcnt > 0) {
		if (s->iov_offset < s->iov->iov_len) {
			break;
		}

		s->iov_offset -= s->iov->iov_len;
		s->iov++;
		s->iovcnt--;
	}
}

static inline void
_nvme_tcp_sgl_get_buf(struct _nvme_tcp_sgl *s, void **_buf, uint32_t *_buf_len)
_nvme_tcp_sgl_get_buf(struct spdk_iov_sgl *s, void **_buf, uint32_t *_buf_len)
{
	if (_buf != NULL) {
		*_buf = s->iov->iov_base + s->iov_offset;
@@ -284,33 +254,12 @@ _nvme_tcp_sgl_get_buf(struct _nvme_tcp_sgl *s, void **_buf, uint32_t *_buf_len)
}

static inline bool
_nvme_tcp_sgl_append(struct _nvme_tcp_sgl *s, uint8_t *data, uint32_t data_len)
{
	if (s->iov_offset >= data_len) {
		s->iov_offset -= data_len;
	} else {
		assert(s->iovcnt > 0);
		s->iov->iov_base = data + s->iov_offset;
		s->iov->iov_len = data_len - s->iov_offset;
		s->total_size += data_len - s->iov_offset;
		s->iov_offset = 0;
		s->iov++;
		s->iovcnt--;
		if (s->iovcnt == 0) {
			return false;
		}
	}

	return true;
}

static inline bool
_nvme_tcp_sgl_append_multi(struct _nvme_tcp_sgl *s, struct iovec *iov, int iovcnt)
_nvme_tcp_sgl_append_multi(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt)
{
	int i;

	for (i = 0; i < iovcnt; i++) {
		if (!_nvme_tcp_sgl_append(s, iov[i].iov_base, iov[i].iov_len)) {
		if (!spdk_iov_sgl_append(s, iov[i].iov_base, iov[i].iov_len)) {
			return false;
		}
	}
@@ -332,7 +281,7 @@ _get_iov_array_size(struct iovec *iov, int iovcnt)
}

static inline bool
_nvme_tcp_sgl_append_multi_with_md(struct _nvme_tcp_sgl *s, struct iovec *iov, int iovcnt,
_nvme_tcp_sgl_append_multi_with_md(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt,
				   uint32_t data_len, const struct spdk_dif_ctx *dif_ctx)
{
	int rc;
@@ -368,14 +317,14 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu,
		    bool hdgst_enable, bool ddgst_enable, uint32_t *_mapped_length)
{
	uint32_t hlen, plen;
	struct _nvme_tcp_sgl *sgl;
	struct spdk_iov_sgl *sgl;

	if (iovcnt == 0) {
		return 0;
	}

	sgl = &pdu->sgl;
	_nvme_tcp_sgl_init(sgl, iov, iovcnt, 0);
	spdk_iov_sgl_init(sgl, iov, iovcnt, 0);
	hlen = pdu->hdr.common.hlen;

	/* Header Digest */
@@ -386,7 +335,7 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu,
	plen = hlen;
	if (!pdu->data_len) {
		/* PDU header + possible header digest */
		_nvme_tcp_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen);
		spdk_iov_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen);
		goto end;
	}

@@ -396,7 +345,7 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu,
		plen = hlen;
	}

	if (!_nvme_tcp_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen)) {
	if (!spdk_iov_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen)) {
		goto end;
	}

@@ -416,7 +365,7 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu,
	/* Data Digest */
	if (g_nvme_tcp_ddgst[pdu->hdr.common.pdu_type] && ddgst_enable) {
		plen += SPDK_NVME_TCP_DIGEST_LEN;
		_nvme_tcp_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN);
		spdk_iov_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN);
	}

	assert(plen == pdu->hdr.common.plen);
@@ -433,14 +382,14 @@ static int
nvme_tcp_build_payload_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu,
			    bool ddgst_enable, uint32_t *_mapped_length)
{
	struct _nvme_tcp_sgl *sgl;
	struct spdk_iov_sgl *sgl;

	if (iovcnt == 0) {
		return 0;
	}

	sgl = &pdu->sgl;
	_nvme_tcp_sgl_init(sgl, iov, iovcnt, pdu->rw_offset);
	spdk_iov_sgl_init(sgl, iov, iovcnt, pdu->rw_offset);

	if (spdk_likely(!pdu->dif_ctx)) {
		if (!_nvme_tcp_sgl_append_multi(sgl, pdu->data_iov, pdu->data_iovcnt)) {
@@ -455,7 +404,7 @@ nvme_tcp_build_payload_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *

	/* Data Digest */
	if (ddgst_enable) {
		_nvme_tcp_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN);
		spdk_iov_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN);
	}

end:
@@ -565,7 +514,7 @@ nvme_tcp_pdu_set_data_buf(struct nvme_tcp_pdu *pdu,
{
	uint32_t buf_offset, buf_len, remain_len, len;
	uint8_t *buf;
	struct _nvme_tcp_sgl *pdu_sgl, buf_sgl;
	struct spdk_iov_sgl *pdu_sgl, buf_sgl;

	pdu->data_len = data_len;

@@ -583,20 +532,20 @@ nvme_tcp_pdu_set_data_buf(struct nvme_tcp_pdu *pdu,
	} else {
		pdu_sgl = &pdu->sgl;

		_nvme_tcp_sgl_init(pdu_sgl, pdu->data_iov, NVME_TCP_MAX_SGL_DESCRIPTORS, 0);
		_nvme_tcp_sgl_init(&buf_sgl, iov, iovcnt, 0);
		spdk_iov_sgl_init(pdu_sgl, pdu->data_iov, NVME_TCP_MAX_SGL_DESCRIPTORS, 0);
		spdk_iov_sgl_init(&buf_sgl, iov, iovcnt, 0);

		_nvme_tcp_sgl_advance(&buf_sgl, buf_offset);
		spdk_iov_sgl_advance(&buf_sgl, buf_offset);
		remain_len = buf_len;

		while (remain_len > 0) {
			_nvme_tcp_sgl_get_buf(&buf_sgl, (void *)&buf, &len);
			len = spdk_min(len, remain_len);

			_nvme_tcp_sgl_advance(&buf_sgl, len);
			spdk_iov_sgl_advance(&buf_sgl, len);
			remain_len -= len;

			if (!_nvme_tcp_sgl_append(pdu_sgl, buf, len)) {
			if (!spdk_iov_sgl_append(pdu_sgl, buf, len)) {
				break;
			}
		}
+127 −0
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __SGL_INTERNAL_H__
#define __SGL_INTERNAL_H__

#include "spdk/stdinc.h"

#ifdef __cplusplus
extern "C" {
#endif

struct spdk_iov_sgl {
	struct iovec    *iov;
	int             iovcnt;
	uint32_t        iov_offset;
	uint32_t        total_size;
};

/**
 * Initialize struct spdk_iov_sgl with iov, iovcnt and iov_offset.
 *
 * \param s the spdk_iov_sgl to be filled.
 * \param iov the io vector to fill the s
 * \param iovcnt the size the iov
 * \param iov_offset the current filled iov_offset for s.
 */

static inline void
spdk_iov_sgl_init(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt,
		  uint32_t iov_offset)
{
	s->iov = iov;
	s->iovcnt = iovcnt;
	s->iov_offset = iov_offset;
	s->total_size = 0;
}

/**
 * Consume the iovs in spdk_iov_sgl with passed bytes
 *
 * \param s the spdk_iov_sgl which contains the iov
 * \param step the bytes_size consumed.
 */

static inline void
spdk_iov_sgl_advance(struct spdk_iov_sgl *s, uint32_t step)
{
	s->iov_offset += step;
	while (s->iovcnt > 0) {
		assert(s->iov != NULL);
		if (s->iov_offset < s->iov->iov_len) {
			break;
		}

		s->iov_offset -= s->iov->iov_len;
		s->iov++;
		s->iovcnt--;
	}
}

/**
 * Append the data to the struct spdk_iov_sgl pointed by s
 *
 * \param s the address of the struct spdk_iov_sgl
 * \param data the data buffer to be appended
 * \param data_len the length of the data.
 *
 * \return true if all the data is appended.
 */

static inline bool
spdk_iov_sgl_append(struct spdk_iov_sgl *s, uint8_t *data, uint32_t data_len)
{
	if (s->iov_offset >= data_len) {
		s->iov_offset -= data_len;
	} else {
		assert(s->iovcnt > 0);
		s->iov->iov_base = data + s->iov_offset;
		s->iov->iov_len = data_len - s->iov_offset;
		s->total_size += data_len - s->iov_offset;
		s->iov_offset = 0;
		s->iov++;
		s->iovcnt--;
		if (s->iovcnt == 0) {
			return false;
		}
	}

	return true;
}

#ifdef __cplusplus
}
#endif

#endif /* __SGL_INTERNAL_H__ */
+10 −46
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@

#include "spdk/log.h"

#include "spdk_internal/sgl.h"

#define MAX_TMPBUF 1024

#ifdef __FreeBSD__
@@ -387,49 +389,11 @@ iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn,
	}
}

struct _iscsi_sgl {
	struct iovec	*iov;
	int		iovcnt;
	uint32_t	iov_offset;
	uint32_t	total_size;
};

static inline void
_iscsi_sgl_init(struct _iscsi_sgl *s, struct iovec *iovs, int iovcnt,
		uint32_t iov_offset)
{
	s->iov = iovs;
	s->iovcnt = iovcnt;
	s->iov_offset = iov_offset;
	s->total_size = 0;
}

static inline bool
_iscsi_sgl_append(struct _iscsi_sgl *s, uint8_t *data, uint32_t data_len)
{
	if (s->iov_offset >= data_len) {
		s->iov_offset -= data_len;
	} else {
		assert(s->iovcnt > 0);
		s->iov->iov_base = data + s->iov_offset;
		s->iov->iov_len = data_len - s->iov_offset;
		s->total_size += data_len - s->iov_offset;
		s->iov_offset = 0;
		s->iov++;
		s->iovcnt--;
		if (s->iovcnt == 0) {
			return false;
		}
	}

	return true;
}

/* Build iovec array to leave metadata space for every data block
 * when reading data segment from socket.
 */
static inline bool
_iscsi_sgl_append_with_md(struct _iscsi_sgl *s,
_iscsi_sgl_append_with_md(struct spdk_iov_sgl *s,
			  void *buf, uint32_t buf_len, uint32_t data_len,
			  struct spdk_dif_ctx *dif_ctx)
{
@@ -468,7 +432,7 @@ int
iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt,
		 struct spdk_iscsi_pdu *pdu, uint32_t *_mapped_length)
{
	struct _iscsi_sgl sgl;
	struct spdk_iov_sgl sgl;
	int enable_digest;
	uint32_t total_ahs_len;
	uint32_t data_len;
@@ -487,22 +451,22 @@ iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt,
		enable_digest = 0;
	}

	_iscsi_sgl_init(&sgl, iovs, iovcnt, pdu->writev_offset);
	spdk_iov_sgl_init(&sgl, iovs, iovcnt, pdu->writev_offset);

	/* BHS */
	if (!_iscsi_sgl_append(&sgl, (uint8_t *)&pdu->bhs, ISCSI_BHS_LEN)) {
	if (!spdk_iov_sgl_append(&sgl, (uint8_t *)&pdu->bhs, ISCSI_BHS_LEN)) {
		goto end;
	}
	/* AHS */
	if (total_ahs_len > 0) {
		if (!_iscsi_sgl_append(&sgl, pdu->ahs, 4 * total_ahs_len)) {
		if (!spdk_iov_sgl_append(&sgl, pdu->ahs, 4 * total_ahs_len)) {
			goto end;
		}
	}

	/* Header Digest */
	if (enable_digest && conn->header_digest) {
		if (!_iscsi_sgl_append(&sgl, pdu->header_digest, ISCSI_DIGEST_LEN)) {
		if (!spdk_iov_sgl_append(&sgl, pdu->header_digest, ISCSI_DIGEST_LEN)) {
			goto end;
		}
	}
@@ -510,7 +474,7 @@ iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt,
	/* Data Segment */
	if (data_len > 0) {
		if (!pdu->dif_insert_or_strip) {
			if (!_iscsi_sgl_append(&sgl, pdu->data, data_len)) {
			if (!spdk_iov_sgl_append(&sgl, pdu->data, data_len)) {
				goto end;
			}
		} else {
@@ -523,7 +487,7 @@ iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt,

	/* Data Digest */
	if (enable_digest && conn->data_digest && data_len != 0) {
		_iscsi_sgl_append(&sgl, pdu->data_digest, ISCSI_DIGEST_LEN);
		spdk_iov_sgl_append(&sgl, pdu->data_digest, ISCSI_DIGEST_LEN);
	}

end: