linux/net/smc/smc.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
   4 *
   5 *  Definitions for the SMC module (socket related)
   6 *
   7 *  Copyright IBM Corp. 2016
   8 *
   9 *  Author(s):  Ursula Braun <ubraun@linux.vnet.ibm.com>
  10 */
  11#ifndef __SMC_H
  12#define __SMC_H
  13
  14#include <linux/socket.h>
  15#include <linux/types.h>
  16#include <linux/compiler.h> /* __aligned */
  17#include <net/sock.h>
  18
  19#include "smc_ib.h"
  20
  21#define SMC_V1          1               /* SMC version V1 */
  22#define SMC_V2          2               /* SMC version V2 */
  23#define SMC_RELEASE     0
  24
  25#define SMCPROTO_SMC            0       /* SMC protocol, IPv4 */
  26#define SMCPROTO_SMC6           1       /* SMC protocol, IPv6 */
  27
  28#define SMC_MAX_ISM_DEVS        8       /* max # of proposed non-native ISM
  29                                         * devices
  30                                         */
  31
  32#define SMC_MAX_HOSTNAME_LEN    32
  33#define SMC_MAX_EID_LEN         32
  34
  35extern struct proto smc_proto;
  36extern struct proto smc_proto6;
  37
  38#ifdef ATOMIC64_INIT
  39#define KERNEL_HAS_ATOMIC64
  40#endif
  41
  42enum smc_state {                /* possible states of an SMC socket */
  43        SMC_ACTIVE      = 1,
  44        SMC_INIT        = 2,
  45        SMC_CLOSED      = 7,
  46        SMC_LISTEN      = 10,
  47        /* normal close */
  48        SMC_PEERCLOSEWAIT1      = 20,
  49        SMC_PEERCLOSEWAIT2      = 21,
  50        SMC_APPFINCLOSEWAIT     = 24,
  51        SMC_APPCLOSEWAIT1       = 22,
  52        SMC_APPCLOSEWAIT2       = 23,
  53        SMC_PEERFINCLOSEWAIT    = 25,
  54        /* abnormal close */
  55        SMC_PEERABORTWAIT       = 26,
  56        SMC_PROCESSABORT        = 27,
  57};
  58
  59struct smc_link_group;
  60
  61struct smc_wr_rx_hdr {  /* common prefix part of LLC and CDC to demultiplex */
  62        u8                      type;
  63} __aligned(1);
  64
  65struct smc_cdc_conn_state_flags {
  66#if defined(__BIG_ENDIAN_BITFIELD)
  67        u8      peer_done_writing : 1;  /* Sending done indicator */
  68        u8      peer_conn_closed : 1;   /* Peer connection closed indicator */
  69        u8      peer_conn_abort : 1;    /* Abnormal close indicator */
  70        u8      reserved : 5;
  71#elif defined(__LITTLE_ENDIAN_BITFIELD)
  72        u8      reserved : 5;
  73        u8      peer_conn_abort : 1;
  74        u8      peer_conn_closed : 1;
  75        u8      peer_done_writing : 1;
  76#endif
  77};
  78
  79struct smc_cdc_producer_flags {
  80#if defined(__BIG_ENDIAN_BITFIELD)
  81        u8      write_blocked : 1;      /* Writing Blocked, no rx buf space */
  82        u8      urg_data_pending : 1;   /* Urgent Data Pending */
  83        u8      urg_data_present : 1;   /* Urgent Data Present */
  84        u8      cons_curs_upd_req : 1;  /* cursor update requested */
  85        u8      failover_validation : 1;/* message replay due to failover */
  86        u8      reserved : 3;
  87#elif defined(__LITTLE_ENDIAN_BITFIELD)
  88        u8      reserved : 3;
  89        u8      failover_validation : 1;
  90        u8      cons_curs_upd_req : 1;
  91        u8      urg_data_present : 1;
  92        u8      urg_data_pending : 1;
  93        u8      write_blocked : 1;
  94#endif
  95};
  96
  97/* in host byte order */
  98union smc_host_cursor { /* SMC cursor - an offset in an RMBE */
  99        struct {
 100                u16     reserved;
 101                u16     wrap;           /* window wrap sequence number */
 102                u32     count;          /* cursor (= offset) part */
 103        };
 104#ifdef KERNEL_HAS_ATOMIC64
 105        atomic64_t              acurs;  /* for atomic processing */
 106#else
 107        u64                     acurs;  /* for atomic processing */
 108#endif
 109} __aligned(8);
 110
 111/* in host byte order, except for flag bitfields in network byte order */
 112struct smc_host_cdc_msg {               /* Connection Data Control message */
 113        struct smc_wr_rx_hdr            common; /* .type = 0xFE */
 114        u8                              len;    /* length = 44 */
 115        u16                             seqno;  /* connection seq # */
 116        u32                             token;  /* alert_token */
 117        union smc_host_cursor           prod;           /* producer cursor */
 118        union smc_host_cursor           cons;           /* consumer cursor,
 119                                                         * piggy backed "ack"
 120                                                         */
 121        struct smc_cdc_producer_flags   prod_flags;     /* conn. tx/rx status */
 122        struct smc_cdc_conn_state_flags conn_state_flags; /* peer conn. status*/
 123        u8                              reserved[18];
 124} __aligned(8);
 125
 126enum smc_urg_state {
 127        SMC_URG_VALID   = 1,                    /* data present */
 128        SMC_URG_NOTYET  = 2,                    /* data pending */
 129        SMC_URG_READ    = 3,                    /* data was already read */
 130};
 131
 132struct smc_connection {
 133        struct rb_node          alert_node;
 134        struct smc_link_group   *lgr;           /* link group of connection */
 135        struct smc_link         *lnk;           /* assigned SMC-R link */
 136        u32                     alert_token_local; /* unique conn. id */
 137        u8                      peer_rmbe_idx;  /* from tcp handshake */
 138        int                     peer_rmbe_size; /* size of peer rx buffer */
 139        atomic_t                peer_rmbe_space;/* remaining free bytes in peer
 140                                                 * rmbe
 141                                                 */
 142        int                     rtoken_idx;     /* idx to peer RMB rkey/addr */
 143
 144        struct smc_buf_desc     *sndbuf_desc;   /* send buffer descriptor */
 145        struct smc_buf_desc     *rmb_desc;      /* RMBE descriptor */
 146        int                     rmbe_size_short;/* compressed notation */
 147        int                     rmbe_update_limit;
 148                                                /* lower limit for consumer
 149                                                 * cursor update
 150                                                 */
 151
 152        struct smc_host_cdc_msg local_tx_ctrl;  /* host byte order staging
 153                                                 * buffer for CDC msg send
 154                                                 * .prod cf. TCP snd_nxt
 155                                                 * .cons cf. TCP sends ack
 156                                                 */
 157        union smc_host_cursor   local_tx_ctrl_fin;
 158                                                /* prod crsr - confirmed by peer
 159                                                 */
 160        union smc_host_cursor   tx_curs_prep;   /* tx - prepared data
 161                                                 * snd_max..wmem_alloc
 162                                                 */
 163        union smc_host_cursor   tx_curs_sent;   /* tx - sent data
 164                                                 * snd_nxt ?
 165                                                 */
 166        union smc_host_cursor   tx_curs_fin;    /* tx - confirmed by peer
 167                                                 * snd-wnd-begin ?
 168                                                 */
 169        atomic_t                sndbuf_space;   /* remaining space in sndbuf */
 170        u16                     tx_cdc_seq;     /* sequence # for CDC send */
 171        u16                     tx_cdc_seq_fin; /* sequence # - tx completed */
 172        spinlock_t              send_lock;      /* protect wr_sends */
 173        struct delayed_work     tx_work;        /* retry of smc_cdc_msg_send */
 174        u32                     tx_off;         /* base offset in peer rmb */
 175
 176        struct smc_host_cdc_msg local_rx_ctrl;  /* filled during event_handl.
 177                                                 * .prod cf. TCP rcv_nxt
 178                                                 * .cons cf. TCP snd_una
 179                                                 */
 180        union smc_host_cursor   rx_curs_confirmed; /* confirmed to peer
 181                                                    * source of snd_una ?
 182                                                    */
 183        union smc_host_cursor   urg_curs;       /* points at urgent byte */
 184        enum smc_urg_state      urg_state;
 185        bool                    urg_tx_pend;    /* urgent data staged */
 186        bool                    urg_rx_skip_pend;
 187                                                /* indicate urgent oob data
 188                                                 * read, but previous regular
 189                                                 * data still pending
 190                                                 */
 191        char                    urg_rx_byte;    /* urgent byte */
 192        atomic_t                bytes_to_rcv;   /* arrived data,
 193                                                 * not yet received
 194                                                 */
 195        atomic_t                splice_pending; /* number of spliced bytes
 196                                                 * pending processing
 197                                                 */
 198#ifndef KERNEL_HAS_ATOMIC64
 199        spinlock_t              acurs_lock;     /* protect cursors */
 200#endif
 201        struct work_struct      close_work;     /* peer sent some closing */
 202        struct work_struct      abort_work;     /* abort the connection */
 203        struct tasklet_struct   rx_tsklet;      /* Receiver tasklet for SMC-D */
 204        u8                      rx_off;         /* receive offset:
 205                                                 * 0 for SMC-R, 32 for SMC-D
 206                                                 */
 207        u64                     peer_token;     /* SMC-D token of peer */
 208        u8                      killed : 1;     /* abnormal termination */
 209        u8                      out_of_sync : 1; /* out of sync with peer */
 210};
 211
 212struct smc_sock {                               /* smc sock container */
 213        struct sock             sk;
 214        struct socket           *clcsock;       /* internal tcp socket */
 215        void                    (*clcsk_data_ready)(struct sock *sk);
 216                                                /* original data_ready fct. **/
 217        struct smc_connection   conn;           /* smc connection */
 218        struct smc_sock         *listen_smc;    /* listen parent */
 219        struct work_struct      connect_work;   /* handle non-blocking connect*/
 220        struct work_struct      tcp_listen_work;/* handle tcp socket accepts */
 221        struct work_struct      smc_listen_work;/* prepare new accept socket */
 222        struct list_head        accept_q;       /* sockets to be accepted */
 223        spinlock_t              accept_q_lock;  /* protects accept_q */
 224        bool                    use_fallback;   /* fallback to tcp */
 225        int                     fallback_rsn;   /* reason for fallback */
 226        u32                     peer_diagnosis; /* decline reason from peer */
 227        int                     sockopt_defer_accept;
 228                                                /* sockopt TCP_DEFER_ACCEPT
 229                                                 * value
 230                                                 */
 231        u8                      wait_close_tx_prepared : 1;
 232                                                /* shutdown wr or close
 233                                                 * started, waiting for unsent
 234                                                 * data to be sent
 235                                                 */
 236        u8                      connect_nonblock : 1;
 237                                                /* non-blocking connect in
 238                                                 * flight
 239                                                 */
 240        struct mutex            clcsock_release_lock;
 241                                                /* protects clcsock of a listen
 242                                                 * socket
 243                                                 * */
 244};
 245
 246static inline struct smc_sock *smc_sk(const struct sock *sk)
 247{
 248        return (struct smc_sock *)sk;
 249}
 250
 251extern struct workqueue_struct  *smc_hs_wq;     /* wq for handshake work */
 252extern struct workqueue_struct  *smc_close_wq;  /* wq for close work */
 253
 254#define SMC_SYSTEMID_LEN                8
 255
 256extern u8       local_systemid[SMC_SYSTEMID_LEN]; /* unique system identifier */
 257
 258#define ntohll(x) be64_to_cpu(x)
 259#define htonll(x) cpu_to_be64(x)
 260
 261/* convert an u32 value into network byte order, store it into a 3 byte field */
 262static inline void hton24(u8 *net, u32 host)
 263{
 264        __be32 t;
 265
 266        t = cpu_to_be32(host);
 267        memcpy(net, ((u8 *)&t) + 1, 3);
 268}
 269
 270/* convert a received 3 byte field into host byte order*/
 271static inline u32 ntoh24(u8 *net)
 272{
 273        __be32 t = 0;
 274
 275        memcpy(((u8 *)&t) + 1, net, 3);
 276        return be32_to_cpu(t);
 277}
 278
 279#ifdef CONFIG_XFRM
 280static inline bool using_ipsec(struct smc_sock *smc)
 281{
 282        return (smc->clcsock->sk->sk_policy[0] ||
 283                smc->clcsock->sk->sk_policy[1]) ? true : false;
 284}
 285#else
 286static inline bool using_ipsec(struct smc_sock *smc)
 287{
 288        return false;
 289}
 290#endif
 291
 292struct sock *smc_accept_dequeue(struct sock *parent, struct socket *new_sock);
 293void smc_close_non_accepted(struct sock *sk);
 294
 295#endif  /* __SMC_H */
 296