1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (C) 2017, Microsoft Corporation.
4 *
5 * Author(s): Long Li <longli@microsoft.com>
6 */
7 #ifndef _SMBDIRECT_H
8 #define _SMBDIRECT_H
9
10 #ifdef CONFIG_CIFS_SMB_DIRECT
11 #define cifs_rdma_enabled(server) ((server)->rdma)
12
13 #include "cifsglob.h"
14 #include <rdma/ib_verbs.h>
15 #include <rdma/rdma_cm.h>
16 #include <linux/mempool.h>
17
18 #include "../common/smbdirect/smbdirect.h"
19 #include "../common/smbdirect/smbdirect_socket.h"
20
21 extern int rdma_readwrite_threshold;
22 extern int smbd_max_frmr_depth;
23 extern int smbd_keep_alive_interval;
24 extern int smbd_max_receive_size;
25 extern int smbd_max_fragmented_recv_size;
26 extern int smbd_max_send_size;
27 extern int smbd_send_credit_target;
28 extern int smbd_receive_credit_max;
29
30 enum keep_alive_status {
31 KEEP_ALIVE_NONE,
32 KEEP_ALIVE_PENDING,
33 KEEP_ALIVE_SENT,
34 };
35
36 /*
37 * The context for the SMBDirect transport
38 * Everything related to the transport is here. It has several logical parts
39 * 1. RDMA related structures
40 * 2. SMBDirect connection parameters
41 * 3. Memory registrations
42 * 4. Receive and reassembly queues for data receive path
43 * 5. mempools for allocating packets
44 */
45 struct smbd_connection {
46 struct smbdirect_socket socket;
47
48 int ri_rc;
49 struct completion ri_done;
50 wait_queue_head_t status_wait;
51
52 struct completion negotiate_completion;
53 bool negotiate_done;
54
55 struct work_struct disconnect_work;
56 struct work_struct post_send_credits_work;
57
58 spinlock_t lock_new_credits_offered;
59 int new_credits_offered;
60
61 /* dynamic connection parameters defined in [MS-SMBD] 3.1.1.1 */
62 enum keep_alive_status keep_alive_requested;
63 int protocol;
64 atomic_t send_credits;
65 atomic_t receive_credits;
66 int receive_credit_target;
67
68 /* Memory registrations */
69 /* Maximum number of RDMA read/write outstanding on this connection */
70 int responder_resources;
71 /* Maximum number of pages in a single RDMA write/read on this connection */
72 int max_frmr_depth;
73 /*
74 * If payload is less than or equal to the threshold,
75 * use RDMA send/recv to send upper layer I/O.
76 * If payload is more than the threshold,
77 * use RDMA read/write through memory registration for I/O.
78 */
79 int rdma_readwrite_threshold;
80 enum ib_mr_type mr_type;
81 struct list_head mr_list;
82 spinlock_t mr_list_lock;
83 /* The number of available MRs ready for memory registration */
84 atomic_t mr_ready_count;
85 atomic_t mr_used_count;
86 wait_queue_head_t wait_mr;
87 struct work_struct mr_recovery_work;
88 /* Used by transport to wait until all MRs are returned */
89 wait_queue_head_t wait_for_mr_cleanup;
90
91 /* Activity accounting */
92 atomic_t send_pending;
93 wait_queue_head_t wait_send_pending;
94 wait_queue_head_t wait_post_send;
95
96 /* Receive queue */
97 int count_receive_queue;
98 wait_queue_head_t wait_receive_queues;
99
100 bool send_immediate;
101
102 wait_queue_head_t wait_send_queue;
103
104 struct workqueue_struct *workqueue;
105 struct delayed_work idle_timer_work;
106
107 /* for debug purposes */
108 unsigned int count_get_receive_buffer;
109 unsigned int count_put_receive_buffer;
110 unsigned int count_reassembly_queue;
111 unsigned int count_enqueue_reassembly_queue;
112 unsigned int count_dequeue_reassembly_queue;
113 unsigned int count_send_empty;
114 };
115
116 /* Create a SMBDirect session */
117 struct smbd_connection *smbd_get_connection(
118 struct TCP_Server_Info *server, struct sockaddr *dstaddr);
119
120 /* Reconnect SMBDirect session */
121 int smbd_reconnect(struct TCP_Server_Info *server);
122 /* Destroy SMBDirect session */
123 void smbd_destroy(struct TCP_Server_Info *server);
124
125 /* Interface for carrying upper layer I/O through send/recv */
126 int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
127 int smbd_send(struct TCP_Server_Info *server,
128 int num_rqst, struct smb_rqst *rqst);
129
130 enum mr_state {
131 MR_READY,
132 MR_REGISTERED,
133 MR_INVALIDATED,
134 MR_ERROR
135 };
136
137 struct smbd_mr {
138 struct smbd_connection *conn;
139 struct list_head list;
140 enum mr_state state;
141 struct ib_mr *mr;
142 struct sg_table sgt;
143 enum dma_data_direction dir;
144 union {
145 struct ib_reg_wr wr;
146 struct ib_send_wr inv_wr;
147 };
148 struct ib_cqe cqe;
149 bool need_invalidate;
150 struct completion invalidate_done;
151 };
152
153 /* Interfaces to register and deregister MR for RDMA read/write */
154 struct smbd_mr *smbd_register_mr(
155 struct smbd_connection *info, struct iov_iter *iter,
156 bool writing, bool need_invalidate);
157 int smbd_deregister_mr(struct smbd_mr *mr);
158
159 #else
160 #define cifs_rdma_enabled(server) 0
161 struct smbd_connection {};
smbd_get_connection(struct TCP_Server_Info * server,struct sockaddr * dstaddr)162 static inline void *smbd_get_connection(
163 struct TCP_Server_Info *server, struct sockaddr *dstaddr) {return NULL;}
smbd_reconnect(struct TCP_Server_Info * server)164 static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }
smbd_destroy(struct TCP_Server_Info * server)165 static inline void smbd_destroy(struct TCP_Server_Info *server) {}
smbd_recv(struct smbd_connection * info,struct msghdr * msg)166 static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }
smbd_send(struct TCP_Server_Info * server,int num_rqst,struct smb_rqst * rqst)167 static inline int smbd_send(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst) {return -1; }
168 #endif
169
170 #endif
171