Blame view

net/rxrpc/call_object.c 15.6 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
  };
fff72429c   David Howells   rxrpc: Improve th...
42
43
44
45
46
  const char rxrpc_call_traces[rxrpc_call__nr_trace][4] = {
  	[rxrpc_call_new_client]		= "NWc",
  	[rxrpc_call_new_service]	= "NWs",
  	[rxrpc_call_queued]		= "QUE",
  	[rxrpc_call_queued_ref]		= "QUR",
a84a46d73   David Howells   rxrpc: Add some a...
47
48
  	[rxrpc_call_connected]		= "CON",
  	[rxrpc_call_release]		= "RLS",
fff72429c   David Howells   rxrpc: Improve th...
49
50
  	[rxrpc_call_seen]		= "SEE",
  	[rxrpc_call_got]		= "GOT",
fff72429c   David Howells   rxrpc: Improve th...
51
  	[rxrpc_call_got_userid]		= "Gus",
cbd00891d   David Howells   rxrpc: Adjust the...
52
  	[rxrpc_call_got_kernel]		= "Gke",
fff72429c   David Howells   rxrpc: Improve th...
53
  	[rxrpc_call_put]		= "PUT",
fff72429c   David Howells   rxrpc: Improve th...
54
  	[rxrpc_call_put_userid]		= "Pus",
cbd00891d   David Howells   rxrpc: Adjust the...
55
  	[rxrpc_call_put_kernel]		= "Pke",
fff72429c   David Howells   rxrpc: Improve th...
56
  	[rxrpc_call_put_noqueue]	= "PNQ",
a84a46d73   David Howells   rxrpc: Add some a...
57
  	[rxrpc_call_error]		= "*E*",
fff72429c   David Howells   rxrpc: Improve th...
58
  };
17926a793   David Howells   [AF_RXRPC]: Provi...
59
60
61
  struct kmem_cache *rxrpc_call_jar;
  LIST_HEAD(rxrpc_calls);
  DEFINE_RWLOCK(rxrpc_call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
62

248f219cb   David Howells   rxrpc: Rewrite th...
63
64
65
66
67
  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...
68
69
  	if (call->state < RXRPC_CALL_COMPLETE)
  		rxrpc_set_timer(call, rxrpc_timer_expired, ktime_get_real());
248f219cb   David Howells   rxrpc: Rewrite th...
70
  }
17926a793   David Howells   [AF_RXRPC]: Provi...
71
72
  
  /*
2341e0775   David Howells   rxrpc: Simplify c...
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
   * 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...
103
  	rxrpc_get_call(call, rxrpc_call_got);
2341e0775   David Howells   rxrpc: Simplify c...
104
105
106
107
108
109
  	read_unlock(&rx->call_lock);
  	_leave(" = %p [%d]", call, atomic_read(&call->usage));
  	return call;
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
110
111
   * allocate a new call
   */
00e907127   David Howells   rxrpc: Preallocat...
112
  struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
17926a793   David Howells   [AF_RXRPC]: Provi...
113
114
115
116
117
118
  {
  	struct rxrpc_call *call;
  
  	call = kmem_cache_zalloc(rxrpc_call_jar, gfp);
  	if (!call)
  		return NULL;
248f219cb   David Howells   rxrpc: Rewrite th...
119
120
  	call->rxtx_buffer = kcalloc(RXRPC_RXTX_BUFF_SIZE,
  				    sizeof(struct sk_buff *),
17926a793   David Howells   [AF_RXRPC]: Provi...
121
  				    gfp);
248f219cb   David Howells   rxrpc: Rewrite th...
122
123
  	if (!call->rxtx_buffer)
  		goto nomem;
17926a793   David Howells   [AF_RXRPC]: Provi...
124

248f219cb   David Howells   rxrpc: Rewrite th...
125
126
127
128
129
130
  	call->rxtx_annotations = kcalloc(RXRPC_RXTX_BUFF_SIZE, sizeof(u8), gfp);
  	if (!call->rxtx_annotations)
  		goto nomem_2;
  
  	setup_timer(&call->timer, rxrpc_call_timer_expired,
  		    (unsigned long)call);
17926a793   David Howells   [AF_RXRPC]: Provi...
131
  	INIT_WORK(&call->processor, &rxrpc_process_call);
999b69f89   David Howells   rxrpc: Kill the c...
132
  	INIT_LIST_HEAD(&call->link);
45025bcee   David Howells   rxrpc: Improve ma...
133
  	INIT_LIST_HEAD(&call->chan_wait_link);
17926a793   David Howells   [AF_RXRPC]: Provi...
134
  	INIT_LIST_HEAD(&call->accept_link);
248f219cb   David Howells   rxrpc: Rewrite th...
135
136
  	INIT_LIST_HEAD(&call->recvmsg_link);
  	INIT_LIST_HEAD(&call->sock_link);
45025bcee   David Howells   rxrpc: Improve ma...
137
  	init_waitqueue_head(&call->waitq);
17926a793   David Howells   [AF_RXRPC]: Provi...
138
139
140
141
  	spin_lock_init(&call->lock);
  	rwlock_init(&call->state_lock);
  	atomic_set(&call->usage, 1);
  	call->debug_id = atomic_inc_return(&rxrpc_debug_id);
17926a793   David Howells   [AF_RXRPC]: Provi...
142
143
  
  	memset(&call->sock_node, 0xed, sizeof(call->sock_node));
248f219cb   David Howells   rxrpc: Rewrite th...
144
  	/* Leave space in the ring to handle a maxed-out jumbo packet */
75e421263   David Howells   rxrpc: Correctly ...
145
  	call->rx_winsize = rxrpc_rx_window_size;
248f219cb   David Howells   rxrpc: Rewrite th...
146
147
  	call->tx_winsize = 16;
  	call->rx_expect_next = 1;
57494343c   David Howells   rxrpc: Implement ...
148
149
150
151
152
153
154
155
  
  	if (RXRPC_TX_SMSS > 2190)
  		call->cong_cwnd = 2;
  	else if (RXRPC_TX_SMSS > 1095)
  		call->cong_cwnd = 3;
  	else
  		call->cong_cwnd = 4;
  	call->cong_ssthresh = RXRPC_RXTX_BUFF_SIZE - 1;
17926a793   David Howells   [AF_RXRPC]: Provi...
156
  	return call;
248f219cb   David Howells   rxrpc: Rewrite th...
157
158
159
160
161
162
  
  nomem_2:
  	kfree(call->rxtx_buffer);
  nomem:
  	kmem_cache_free(rxrpc_call_jar, call);
  	return NULL;
17926a793   David Howells   [AF_RXRPC]: Provi...
163
164
165
  }
  
  /*
999b69f89   David Howells   rxrpc: Kill the c...
166
   * Allocate a new client call.
17926a793   David Howells   [AF_RXRPC]: Provi...
167
   */
248f219cb   David Howells   rxrpc: Rewrite th...
168
  static struct rxrpc_call *rxrpc_alloc_client_call(struct sockaddr_rxrpc *srx,
aa390bbe2   David Howells   rxrpc: Kill off t...
169
  						  gfp_t gfp)
17926a793   David Howells   [AF_RXRPC]: Provi...
170
171
  {
  	struct rxrpc_call *call;
57494343c   David Howells   rxrpc: Implement ...
172
  	ktime_t now;
17926a793   David Howells   [AF_RXRPC]: Provi...
173
174
  
  	_enter("");
17926a793   David Howells   [AF_RXRPC]: Provi...
175
176
177
  	call = rxrpc_alloc_call(gfp);
  	if (!call)
  		return ERR_PTR(-ENOMEM);
999b69f89   David Howells   rxrpc: Kill the c...
178
  	call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
999b69f89   David Howells   rxrpc: Kill the c...
179
  	call->service_id = srx->srx_service;
71f3ca408   David Howells   rxrpc: Improve sk...
180
  	call->tx_phase = true;
57494343c   David Howells   rxrpc: Implement ...
181
182
183
  	now = ktime_get_real();
  	call->acks_latest_ts = now;
  	call->cong_tstamp = now;
999b69f89   David Howells   rxrpc: Kill the c...
184
185
186
187
188
189
  
  	_leave(" = %p", call);
  	return call;
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
190
   * Initiate the call ack/resend/expiry timer.
999b69f89   David Howells   rxrpc: Kill the c...
191
   */
248f219cb   David Howells   rxrpc: Rewrite th...
192
  static void rxrpc_start_call_timer(struct rxrpc_call *call)
999b69f89   David Howells   rxrpc: Kill the c...
193
  {
df0adc788   David Howells   rxrpc: Keep the c...
194
  	ktime_t now = ktime_get_real(), expire_at;
248f219cb   David Howells   rxrpc: Rewrite th...
195

df0adc788   David Howells   rxrpc: Keep the c...
196
  	expire_at = ktime_add_ms(now, rxrpc_max_call_lifetime);
248f219cb   David Howells   rxrpc: Rewrite th...
197
198
  	call->expire_at = expire_at;
  	call->ack_at = expire_at;
a5af7e1fc   David Howells   rxrpc: Fix loss o...
199
  	call->ping_at = expire_at;
248f219cb   David Howells   rxrpc: Rewrite th...
200
  	call->resend_at = expire_at;
df0adc788   David Howells   rxrpc: Keep the c...
201
202
  	call->timer.expires = jiffies + LONG_MAX / 2;
  	rxrpc_set_timer(call, rxrpc_timer_begin, now);
17926a793   David Howells   [AF_RXRPC]: Provi...
203
204
205
206
207
208
  }
  
  /*
   * set up a call for the given data
   * - called in process context with IRQs enabled
   */
2341e0775   David Howells   rxrpc: Simplify c...
209
  struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
19ffa01c9   David Howells   rxrpc: Use struct...
210
  					 struct rxrpc_conn_parameters *cp,
999b69f89   David Howells   rxrpc: Kill the c...
211
  					 struct sockaddr_rxrpc *srx,
17926a793   David Howells   [AF_RXRPC]: Provi...
212
  					 unsigned long user_call_ID,
17926a793   David Howells   [AF_RXRPC]: Provi...
213
214
  					 gfp_t gfp)
  {
2341e0775   David Howells   rxrpc: Simplify c...
215
216
  	struct rxrpc_call *call, *xcall;
  	struct rb_node *parent, **pp;
e34d4234b   David Howells   rxrpc: Trace rxrp...
217
  	const void *here = __builtin_return_address(0);
999b69f89   David Howells   rxrpc: Kill the c...
218
  	int ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
219

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

248f219cb   David Howells   rxrpc: Rewrite th...
222
  	call = rxrpc_alloc_client_call(srx, gfp);
2341e0775   David Howells   rxrpc: Simplify c...
223
224
225
  	if (IS_ERR(call)) {
  		_leave(" = %ld", PTR_ERR(call));
  		return call;
17926a793   David Howells   [AF_RXRPC]: Provi...
226
  	}
a84a46d73   David Howells   rxrpc: Add some a...
227
228
  	trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage),
  			 here, (const void *)user_call_ID);
e34d4234b   David Howells   rxrpc: Trace rxrp...
229

999b69f89   David Howells   rxrpc: Kill the c...
230
  	/* Publish the call, even though it is incompletely set up as yet */
17926a793   David Howells   [AF_RXRPC]: Provi...
231
232
233
234
235
236
  	write_lock(&rx->call_lock);
  
  	pp = &rx->calls.rb_node;
  	parent = NULL;
  	while (*pp) {
  		parent = *pp;
2341e0775   David Howells   rxrpc: Simplify c...
237
  		xcall = rb_entry(parent, struct rxrpc_call, sock_node);
17926a793   David Howells   [AF_RXRPC]: Provi...
238

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

248f219cb   David Howells   rxrpc: Rewrite th...
258
259
260
261
  	/* 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...
262
263
  	if (ret < 0)
  		goto error;
a84a46d73   David Howells   rxrpc: Add some a...
264
  	trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage),
54fde4234   David Howells   rxrpc: Fix checke...
265
  			 here, NULL);
a84a46d73   David Howells   rxrpc: Add some a...
266

248f219cb   David Howells   rxrpc: Rewrite th...
267
268
269
270
271
272
  	spin_lock_bh(&call->conn->params.peer->lock);
  	hlist_add_head(&call->error_link,
  		       &call->conn->params.peer->error_targets);
  	spin_unlock_bh(&call->conn->params.peer->lock);
  
  	rxrpc_start_call_timer(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
273
274
275
276
  	_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...
277
278
279
280
281
  	/* 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...
282
  error_dup_user_ID:
17926a793   David Howells   [AF_RXRPC]: Provi...
283
  	write_unlock(&rx->call_lock);
8d94aa381   David Howells   rxrpc: Calls shou...
284
  	ret = -EEXIST;
357f5ef64   David Howells   rxrpc: Call rxrpc...
285
286
287
288
  
  error:
  	__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
  				    RX_CALL_DEAD, ret);
a84a46d73   David Howells   rxrpc: Add some a...
289
290
  	trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage),
  			 here, ERR_PTR(ret));
357f5ef64   David Howells   rxrpc: Call rxrpc...
291
292
293
294
  	rxrpc_release_call(rx, call);
  	rxrpc_put_call(call, rxrpc_call_put);
  	_leave(" = %d", ret);
  	return ERR_PTR(ret);
17926a793   David Howells   [AF_RXRPC]: Provi...
295
296
297
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
298
299
   * 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...
300
   */
248f219cb   David Howells   rxrpc: Rewrite th...
301
302
303
  void rxrpc_incoming_call(struct rxrpc_sock *rx,
  			 struct rxrpc_call *call,
  			 struct sk_buff *skb)
17926a793   David Howells   [AF_RXRPC]: Provi...
304
  {
248f219cb   David Howells   rxrpc: Rewrite th...
305
  	struct rxrpc_connection *conn = call->conn;
42886ffe7   David Howells   rxrpc: Pass sk_bu...
306
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
248f219cb   David Howells   rxrpc: Rewrite th...
307
  	u32 chan;
17926a793   David Howells   [AF_RXRPC]: Provi...
308

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

248f219cb   David Howells   rxrpc: Rewrite th...
311
312
313
314
315
316
317
  	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 ...
318
  	call->cong_tstamp	= skb->tstamp;
248f219cb   David Howells   rxrpc: Rewrite th...
319
320
321
322
323
324
  
  	/* 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...
325
  	 */
248f219cb   David Howells   rxrpc: Rewrite th...
326
327
328
  	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...
329
  	rcu_assign_pointer(conn->channels[chan].call, call);
17926a793   David Howells   [AF_RXRPC]: Provi...
330

85f32278b   David Howells   rxrpc: Replace co...
331
332
333
  	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...
334

17926a793   David Howells   [AF_RXRPC]: Provi...
335
  	_net("CALL incoming %d on CONN %d", call->debug_id, call->conn->debug_id);
248f219cb   David Howells   rxrpc: Rewrite th...
336
337
  	rxrpc_start_call_timer(call);
  	_leave("");
17926a793   David Howells   [AF_RXRPC]: Provi...
338
339
340
  }
  
  /*
8d94aa381   David Howells   rxrpc: Calls shou...
341
342
343
344
345
346
   * 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...
347
348
349
  	if (n == 0)
  		return false;
  	if (rxrpc_queue_work(&call->processor))
2ab27215e   David Howells   rxrpc: Remove skb...
350
  		trace_rxrpc_call(call, rxrpc_call_queued, n + 1, here, NULL);
8d94aa381   David Howells   rxrpc: Calls shou...
351
352
353
354
355
356
357
358
359
360
361
362
  	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...
363
364
  	ASSERTCMP(n, >=, 1);
  	if (rxrpc_queue_work(&call->processor))
2ab27215e   David Howells   rxrpc: Remove skb...
365
  		trace_rxrpc_call(call, rxrpc_call_queued_ref, n, here, NULL);
8d94aa381   David Howells   rxrpc: Calls shou...
366
367
368
369
370
371
  	else
  		rxrpc_put_call(call, rxrpc_call_put_noqueue);
  	return true;
  }
  
  /*
e34d4234b   David Howells   rxrpc: Trace rxrp...
372
373
374
375
376
377
378
   * 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...
379

2ab27215e   David Howells   rxrpc: Remove skb...
380
  		trace_rxrpc_call(call, rxrpc_call_seen, n, here, NULL);
e34d4234b   David Howells   rxrpc: Trace rxrp...
381
382
383
384
385
386
  	}
  }
  
  /*
   * Note the addition of a ref on a call.
   */
fff72429c   David Howells   rxrpc: Improve th...
387
  void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
e34d4234b   David Howells   rxrpc: Trace rxrp...
388
389
390
  {
  	const void *here = __builtin_return_address(0);
  	int n = atomic_inc_return(&call->usage);
e34d4234b   David Howells   rxrpc: Trace rxrp...
391

2ab27215e   David Howells   rxrpc: Remove skb...
392
  	trace_rxrpc_call(call, op, n, here, NULL);
e34d4234b   David Howells   rxrpc: Trace rxrp...
393
394
395
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
396
   * Detach a call from its owning socket.
e34d4234b   David Howells   rxrpc: Trace rxrp...
397
   */
248f219cb   David Howells   rxrpc: Rewrite th...
398
  void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
e34d4234b   David Howells   rxrpc: Trace rxrp...
399
  {
a84a46d73   David Howells   rxrpc: Add some a...
400
  	const void *here = __builtin_return_address(0);
248f219cb   David Howells   rxrpc: Rewrite th...
401
402
403
  	struct rxrpc_connection *conn = call->conn;
  	bool put = false;
  	int i;
e34d4234b   David Howells   rxrpc: Trace rxrp...
404

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

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

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

17926a793   David Howells   [AF_RXRPC]: Provi...
412
413
414
415
  	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...
416
  	del_timer_sync(&call->timer);
17926a793   David Howells   [AF_RXRPC]: Provi...
417

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

248f219cb   David Howells   rxrpc: Rewrite th...
421
  	if (!list_empty(&call->recvmsg_link)) {
17926a793   David Howells   [AF_RXRPC]: Provi...
422
423
  		_debug("unlinking once-pending call %p { e=%lx f=%lx }",
  		       call, call->events, call->flags);
248f219cb   David Howells   rxrpc: Rewrite th...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
  		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...
439
440
  		rb_erase(&call->sock_node, &rx->calls);
  		memset(&call->sock_node, 0xdd, sizeof(call->sock_node));
8d94aa381   David Howells   rxrpc: Calls shou...
441
  		rxrpc_put_call(call, rxrpc_call_put_userid);
17926a793   David Howells   [AF_RXRPC]: Provi...
442
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
443

248f219cb   David Howells   rxrpc: Rewrite th...
444
445
446
447
448
449
  	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...
450
  		rxrpc_disconnect_call(call);
e653cfe49   David Howells   rxrpc: Release a ...
451

248f219cb   David Howells   rxrpc: Rewrite th...
452
  	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
71f3ca408   David Howells   rxrpc: Improve sk...
453
454
455
  		rxrpc_free_skb(call->rxtx_buffer[i],
  			       (call->tx_phase ? rxrpc_skb_tx_cleaned :
  				rxrpc_skb_rx_cleaned));
248f219cb   David Howells   rxrpc: Rewrite th...
456
  		call->rxtx_buffer[i] = NULL;
17926a793   David Howells   [AF_RXRPC]: Provi...
457
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
458
459
460
461
462
  
  	_leave("");
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
463
464
465
466
467
   * 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...
468
469
  
  	_enter("%p", rx);
0360da6db   David Howells   rxrpc: Purge the ...
470
471
472
473
474
  	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);
  		rxrpc_abort_call("SKR", call, 0, RX_CALL_DEAD, ECONNRESET);
0360da6db   David Howells   rxrpc: Purge the ...
475
476
  		rxrpc_put_call(call, rxrpc_call_put);
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
477
478
479
480
481
  	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);
  		rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, ECONNRESET);
26cb02aa6   David Howells   rxrpc: Fix warnin...
482
  		rxrpc_send_abort_packet(call);
8d94aa381   David Howells   rxrpc: Calls shou...
483
  		rxrpc_release_call(rx, call);
248f219cb   David Howells   rxrpc: Rewrite th...
484
  		rxrpc_put_call(call, rxrpc_call_put);
f36b5e444   David Howells   rxrpc: When clear...
485
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
486
487
488
489
490
491
  	_leave("");
  }
  
  /*
   * release a call
   */
fff72429c   David Howells   rxrpc: Improve th...
492
  void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
17926a793   David Howells   [AF_RXRPC]: Provi...
493
  {
e34d4234b   David Howells   rxrpc: Trace rxrp...
494
  	const void *here = __builtin_return_address(0);
2ab27215e   David Howells   rxrpc: Remove skb...
495
  	int n;
17926a793   David Howells   [AF_RXRPC]: Provi...
496

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

e34d4234b   David Howells   rxrpc: Trace rxrp...
499
  	n = atomic_dec_return(&call->usage);
2ab27215e   David Howells   rxrpc: Remove skb...
500
  	trace_rxrpc_call(call, op, n, here, NULL);
e34d4234b   David Howells   rxrpc: Trace rxrp...
501
502
503
  	ASSERTCMP(n, >=, 0);
  	if (n == 0) {
  		_debug("call %d dead", call->debug_id);
248f219cb   David Howells   rxrpc: Rewrite th...
504
  		ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
17926a793   David Howells   [AF_RXRPC]: Provi...
505

248f219cb   David Howells   rxrpc: Rewrite th...
506
507
508
  		write_lock(&rxrpc_call_lock);
  		list_del_init(&call->link);
  		write_unlock(&rxrpc_call_lock);
e34d4234b   David Howells   rxrpc: Trace rxrp...
509

8d94aa381   David Howells   rxrpc: Calls shou...
510
  		rxrpc_cleanup_call(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
511
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
512
513
514
  }
  
  /*
dee46364c   David Howells   rxrpc: Add RCU de...
515
516
517
518
519
   * 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...
520
  	rxrpc_put_peer(call->peer);
248f219cb   David Howells   rxrpc: Rewrite th...
521
522
  	kfree(call->rxtx_buffer);
  	kfree(call->rxtx_annotations);
dee46364c   David Howells   rxrpc: Add RCU de...
523
524
525
526
  	kmem_cache_free(rxrpc_call_jar, call);
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
527
528
   * clean up a call
   */
00e907127   David Howells   rxrpc: Preallocat...
529
  void rxrpc_cleanup_call(struct rxrpc_call *call)
17926a793   David Howells   [AF_RXRPC]: Provi...
530
  {
248f219cb   David Howells   rxrpc: Rewrite th...
531
  	int i;
17926a793   David Howells   [AF_RXRPC]: Provi...
532

248f219cb   David Howells   rxrpc: Rewrite th...
533
  	_net("DESTROY CALL %d", call->debug_id);
17926a793   David Howells   [AF_RXRPC]: Provi...
534
535
  
  	memset(&call->sock_node, 0xcd, sizeof(call->sock_node));
248f219cb   David Howells   rxrpc: Rewrite th...
536
  	del_timer_sync(&call->timer);
17926a793   David Howells   [AF_RXRPC]: Provi...
537

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

248f219cb   David Howells   rxrpc: Rewrite th...
542
543
  	/* Clean up the Rx/Tx buffer */
  	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++)
71f3ca408   David Howells   rxrpc: Improve sk...
544
545
546
  		rxrpc_free_skb(call->rxtx_buffer[i],
  			       (call->tx_phase ? rxrpc_skb_tx_cleaned :
  				rxrpc_skb_rx_cleaned));
17926a793   David Howells   [AF_RXRPC]: Provi...
547

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

dee46364c   David Howells   rxrpc: Add RCU de...
550
  	call_rcu(&call->rcu, rxrpc_rcu_destroy_call);
17926a793   David Howells   [AF_RXRPC]: Provi...
551
552
553
  }
  
  /*
8d94aa381   David Howells   rxrpc: Calls shou...
554
   * Make sure that all calls are gone.
17926a793   David Howells   [AF_RXRPC]: Provi...
555
556
557
558
559
560
   */
  void __exit rxrpc_destroy_all_calls(void)
  {
  	struct rxrpc_call *call;
  
  	_enter("");
8d94aa381   David Howells   rxrpc: Calls shou...
561
562
563
  
  	if (list_empty(&rxrpc_calls))
  		return;
248f219cb   David Howells   rxrpc: Rewrite th...
564
565
  
  	write_lock(&rxrpc_call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
566
567
568
569
  
  	while (!list_empty(&rxrpc_calls)) {
  		call = list_entry(rxrpc_calls.next, struct rxrpc_call, link);
  		_debug("Zapping call %p", call);
e34d4234b   David Howells   rxrpc: Trace rxrp...
570
  		rxrpc_see_call(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
571
  		list_del_init(&call->link);
248f219cb   David Howells   rxrpc: Rewrite th...
572
573
  		pr_err("Call %p still in use (%d,%s,%lx,%lx)!
  ",
8d94aa381   David Howells   rxrpc: Calls shou...
574
  		       call, atomic_read(&call->usage),
8d94aa381   David Howells   rxrpc: Calls shou...
575
576
  		       rxrpc_call_states[call->state],
  		       call->flags, call->events);
17926a793   David Howells   [AF_RXRPC]: Provi...
577

248f219cb   David Howells   rxrpc: Rewrite th...
578
  		write_unlock(&rxrpc_call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
579
  		cond_resched();
248f219cb   David Howells   rxrpc: Rewrite th...
580
  		write_lock(&rxrpc_call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
581
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
582
  	write_unlock(&rxrpc_call_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
583
  }