Blame view

net/rxrpc/call_object.c 18.5 KB
17926a793   David Howells   [AF_RXRPC]: Provi...
1
2
3
4
5
6
7
8
9
10
  /* RxRPC individual remote procedure call handling
   *
   * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   * Written by David Howells (dhowells@redhat.com)
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version
   * 2 of the License, or (at your option) any later version.
   */
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
11
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5a0e3ad6a   Tejun Heo   include cleanup: ...
12
  #include <linux/slab.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
13
14
  #include <linux/module.h>
  #include <linux/circ_buf.h>
7727640cc   Tim Smith   af_rxrpc: Keep rx...
15
  #include <linux/spinlock_types.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
16
17
18
  #include <net/sock.h>
  #include <net/af_rxrpc.h>
  #include "ar-internal.h"
5b8848d14   David Howells   rxrpc: Convert ca...
19
  const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = {
f5c17aaeb   David Howells   rxrpc: Calls shou...
20
  	[RXRPC_CALL_UNINITIALISED]		= "Uninit  ",
999b69f89   David Howells   rxrpc: Kill the c...
21
  	[RXRPC_CALL_CLIENT_AWAIT_CONN]		= "ClWtConn",
1f8481d19   David Howells   [AF_RXRPC]: Make ...
22
23
24
  	[RXRPC_CALL_CLIENT_SEND_REQUEST]	= "ClSndReq",
  	[RXRPC_CALL_CLIENT_AWAIT_REPLY]		= "ClAwtRpl",
  	[RXRPC_CALL_CLIENT_RECV_REPLY]		= "ClRcvRpl",
00e907127   David Howells   rxrpc: Preallocat...
25
  	[RXRPC_CALL_SERVER_PREALLOC]		= "SvPrealc",
1f8481d19   David Howells   [AF_RXRPC]: Make ...
26
27
28
29
30
31
32
  	[RXRPC_CALL_SERVER_SECURING]		= "SvSecure",
  	[RXRPC_CALL_SERVER_ACCEPTING]		= "SvAccept",
  	[RXRPC_CALL_SERVER_RECV_REQUEST]	= "SvRcvReq",
  	[RXRPC_CALL_SERVER_ACK_REQUEST]		= "SvAckReq",
  	[RXRPC_CALL_SERVER_SEND_REPLY]		= "SvSndRpl",
  	[RXRPC_CALL_SERVER_AWAIT_ACK]		= "SvAwtACK",
  	[RXRPC_CALL_COMPLETE]			= "Complete",
f5c17aaeb   David Howells   rxrpc: Calls shou...
33
34
35
36
  };
  
  const char *const rxrpc_call_completions[NR__RXRPC_CALL_COMPLETIONS] = {
  	[RXRPC_CALL_SUCCEEDED]			= "Complete",
1f8481d19   David Howells   [AF_RXRPC]: Make ...
37
38
  	[RXRPC_CALL_REMOTELY_ABORTED]		= "RmtAbort",
  	[RXRPC_CALL_LOCALLY_ABORTED]		= "LocAbort",
f5c17aaeb   David Howells   rxrpc: Calls shou...
39
  	[RXRPC_CALL_LOCAL_ERROR]		= "LocError",
1f8481d19   David Howells   [AF_RXRPC]: Make ...
40
  	[RXRPC_CALL_NETWORK_ERROR]		= "NetError",
1f8481d19   David Howells   [AF_RXRPC]: Make ...
41
  };
17926a793   David Howells   [AF_RXRPC]: Provi...
42
  struct kmem_cache *rxrpc_call_jar;
17926a793   David Howells   [AF_RXRPC]: Provi...
43

248f219cb   David Howells   rxrpc: Rewrite th...
44
45
46
47
48
  static void rxrpc_call_timer_expired(unsigned long _call)
  {
  	struct rxrpc_call *call = (struct rxrpc_call *)_call;
  
  	_enter("%d", call->debug_id);
405dea1de   David Howells   rxrpc: Fix the ca...
49
50
  	if (call->state < RXRPC_CALL_COMPLETE)
  		rxrpc_set_timer(call, rxrpc_timer_expired, ktime_get_real());
248f219cb   David Howells   rxrpc: Rewrite th...
51
  }
17926a793   David Howells   [AF_RXRPC]: Provi...
52

b89372f23   David Howells   rxrpc: Provide a ...
53
  static struct lock_class_key rxrpc_call_user_mutex_lock_class_key;
17926a793   David Howells   [AF_RXRPC]: Provi...
54
  /*
2341e0775   David Howells   rxrpc: Simplify c...
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
   * find an extant server call
   * - called in process context with IRQs enabled
   */
  struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *rx,
  					      unsigned long user_call_ID)
  {
  	struct rxrpc_call *call;
  	struct rb_node *p;
  
  	_enter("%p,%lx", rx, user_call_ID);
  
  	read_lock(&rx->call_lock);
  
  	p = rx->calls.rb_node;
  	while (p) {
  		call = rb_entry(p, struct rxrpc_call, sock_node);
  
  		if (user_call_ID < call->user_call_ID)
  			p = p->rb_left;
  		else if (user_call_ID > call->user_call_ID)
  			p = p->rb_right;
  		else
  			goto found_extant_call;
  	}
  
  	read_unlock(&rx->call_lock);
  	_leave(" = NULL");
  	return NULL;
  
  found_extant_call:
fff72429c   David Howells   rxrpc: Improve th...
85
  	rxrpc_get_call(call, rxrpc_call_got);
2341e0775   David Howells   rxrpc: Simplify c...
86
87
88
89
90
91
  	read_unlock(&rx->call_lock);
  	_leave(" = %p [%d]", call, atomic_read(&call->usage));
  	return call;
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
92
93
   * allocate a new call
   */
b89372f23   David Howells   rxrpc: Provide a ...
94
  struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp)
17926a793   David Howells   [AF_RXRPC]: Provi...
95
96
97
98
99
100
  {
  	struct rxrpc_call *call;
  
  	call = kmem_cache_zalloc(rxrpc_call_jar, gfp);
  	if (!call)
  		return NULL;
248f219cb   David Howells   rxrpc: Rewrite th...
101
102
  	call->rxtx_buffer = kcalloc(RXRPC_RXTX_BUFF_SIZE,
  				    sizeof(struct sk_buff *),
17926a793   David Howells   [AF_RXRPC]: Provi...
103
  				    gfp);
248f219cb   David Howells   rxrpc: Rewrite th...
104
105
  	if (!call->rxtx_buffer)
  		goto nomem;
17926a793   David Howells   [AF_RXRPC]: Provi...
106

248f219cb   David Howells   rxrpc: Rewrite th...
107
108
109
  	call->rxtx_annotations = kcalloc(RXRPC_RXTX_BUFF_SIZE, sizeof(u8), gfp);
  	if (!call->rxtx_annotations)
  		goto nomem_2;
540b1c48c   David Howells   rxrpc: Fix deadlo...
110
  	mutex_init(&call->user_mutex);
b89372f23   David Howells   rxrpc: Provide a ...
111
112
113
114
115
116
117
  
  	/* Prevent lockdep reporting a deadlock false positive between the afs
  	 * filesystem and sys_sendmsg() via the mmap sem.
  	 */
  	if (rx->sk.sk_kern_sock)
  		lockdep_set_class(&call->user_mutex,
  				  &rxrpc_call_user_mutex_lock_class_key);
248f219cb   David Howells   rxrpc: Rewrite th...
118
119
  	setup_timer(&call->timer, rxrpc_call_timer_expired,
  		    (unsigned long)call);
17926a793   David Howells   [AF_RXRPC]: Provi...
120
  	INIT_WORK(&call->processor, &rxrpc_process_call);
999b69f89   David Howells   rxrpc: Kill the c...
121
  	INIT_LIST_HEAD(&call->link);
45025bcee   David Howells   rxrpc: Improve ma...
122
  	INIT_LIST_HEAD(&call->chan_wait_link);
17926a793   David Howells   [AF_RXRPC]: Provi...
123
  	INIT_LIST_HEAD(&call->accept_link);
248f219cb   David Howells   rxrpc: Rewrite th...
124
125
  	INIT_LIST_HEAD(&call->recvmsg_link);
  	INIT_LIST_HEAD(&call->sock_link);
45025bcee   David Howells   rxrpc: Improve ma...
126
  	init_waitqueue_head(&call->waitq);
17926a793   David Howells   [AF_RXRPC]: Provi...
127
128
129
130
  	spin_lock_init(&call->lock);
  	rwlock_init(&call->state_lock);
  	atomic_set(&call->usage, 1);
  	call->debug_id = atomic_inc_return(&rxrpc_debug_id);
e754eba68   David Howells   rxrpc: Provide a ...
131
  	call->tx_total_len = -1;
17926a793   David Howells   [AF_RXRPC]: Provi...
132
133
  
  	memset(&call->sock_node, 0xed, sizeof(call->sock_node));
248f219cb   David Howells   rxrpc: Rewrite th...
134
  	/* Leave space in the ring to handle a maxed-out jumbo packet */
75e421263   David Howells   rxrpc: Correctly ...
135
  	call->rx_winsize = rxrpc_rx_window_size;
248f219cb   David Howells   rxrpc: Rewrite th...
136
137
  	call->tx_winsize = 16;
  	call->rx_expect_next = 1;
57494343c   David Howells   rxrpc: Implement ...
138

f7aec129a   David Howells   rxrpc: Cache the ...
139
  	call->cong_cwnd = 2;
57494343c   David Howells   rxrpc: Implement ...
140
  	call->cong_ssthresh = RXRPC_RXTX_BUFF_SIZE - 1;
17926a793   David Howells   [AF_RXRPC]: Provi...
141
  	return call;
248f219cb   David Howells   rxrpc: Rewrite th...
142
143
144
145
146
147
  
  nomem_2:
  	kfree(call->rxtx_buffer);
  nomem:
  	kmem_cache_free(rxrpc_call_jar, call);
  	return NULL;
17926a793   David Howells   [AF_RXRPC]: Provi...
148
149
150
  }
  
  /*
999b69f89   David Howells   rxrpc: Kill the c...
151
   * Allocate a new client call.
17926a793   David Howells   [AF_RXRPC]: Provi...
152
   */
b89372f23   David Howells   rxrpc: Provide a ...
153
154
  static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
  						  struct sockaddr_rxrpc *srx,
aa390bbe2   David Howells   rxrpc: Kill off t...
155
  						  gfp_t gfp)
17926a793   David Howells   [AF_RXRPC]: Provi...
156
157
  {
  	struct rxrpc_call *call;
57494343c   David Howells   rxrpc: Implement ...
158
  	ktime_t now;
17926a793   David Howells   [AF_RXRPC]: Provi...
159
160
  
  	_enter("");
b89372f23   David Howells   rxrpc: Provide a ...
161
  	call = rxrpc_alloc_call(rx, gfp);
17926a793   David Howells   [AF_RXRPC]: Provi...
162
163
  	if (!call)
  		return ERR_PTR(-ENOMEM);
999b69f89   David Howells   rxrpc: Kill the c...
164
  	call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
999b69f89   David Howells   rxrpc: Kill the c...
165
  	call->service_id = srx->srx_service;
71f3ca408   David Howells   rxrpc: Improve sk...
166
  	call->tx_phase = true;
57494343c   David Howells   rxrpc: Implement ...
167
168
169
  	now = ktime_get_real();
  	call->acks_latest_ts = now;
  	call->cong_tstamp = now;
999b69f89   David Howells   rxrpc: Kill the c...
170
171
172
173
174
175
  
  	_leave(" = %p", call);
  	return call;
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
176
   * Initiate the call ack/resend/expiry timer.
999b69f89   David Howells   rxrpc: Kill the c...
177
   */
248f219cb   David Howells   rxrpc: Rewrite th...
178
  static void rxrpc_start_call_timer(struct rxrpc_call *call)
999b69f89   David Howells   rxrpc: Kill the c...
179
  {
df0adc788   David Howells   rxrpc: Keep the c...
180
  	ktime_t now = ktime_get_real(), expire_at;
248f219cb   David Howells   rxrpc: Rewrite th...
181

df0adc788   David Howells   rxrpc: Keep the c...
182
  	expire_at = ktime_add_ms(now, rxrpc_max_call_lifetime);
248f219cb   David Howells   rxrpc: Rewrite th...
183
184
  	call->expire_at = expire_at;
  	call->ack_at = expire_at;
a5af7e1fc   David Howells   rxrpc: Fix loss o...
185
  	call->ping_at = expire_at;
248f219cb   David Howells   rxrpc: Rewrite th...
186
  	call->resend_at = expire_at;
df0adc788   David Howells   rxrpc: Keep the c...
187
188
  	call->timer.expires = jiffies + LONG_MAX / 2;
  	rxrpc_set_timer(call, rxrpc_timer_begin, now);
17926a793   David Howells   [AF_RXRPC]: Provi...
189
190
191
  }
  
  /*
540b1c48c   David Howells   rxrpc: Fix deadlo...
192
193
194
   * Set up a call for the given parameters.
   * - Called with the socket lock held, which it must release.
   * - If it returns a call, the call's lock will need releasing by the caller.
17926a793   David Howells   [AF_RXRPC]: Provi...
195
   */
2341e0775   David Howells   rxrpc: Simplify c...
196
  struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
19ffa01c9   David Howells   rxrpc: Use struct...
197
  					 struct rxrpc_conn_parameters *cp,
999b69f89   David Howells   rxrpc: Kill the c...
198
  					 struct sockaddr_rxrpc *srx,
17926a793   David Howells   [AF_RXRPC]: Provi...
199
  					 unsigned long user_call_ID,
e754eba68   David Howells   rxrpc: Provide a ...
200
  					 s64 tx_total_len,
17926a793   David Howells   [AF_RXRPC]: Provi...
201
  					 gfp_t gfp)
540b1c48c   David Howells   rxrpc: Fix deadlo...
202
  	__releases(&rx->sk.sk_lock.slock)
17926a793   David Howells   [AF_RXRPC]: Provi...
203
  {
2341e0775   David Howells   rxrpc: Simplify c...
204
  	struct rxrpc_call *call, *xcall;
2baec2c3f   David Howells   rxrpc: Support ne...
205
  	struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk));
2341e0775   David Howells   rxrpc: Simplify c...
206
  	struct rb_node *parent, **pp;
e34d4234b   David Howells   rxrpc: Trace rxrp...
207
  	const void *here = __builtin_return_address(0);
999b69f89   David Howells   rxrpc: Kill the c...
208
  	int ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
209

999b69f89   David Howells   rxrpc: Kill the c...
210
  	_enter("%p,%lx", rx, user_call_ID);
17926a793   David Howells   [AF_RXRPC]: Provi...
211

b89372f23   David Howells   rxrpc: Provide a ...
212
  	call = rxrpc_alloc_client_call(rx, srx, gfp);
2341e0775   David Howells   rxrpc: Simplify c...
213
  	if (IS_ERR(call)) {
540b1c48c   David Howells   rxrpc: Fix deadlo...
214
  		release_sock(&rx->sk);
2341e0775   David Howells   rxrpc: Simplify c...
215
216
  		_leave(" = %ld", PTR_ERR(call));
  		return call;
17926a793   David Howells   [AF_RXRPC]: Provi...
217
  	}
e754eba68   David Howells   rxrpc: Provide a ...
218
  	call->tx_total_len = tx_total_len;
a84a46d73   David Howells   rxrpc: Add some a...
219
220
  	trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage),
  			 here, (const void *)user_call_ID);
e34d4234b   David Howells   rxrpc: Trace rxrp...
221

540b1c48c   David Howells   rxrpc: Fix deadlo...
222
223
224
225
  	/* We need to protect a partially set up call against the user as we
  	 * will be acting outside the socket lock.
  	 */
  	mutex_lock(&call->user_mutex);
999b69f89   David Howells   rxrpc: Kill the c...
226
  	/* Publish the call, even though it is incompletely set up as yet */
17926a793   David Howells   [AF_RXRPC]: Provi...
227
228
229
230
231
232
  	write_lock(&rx->call_lock);
  
  	pp = &rx->calls.rb_node;
  	parent = NULL;
  	while (*pp) {
  		parent = *pp;
2341e0775   David Howells   rxrpc: Simplify c...
233
  		xcall = rb_entry(parent, struct rxrpc_call, sock_node);
17926a793   David Howells   [AF_RXRPC]: Provi...
234

2341e0775   David Howells   rxrpc: Simplify c...
235
  		if (user_call_ID < xcall->user_call_ID)
17926a793   David Howells   [AF_RXRPC]: Provi...
236
  			pp = &(*pp)->rb_left;
2341e0775   David Howells   rxrpc: Simplify c...
237
  		else if (user_call_ID > xcall->user_call_ID)
17926a793   David Howells   [AF_RXRPC]: Provi...
238
239
  			pp = &(*pp)->rb_right;
  		else
357f5ef64   David Howells   rxrpc: Call rxrpc...
240
  			goto error_dup_user_ID;
17926a793   David Howells   [AF_RXRPC]: Provi...
241
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
242
  	rcu_assign_pointer(call->socket, rx);
357f5ef64   David Howells   rxrpc: Call rxrpc...
243
244
  	call->user_call_ID = user_call_ID;
  	__set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
fff72429c   David Howells   rxrpc: Improve th...
245
  	rxrpc_get_call(call, rxrpc_call_got_userid);
17926a793   David Howells   [AF_RXRPC]: Provi...
246
247
  	rb_link_node(&call->sock_node, parent, pp);
  	rb_insert_color(&call->sock_node, &rx->calls);
248f219cb   David Howells   rxrpc: Rewrite th...
248
  	list_add(&call->sock_link, &rx->sock_calls);
17926a793   David Howells   [AF_RXRPC]: Provi...
249
  	write_unlock(&rx->call_lock);
2baec2c3f   David Howells   rxrpc: Support ne...
250
251
252
  	write_lock(&rxnet->call_lock);
  	list_add_tail(&call->link, &rxnet->calls);
  	write_unlock(&rxnet->call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
253

540b1c48c   David Howells   rxrpc: Fix deadlo...
254
255
  	/* From this point on, the call is protected by its own lock. */
  	release_sock(&rx->sk);
248f219cb   David Howells   rxrpc: Rewrite th...
256
257
258
259
  	/* Set up or get a connection record and set the protocol parameters,
  	 * including channel number and call ID.
  	 */
  	ret = rxrpc_connect_call(call, cp, srx, gfp);
999b69f89   David Howells   rxrpc: Kill the c...
260
261
  	if (ret < 0)
  		goto error;
a84a46d73   David Howells   rxrpc: Add some a...
262
  	trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage),
54fde4234   David Howells   rxrpc: Fix checke...
263
  			 here, NULL);
a84a46d73   David Howells   rxrpc: Add some a...
264

248f219cb   David Howells   rxrpc: Rewrite th...
265
  	rxrpc_start_call_timer(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
266
267
268
269
  	_net("CALL new %d on CONN %d", call->debug_id, call->conn->debug_id);
  
  	_leave(" = %p [new]", call);
  	return call;
2341e0775   David Howells   rxrpc: Simplify c...
270
271
272
273
274
  	/* We unexpectedly found the user ID in the list after taking
  	 * the call_lock.  This shouldn't happen unless the user races
  	 * with itself and tries to add the same user ID twice at the
  	 * same time in different threads.
  	 */
357f5ef64   David Howells   rxrpc: Call rxrpc...
275
  error_dup_user_ID:
17926a793   David Howells   [AF_RXRPC]: Provi...
276
  	write_unlock(&rx->call_lock);
540b1c48c   David Howells   rxrpc: Fix deadlo...
277
  	release_sock(&rx->sk);
8d94aa381   David Howells   rxrpc: Calls shou...
278
  	ret = -EEXIST;
357f5ef64   David Howells   rxrpc: Call rxrpc...
279
280
281
282
  
  error:
  	__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
  				    RX_CALL_DEAD, ret);
a84a46d73   David Howells   rxrpc: Add some a...
283
284
  	trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage),
  			 here, ERR_PTR(ret));
357f5ef64   David Howells   rxrpc: Call rxrpc...
285
  	rxrpc_release_call(rx, call);
540b1c48c   David Howells   rxrpc: Fix deadlo...
286
  	mutex_unlock(&call->user_mutex);
357f5ef64   David Howells   rxrpc: Call rxrpc...
287
288
289
  	rxrpc_put_call(call, rxrpc_call_put);
  	_leave(" = %d", ret);
  	return ERR_PTR(ret);
17926a793   David Howells   [AF_RXRPC]: Provi...
290
291
292
  }
  
  /*
c038a58cc   David Howells   rxrpc: Allow fail...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
   * Retry a call to a new address.  It is expected that the Tx queue of the call
   * will contain data previously packaged for an old call.
   */
  int rxrpc_retry_client_call(struct rxrpc_sock *rx,
  			    struct rxrpc_call *call,
  			    struct rxrpc_conn_parameters *cp,
  			    struct sockaddr_rxrpc *srx,
  			    gfp_t gfp)
  {
  	const void *here = __builtin_return_address(0);
  	int ret;
  
  	/* Set up or get a connection record and set the protocol parameters,
  	 * including channel number and call ID.
  	 */
  	ret = rxrpc_connect_call(call, cp, srx, gfp);
  	if (ret < 0)
  		goto error;
  
  	trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage),
  			 here, NULL);
  
  	rxrpc_start_call_timer(call);
  
  	_net("CALL new %d on CONN %d", call->debug_id, call->conn->debug_id);
  
  	if (!test_and_set_bit(RXRPC_CALL_EV_RESEND, &call->events))
  		rxrpc_queue_call(call);
  
  	_leave(" = 0");
  	return 0;
  
  error:
  	rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
  				  RX_CALL_DEAD, ret);
  	trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage),
  			 here, ERR_PTR(ret));
  	_leave(" = %d", ret);
  	return ret;
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
335
336
   * Set up an incoming call.  call->conn points to the connection.
   * This is called in BH context and isn't allowed to fail.
17926a793   David Howells   [AF_RXRPC]: Provi...
337
   */
248f219cb   David Howells   rxrpc: Rewrite th...
338
339
340
  void rxrpc_incoming_call(struct rxrpc_sock *rx,
  			 struct rxrpc_call *call,
  			 struct sk_buff *skb)
17926a793   David Howells   [AF_RXRPC]: Provi...
341
  {
248f219cb   David Howells   rxrpc: Rewrite th...
342
  	struct rxrpc_connection *conn = call->conn;
42886ffe7   David Howells   rxrpc: Pass sk_bu...
343
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
248f219cb   David Howells   rxrpc: Rewrite th...
344
  	u32 chan;
17926a793   David Howells   [AF_RXRPC]: Provi...
345

248f219cb   David Howells   rxrpc: Rewrite th...
346
  	_enter(",%d", call->conn->debug_id);
e34d4234b   David Howells   rxrpc: Trace rxrp...
347

248f219cb   David Howells   rxrpc: Rewrite th...
348
349
350
351
352
353
354
  	rcu_assign_pointer(call->socket, rx);
  	call->call_id		= sp->hdr.callNumber;
  	call->service_id	= sp->hdr.serviceId;
  	call->cid		= sp->hdr.cid;
  	call->state		= RXRPC_CALL_SERVER_ACCEPTING;
  	if (sp->hdr.securityIndex > 0)
  		call->state	= RXRPC_CALL_SERVER_SECURING;
57494343c   David Howells   rxrpc: Implement ...
355
  	call->cong_tstamp	= skb->tstamp;
248f219cb   David Howells   rxrpc: Rewrite th...
356
357
358
359
360
361
  
  	/* Set the channel for this call.  We don't get channel_lock as we're
  	 * only defending against the data_ready handler (which we're called
  	 * from) and the RESPONSE packet parser (which is only really
  	 * interested in call_counter and can cope with a disagreement with the
  	 * call pointer).
a1399f8bb   David Howells   rxrpc: Call chann...
362
  	 */
248f219cb   David Howells   rxrpc: Rewrite th...
363
364
365
  	chan = sp->hdr.cid & RXRPC_CHANNELMASK;
  	conn->channels[chan].call_counter = call->call_id;
  	conn->channels[chan].call_id = call->call_id;
a1399f8bb   David Howells   rxrpc: Call chann...
366
  	rcu_assign_pointer(conn->channels[chan].call, call);
17926a793   David Howells   [AF_RXRPC]: Provi...
367

85f32278b   David Howells   rxrpc: Replace co...
368
369
370
  	spin_lock(&conn->params.peer->lock);
  	hlist_add_head(&call->error_link, &conn->params.peer->error_targets);
  	spin_unlock(&conn->params.peer->lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
371

17926a793   David Howells   [AF_RXRPC]: Provi...
372
  	_net("CALL incoming %d on CONN %d", call->debug_id, call->conn->debug_id);
248f219cb   David Howells   rxrpc: Rewrite th...
373
374
  	rxrpc_start_call_timer(call);
  	_leave("");
17926a793   David Howells   [AF_RXRPC]: Provi...
375
376
377
  }
  
  /*
8d94aa381   David Howells   rxrpc: Calls shou...
378
379
380
381
382
383
   * Queue a call's work processor, getting a ref to pass to the work queue.
   */
  bool rxrpc_queue_call(struct rxrpc_call *call)
  {
  	const void *here = __builtin_return_address(0);
  	int n = __atomic_add_unless(&call->usage, 1, 0);
8d94aa381   David Howells   rxrpc: Calls shou...
384
385
386
  	if (n == 0)
  		return false;
  	if (rxrpc_queue_work(&call->processor))
2ab27215e   David Howells   rxrpc: Remove skb...
387
  		trace_rxrpc_call(call, rxrpc_call_queued, n + 1, here, NULL);
8d94aa381   David Howells   rxrpc: Calls shou...
388
389
390
391
392
393
394
395
396
397
398
399
  	else
  		rxrpc_put_call(call, rxrpc_call_put_noqueue);
  	return true;
  }
  
  /*
   * Queue a call's work processor, passing the callers ref to the work queue.
   */
  bool __rxrpc_queue_call(struct rxrpc_call *call)
  {
  	const void *here = __builtin_return_address(0);
  	int n = atomic_read(&call->usage);
8d94aa381   David Howells   rxrpc: Calls shou...
400
401
  	ASSERTCMP(n, >=, 1);
  	if (rxrpc_queue_work(&call->processor))
2ab27215e   David Howells   rxrpc: Remove skb...
402
  		trace_rxrpc_call(call, rxrpc_call_queued_ref, n, here, NULL);
8d94aa381   David Howells   rxrpc: Calls shou...
403
404
405
406
407
408
  	else
  		rxrpc_put_call(call, rxrpc_call_put_noqueue);
  	return true;
  }
  
  /*
e34d4234b   David Howells   rxrpc: Trace rxrp...
409
410
411
412
413
414
415
   * Note the re-emergence of a call.
   */
  void rxrpc_see_call(struct rxrpc_call *call)
  {
  	const void *here = __builtin_return_address(0);
  	if (call) {
  		int n = atomic_read(&call->usage);
e34d4234b   David Howells   rxrpc: Trace rxrp...
416

2ab27215e   David Howells   rxrpc: Remove skb...
417
  		trace_rxrpc_call(call, rxrpc_call_seen, n, here, NULL);
e34d4234b   David Howells   rxrpc: Trace rxrp...
418
419
420
421
422
423
  	}
  }
  
  /*
   * Note the addition of a ref on a call.
   */
fff72429c   David Howells   rxrpc: Improve th...
424
  void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
e34d4234b   David Howells   rxrpc: Trace rxrp...
425
426
427
  {
  	const void *here = __builtin_return_address(0);
  	int n = atomic_inc_return(&call->usage);
e34d4234b   David Howells   rxrpc: Trace rxrp...
428

2ab27215e   David Howells   rxrpc: Remove skb...
429
  	trace_rxrpc_call(call, op, n, here, NULL);
e34d4234b   David Howells   rxrpc: Trace rxrp...
430
431
432
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
433
   * Detach a call from its owning socket.
e34d4234b   David Howells   rxrpc: Trace rxrp...
434
   */
248f219cb   David Howells   rxrpc: Rewrite th...
435
  void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
e34d4234b   David Howells   rxrpc: Trace rxrp...
436
  {
a84a46d73   David Howells   rxrpc: Add some a...
437
  	const void *here = __builtin_return_address(0);
248f219cb   David Howells   rxrpc: Rewrite th...
438
439
440
  	struct rxrpc_connection *conn = call->conn;
  	bool put = false;
  	int i;
e34d4234b   David Howells   rxrpc: Trace rxrp...
441

248f219cb   David Howells   rxrpc: Rewrite th...
442
  	_enter("{%d,%d}", call->debug_id, atomic_read(&call->usage));
e34d4234b   David Howells   rxrpc: Trace rxrp...
443

a84a46d73   David Howells   rxrpc: Add some a...
444
445
  	trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage),
  			 here, (const void *)call->flags);
17926a793   David Howells   [AF_RXRPC]: Provi...
446

a84a46d73   David Howells   rxrpc: Add some a...
447
  	ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
e34d4234b   David Howells   rxrpc: Trace rxrp...
448

17926a793   David Howells   [AF_RXRPC]: Provi...
449
450
451
452
  	spin_lock_bh(&call->lock);
  	if (test_and_set_bit(RXRPC_CALL_RELEASED, &call->flags))
  		BUG();
  	spin_unlock_bh(&call->lock);
248f219cb   David Howells   rxrpc: Rewrite th...
453
  	del_timer_sync(&call->timer);
17926a793   David Howells   [AF_RXRPC]: Provi...
454

248f219cb   David Howells   rxrpc: Rewrite th...
455
456
  	/* Make sure we don't get any more notifications */
  	write_lock_bh(&rx->recvmsg_lock);
e653cfe49   David Howells   rxrpc: Release a ...
457

248f219cb   David Howells   rxrpc: Rewrite th...
458
  	if (!list_empty(&call->recvmsg_link)) {
17926a793   David Howells   [AF_RXRPC]: Provi...
459
460
  		_debug("unlinking once-pending call %p { e=%lx f=%lx }",
  		       call, call->events, call->flags);
248f219cb   David Howells   rxrpc: Rewrite th...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  		list_del(&call->recvmsg_link);
  		put = true;
  	}
  
  	/* list_empty() must return false in rxrpc_notify_socket() */
  	call->recvmsg_link.next = NULL;
  	call->recvmsg_link.prev = NULL;
  
  	write_unlock_bh(&rx->recvmsg_lock);
  	if (put)
  		rxrpc_put_call(call, rxrpc_call_put);
  
  	write_lock(&rx->call_lock);
  
  	if (test_and_clear_bit(RXRPC_CALL_HAS_USERID, &call->flags)) {
17926a793   David Howells   [AF_RXRPC]: Provi...
476
477
  		rb_erase(&call->sock_node, &rx->calls);
  		memset(&call->sock_node, 0xdd, sizeof(call->sock_node));
8d94aa381   David Howells   rxrpc: Calls shou...
478
  		rxrpc_put_call(call, rxrpc_call_put_userid);
17926a793   David Howells   [AF_RXRPC]: Provi...
479
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
480

248f219cb   David Howells   rxrpc: Rewrite th...
481
482
483
484
485
486
  	list_del(&call->sock_link);
  	write_unlock(&rx->call_lock);
  
  	_debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, conn);
  
  	if (conn)
8d94aa381   David Howells   rxrpc: Calls shou...
487
  		rxrpc_disconnect_call(call);
e653cfe49   David Howells   rxrpc: Release a ...
488

248f219cb   David Howells   rxrpc: Rewrite th...
489
  	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
71f3ca408   David Howells   rxrpc: Improve sk...
490
491
492
  		rxrpc_free_skb(call->rxtx_buffer[i],
  			       (call->tx_phase ? rxrpc_skb_tx_cleaned :
  				rxrpc_skb_rx_cleaned));
248f219cb   David Howells   rxrpc: Rewrite th...
493
  		call->rxtx_buffer[i] = NULL;
17926a793   David Howells   [AF_RXRPC]: Provi...
494
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
495
496
497
498
499
  
  	_leave("");
  }
  
  /*
c038a58cc   David Howells   rxrpc: Allow fail...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
   * Prepare a kernel service call for retry.
   */
  int rxrpc_prepare_call_for_retry(struct rxrpc_sock *rx, struct rxrpc_call *call)
  {
  	const void *here = __builtin_return_address(0);
  	int i;
  	u8 last = 0;
  
  	_enter("{%d,%d}", call->debug_id, atomic_read(&call->usage));
  
  	trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage),
  			 here, (const void *)call->flags);
  
  	ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
  	ASSERTCMP(call->completion, !=, RXRPC_CALL_REMOTELY_ABORTED);
  	ASSERTCMP(call->completion, !=, RXRPC_CALL_LOCALLY_ABORTED);
  	ASSERT(list_empty(&call->recvmsg_link));
  
  	del_timer_sync(&call->timer);
  
  	_debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, call->conn);
  
  	if (call->conn)
  		rxrpc_disconnect_call(call);
  
  	if (rxrpc_is_service_call(call) ||
  	    !call->tx_phase ||
  	    call->tx_hard_ack != 0 ||
  	    call->rx_hard_ack != 0 ||
  	    call->rx_top != 0)
  		return -EINVAL;
  
  	call->state = RXRPC_CALL_UNINITIALISED;
  	call->completion = RXRPC_CALL_SUCCEEDED;
  	call->call_id = 0;
  	call->cid = 0;
  	call->cong_cwnd = 0;
  	call->cong_extra = 0;
  	call->cong_ssthresh = 0;
  	call->cong_mode = 0;
  	call->cong_dup_acks = 0;
  	call->cong_cumul_acks = 0;
  	call->acks_lowest_nak = 0;
  
  	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
  		last |= call->rxtx_annotations[i];
  		call->rxtx_annotations[i] &= RXRPC_TX_ANNO_LAST;
  		call->rxtx_annotations[i] |= RXRPC_TX_ANNO_RETRANS;
  	}
  
  	_leave(" = 0");
  	return 0;
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
555
556
557
558
559
   * release all the calls associated with a socket
   */
  void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
  {
  	struct rxrpc_call *call;
17926a793   David Howells   [AF_RXRPC]: Provi...
560
561
  
  	_enter("%p", rx);
0360da6db   David Howells   rxrpc: Purge the ...
562
563
564
565
  	while (!list_empty(&rx->to_be_accepted)) {
  		call = list_entry(rx->to_be_accepted.next,
  				  struct rxrpc_call, accept_link);
  		list_del(&call->accept_link);
3a92789af   David Howells   rxrpc: Use negati...
566
  		rxrpc_abort_call("SKR", call, 0, RX_CALL_DEAD, -ECONNRESET);
0360da6db   David Howells   rxrpc: Purge the ...
567
568
  		rxrpc_put_call(call, rxrpc_call_put);
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
569
570
571
572
  	while (!list_empty(&rx->sock_calls)) {
  		call = list_entry(rx->sock_calls.next,
  				  struct rxrpc_call, sock_link);
  		rxrpc_get_call(call, rxrpc_call_got);
3a92789af   David Howells   rxrpc: Use negati...
573
  		rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, -ECONNRESET);
26cb02aa6   David Howells   rxrpc: Fix warnin...
574
  		rxrpc_send_abort_packet(call);
8d94aa381   David Howells   rxrpc: Calls shou...
575
  		rxrpc_release_call(rx, call);
248f219cb   David Howells   rxrpc: Rewrite th...
576
  		rxrpc_put_call(call, rxrpc_call_put);
f36b5e444   David Howells   rxrpc: When clear...
577
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
578
579
580
581
582
583
  	_leave("");
  }
  
  /*
   * release a call
   */
fff72429c   David Howells   rxrpc: Improve th...
584
  void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
17926a793   David Howells   [AF_RXRPC]: Provi...
585
  {
2baec2c3f   David Howells   rxrpc: Support ne...
586
  	struct rxrpc_net *rxnet;
e34d4234b   David Howells   rxrpc: Trace rxrp...
587
  	const void *here = __builtin_return_address(0);
2ab27215e   David Howells   rxrpc: Remove skb...
588
  	int n;
17926a793   David Howells   [AF_RXRPC]: Provi...
589

e34d4234b   David Howells   rxrpc: Trace rxrp...
590
  	ASSERT(call != NULL);
17926a793   David Howells   [AF_RXRPC]: Provi...
591

e34d4234b   David Howells   rxrpc: Trace rxrp...
592
  	n = atomic_dec_return(&call->usage);
2ab27215e   David Howells   rxrpc: Remove skb...
593
  	trace_rxrpc_call(call, op, n, here, NULL);
e34d4234b   David Howells   rxrpc: Trace rxrp...
594
595
596
  	ASSERTCMP(n, >=, 0);
  	if (n == 0) {
  		_debug("call %d dead", call->debug_id);
248f219cb   David Howells   rxrpc: Rewrite th...
597
  		ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
17926a793   David Howells   [AF_RXRPC]: Provi...
598

2baec2c3f   David Howells   rxrpc: Support ne...
599
600
601
602
603
604
  		if (!list_empty(&call->link)) {
  			rxnet = rxrpc_net(sock_net(&call->socket->sk));
  			write_lock(&rxnet->call_lock);
  			list_del_init(&call->link);
  			write_unlock(&rxnet->call_lock);
  		}
e34d4234b   David Howells   rxrpc: Trace rxrp...
605

8d94aa381   David Howells   rxrpc: Calls shou...
606
  		rxrpc_cleanup_call(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
607
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
608
609
610
  }
  
  /*
dee46364c   David Howells   rxrpc: Add RCU de...
611
612
613
614
615
   * Final call destruction under RCU.
   */
  static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
  {
  	struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
df5d8bf70   David Howells   rxrpc: Make /proc...
616
  	rxrpc_put_peer(call->peer);
248f219cb   David Howells   rxrpc: Rewrite th...
617
618
  	kfree(call->rxtx_buffer);
  	kfree(call->rxtx_annotations);
dee46364c   David Howells   rxrpc: Add RCU de...
619
620
621
622
  	kmem_cache_free(rxrpc_call_jar, call);
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
623
624
   * clean up a call
   */
00e907127   David Howells   rxrpc: Preallocat...
625
  void rxrpc_cleanup_call(struct rxrpc_call *call)
17926a793   David Howells   [AF_RXRPC]: Provi...
626
  {
248f219cb   David Howells   rxrpc: Rewrite th...
627
  	int i;
17926a793   David Howells   [AF_RXRPC]: Provi...
628

248f219cb   David Howells   rxrpc: Rewrite th...
629
  	_net("DESTROY CALL %d", call->debug_id);
17926a793   David Howells   [AF_RXRPC]: Provi...
630
631
  
  	memset(&call->sock_node, 0xcd, sizeof(call->sock_node));
248f219cb   David Howells   rxrpc: Rewrite th...
632
  	del_timer_sync(&call->timer);
17926a793   David Howells   [AF_RXRPC]: Provi...
633

8d94aa381   David Howells   rxrpc: Calls shou...
634
  	ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
17926a793   David Howells   [AF_RXRPC]: Provi...
635
  	ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags));
e653cfe49   David Howells   rxrpc: Release a ...
636
  	ASSERTCMP(call->conn, ==, NULL);
17926a793   David Howells   [AF_RXRPC]: Provi...
637

248f219cb   David Howells   rxrpc: Rewrite th...
638
639
  	/* Clean up the Rx/Tx buffer */
  	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++)
71f3ca408   David Howells   rxrpc: Improve sk...
640
641
642
  		rxrpc_free_skb(call->rxtx_buffer[i],
  			       (call->tx_phase ? rxrpc_skb_tx_cleaned :
  				rxrpc_skb_rx_cleaned));
17926a793   David Howells   [AF_RXRPC]: Provi...
643

71f3ca408   David Howells   rxrpc: Improve sk...
644
  	rxrpc_free_skb(call->tx_pending, rxrpc_skb_tx_cleaned);
17926a793   David Howells   [AF_RXRPC]: Provi...
645

dee46364c   David Howells   rxrpc: Add RCU de...
646
  	call_rcu(&call->rcu, rxrpc_rcu_destroy_call);
17926a793   David Howells   [AF_RXRPC]: Provi...
647
648
649
  }
  
  /*
2baec2c3f   David Howells   rxrpc: Support ne...
650
651
652
   * Make sure that all calls are gone from a network namespace.  To reach this
   * point, any open UDP sockets in that namespace must have been closed, so any
   * outstanding calls cannot be doing I/O.
17926a793   David Howells   [AF_RXRPC]: Provi...
653
   */
2baec2c3f   David Howells   rxrpc: Support ne...
654
  void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
17926a793   David Howells   [AF_RXRPC]: Provi...
655
656
657
658
  {
  	struct rxrpc_call *call;
  
  	_enter("");
8d94aa381   David Howells   rxrpc: Calls shou...
659

2baec2c3f   David Howells   rxrpc: Support ne...
660
  	if (list_empty(&rxnet->calls))
8d94aa381   David Howells   rxrpc: Calls shou...
661
  		return;
248f219cb   David Howells   rxrpc: Rewrite th...
662

2baec2c3f   David Howells   rxrpc: Support ne...
663
  	write_lock(&rxnet->call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
664

2baec2c3f   David Howells   rxrpc: Support ne...
665
666
  	while (!list_empty(&rxnet->calls)) {
  		call = list_entry(rxnet->calls.next, struct rxrpc_call, link);
17926a793   David Howells   [AF_RXRPC]: Provi...
667
  		_debug("Zapping call %p", call);
e34d4234b   David Howells   rxrpc: Trace rxrp...
668
  		rxrpc_see_call(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
669
  		list_del_init(&call->link);
248f219cb   David Howells   rxrpc: Rewrite th...
670
671
  		pr_err("Call %p still in use (%d,%s,%lx,%lx)!
  ",
8d94aa381   David Howells   rxrpc: Calls shou...
672
  		       call, atomic_read(&call->usage),
8d94aa381   David Howells   rxrpc: Calls shou...
673
674
  		       rxrpc_call_states[call->state],
  		       call->flags, call->events);
17926a793   David Howells   [AF_RXRPC]: Provi...
675

2baec2c3f   David Howells   rxrpc: Support ne...
676
  		write_unlock(&rxnet->call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
677
  		cond_resched();
2baec2c3f   David Howells   rxrpc: Support ne...
678
  		write_lock(&rxnet->call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
679
  	}
2baec2c3f   David Howells   rxrpc: Support ne...
680
  	write_unlock(&rxnet->call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
681
  }