xref: /linux/fs/smb/client/smbdirect.h (revision cfaf773b7946fa911e311acd3b82d61c7a9e42c2)
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