1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 #ifndef _KRRP_PDU_H
17 #define _KRRP_PDU_H
18
19 #include <sys/types.h>
20 #include <sys/ddi.h>
21 #include <sys/sunddi.h>
22 #include <sys/time.h>
23 #include <sys/sysmacros.h>
24 #include <sys/kmem.h>
25 #include <sys/modctl.h>
26 #include <sys/class.h>
27 #include <sys/cmn_err.h>
28
29 #include "krrp_dblk.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #define KRRP_PDU_DEFAULT_SIZE 512 * 1024
36 #define KRRP_DBLKS_PER_PDU_DEFAULT 100
37 #define KRRP_MAX_MEMORY_FOR_PDU_DEFAULT 1024
38
39 #define KRRP_PDU_WITH_HDR B_TRUE
40 #define KRRP_PDU_WITHOUT_HDR B_FALSE
41
42 /* Flags for data-pdu: first byte */
43 #define KRRP_HDR_FLAG_INIT_PDU 0x0001
44 #define KRRP_HDR_FLAG_FINI_PDU 0x0002
45
46 /* Flags for ctrl-pdu: second byte */
47 #define KRRP_HDR_FLAG_SHUTDOWN_GRACEFULLY 0x0100
48
49 #define krrp_pdu_opcode(a) (a)->hdr->opcode
50 #define krrp_pdu_type(a) (a)->type
51
52 #define krrp_pdu_hdr(a) (a)->hdr
53
54 typedef void (krrp_pdu_free_notify_cb_t)(void *, size_t);
55
56 typedef enum {
57 KRRP_PET_DATA,
58 KRRP_PET_CTRL
59 } krrp_pdu_engine_type_t;
60
61 typedef enum {
62 KRRP_PT_DATA,
63 KRRP_PT_CTRL,
64 } krrp_pdu_type_t;
65
66 typedef struct krrp_pdu_engine_s {
67 krrp_pdu_engine_type_t type;
68
69 kmutex_t mtx;
70 kcondvar_t cv;
71
72 struct {
73 krrp_pdu_free_notify_cb_t *cb;
74 void *cb_arg;
75 size_t init_value;
76 size_t cnt;
77 } notify_free;
78
79 size_t cur_pdu_cnt;
80 size_t max_pdu_cnt;
81
82 krrp_dblk_engine_t *dblk_engine;
83 size_t dblks_per_pdu;
84 size_t pdu_data_sz;
85 } krrp_pdu_engine_t;
86
87 typedef struct krrp_hdr_s {
88 uint16_t opcode;
89 uint16_t flags;
90 uint32_t payload_sz;
91 uint8_t reserved[36];
92 uint32_t hdr_chksum;
93 } krrp_hdr_t;
94
95 typedef struct krrp_hdr_data_s {
96 uint16_t opcode;
97 uint16_t flags;
98 uint32_t payload_sz;
99 uint64_t pdu_seq_num;
100 uint64_t txg;
101 uint8_t reserved[20];
102 uint32_t hdr_chksum;
103 } krrp_hdr_data_t;
104
105 typedef struct krrp_hdr_ctrl_s {
106 uint16_t opcode;
107 uint16_t flags;
108 uint32_t payload_sz;
109 uint8_t data[36];
110 uint32_t hdr_chksum;
111 } krrp_hdr_ctrl_t;
112
113 typedef struct krrp_pdu_s {
114 list_node_t node;
115
116 krrp_pdu_type_t type;
117
118 krrp_hdr_t *hdr;
119 krrp_dblk_t *dblk;
120
121 size_t max_data_sz;
122 size_t cur_data_sz;
123 } krrp_pdu_t;
124
125 typedef struct krrp_pdu_data_s {
126 list_node_t node;
127
128 krrp_pdu_type_t type;
129
130 krrp_hdr_data_t *hdr;
131 krrp_dblk_t *dblk;
132
133 size_t max_data_sz;
134 size_t cur_data_sz;
135
136 uint64_t txg;
137 hrtime_t tx_start_ts;
138 boolean_t initial;
139 boolean_t final;
140 } krrp_pdu_data_t;
141
142 typedef struct krrp_pdu_ctrl_s {
143 list_node_t node;
144
145 krrp_pdu_type_t type;
146
147 krrp_hdr_ctrl_t *hdr;
148 krrp_dblk_t *dblk;
149
150 size_t max_data_sz;
151 size_t cur_data_sz;
152 } krrp_pdu_ctrl_t;
153
154 int krrp_pdu_engine_global_init();
155 void krrp_pdu_engine_global_fini();
156
157 void krrp_pdu_ctrl_alloc(krrp_pdu_ctrl_t **result_pdu,
158 boolean_t with_header);
159
160 int krrp_pdu_engine_create(krrp_pdu_engine_t **result_engine, boolean_t ctrl,
161 boolean_t prealloc, size_t max_memory, size_t dblks_per_pdu,
162 size_t dblk_head_sz, size_t dblk_data_sz, krrp_error_t *error);
163 void krrp_pdu_engine_destroy(krrp_pdu_engine_t *engine);
164
165 void krrp_pdu_engine_register_callback(krrp_pdu_engine_t *engine,
166 krrp_pdu_free_notify_cb_t *notify_cb, void *notify_cb_arg);
167 void krrp_pdu_engine_force_notify(krrp_pdu_engine_t *engine,
168 boolean_t initial);
169
170 size_t krrp_pdu_engine_get_used_mem(krrp_pdu_engine_t *pdu_engine);
171 size_t krrp_pdu_engine_get_free_mem(krrp_pdu_engine_t *pdu_engine);
172
173 void krrp_pdu_alloc(krrp_pdu_engine_t *, krrp_pdu_t **, boolean_t);
174 void krrp_pdu_rele(krrp_pdu_t *);
175
176 int krrp_pdu_get_payload(krrp_pdu_ctrl_t *pdu, void **res_data,
177 size_t *res_data_sz);
178 int krrp_pdu_get_nvl_from_payload(krrp_pdu_ctrl_t *pdu, nvlist_t **res_nvl);
179
180 #ifdef __cplusplus
181 }
182 #endif
183
184 #endif /* _KRRP_PDU_H */