Blame view
net/rxrpc/call_object.c
15.6 KB
17926a793 [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 rxrpc: Use pr_<le... |
11 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
5a0e3ad6a include cleanup: ... |
12 |
#include <linux/slab.h> |
17926a793 [AF_RXRPC]: Provi... |
13 14 |
#include <linux/module.h> #include <linux/circ_buf.h> |
7727640cc af_rxrpc: Keep rx... |
15 |
#include <linux/spinlock_types.h> |
17926a793 [AF_RXRPC]: Provi... |
16 17 18 |
#include <net/sock.h> #include <net/af_rxrpc.h> #include "ar-internal.h" |
5b8848d14 rxrpc: Convert ca... |
19 |
const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = { |
f5c17aaeb rxrpc: Calls shou... |
20 |
[RXRPC_CALL_UNINITIALISED] = "Uninit ", |
999b69f89 rxrpc: Kill the c... |
21 |
[RXRPC_CALL_CLIENT_AWAIT_CONN] = "ClWtConn", |
1f8481d19 [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 rxrpc: Preallocat... |
25 |
[RXRPC_CALL_SERVER_PREALLOC] = "SvPrealc", |
1f8481d19 [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 rxrpc: Calls shou... |
33 34 35 36 |
}; const char *const rxrpc_call_completions[NR__RXRPC_CALL_COMPLETIONS] = { [RXRPC_CALL_SUCCEEDED] = "Complete", |
1f8481d19 [AF_RXRPC]: Make ... |
37 38 |
[RXRPC_CALL_REMOTELY_ABORTED] = "RmtAbort", [RXRPC_CALL_LOCALLY_ABORTED] = "LocAbort", |
f5c17aaeb rxrpc: Calls shou... |
39 |
[RXRPC_CALL_LOCAL_ERROR] = "LocError", |
1f8481d19 [AF_RXRPC]: Make ... |
40 |
[RXRPC_CALL_NETWORK_ERROR] = "NetError", |
1f8481d19 [AF_RXRPC]: Make ... |
41 |
}; |
fff72429c 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 rxrpc: Add some a... |
47 48 |
[rxrpc_call_connected] = "CON", [rxrpc_call_release] = "RLS", |
fff72429c rxrpc: Improve th... |
49 50 |
[rxrpc_call_seen] = "SEE", [rxrpc_call_got] = "GOT", |
fff72429c rxrpc: Improve th... |
51 |
[rxrpc_call_got_userid] = "Gus", |
cbd00891d rxrpc: Adjust the... |
52 |
[rxrpc_call_got_kernel] = "Gke", |
fff72429c rxrpc: Improve th... |
53 |
[rxrpc_call_put] = "PUT", |
fff72429c rxrpc: Improve th... |
54 |
[rxrpc_call_put_userid] = "Pus", |
cbd00891d rxrpc: Adjust the... |
55 |
[rxrpc_call_put_kernel] = "Pke", |
fff72429c rxrpc: Improve th... |
56 |
[rxrpc_call_put_noqueue] = "PNQ", |
a84a46d73 rxrpc: Add some a... |
57 |
[rxrpc_call_error] = "*E*", |
fff72429c rxrpc: Improve th... |
58 |
}; |
17926a793 [AF_RXRPC]: Provi... |
59 60 61 |
struct kmem_cache *rxrpc_call_jar; LIST_HEAD(rxrpc_calls); DEFINE_RWLOCK(rxrpc_call_lock); |
17926a793 [AF_RXRPC]: Provi... |
62 |
|
248f219cb 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 rxrpc: Fix the ca... |
68 69 |
if (call->state < RXRPC_CALL_COMPLETE) rxrpc_set_timer(call, rxrpc_timer_expired, ktime_get_real()); |
248f219cb rxrpc: Rewrite th... |
70 |
} |
17926a793 [AF_RXRPC]: Provi... |
71 72 |
/* |
2341e0775 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 rxrpc: Improve th... |
103 |
rxrpc_get_call(call, rxrpc_call_got); |
2341e0775 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 [AF_RXRPC]: Provi... |
110 111 |
* allocate a new call */ |
00e907127 rxrpc: Preallocat... |
112 |
struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp) |
17926a793 [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 rxrpc: Rewrite th... |
119 120 |
call->rxtx_buffer = kcalloc(RXRPC_RXTX_BUFF_SIZE, sizeof(struct sk_buff *), |
17926a793 [AF_RXRPC]: Provi... |
121 |
gfp); |
248f219cb rxrpc: Rewrite th... |
122 123 |
if (!call->rxtx_buffer) goto nomem; |
17926a793 [AF_RXRPC]: Provi... |
124 |
|
248f219cb 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 [AF_RXRPC]: Provi... |
131 |
INIT_WORK(&call->processor, &rxrpc_process_call); |
999b69f89 rxrpc: Kill the c... |
132 |
INIT_LIST_HEAD(&call->link); |
45025bcee rxrpc: Improve ma... |
133 |
INIT_LIST_HEAD(&call->chan_wait_link); |
17926a793 [AF_RXRPC]: Provi... |
134 |
INIT_LIST_HEAD(&call->accept_link); |
248f219cb rxrpc: Rewrite th... |
135 136 |
INIT_LIST_HEAD(&call->recvmsg_link); INIT_LIST_HEAD(&call->sock_link); |
45025bcee rxrpc: Improve ma... |
137 |
init_waitqueue_head(&call->waitq); |
17926a793 [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 [AF_RXRPC]: Provi... |
142 143 |
memset(&call->sock_node, 0xed, sizeof(call->sock_node)); |
248f219cb rxrpc: Rewrite th... |
144 |
/* Leave space in the ring to handle a maxed-out jumbo packet */ |
75e421263 rxrpc: Correctly ... |
145 |
call->rx_winsize = rxrpc_rx_window_size; |
248f219cb rxrpc: Rewrite th... |
146 147 |
call->tx_winsize = 16; call->rx_expect_next = 1; |
57494343c 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 [AF_RXRPC]: Provi... |
156 |
return call; |
248f219cb 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 [AF_RXRPC]: Provi... |
163 164 165 |
} /* |
999b69f89 rxrpc: Kill the c... |
166 |
* Allocate a new client call. |
17926a793 [AF_RXRPC]: Provi... |
167 |
*/ |
248f219cb rxrpc: Rewrite th... |
168 |
static struct rxrpc_call *rxrpc_alloc_client_call(struct sockaddr_rxrpc *srx, |
aa390bbe2 rxrpc: Kill off t... |
169 |
gfp_t gfp) |
17926a793 [AF_RXRPC]: Provi... |
170 171 |
{ struct rxrpc_call *call; |
57494343c rxrpc: Implement ... |
172 |
ktime_t now; |
17926a793 [AF_RXRPC]: Provi... |
173 174 |
_enter(""); |
17926a793 [AF_RXRPC]: Provi... |
175 176 177 |
call = rxrpc_alloc_call(gfp); if (!call) return ERR_PTR(-ENOMEM); |
999b69f89 rxrpc: Kill the c... |
178 |
call->state = RXRPC_CALL_CLIENT_AWAIT_CONN; |
999b69f89 rxrpc: Kill the c... |
179 |
call->service_id = srx->srx_service; |
71f3ca408 rxrpc: Improve sk... |
180 |
call->tx_phase = true; |
57494343c rxrpc: Implement ... |
181 182 183 |
now = ktime_get_real(); call->acks_latest_ts = now; call->cong_tstamp = now; |
999b69f89 rxrpc: Kill the c... |
184 185 186 187 188 189 |
_leave(" = %p", call); return call; } /* |
248f219cb rxrpc: Rewrite th... |
190 |
* Initiate the call ack/resend/expiry timer. |
999b69f89 rxrpc: Kill the c... |
191 |
*/ |
248f219cb rxrpc: Rewrite th... |
192 |
static void rxrpc_start_call_timer(struct rxrpc_call *call) |
999b69f89 rxrpc: Kill the c... |
193 |
{ |
df0adc788 rxrpc: Keep the c... |
194 |
ktime_t now = ktime_get_real(), expire_at; |
248f219cb rxrpc: Rewrite th... |
195 |
|
df0adc788 rxrpc: Keep the c... |
196 |
expire_at = ktime_add_ms(now, rxrpc_max_call_lifetime); |
248f219cb rxrpc: Rewrite th... |
197 198 |
call->expire_at = expire_at; call->ack_at = expire_at; |
a5af7e1fc rxrpc: Fix loss o... |
199 |
call->ping_at = expire_at; |
248f219cb rxrpc: Rewrite th... |
200 |
call->resend_at = expire_at; |
df0adc788 rxrpc: Keep the c... |
201 202 |
call->timer.expires = jiffies + LONG_MAX / 2; rxrpc_set_timer(call, rxrpc_timer_begin, now); |
17926a793 [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 rxrpc: Simplify c... |
209 |
struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, |
19ffa01c9 rxrpc: Use struct... |
210 |
struct rxrpc_conn_parameters *cp, |
999b69f89 rxrpc: Kill the c... |
211 |
struct sockaddr_rxrpc *srx, |
17926a793 [AF_RXRPC]: Provi... |
212 |
unsigned long user_call_ID, |
17926a793 [AF_RXRPC]: Provi... |
213 214 |
gfp_t gfp) { |
2341e0775 rxrpc: Simplify c... |
215 216 |
struct rxrpc_call *call, *xcall; struct rb_node *parent, **pp; |
e34d4234b rxrpc: Trace rxrp... |
217 |
const void *here = __builtin_return_address(0); |
999b69f89 rxrpc: Kill the c... |
218 |
int ret; |
17926a793 [AF_RXRPC]: Provi... |
219 |
|
999b69f89 rxrpc: Kill the c... |
220 |
_enter("%p,%lx", rx, user_call_ID); |
17926a793 [AF_RXRPC]: Provi... |
221 |
|
248f219cb rxrpc: Rewrite th... |
222 |
call = rxrpc_alloc_client_call(srx, gfp); |
2341e0775 rxrpc: Simplify c... |
223 224 225 |
if (IS_ERR(call)) { _leave(" = %ld", PTR_ERR(call)); return call; |
17926a793 [AF_RXRPC]: Provi... |
226 |
} |
a84a46d73 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 rxrpc: Trace rxrp... |
229 |
|
999b69f89 rxrpc: Kill the c... |
230 |
/* Publish the call, even though it is incompletely set up as yet */ |
17926a793 [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 rxrpc: Simplify c... |
237 |
xcall = rb_entry(parent, struct rxrpc_call, sock_node); |
17926a793 [AF_RXRPC]: Provi... |
238 |
|
2341e0775 rxrpc: Simplify c... |
239 |
if (user_call_ID < xcall->user_call_ID) |
17926a793 [AF_RXRPC]: Provi... |
240 |
pp = &(*pp)->rb_left; |
2341e0775 rxrpc: Simplify c... |
241 |
else if (user_call_ID > xcall->user_call_ID) |
17926a793 [AF_RXRPC]: Provi... |
242 243 |
pp = &(*pp)->rb_right; else |
357f5ef64 rxrpc: Call rxrpc... |
244 |
goto error_dup_user_ID; |
17926a793 [AF_RXRPC]: Provi... |
245 |
} |
248f219cb rxrpc: Rewrite th... |
246 |
rcu_assign_pointer(call->socket, rx); |
357f5ef64 rxrpc: Call rxrpc... |
247 248 |
call->user_call_ID = user_call_ID; __set_bit(RXRPC_CALL_HAS_USERID, &call->flags); |
fff72429c rxrpc: Improve th... |
249 |
rxrpc_get_call(call, rxrpc_call_got_userid); |
17926a793 [AF_RXRPC]: Provi... |
250 251 |
rb_link_node(&call->sock_node, parent, pp); rb_insert_color(&call->sock_node, &rx->calls); |
248f219cb rxrpc: Rewrite th... |
252 |
list_add(&call->sock_link, &rx->sock_calls); |
17926a793 [AF_RXRPC]: Provi... |
253 |
write_unlock(&rx->call_lock); |
248f219cb rxrpc: Rewrite th... |
254 |
write_lock(&rxrpc_call_lock); |
17926a793 [AF_RXRPC]: Provi... |
255 |
list_add_tail(&call->link, &rxrpc_calls); |
248f219cb rxrpc: Rewrite th... |
256 |
write_unlock(&rxrpc_call_lock); |
17926a793 [AF_RXRPC]: Provi... |
257 |
|
248f219cb 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 rxrpc: Kill the c... |
262 263 |
if (ret < 0) goto error; |
a84a46d73 rxrpc: Add some a... |
264 |
trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage), |
54fde4234 rxrpc: Fix checke... |
265 |
here, NULL); |
a84a46d73 rxrpc: Add some a... |
266 |
|
248f219cb 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 [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 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 rxrpc: Call rxrpc... |
282 |
error_dup_user_ID: |
17926a793 [AF_RXRPC]: Provi... |
283 |
write_unlock(&rx->call_lock); |
8d94aa381 rxrpc: Calls shou... |
284 |
ret = -EEXIST; |
357f5ef64 rxrpc: Call rxrpc... |
285 286 287 288 |
error: __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, RX_CALL_DEAD, ret); |
a84a46d73 rxrpc: Add some a... |
289 290 |
trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage), here, ERR_PTR(ret)); |
357f5ef64 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 [AF_RXRPC]: Provi... |
295 296 297 |
} /* |
248f219cb 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 [AF_RXRPC]: Provi... |
300 |
*/ |
248f219cb rxrpc: Rewrite th... |
301 302 303 |
void rxrpc_incoming_call(struct rxrpc_sock *rx, struct rxrpc_call *call, struct sk_buff *skb) |
17926a793 [AF_RXRPC]: Provi... |
304 |
{ |
248f219cb rxrpc: Rewrite th... |
305 |
struct rxrpc_connection *conn = call->conn; |
42886ffe7 rxrpc: Pass sk_bu... |
306 |
struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
248f219cb rxrpc: Rewrite th... |
307 |
u32 chan; |
17926a793 [AF_RXRPC]: Provi... |
308 |
|
248f219cb rxrpc: Rewrite th... |
309 |
_enter(",%d", call->conn->debug_id); |
e34d4234b rxrpc: Trace rxrp... |
310 |
|
248f219cb 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 rxrpc: Implement ... |
318 |
call->cong_tstamp = skb->tstamp; |
248f219cb 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 rxrpc: Call chann... |
325 |
*/ |
248f219cb 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 rxrpc: Call chann... |
329 |
rcu_assign_pointer(conn->channels[chan].call, call); |
17926a793 [AF_RXRPC]: Provi... |
330 |
|
85f32278b 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 [AF_RXRPC]: Provi... |
334 |
|
17926a793 [AF_RXRPC]: Provi... |
335 |
_net("CALL incoming %d on CONN %d", call->debug_id, call->conn->debug_id); |
248f219cb rxrpc: Rewrite th... |
336 337 |
rxrpc_start_call_timer(call); _leave(""); |
17926a793 [AF_RXRPC]: Provi... |
338 339 340 |
} /* |
8d94aa381 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 rxrpc: Calls shou... |
347 348 349 |
if (n == 0) return false; if (rxrpc_queue_work(&call->processor)) |
2ab27215e rxrpc: Remove skb... |
350 |
trace_rxrpc_call(call, rxrpc_call_queued, n + 1, here, NULL); |
8d94aa381 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 rxrpc: Calls shou... |
363 364 |
ASSERTCMP(n, >=, 1); if (rxrpc_queue_work(&call->processor)) |
2ab27215e rxrpc: Remove skb... |
365 |
trace_rxrpc_call(call, rxrpc_call_queued_ref, n, here, NULL); |
8d94aa381 rxrpc: Calls shou... |
366 367 368 369 370 371 |
else rxrpc_put_call(call, rxrpc_call_put_noqueue); return true; } /* |
e34d4234b 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 rxrpc: Trace rxrp... |
379 |
|
2ab27215e rxrpc: Remove skb... |
380 |
trace_rxrpc_call(call, rxrpc_call_seen, n, here, NULL); |
e34d4234b rxrpc: Trace rxrp... |
381 382 383 384 385 386 |
} } /* * Note the addition of a ref on a call. */ |
fff72429c rxrpc: Improve th... |
387 |
void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op) |
e34d4234b rxrpc: Trace rxrp... |
388 389 390 |
{ const void *here = __builtin_return_address(0); int n = atomic_inc_return(&call->usage); |
e34d4234b rxrpc: Trace rxrp... |
391 |
|
2ab27215e rxrpc: Remove skb... |
392 |
trace_rxrpc_call(call, op, n, here, NULL); |
e34d4234b rxrpc: Trace rxrp... |
393 394 395 |
} /* |
248f219cb rxrpc: Rewrite th... |
396 |
* Detach a call from its owning socket. |
e34d4234b rxrpc: Trace rxrp... |
397 |
*/ |
248f219cb rxrpc: Rewrite th... |
398 |
void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call) |
e34d4234b rxrpc: Trace rxrp... |
399 |
{ |
a84a46d73 rxrpc: Add some a... |
400 |
const void *here = __builtin_return_address(0); |
248f219cb rxrpc: Rewrite th... |
401 402 403 |
struct rxrpc_connection *conn = call->conn; bool put = false; int i; |
e34d4234b rxrpc: Trace rxrp... |
404 |
|
248f219cb rxrpc: Rewrite th... |
405 |
_enter("{%d,%d}", call->debug_id, atomic_read(&call->usage)); |
e34d4234b rxrpc: Trace rxrp... |
406 |
|
a84a46d73 rxrpc: Add some a... |
407 408 |
trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage), here, (const void *)call->flags); |
17926a793 [AF_RXRPC]: Provi... |
409 |
|
a84a46d73 rxrpc: Add some a... |
410 |
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
e34d4234b rxrpc: Trace rxrp... |
411 |
|
17926a793 [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 rxrpc: Rewrite th... |
416 |
del_timer_sync(&call->timer); |
17926a793 [AF_RXRPC]: Provi... |
417 |
|
248f219cb rxrpc: Rewrite th... |
418 419 |
/* Make sure we don't get any more notifications */ write_lock_bh(&rx->recvmsg_lock); |
e653cfe49 rxrpc: Release a ... |
420 |
|
248f219cb rxrpc: Rewrite th... |
421 |
if (!list_empty(&call->recvmsg_link)) { |
17926a793 [AF_RXRPC]: Provi... |
422 423 |
_debug("unlinking once-pending call %p { e=%lx f=%lx }", call, call->events, call->flags); |
248f219cb 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 [AF_RXRPC]: Provi... |
439 440 |
rb_erase(&call->sock_node, &rx->calls); memset(&call->sock_node, 0xdd, sizeof(call->sock_node)); |
8d94aa381 rxrpc: Calls shou... |
441 |
rxrpc_put_call(call, rxrpc_call_put_userid); |
17926a793 [AF_RXRPC]: Provi... |
442 |
} |
17926a793 [AF_RXRPC]: Provi... |
443 |
|
248f219cb 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 rxrpc: Calls shou... |
450 |
rxrpc_disconnect_call(call); |
e653cfe49 rxrpc: Release a ... |
451 |
|
248f219cb rxrpc: Rewrite th... |
452 |
for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) { |
71f3ca408 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 rxrpc: Rewrite th... |
456 |
call->rxtx_buffer[i] = NULL; |
17926a793 [AF_RXRPC]: Provi... |
457 |
} |
17926a793 [AF_RXRPC]: Provi... |
458 459 460 461 462 |
_leave(""); } /* |
17926a793 [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 [AF_RXRPC]: Provi... |
468 469 |
_enter("%p", rx); |
0360da6db 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 rxrpc: Purge the ... |
475 476 |
rxrpc_put_call(call, rxrpc_call_put); } |
248f219cb 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 rxrpc: Fix warnin... |
482 |
rxrpc_send_abort_packet(call); |
8d94aa381 rxrpc: Calls shou... |
483 |
rxrpc_release_call(rx, call); |
248f219cb rxrpc: Rewrite th... |
484 |
rxrpc_put_call(call, rxrpc_call_put); |
f36b5e444 rxrpc: When clear... |
485 |
} |
17926a793 [AF_RXRPC]: Provi... |
486 487 488 489 490 491 |
_leave(""); } /* * release a call */ |
fff72429c rxrpc: Improve th... |
492 |
void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op) |
17926a793 [AF_RXRPC]: Provi... |
493 |
{ |
e34d4234b rxrpc: Trace rxrp... |
494 |
const void *here = __builtin_return_address(0); |
2ab27215e rxrpc: Remove skb... |
495 |
int n; |
17926a793 [AF_RXRPC]: Provi... |
496 |
|
e34d4234b rxrpc: Trace rxrp... |
497 |
ASSERT(call != NULL); |
17926a793 [AF_RXRPC]: Provi... |
498 |
|
e34d4234b rxrpc: Trace rxrp... |
499 |
n = atomic_dec_return(&call->usage); |
2ab27215e rxrpc: Remove skb... |
500 |
trace_rxrpc_call(call, op, n, here, NULL); |
e34d4234b rxrpc: Trace rxrp... |
501 502 503 |
ASSERTCMP(n, >=, 0); if (n == 0) { _debug("call %d dead", call->debug_id); |
248f219cb rxrpc: Rewrite th... |
504 |
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
17926a793 [AF_RXRPC]: Provi... |
505 |
|
248f219cb rxrpc: Rewrite th... |
506 507 508 |
write_lock(&rxrpc_call_lock); list_del_init(&call->link); write_unlock(&rxrpc_call_lock); |
e34d4234b rxrpc: Trace rxrp... |
509 |
|
8d94aa381 rxrpc: Calls shou... |
510 |
rxrpc_cleanup_call(call); |
17926a793 [AF_RXRPC]: Provi... |
511 |
} |
17926a793 [AF_RXRPC]: Provi... |
512 513 514 |
} /* |
dee46364c 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 rxrpc: Make /proc... |
520 |
rxrpc_put_peer(call->peer); |
248f219cb rxrpc: Rewrite th... |
521 522 |
kfree(call->rxtx_buffer); kfree(call->rxtx_annotations); |
dee46364c rxrpc: Add RCU de... |
523 524 525 526 |
kmem_cache_free(rxrpc_call_jar, call); } /* |
17926a793 [AF_RXRPC]: Provi... |
527 528 |
* clean up a call */ |
00e907127 rxrpc: Preallocat... |
529 |
void rxrpc_cleanup_call(struct rxrpc_call *call) |
17926a793 [AF_RXRPC]: Provi... |
530 |
{ |
248f219cb rxrpc: Rewrite th... |
531 |
int i; |
17926a793 [AF_RXRPC]: Provi... |
532 |
|
248f219cb rxrpc: Rewrite th... |
533 |
_net("DESTROY CALL %d", call->debug_id); |
17926a793 [AF_RXRPC]: Provi... |
534 535 |
memset(&call->sock_node, 0xcd, sizeof(call->sock_node)); |
248f219cb rxrpc: Rewrite th... |
536 |
del_timer_sync(&call->timer); |
17926a793 [AF_RXRPC]: Provi... |
537 |
|
8d94aa381 rxrpc: Calls shou... |
538 |
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
17926a793 [AF_RXRPC]: Provi... |
539 |
ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags)); |
e653cfe49 rxrpc: Release a ... |
540 |
ASSERTCMP(call->conn, ==, NULL); |
17926a793 [AF_RXRPC]: Provi... |
541 |
|
248f219cb rxrpc: Rewrite th... |
542 543 |
/* Clean up the Rx/Tx buffer */ for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) |
71f3ca408 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 [AF_RXRPC]: Provi... |
547 |
|
71f3ca408 rxrpc: Improve sk... |
548 |
rxrpc_free_skb(call->tx_pending, rxrpc_skb_tx_cleaned); |
17926a793 [AF_RXRPC]: Provi... |
549 |
|
dee46364c rxrpc: Add RCU de... |
550 |
call_rcu(&call->rcu, rxrpc_rcu_destroy_call); |
17926a793 [AF_RXRPC]: Provi... |
551 552 553 |
} /* |
8d94aa381 rxrpc: Calls shou... |
554 |
* Make sure that all calls are gone. |
17926a793 [AF_RXRPC]: Provi... |
555 556 557 558 559 560 |
*/ void __exit rxrpc_destroy_all_calls(void) { struct rxrpc_call *call; _enter(""); |
8d94aa381 rxrpc: Calls shou... |
561 562 563 |
if (list_empty(&rxrpc_calls)) return; |
248f219cb rxrpc: Rewrite th... |
564 565 |
write_lock(&rxrpc_call_lock); |
17926a793 [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 rxrpc: Trace rxrp... |
570 |
rxrpc_see_call(call); |
17926a793 [AF_RXRPC]: Provi... |
571 |
list_del_init(&call->link); |
248f219cb rxrpc: Rewrite th... |
572 573 |
pr_err("Call %p still in use (%d,%s,%lx,%lx)! ", |
8d94aa381 rxrpc: Calls shou... |
574 |
call, atomic_read(&call->usage), |
8d94aa381 rxrpc: Calls shou... |
575 576 |
rxrpc_call_states[call->state], call->flags, call->events); |
17926a793 [AF_RXRPC]: Provi... |
577 |
|
248f219cb rxrpc: Rewrite th... |
578 |
write_unlock(&rxrpc_call_lock); |
17926a793 [AF_RXRPC]: Provi... |
579 |
cond_resched(); |
248f219cb rxrpc: Rewrite th... |
580 |
write_lock(&rxrpc_call_lock); |
17926a793 [AF_RXRPC]: Provi... |
581 |
} |
248f219cb rxrpc: Rewrite th... |
582 |
write_unlock(&rxrpc_call_lock); |
17926a793 [AF_RXRPC]: Provi... |
583 |
} |