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