xprt.h 14.8 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0 */
L
Linus Torvalds 已提交
2
/*
3
 *  linux/include/linux/sunrpc/xprt.h
L
Linus Torvalds 已提交
4 5 6 7 8 9 10 11 12 13 14 15
 *
 *  Declarations for the RPC transport interface.
 *
 *  Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
 */

#ifndef _LINUX_SUNRPC_XPRT_H
#define _LINUX_SUNRPC_XPRT_H

#include <linux/uio.h>
#include <linux/socket.h>
#include <linux/in.h>
16
#include <linux/ktime.h>
17
#include <linux/kref.h>
L
Linus Torvalds 已提交
18 19
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xdr.h>
20
#include <linux/sunrpc/msg_prot.h>
L
Linus Torvalds 已提交
21

22 23
#ifdef __KERNEL__

L
Linus Torvalds 已提交
24 25
#define RPC_MIN_SLOT_TABLE	(2U)
#define RPC_DEF_SLOT_TABLE	(16U)
26
#define RPC_MAX_SLOT_TABLE_LIMIT	(65536U)
27
#define RPC_MAX_SLOT_TABLE	RPC_MAX_SLOT_TABLE_LIMIT
L
Linus Torvalds 已提交
28

29 30 31 32 33 34
#define RPC_CWNDSHIFT		(8U)
#define RPC_CWNDSCALE		(1U << RPC_CWNDSHIFT)
#define RPC_INITCWND		RPC_CWNDSCALE
#define RPC_MAXCWND(xprt)	((xprt)->max_reqs << RPC_CWNDSHIFT)
#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)

L
Linus Torvalds 已提交
35 36 37 38 39 40 41 42 43 44 45
/*
 * This describes a timeout strategy
 */
struct rpc_timeout {
	unsigned long		to_initval,		/* initial timeout */
				to_maxval,		/* max timeout */
				to_increment;		/* if !exponential */
	unsigned int		to_retries;		/* max # of retries */
	unsigned char		to_exponential;
};

46 47 48 49
enum rpc_display_format_t {
	RPC_DISPLAY_ADDR = 0,
	RPC_DISPLAY_PORT,
	RPC_DISPLAY_PROTO,
50 51
	RPC_DISPLAY_HEX_ADDR,
	RPC_DISPLAY_HEX_PORT,
52
	RPC_DISPLAY_NETID,
53 54 55
	RPC_DISPLAY_MAX,
};

56 57
struct rpc_task;
struct rpc_xprt;
58
struct seq_file;
59 60
struct svc_serv;
struct net;
61

L
Linus Torvalds 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
/*
 * This describes a complete RPC request
 */
struct rpc_rqst {
	/*
	 * This is the user-visible part
	 */
	struct rpc_xprt *	rq_xprt;		/* RPC client */
	struct xdr_buf		rq_snd_buf;		/* send buffer */
	struct xdr_buf		rq_rcv_buf;		/* recv buffer */

	/*
	 * This is the private part
	 */
	struct rpc_task *	rq_task;	/* RPC task data */
77
	struct rpc_cred *	rq_cred;	/* Bound cred */
78
	__be32			rq_xid;		/* request XID */
L
Linus Torvalds 已提交
79 80
	int			rq_cong;	/* has incremented xprt->cong */
	u32			rq_seqno;	/* gss seq no. used on req. */
81 82 83 84
	int			rq_enc_pages_num;
	struct page		**rq_enc_pages;	/* scratch pages for use by
						   gss privacy code */
	void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */
L
Linus Torvalds 已提交
85 86
	struct list_head	rq_list;

87
	void			*rq_buffer;	/* Call XDR encode buffer */
88 89 90
	size_t			rq_callsize;
	void			*rq_rbuffer;	/* Reply XDR decode buffer */
	size_t			rq_rcvsize;
91 92 93
	size_t			rq_xmit_bytes_sent;	/* total bytes sent */
	size_t			rq_reply_bytes_recvd;	/* total reply bytes */
							/* received */
94

L
Linus Torvalds 已提交
95 96 97 98 99
	struct xdr_buf		rq_private_buf;		/* The receive buffer
							 * used in the softirq.
							 */
	unsigned long		rq_majortimeo;	/* major timeout alarm */
	unsigned long		rq_timeout;	/* Current timeout value */
100
	ktime_t			rq_rtt;		/* round-trip time */
L
Linus Torvalds 已提交
101
	unsigned int		rq_retries;	/* # of retries */
102 103 104 105
	unsigned int		rq_connect_cookie;
						/* A cookie used to track the
						   state of the transport
						   connection */
106
	atomic_t		rq_pin;
L
Linus Torvalds 已提交
107 108 109 110 111 112
	
	/*
	 * Partial send handling
	 */
	u32			rq_bytes_sent;	/* Bytes we have sent */

113
	ktime_t			rq_xtime;	/* transmit time stamp */
L
Linus Torvalds 已提交
114
	int			rq_ntrans;
115

116
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
117 118 119
	struct list_head	rq_bc_list;	/* Callback service list */
	unsigned long		rq_bc_pa_state;	/* Backchannel prealloc state */
	struct list_head	rq_bc_pa_list;	/* Backchannel prealloc list */
120
#endif /* CONFIG_SUNRPC_BACKCHANEL */
L
Linus Torvalds 已提交
121 122 123 124
};
#define rq_svec			rq_snd_buf.head
#define rq_slen			rq_snd_buf.len

125
struct rpc_xprt_ops {
126
	void		(*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
127
	int		(*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
128
	void		(*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
129
	void		(*alloc_slot)(struct rpc_xprt *xprt, struct rpc_task *task);
130 131
	void		(*free_slot)(struct rpc_xprt *xprt,
				     struct rpc_rqst *req);
132
	void		(*rpcbind)(struct rpc_task *task);
133
	void		(*set_port)(struct rpc_xprt *xprt, unsigned short port);
134
	void		(*connect)(struct rpc_xprt *xprt, struct rpc_task *task);
135
	int		(*buf_alloc)(struct rpc_task *task);
136
	void		(*buf_free)(struct rpc_task *task);
137
	int		(*send_request)(struct rpc_task *task);
138
	void		(*set_retrans_timeout)(struct rpc_task *task);
139
	void		(*timer)(struct rpc_xprt *xprt, struct rpc_task *task);
140
	void		(*release_request)(struct rpc_task *task);
141 142
	void		(*close)(struct rpc_xprt *xprt);
	void		(*destroy)(struct rpc_xprt *xprt);
143 144 145
	void		(*set_connect_timeout)(struct rpc_xprt *xprt,
					unsigned long connect_timeout,
					unsigned long reconnect_timeout);
146
	void		(*print_stats)(struct rpc_xprt *xprt, struct seq_file *seq);
147 148
	int		(*enable_swap)(struct rpc_xprt *xprt);
	void		(*disable_swap)(struct rpc_xprt *xprt);
C
Chuck Lever 已提交
149
	void		(*inject_disconnect)(struct rpc_xprt *xprt);
150 151
	int		(*bc_setup)(struct rpc_xprt *xprt,
				    unsigned int min_reqs);
152
	int		(*bc_up)(struct svc_serv *serv, struct net *net);
153
	size_t		(*bc_maxpayload)(struct rpc_xprt *xprt);
154 155 156
	void		(*bc_free_rqst)(struct rpc_rqst *rqst);
	void		(*bc_destroy)(struct rpc_xprt *xprt,
				      unsigned int max_reqs);
157
};
L
Linus Torvalds 已提交
158

159 160 161 162 163 164 165 166 167 168 169 170 171 172
/*
 * RPC transport identifiers
 *
 * To preserve compatibility with the historical use of raw IP protocol
 * id's for transport selection, UDP and TCP identifiers are specified
 * with the previous values. No such restriction exists for new transports,
 * except that they may not collide with these values (17 and 6,
 * respectively).
 */
#define XPRT_TRANSPORT_BC       (1 << 31)
enum xprt_transports {
	XPRT_TRANSPORT_UDP	= IPPROTO_UDP,
	XPRT_TRANSPORT_TCP	= IPPROTO_TCP,
	XPRT_TRANSPORT_BC_TCP	= IPPROTO_TCP | XPRT_TRANSPORT_BC,
173
	XPRT_TRANSPORT_RDMA	= 256,
174
	XPRT_TRANSPORT_BC_RDMA	= XPRT_TRANSPORT_RDMA | XPRT_TRANSPORT_BC,
175
	XPRT_TRANSPORT_LOCAL	= 257,
176 177
};

L
Linus Torvalds 已提交
178
struct rpc_xprt {
179
	struct kref		kref;		/* Reference count */
180
	const struct rpc_xprt_ops *ops;		/* transport methods */
L
Linus Torvalds 已提交
181

182
	const struct rpc_timeout *timeout;	/* timeout parms */
183 184
	struct sockaddr_storage	addr;		/* server address */
	size_t			addrlen;	/* size of server address */
L
Linus Torvalds 已提交
185 186 187 188 189 190 191
	int			prot;		/* IP protocol */

	unsigned long		cong;		/* current congestion */
	unsigned long		cwnd;		/* congestion window */

	size_t			max_payload;	/* largest RPC payload size,
						   in bytes */
192 193
	unsigned int		tsh_size;	/* size of transport specific
						   header */
L
Linus Torvalds 已提交
194

195
	struct rpc_wait_queue	binding;	/* requests waiting on rpcbind */
L
Linus Torvalds 已提交
196 197 198 199
	struct rpc_wait_queue	sending;	/* requests waiting to send */
	struct rpc_wait_queue	pending;	/* requests in flight */
	struct rpc_wait_queue	backlog;	/* waiting for slot */
	struct list_head	free;		/* free slots */
200 201
	unsigned int		max_reqs;	/* max number of slots */
	unsigned int		min_reqs;	/* min number of slots */
202
	unsigned int		num_reqs;	/* total slots */
203
	unsigned long		state;		/* transport state */
204
	unsigned char		resvport   : 1; /* use a reserved port */
205
	atomic_t		swapper;	/* we're swapping over this
M
Mel Gorman 已提交
206
						   transport */
207
	unsigned int		bind_index;	/* bind function index */
L
Linus Torvalds 已提交
208

209 210 211 212 213
	/*
	 * Multipath
	 */
	struct list_head	xprt_switch;

L
Linus Torvalds 已提交
214
	/*
215
	 * Connection of transports
L
Linus Torvalds 已提交
216
	 */
217
	unsigned long		bind_timeout,
218
				reestablish_timeout;
219 220 221
	unsigned int		connect_cookie;	/* A cookie that gets bumped
						   every time the transport
						   is reconnected */
222

L
Linus Torvalds 已提交
223
	/*
224
	 * Disconnection of idle transports
L
Linus Torvalds 已提交
225 226 227
	 */
	struct work_struct	task_cleanup;
	struct timer_list	timer;
228
	unsigned long		last_used,
229
				idle_timeout,
230
				connect_timeout,
231
				max_reconnect_timeout;
L
Linus Torvalds 已提交
232 233 234 235

	/*
	 * Send stuff
	 */
C
Chuck Lever 已提交
236
	spinlock_t		transport_lock;	/* lock transport info */
C
Chuck Lever 已提交
237
	spinlock_t		reserve_lock;	/* lock slot table */
238
	spinlock_t		queue_lock;	/* send/receive queue lock */
239
	u32			xid;		/* Next XID value to use */
L
Linus Torvalds 已提交
240
	struct rpc_task *	snd_task;	/* Task blocked in send */
241
	struct svc_xprt		*bc_xprt;	/* NFSv4.1 backchannel */
242
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
243 244
	struct svc_serv		*bc_serv;       /* The RPC service which will */
						/* process the callback */
T
Trond Myklebust 已提交
245 246
	int			bc_alloc_count;	/* Total number of preallocs */
	atomic_t		bc_free_slots;
247 248 249 250
	spinlock_t		bc_pa_lock;	/* Protects the preallocated
						 * items */
	struct list_head	bc_pa_list;	/* List of preallocated
						 * backchannel rpc_rqst's */
251
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
L
Linus Torvalds 已提交
252 253
	struct list_head	recv;

254 255 256 257 258 259 260
	struct {
		unsigned long		bind_count,	/* total number of binds */
					connect_count,	/* total number of connects */
					connect_start,	/* connect start timestamp */
					connect_time,	/* jiffies waiting for connect */
					sends,		/* how many complete requests */
					recvs,		/* how many complete requests */
261 262
					bad_xids,	/* lookup_rqst didn't find XID */
					max_slots;	/* max rpc_slots used */
263 264

		unsigned long long	req_u,		/* average requests on the wire */
265 266 267
					bklog_u,	/* backlog queue utilization */
					sending_u,	/* send q utilization */
					pending_u;	/* pend q utilization */
268
	} stat;
L
Linus Torvalds 已提交
269

P
Pavel Emelyanov 已提交
270
	struct net		*xprt_net;
271
	const char		*servername;
272
	const char		*address_strings[RPC_DISPLAY_MAX];
273 274
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
	struct dentry		*debugfs;		/* debugfs directory */
C
Chuck Lever 已提交
275
	atomic_t		inject_disconnect;
276
#endif
277
	struct rcu_head		rcu;
L
Linus Torvalds 已提交
278 279
};

280
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
281 282 283 284 285
/*
 * Backchannel flags
 */
#define	RPC_BC_PA_IN_USE	0x0001		/* Preallocated backchannel */
						/* buffer in use */
286
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
287

288
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
289 290 291 292 293 294 295 296 297
static inline int bc_prealloc(struct rpc_rqst *req)
{
	return test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
}
#else
static inline int bc_prealloc(struct rpc_rqst *req)
{
	return 0;
}
298
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
299

300
#define XPRT_CREATE_INFINITE_SLOTS	(1U)
301
#define XPRT_CREATE_NO_IDLE_TIMEOUT	(1U << 1)
302

303
struct xprt_create {
304
	int			ident;		/* XPRT_TRANSPORT identifier */
P
Pavel Emelyanov 已提交
305
	struct net *		net;
306
	struct sockaddr *	srcaddr;	/* optional local address */
307 308
	struct sockaddr *	dstaddr;	/* remote peer address */
	size_t			addrlen;
309
	const char		*servername;
310
	struct svc_xprt		*bc_xprt;	/* NFSv4.1 backchannel */
311
	struct rpc_xprt_switch	*bc_xps;
312
	unsigned int		flags;
313
};
L
Linus Torvalds 已提交
314

315 316
struct xprt_class {
	struct list_head	list;
317
	int			ident;		/* XPRT_TRANSPORT identifier */
318
	struct rpc_xprt *	(*setup)(struct xprt_create *);
319 320 321 322
	struct module		*owner;
	char			name[32];
};

323 324 325
/*
 * Generic internal transport functions
 */
326
struct rpc_xprt		*xprt_create_transport(struct xprt_create *args);
327 328
void			xprt_connect(struct rpc_task *task);
void			xprt_reserve(struct rpc_task *task);
329
void			xprt_retry_reserve(struct rpc_task *task);
330 331
int			xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
int			xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
332
void			xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);
333 334
void			xprt_free_slot(struct rpc_xprt *xprt,
				       struct rpc_rqst *req);
335
void			xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);
336
bool			xprt_prepare_transmit(struct rpc_task *task);
337
void			xprt_transmit(struct rpc_task *task);
338
void			xprt_end_transmit(struct rpc_task *task);
L
Linus Torvalds 已提交
339
int			xprt_adjust_timeout(struct rpc_rqst *req);
340 341
void			xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
void			xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
342
void			xprt_release(struct rpc_task *task);
343
struct rpc_xprt *	xprt_get(struct rpc_xprt *xprt);
344
void			xprt_put(struct rpc_xprt *xprt);
345 346 347
struct rpc_xprt *	xprt_alloc(struct net *net, size_t size,
				unsigned int num_prealloc,
				unsigned int max_req);
348
void			xprt_free(struct rpc_xprt *);
349

350
static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p)
351 352 353 354
{
	return p + xprt->tsh_size;
}

355 356 357 358 359 360 361 362 363 364 365 366
static inline int
xprt_enable_swap(struct rpc_xprt *xprt)
{
	return xprt->ops->enable_swap(xprt);
}

static inline void
xprt_disable_swap(struct rpc_xprt *xprt)
{
	xprt->ops->disable_swap(xprt);
}

367 368 369
/*
 * Transport switch helper functions
 */
370 371
int			xprt_register_transport(struct xprt_class *type);
int			xprt_unregister_transport(struct xprt_class *type);
372
int			xprt_load_transport(const char *);
373 374
void			xprt_set_retrans_timeout_def(struct rpc_task *task);
void			xprt_set_retrans_timeout_rtt(struct rpc_task *task);
375
void			xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
376
void			xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action);
377
void			xprt_write_space(struct rpc_xprt *xprt);
378
void			xprt_adjust_cwnd(struct rpc_xprt *xprt, struct rpc_task *task, int result);
379
struct rpc_rqst *	xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid);
380
void			xprt_update_rtt(struct rpc_task *task);
381
void			xprt_complete_rqst(struct rpc_task *task, int copied);
382 383
void			xprt_pin_rqst(struct rpc_rqst *req);
void			xprt_unpin_rqst(struct rpc_rqst *req);
384
void			xprt_release_rqst_cong(struct rpc_task *task);
385
void			xprt_disconnect_done(struct rpc_xprt *xprt);
386
void			xprt_force_disconnect(struct rpc_xprt *xprt);
387
void			xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie);
388

389 390 391
bool			xprt_lock_connect(struct rpc_xprt *, struct rpc_task *, void *);
void			xprt_unlock_connect(struct rpc_xprt *, void *);

392 393 394 395 396 397
/*
 * Reserved bit positions in xprt->state
 */
#define XPRT_LOCKED		(0)
#define XPRT_CONNECTED		(1)
#define XPRT_CONNECTING		(2)
398
#define XPRT_CLOSE_WAIT		(3)
399
#define XPRT_BOUND		(4)
400
#define XPRT_BINDING		(5)
401
#define XPRT_CLOSING		(6)
402
#define XPRT_CONGESTED		(9)
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430

static inline void xprt_set_connected(struct rpc_xprt *xprt)
{
	set_bit(XPRT_CONNECTED, &xprt->state);
}

static inline void xprt_clear_connected(struct rpc_xprt *xprt)
{
	clear_bit(XPRT_CONNECTED, &xprt->state);
}

static inline int xprt_connected(struct rpc_xprt *xprt)
{
	return test_bit(XPRT_CONNECTED, &xprt->state);
}

static inline int xprt_test_and_set_connected(struct rpc_xprt *xprt)
{
	return test_and_set_bit(XPRT_CONNECTED, &xprt->state);
}

static inline int xprt_test_and_clear_connected(struct rpc_xprt *xprt)
{
	return test_and_clear_bit(XPRT_CONNECTED, &xprt->state);
}

static inline void xprt_clear_connecting(struct rpc_xprt *xprt)
{
431
	smp_mb__before_atomic();
432
	clear_bit(XPRT_CONNECTING, &xprt->state);
433
	smp_mb__after_atomic();
434 435 436 437 438 439 440 441 442 443 444
}

static inline int xprt_connecting(struct rpc_xprt *xprt)
{
	return test_bit(XPRT_CONNECTING, &xprt->state);
}

static inline int xprt_test_and_set_connecting(struct rpc_xprt *xprt)
{
	return test_and_set_bit(XPRT_CONNECTING, &xprt->state);
}
L
Linus Torvalds 已提交
445

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
static inline void xprt_set_bound(struct rpc_xprt *xprt)
{
	test_and_set_bit(XPRT_BOUND, &xprt->state);
}

static inline int xprt_bound(struct rpc_xprt *xprt)
{
	return test_bit(XPRT_BOUND, &xprt->state);
}

static inline void xprt_clear_bound(struct rpc_xprt *xprt)
{
	clear_bit(XPRT_BOUND, &xprt->state);
}

461 462
static inline void xprt_clear_binding(struct rpc_xprt *xprt)
{
463
	smp_mb__before_atomic();
464
	clear_bit(XPRT_BINDING, &xprt->state);
465
	smp_mb__after_atomic();
466 467 468 469 470 471 472
}

static inline int xprt_test_and_set_binding(struct rpc_xprt *xprt)
{
	return test_and_set_bit(XPRT_BINDING, &xprt->state);
}

C
Chuck Lever 已提交
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
extern unsigned int rpc_inject_disconnect;
static inline void xprt_inject_disconnect(struct rpc_xprt *xprt)
{
	if (!rpc_inject_disconnect)
		return;
	if (atomic_dec_return(&xprt->inject_disconnect))
		return;
	atomic_set(&xprt->inject_disconnect, rpc_inject_disconnect);
	xprt->ops->inject_disconnect(xprt);
}
#else
static inline void xprt_inject_disconnect(struct rpc_xprt *xprt)
{
}
#endif

L
Linus Torvalds 已提交
490 491 492
#endif /* __KERNEL__*/

#endif /* _LINUX_SUNRPC_XPRT_H */