File: iser-private.h

package info (click to toggle)
libiscsi 1.20.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,080 kB
  • sloc: ansic: 40,928; xml: 749; sh: 689; makefile: 352
file content (207 lines) | stat: -rw-r--r-- 5,955 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
   Copyright (c) 2014-2016, Mellanox Technologies, Ltd.  All rights reserved.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __iser_private_h__
#define __iser_private_h__

#include <stdint.h>
#include <stddef.h>
#include <time.h>

#include "iscsi-private.h"
#include "scsi-lowlevel.h"
#include <strings.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>

#ifdef __linux

#include <infiniband/verbs.h>
#include <rdma/rdma_cma.h>
#include <rdma/rdma_verbs.h>

#define unlikely(x)  __builtin_expect (!!(x), 0)

#define ISER_VER                        0x10
#define ISER_WSV                        0x08
#define ISER_RSV                        0x04

#define DATA_BUFFER_UNIT_SHIFT        SHIFT_4K
#define DATA_BUFFER_UNIT_SIZE         SIZE_4K
#define DATA_BUFFER_CHUNK_SHIFT       22
#define DATA_BUFFER_CHUNK_SIZE        (1ULL << DATA_BUFFER_CHUNK_SHIFT)
#define DATA_BUFFER_CHUNK_UNITS_SHIFT (DATA_BUFFER_CHUNK_SHIFT - DATA_BUFFER_UNIT_SHIFT)
#define DATA_BUFFER_CHUNK_UNITS       (1 << DATA_BUFFER_CHUNK_UNITS_SHIFT)

#define ISER_HEADERS_LEN  (sizeof(struct iser_hdr) + ISCSI_RAW_HEADER_SIZE)

#define ISER_RECV_DATA_SEG_LEN  128
#define ISER_RX_PAYLOAD_SIZE    (ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)

#define ISER_RX_LOGIN_SIZE      (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)

#define ISCSI_DEF_MAX_RECV_SEG_LEN 8192

#define	BHSSC_FLAGS_R		0x40
#define	BHSSC_FLAGS_W		0x20

#define ISER_MAX_CQ_LEN 1024

#define ISER_ZBVA_NOT_SUPPORTED         0x80
#define ISER_SEND_W_INV_NOT_SUPPORTED   0x40

enum desc_type {
	ISCSI_CONTROL = 0,
	ISCSI_COMMAND};

enum data_dir{
	DATA_WRITE = 0,
	DATA_READ,
	DATA_NONE};

#define SHIFT_4K	12
#define SIZE_4K	(1ULL << SHIFT_4K)
#define MASK_4K	(~(SIZE_4K-1))

#define ISER_DEF_XMIT_CMDS_MAX  512
#define ISER_QP_MAX_RECV_DTOS  (ISER_DEF_XMIT_CMDS_MAX)
#define ISER_MIN_POSTED_RX     (ISER_DEF_XMIT_CMDS_MAX >> 2)


/**
 * struct iser_hdr - iSER header
 *
 * @flags:        flags support (zbva, remote_inv)
 * @rsvd:         reserved
 * @write_stag:   write rkey
 * @write_va:     write virtual address
 * @reaf_stag:    read rkey
 * @read_va:      read virtual address
 */

struct iser_hdr {
	uint8_t    flags;
	uint8_t    rsvd[3];
	uint32_t   write_stag;
	uint64_t   write_va;
	uint32_t   read_stag;
	uint64_t   read_va;
} __attribute__((packed));

/**
 * struct iser_rx_desc - iSER RX descriptor (for recv wr_id)
 *
 * @isr_hdr:       iser header
 * @iscsi_data:    iscsi header
 * @data:          received data segment
 * @rx_sg:         ibv_sge of receive buffer
 * @pad:           padding
 */


struct iser_rx_desc {
	struct iser_hdr              iser_header;
	char                         iscsi_header[ISCSI_RAW_HEADER_SIZE];
	char                         data[ISER_RECV_DATA_SEG_LEN];
	char                         pad[4];
	struct ibv_mr               *hdr_mr;
	struct ibv_sge               rx_sg;
};

static_assert(offsetof(struct iser_rx_desc, hdr_mr) % 8 == 0, "iser_rx_desc is not aligned on 8-byte boundary");

/**
 * struct iser_tx_desc - iSER TX descriptor (for send wr_id)
 *
 * @iser_hdr:      iser header
 * @iscsi_header:  iscsi header (bhs)
 * @tx_sg:         sg[0] points to iser/iscsi headers
 *                 sg[1] optionally points to either of immediate data
 *                 unsolicited data-out or control
 * @num_sge:       number sges used on this TX task
 * @mr:            iser/iscsi headers mr
 * @data_mr:       mr for case we need to allocate mr for read
 * @next:          next descriptor on the list
 */

struct iser_tx_desc {
	struct iser_hdr              iser_header;
	unsigned char                iscsi_header[ISCSI_RAW_HEADER_SIZE];
	struct ibv_sge               tx_sg[2];
	int                          num_sge;
	struct ibv_mr                *hdr_mr;
	char			     *data_buff;
	struct ibv_mr                *data_mr;
	enum desc_type		     type;
	enum data_dir                data_dir;
	struct iser_tx_desc          *next;
};

struct iser_cm_hdr {
	uint8_t      flags;
	uint8_t      rsvd[3];
};

struct iser_pdu {
	struct iscsi_pdu              iscsi_pdu;
	struct iser_tx_desc           *desc;
};

struct iser_buf_chunk {
    unsigned char *buf;
    struct ibv_mr *mr;
    struct iser_buf_chunk *next;
    int8_t tree[DATA_BUFFER_CHUNK_UNITS << 1];
};

struct iser_conn {
	struct rdma_cm_id            *cma_id;
	struct rdma_event_channel    *cma_channel;

	struct ibv_pd                *pd;
	struct ibv_cq                *cq;
	struct ibv_qp                *qp;
	struct ibv_comp_channel      *comp_channel;

	int                          rdma_connect_sent;

	struct ibv_recv_wr           rx_wr[ISER_MIN_POSTED_RX];

	struct ibv_mr                *login_resp_mr;
	unsigned char                *login_resp_buf;

	struct iser_rx_desc          *rx_descs;
	uint32_t                     num_rx_descs;
	unsigned int                 rx_desc_head;

	unsigned int                 cq_nevents;
	int                          post_recv_buf_count;
	int                          qp_max_recv_dtos;
	int                          min_posted_rx;
	uint16_t                     max_cmds;

	struct iser_tx_desc          *tx_desc;
	struct iser_buf_chunk        *buf_chunk;
};

void iscsi_init_iser_transport(struct iscsi_context *iscsi);

#endif /* __linux */

#endif   /* __iser_private_h__ */