.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* RxRPC individual remote procedure call handling |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
---|
4 | 5 | * Written by David Howells (dhowells@redhat.com) |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
27 | 23 | [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl", |
---|
28 | 24 | [RXRPC_CALL_SERVER_PREALLOC] = "SvPrealc", |
---|
29 | 25 | [RXRPC_CALL_SERVER_SECURING] = "SvSecure", |
---|
30 | | - [RXRPC_CALL_SERVER_ACCEPTING] = "SvAccept", |
---|
31 | 26 | [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq", |
---|
32 | 27 | [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq", |
---|
33 | 28 | [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl", |
---|
.. | .. |
---|
45 | 40 | |
---|
46 | 41 | struct kmem_cache *rxrpc_call_jar; |
---|
47 | 42 | |
---|
| 43 | +static struct semaphore rxrpc_call_limiter = |
---|
| 44 | + __SEMAPHORE_INITIALIZER(rxrpc_call_limiter, 1000); |
---|
| 45 | +static struct semaphore rxrpc_kernel_call_limiter = |
---|
| 46 | + __SEMAPHORE_INITIALIZER(rxrpc_kernel_call_limiter, 1000); |
---|
| 47 | + |
---|
48 | 48 | static void rxrpc_call_timer_expired(struct timer_list *t) |
---|
49 | 49 | { |
---|
50 | 50 | struct rxrpc_call *call = from_timer(call, t, timer); |
---|
.. | .. |
---|
53 | 53 | |
---|
54 | 54 | if (call->state < RXRPC_CALL_COMPLETE) { |
---|
55 | 55 | trace_rxrpc_timer(call, rxrpc_timer_expired, jiffies); |
---|
56 | | - rxrpc_queue_call(call); |
---|
| 56 | + __rxrpc_queue_call(call); |
---|
| 57 | + } else { |
---|
| 58 | + rxrpc_put_call(call, rxrpc_call_put); |
---|
57 | 59 | } |
---|
| 60 | +} |
---|
| 61 | + |
---|
| 62 | +void rxrpc_reduce_call_timer(struct rxrpc_call *call, |
---|
| 63 | + unsigned long expire_at, |
---|
| 64 | + unsigned long now, |
---|
| 65 | + enum rxrpc_timer_trace why) |
---|
| 66 | +{ |
---|
| 67 | + if (rxrpc_try_get_call(call, rxrpc_call_got_timer)) { |
---|
| 68 | + trace_rxrpc_timer(call, why, now); |
---|
| 69 | + if (timer_reduce(&call->timer, expire_at)) |
---|
| 70 | + rxrpc_put_call(call, rxrpc_call_put_notimer); |
---|
| 71 | + } |
---|
| 72 | +} |
---|
| 73 | + |
---|
| 74 | +void rxrpc_delete_call_timer(struct rxrpc_call *call) |
---|
| 75 | +{ |
---|
| 76 | + if (del_timer_sync(&call->timer)) |
---|
| 77 | + rxrpc_put_call(call, rxrpc_call_put_timer); |
---|
58 | 78 | } |
---|
59 | 79 | |
---|
60 | 80 | static struct lock_class_key rxrpc_call_user_mutex_lock_class_key; |
---|
.. | .. |
---|
92 | 112 | found_extant_call: |
---|
93 | 113 | rxrpc_get_call(call, rxrpc_call_got); |
---|
94 | 114 | read_unlock(&rx->call_lock); |
---|
95 | | - _leave(" = %p [%d]", call, atomic_read(&call->usage)); |
---|
| 115 | + _leave(" = %p [%d]", call, refcount_read(&call->ref)); |
---|
96 | 116 | return call; |
---|
97 | 117 | } |
---|
98 | 118 | |
---|
.. | .. |
---|
140 | 160 | spin_lock_init(&call->notify_lock); |
---|
141 | 161 | spin_lock_init(&call->input_lock); |
---|
142 | 162 | rwlock_init(&call->state_lock); |
---|
143 | | - atomic_set(&call->usage, 1); |
---|
| 163 | + refcount_set(&call->ref, 1); |
---|
144 | 164 | call->debug_id = debug_id; |
---|
145 | 165 | call->tx_total_len = -1; |
---|
146 | 166 | call->next_rx_timo = 20 * HZ; |
---|
.. | .. |
---|
157 | 177 | call->cong_ssthresh = RXRPC_RXTX_BUFF_SIZE - 1; |
---|
158 | 178 | |
---|
159 | 179 | call->rxnet = rxnet; |
---|
| 180 | + call->rtt_avail = RXRPC_CALL_RTT_AVAIL_MASK; |
---|
160 | 181 | atomic_inc(&rxnet->nr_calls); |
---|
161 | 182 | return call; |
---|
162 | 183 | |
---|
.. | .. |
---|
213 | 234 | } |
---|
214 | 235 | |
---|
215 | 236 | /* |
---|
| 237 | + * Wait for a call slot to become available. |
---|
| 238 | + */ |
---|
| 239 | +static struct semaphore *rxrpc_get_call_slot(struct rxrpc_call_params *p, gfp_t gfp) |
---|
| 240 | +{ |
---|
| 241 | + struct semaphore *limiter = &rxrpc_call_limiter; |
---|
| 242 | + |
---|
| 243 | + if (p->kernel) |
---|
| 244 | + limiter = &rxrpc_kernel_call_limiter; |
---|
| 245 | + if (p->interruptibility == RXRPC_UNINTERRUPTIBLE) { |
---|
| 246 | + down(limiter); |
---|
| 247 | + return limiter; |
---|
| 248 | + } |
---|
| 249 | + return down_interruptible(limiter) < 0 ? NULL : limiter; |
---|
| 250 | +} |
---|
| 251 | + |
---|
| 252 | +/* |
---|
| 253 | + * Release a call slot. |
---|
| 254 | + */ |
---|
| 255 | +static void rxrpc_put_call_slot(struct rxrpc_call *call) |
---|
| 256 | +{ |
---|
| 257 | + struct semaphore *limiter = &rxrpc_call_limiter; |
---|
| 258 | + |
---|
| 259 | + if (test_bit(RXRPC_CALL_KERNEL, &call->flags)) |
---|
| 260 | + limiter = &rxrpc_kernel_call_limiter; |
---|
| 261 | + up(limiter); |
---|
| 262 | +} |
---|
| 263 | + |
---|
| 264 | +/* |
---|
216 | 265 | * Set up a call for the given parameters. |
---|
217 | 266 | * - Called with the socket lock held, which it must release. |
---|
218 | 267 | * - If it returns a call, the call's lock will need releasing by the caller. |
---|
.. | .. |
---|
228 | 277 | { |
---|
229 | 278 | struct rxrpc_call *call, *xcall; |
---|
230 | 279 | struct rxrpc_net *rxnet; |
---|
| 280 | + struct semaphore *limiter; |
---|
231 | 281 | struct rb_node *parent, **pp; |
---|
232 | 282 | const void *here = __builtin_return_address(0); |
---|
233 | 283 | int ret; |
---|
234 | 284 | |
---|
235 | 285 | _enter("%p,%lx", rx, p->user_call_ID); |
---|
236 | 286 | |
---|
| 287 | + limiter = rxrpc_get_call_slot(p, gfp); |
---|
| 288 | + if (!limiter) { |
---|
| 289 | + release_sock(&rx->sk); |
---|
| 290 | + return ERR_PTR(-ERESTARTSYS); |
---|
| 291 | + } |
---|
| 292 | + |
---|
237 | 293 | call = rxrpc_alloc_client_call(rx, srx, gfp, debug_id); |
---|
238 | 294 | if (IS_ERR(call)) { |
---|
239 | 295 | release_sock(&rx->sk); |
---|
| 296 | + up(limiter); |
---|
240 | 297 | _leave(" = %ld", PTR_ERR(call)); |
---|
241 | 298 | return call; |
---|
242 | 299 | } |
---|
243 | 300 | |
---|
| 301 | + call->interruptibility = p->interruptibility; |
---|
244 | 302 | call->tx_total_len = p->tx_total_len; |
---|
245 | | - trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage), |
---|
| 303 | + trace_rxrpc_call(call->debug_id, rxrpc_call_new_client, |
---|
| 304 | + refcount_read(&call->ref), |
---|
246 | 305 | here, (const void *)p->user_call_ID); |
---|
| 306 | + if (p->kernel) |
---|
| 307 | + __set_bit(RXRPC_CALL_KERNEL, &call->flags); |
---|
247 | 308 | |
---|
248 | 309 | /* We need to protect a partially set up call against the user as we |
---|
249 | 310 | * will be acting outside the socket lock. |
---|
.. | .. |
---|
292 | 353 | if (ret < 0) |
---|
293 | 354 | goto error_attached_to_socket; |
---|
294 | 355 | |
---|
295 | | - trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage), |
---|
296 | | - here, NULL); |
---|
| 356 | + trace_rxrpc_call(call->debug_id, rxrpc_call_connected, |
---|
| 357 | + refcount_read(&call->ref), here, NULL); |
---|
297 | 358 | |
---|
298 | 359 | rxrpc_start_call_timer(call); |
---|
299 | 360 | |
---|
.. | .. |
---|
312 | 373 | release_sock(&rx->sk); |
---|
313 | 374 | __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, |
---|
314 | 375 | RX_CALL_DEAD, -EEXIST); |
---|
315 | | - trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage), |
---|
316 | | - here, ERR_PTR(-EEXIST)); |
---|
| 376 | + trace_rxrpc_call(call->debug_id, rxrpc_call_error, |
---|
| 377 | + refcount_read(&call->ref), here, ERR_PTR(-EEXIST)); |
---|
317 | 378 | rxrpc_release_call(rx, call); |
---|
318 | 379 | mutex_unlock(&call->user_mutex); |
---|
319 | 380 | rxrpc_put_call(call, rxrpc_call_put); |
---|
.. | .. |
---|
326 | 387 | * leave the error to recvmsg() to deal with. |
---|
327 | 388 | */ |
---|
328 | 389 | error_attached_to_socket: |
---|
329 | | - trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage), |
---|
330 | | - here, ERR_PTR(ret)); |
---|
| 390 | + trace_rxrpc_call(call->debug_id, rxrpc_call_error, |
---|
| 391 | + refcount_read(&call->ref), here, ERR_PTR(ret)); |
---|
331 | 392 | set_bit(RXRPC_CALL_DISCONNECTED, &call->flags); |
---|
332 | 393 | __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, |
---|
333 | 394 | RX_CALL_DEAD, ret); |
---|
334 | 395 | _leave(" = c=%08x [err]", call->debug_id); |
---|
335 | 396 | return call; |
---|
336 | | -} |
---|
337 | | - |
---|
338 | | -/* |
---|
339 | | - * Retry a call to a new address. It is expected that the Tx queue of the call |
---|
340 | | - * will contain data previously packaged for an old call. |
---|
341 | | - */ |
---|
342 | | -int rxrpc_retry_client_call(struct rxrpc_sock *rx, |
---|
343 | | - struct rxrpc_call *call, |
---|
344 | | - struct rxrpc_conn_parameters *cp, |
---|
345 | | - struct sockaddr_rxrpc *srx, |
---|
346 | | - gfp_t gfp) |
---|
347 | | -{ |
---|
348 | | - const void *here = __builtin_return_address(0); |
---|
349 | | - int ret; |
---|
350 | | - |
---|
351 | | - /* Set up or get a connection record and set the protocol parameters, |
---|
352 | | - * including channel number and call ID. |
---|
353 | | - */ |
---|
354 | | - ret = rxrpc_connect_call(rx, call, cp, srx, gfp); |
---|
355 | | - if (ret < 0) |
---|
356 | | - goto error; |
---|
357 | | - |
---|
358 | | - trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage), |
---|
359 | | - here, NULL); |
---|
360 | | - |
---|
361 | | - rxrpc_start_call_timer(call); |
---|
362 | | - |
---|
363 | | - _net("CALL new %d on CONN %d", call->debug_id, call->conn->debug_id); |
---|
364 | | - |
---|
365 | | - if (!test_and_set_bit(RXRPC_CALL_EV_RESEND, &call->events)) |
---|
366 | | - rxrpc_queue_call(call); |
---|
367 | | - |
---|
368 | | - _leave(" = 0"); |
---|
369 | | - return 0; |
---|
370 | | - |
---|
371 | | -error: |
---|
372 | | - rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, |
---|
373 | | - RX_CALL_DEAD, ret); |
---|
374 | | - trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage), |
---|
375 | | - here, ERR_PTR(ret)); |
---|
376 | | - _leave(" = %d", ret); |
---|
377 | | - return ret; |
---|
378 | 397 | } |
---|
379 | 398 | |
---|
380 | 399 | /* |
---|
.. | .. |
---|
395 | 414 | call->call_id = sp->hdr.callNumber; |
---|
396 | 415 | call->service_id = sp->hdr.serviceId; |
---|
397 | 416 | call->cid = sp->hdr.cid; |
---|
398 | | - call->state = RXRPC_CALL_SERVER_ACCEPTING; |
---|
399 | | - if (sp->hdr.securityIndex > 0) |
---|
400 | | - call->state = RXRPC_CALL_SERVER_SECURING; |
---|
| 417 | + call->state = RXRPC_CALL_SERVER_SECURING; |
---|
401 | 418 | call->cong_tstamp = skb->tstamp; |
---|
402 | 419 | |
---|
403 | 420 | /* Set the channel for this call. We don't get channel_lock as we're |
---|
.. | .. |
---|
427 | 444 | bool rxrpc_queue_call(struct rxrpc_call *call) |
---|
428 | 445 | { |
---|
429 | 446 | const void *here = __builtin_return_address(0); |
---|
430 | | - int n = atomic_fetch_add_unless(&call->usage, 1, 0); |
---|
431 | | - if (n == 0) |
---|
| 447 | + int n; |
---|
| 448 | + |
---|
| 449 | + if (!__refcount_inc_not_zero(&call->ref, &n)) |
---|
432 | 450 | return false; |
---|
433 | 451 | if (rxrpc_queue_work(&call->processor)) |
---|
434 | | - trace_rxrpc_call(call, rxrpc_call_queued, n + 1, here, NULL); |
---|
| 452 | + trace_rxrpc_call(call->debug_id, rxrpc_call_queued, n + 1, |
---|
| 453 | + here, NULL); |
---|
435 | 454 | else |
---|
436 | 455 | rxrpc_put_call(call, rxrpc_call_put_noqueue); |
---|
437 | 456 | return true; |
---|
.. | .. |
---|
443 | 462 | bool __rxrpc_queue_call(struct rxrpc_call *call) |
---|
444 | 463 | { |
---|
445 | 464 | const void *here = __builtin_return_address(0); |
---|
446 | | - int n = atomic_read(&call->usage); |
---|
| 465 | + int n = refcount_read(&call->ref); |
---|
447 | 466 | ASSERTCMP(n, >=, 1); |
---|
448 | 467 | if (rxrpc_queue_work(&call->processor)) |
---|
449 | | - trace_rxrpc_call(call, rxrpc_call_queued_ref, n, here, NULL); |
---|
| 468 | + trace_rxrpc_call(call->debug_id, rxrpc_call_queued_ref, n, |
---|
| 469 | + here, NULL); |
---|
450 | 470 | else |
---|
451 | 471 | rxrpc_put_call(call, rxrpc_call_put_noqueue); |
---|
452 | 472 | return true; |
---|
.. | .. |
---|
459 | 479 | { |
---|
460 | 480 | const void *here = __builtin_return_address(0); |
---|
461 | 481 | if (call) { |
---|
462 | | - int n = atomic_read(&call->usage); |
---|
| 482 | + int n = refcount_read(&call->ref); |
---|
463 | 483 | |
---|
464 | | - trace_rxrpc_call(call, rxrpc_call_seen, n, here, NULL); |
---|
| 484 | + trace_rxrpc_call(call->debug_id, rxrpc_call_seen, n, |
---|
| 485 | + here, NULL); |
---|
465 | 486 | } |
---|
| 487 | +} |
---|
| 488 | + |
---|
| 489 | +bool rxrpc_try_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op) |
---|
| 490 | +{ |
---|
| 491 | + const void *here = __builtin_return_address(0); |
---|
| 492 | + int n; |
---|
| 493 | + |
---|
| 494 | + if (!__refcount_inc_not_zero(&call->ref, &n)) |
---|
| 495 | + return false; |
---|
| 496 | + trace_rxrpc_call(call->debug_id, op, n + 1, here, NULL); |
---|
| 497 | + return true; |
---|
466 | 498 | } |
---|
467 | 499 | |
---|
468 | 500 | /* |
---|
.. | .. |
---|
471 | 503 | void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op) |
---|
472 | 504 | { |
---|
473 | 505 | const void *here = __builtin_return_address(0); |
---|
474 | | - int n = atomic_inc_return(&call->usage); |
---|
| 506 | + int n; |
---|
475 | 507 | |
---|
476 | | - trace_rxrpc_call(call, op, n, here, NULL); |
---|
| 508 | + __refcount_inc(&call->ref, &n); |
---|
| 509 | + trace_rxrpc_call(call->debug_id, op, n + 1, here, NULL); |
---|
| 510 | +} |
---|
| 511 | + |
---|
| 512 | +/* |
---|
| 513 | + * Clean up the RxTx skb ring. |
---|
| 514 | + */ |
---|
| 515 | +static void rxrpc_cleanup_ring(struct rxrpc_call *call) |
---|
| 516 | +{ |
---|
| 517 | + int i; |
---|
| 518 | + |
---|
| 519 | + for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) { |
---|
| 520 | + rxrpc_free_skb(call->rxtx_buffer[i], rxrpc_skb_cleaned); |
---|
| 521 | + call->rxtx_buffer[i] = NULL; |
---|
| 522 | + } |
---|
477 | 523 | } |
---|
478 | 524 | |
---|
479 | 525 | /* |
---|
.. | .. |
---|
484 | 530 | const void *here = __builtin_return_address(0); |
---|
485 | 531 | struct rxrpc_connection *conn = call->conn; |
---|
486 | 532 | bool put = false; |
---|
487 | | - int i; |
---|
488 | 533 | |
---|
489 | | - _enter("{%d,%d}", call->debug_id, atomic_read(&call->usage)); |
---|
| 534 | + _enter("{%d,%d}", call->debug_id, refcount_read(&call->ref)); |
---|
490 | 535 | |
---|
491 | | - trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage), |
---|
| 536 | + trace_rxrpc_call(call->debug_id, rxrpc_call_release, |
---|
| 537 | + refcount_read(&call->ref), |
---|
492 | 538 | here, (const void *)call->flags); |
---|
493 | 539 | |
---|
494 | 540 | ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
---|
.. | .. |
---|
498 | 544 | BUG(); |
---|
499 | 545 | spin_unlock_bh(&call->lock); |
---|
500 | 546 | |
---|
501 | | - del_timer_sync(&call->timer); |
---|
| 547 | + rxrpc_put_call_slot(call); |
---|
| 548 | + rxrpc_delete_call_timer(call); |
---|
502 | 549 | |
---|
503 | 550 | /* Make sure we don't get any more notifications */ |
---|
504 | 551 | write_lock_bh(&rx->recvmsg_lock); |
---|
.. | .. |
---|
533 | 580 | |
---|
534 | 581 | if (conn && !test_bit(RXRPC_CALL_DISCONNECTED, &call->flags)) |
---|
535 | 582 | rxrpc_disconnect_call(call); |
---|
536 | | - |
---|
537 | | - for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) { |
---|
538 | | - rxrpc_free_skb(call->rxtx_buffer[i], |
---|
539 | | - (call->tx_phase ? rxrpc_skb_tx_cleaned : |
---|
540 | | - rxrpc_skb_rx_cleaned)); |
---|
541 | | - call->rxtx_buffer[i] = NULL; |
---|
542 | | - } |
---|
543 | | - |
---|
| 583 | + if (call->security) |
---|
| 584 | + call->security->free_call_crypto(call); |
---|
544 | 585 | _leave(""); |
---|
545 | | -} |
---|
546 | | - |
---|
547 | | -/* |
---|
548 | | - * Prepare a kernel service call for retry. |
---|
549 | | - */ |
---|
550 | | -int rxrpc_prepare_call_for_retry(struct rxrpc_sock *rx, struct rxrpc_call *call) |
---|
551 | | -{ |
---|
552 | | - const void *here = __builtin_return_address(0); |
---|
553 | | - int i; |
---|
554 | | - u8 last = 0; |
---|
555 | | - |
---|
556 | | - _enter("{%d,%d}", call->debug_id, atomic_read(&call->usage)); |
---|
557 | | - |
---|
558 | | - trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage), |
---|
559 | | - here, (const void *)call->flags); |
---|
560 | | - |
---|
561 | | - ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
---|
562 | | - ASSERTCMP(call->completion, !=, RXRPC_CALL_REMOTELY_ABORTED); |
---|
563 | | - ASSERTCMP(call->completion, !=, RXRPC_CALL_LOCALLY_ABORTED); |
---|
564 | | - ASSERT(list_empty(&call->recvmsg_link)); |
---|
565 | | - |
---|
566 | | - del_timer_sync(&call->timer); |
---|
567 | | - |
---|
568 | | - _debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, call->conn); |
---|
569 | | - |
---|
570 | | - if (call->conn) |
---|
571 | | - rxrpc_disconnect_call(call); |
---|
572 | | - |
---|
573 | | - if (rxrpc_is_service_call(call) || |
---|
574 | | - !call->tx_phase || |
---|
575 | | - call->tx_hard_ack != 0 || |
---|
576 | | - call->rx_hard_ack != 0 || |
---|
577 | | - call->rx_top != 0) |
---|
578 | | - return -EINVAL; |
---|
579 | | - |
---|
580 | | - call->state = RXRPC_CALL_UNINITIALISED; |
---|
581 | | - call->completion = RXRPC_CALL_SUCCEEDED; |
---|
582 | | - call->call_id = 0; |
---|
583 | | - call->cid = 0; |
---|
584 | | - call->cong_cwnd = 0; |
---|
585 | | - call->cong_extra = 0; |
---|
586 | | - call->cong_ssthresh = 0; |
---|
587 | | - call->cong_mode = 0; |
---|
588 | | - call->cong_dup_acks = 0; |
---|
589 | | - call->cong_cumul_acks = 0; |
---|
590 | | - call->acks_lowest_nak = 0; |
---|
591 | | - |
---|
592 | | - for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) { |
---|
593 | | - last |= call->rxtx_annotations[i]; |
---|
594 | | - call->rxtx_annotations[i] &= RXRPC_TX_ANNO_LAST; |
---|
595 | | - call->rxtx_annotations[i] |= RXRPC_TX_ANNO_RETRANS; |
---|
596 | | - } |
---|
597 | | - |
---|
598 | | - _leave(" = 0"); |
---|
599 | | - return 0; |
---|
600 | 586 | } |
---|
601 | 587 | |
---|
602 | 588 | /* |
---|
.. | .. |
---|
636 | 622 | { |
---|
637 | 623 | struct rxrpc_net *rxnet = call->rxnet; |
---|
638 | 624 | const void *here = __builtin_return_address(0); |
---|
| 625 | + unsigned int debug_id = call->debug_id; |
---|
| 626 | + bool dead; |
---|
639 | 627 | int n; |
---|
640 | 628 | |
---|
641 | 629 | ASSERT(call != NULL); |
---|
642 | 630 | |
---|
643 | | - n = atomic_dec_return(&call->usage); |
---|
644 | | - trace_rxrpc_call(call, op, n, here, NULL); |
---|
645 | | - ASSERTCMP(n, >=, 0); |
---|
646 | | - if (n == 0) { |
---|
| 631 | + dead = __refcount_dec_and_test(&call->ref, &n); |
---|
| 632 | + trace_rxrpc_call(debug_id, op, n, here, NULL); |
---|
| 633 | + if (dead) { |
---|
647 | 634 | _debug("call %d dead", call->debug_id); |
---|
648 | 635 | ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
---|
649 | 636 | |
---|
.. | .. |
---|
664 | 651 | { |
---|
665 | 652 | struct rxrpc_call *call = container_of(work, struct rxrpc_call, processor); |
---|
666 | 653 | struct rxrpc_net *rxnet = call->rxnet; |
---|
| 654 | + |
---|
| 655 | + rxrpc_delete_call_timer(call); |
---|
667 | 656 | |
---|
668 | 657 | rxrpc_put_connection(call->conn); |
---|
669 | 658 | rxrpc_put_peer(call->peer); |
---|
.. | .. |
---|
695 | 684 | */ |
---|
696 | 685 | void rxrpc_cleanup_call(struct rxrpc_call *call) |
---|
697 | 686 | { |
---|
698 | | - int i; |
---|
699 | | - |
---|
700 | 687 | _net("DESTROY CALL %d", call->debug_id); |
---|
701 | 688 | |
---|
702 | 689 | memset(&call->sock_node, 0xcd, sizeof(call->sock_node)); |
---|
703 | 690 | |
---|
704 | | - del_timer_sync(&call->timer); |
---|
705 | | - |
---|
706 | 691 | ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); |
---|
707 | 692 | ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags)); |
---|
708 | 693 | |
---|
709 | | - /* Clean up the Rx/Tx buffer */ |
---|
710 | | - for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) |
---|
711 | | - rxrpc_free_skb(call->rxtx_buffer[i], |
---|
712 | | - (call->tx_phase ? rxrpc_skb_tx_cleaned : |
---|
713 | | - rxrpc_skb_rx_cleaned)); |
---|
714 | | - |
---|
715 | | - rxrpc_free_skb(call->tx_pending, rxrpc_skb_tx_cleaned); |
---|
| 694 | + rxrpc_cleanup_ring(call); |
---|
| 695 | + rxrpc_free_skb(call->tx_pending, rxrpc_skb_cleaned); |
---|
716 | 696 | |
---|
717 | 697 | call_rcu(&call->rcu, rxrpc_rcu_destroy_call); |
---|
718 | 698 | } |
---|
.. | .. |
---|
740 | 720 | list_del_init(&call->link); |
---|
741 | 721 | |
---|
742 | 722 | pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", |
---|
743 | | - call, atomic_read(&call->usage), |
---|
| 723 | + call, refcount_read(&call->ref), |
---|
744 | 724 | rxrpc_call_states[call->state], |
---|
745 | 725 | call->flags, call->events); |
---|
746 | 726 | |
---|