| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* RxRPC packet reception |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2007, 2016 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 |
|---|
| .. | .. |
|---|
| 95 | 91 | /* We analyse the number of packets that get ACK'd per RTT |
|---|
| 96 | 92 | * period and increase the window if we managed to fill it. |
|---|
| 97 | 93 | */ |
|---|
| 98 | | - if (call->peer->rtt_usage == 0) |
|---|
| 94 | + if (call->peer->rtt_count == 0) |
|---|
| 99 | 95 | goto out; |
|---|
| 100 | 96 | if (ktime_before(skb->tstamp, |
|---|
| 101 | | - ktime_add_ns(call->cong_tstamp, |
|---|
| 102 | | - call->peer->rtt))) |
|---|
| 97 | + ktime_add_us(call->cong_tstamp, |
|---|
| 98 | + call->peer->srtt_us >> 3))) |
|---|
| 103 | 99 | goto out_no_clear_ca; |
|---|
| 104 | 100 | change = rxrpc_cong_rtt_window_end; |
|---|
| 105 | 101 | call->cong_tstamp = skb->tstamp; |
|---|
| .. | .. |
|---|
| 197 | 193 | } |
|---|
| 198 | 194 | |
|---|
| 199 | 195 | /* |
|---|
| 200 | | - * Ping the other end to fill our RTT cache and to retrieve the rwind |
|---|
| 201 | | - * and MTU parameters. |
|---|
| 202 | | - */ |
|---|
| 203 | | -static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb, |
|---|
| 204 | | - int skew) |
|---|
| 205 | | -{ |
|---|
| 206 | | - struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
|---|
| 207 | | - ktime_t now = skb->tstamp; |
|---|
| 208 | | - |
|---|
| 209 | | - if (call->peer->rtt_usage < 3 || |
|---|
| 210 | | - ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now)) |
|---|
| 211 | | - rxrpc_propose_ACK(call, RXRPC_ACK_PING, skew, sp->hdr.serial, |
|---|
| 212 | | - true, true, |
|---|
| 213 | | - rxrpc_propose_ack_ping_for_params); |
|---|
| 214 | | -} |
|---|
| 215 | | - |
|---|
| 216 | | -/* |
|---|
| 217 | 196 | * Apply a hard ACK by advancing the Tx window. |
|---|
| 218 | 197 | */ |
|---|
| 219 | 198 | static bool rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to, |
|---|
| .. | .. |
|---|
| 238 | 217 | ix = call->tx_hard_ack & RXRPC_RXTX_BUFF_MASK; |
|---|
| 239 | 218 | skb = call->rxtx_buffer[ix]; |
|---|
| 240 | 219 | annotation = call->rxtx_annotations[ix]; |
|---|
| 241 | | - rxrpc_see_skb(skb, rxrpc_skb_tx_rotated); |
|---|
| 220 | + rxrpc_see_skb(skb, rxrpc_skb_rotated); |
|---|
| 242 | 221 | call->rxtx_buffer[ix] = NULL; |
|---|
| 243 | 222 | call->rxtx_annotations[ix] = 0; |
|---|
| 244 | 223 | skb->next = list; |
|---|
| .. | .. |
|---|
| 262 | 241 | while (list) { |
|---|
| 263 | 242 | skb = list; |
|---|
| 264 | 243 | list = skb->next; |
|---|
| 265 | | - skb->next = NULL; |
|---|
| 266 | | - rxrpc_free_skb(skb, rxrpc_skb_tx_freed); |
|---|
| 244 | + skb_mark_not_on_list(skb); |
|---|
| 245 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 267 | 246 | } |
|---|
| 268 | 247 | |
|---|
| 269 | 248 | return rot_last; |
|---|
| .. | .. |
|---|
| 296 | 275 | |
|---|
| 297 | 276 | case RXRPC_CALL_SERVER_AWAIT_ACK: |
|---|
| 298 | 277 | __rxrpc_call_completed(call); |
|---|
| 299 | | - rxrpc_notify_socket(call); |
|---|
| 300 | 278 | state = call->state; |
|---|
| 301 | 279 | break; |
|---|
| 302 | 280 | |
|---|
| .. | .. |
|---|
| 352 | 330 | } |
|---|
| 353 | 331 | |
|---|
| 354 | 332 | /* |
|---|
| 355 | | - * Scan a jumbo packet to validate its structure and to work out how many |
|---|
| 333 | + * Scan a data packet to validate its structure and to work out how many |
|---|
| 356 | 334 | * subpackets it contains. |
|---|
| 357 | 335 | * |
|---|
| 358 | 336 | * A jumbo packet is a collection of consecutive packets glued together with |
|---|
| .. | .. |
|---|
| 363 | 341 | * the last are RXRPC_JUMBO_DATALEN in size. The last subpacket may be of any |
|---|
| 364 | 342 | * size. |
|---|
| 365 | 343 | */ |
|---|
| 366 | | -static bool rxrpc_validate_jumbo(struct sk_buff *skb) |
|---|
| 344 | +static bool rxrpc_validate_data(struct sk_buff *skb) |
|---|
| 367 | 345 | { |
|---|
| 368 | 346 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
|---|
| 369 | 347 | unsigned int offset = sizeof(struct rxrpc_wire_header); |
|---|
| 370 | 348 | unsigned int len = skb->len; |
|---|
| 371 | | - int nr_jumbo = 1; |
|---|
| 372 | 349 | u8 flags = sp->hdr.flags; |
|---|
| 373 | 350 | |
|---|
| 374 | | - do { |
|---|
| 375 | | - nr_jumbo++; |
|---|
| 351 | + for (;;) { |
|---|
| 352 | + if (flags & RXRPC_REQUEST_ACK) |
|---|
| 353 | + __set_bit(sp->nr_subpackets, sp->rx_req_ack); |
|---|
| 354 | + sp->nr_subpackets++; |
|---|
| 355 | + |
|---|
| 356 | + if (!(flags & RXRPC_JUMBO_PACKET)) |
|---|
| 357 | + break; |
|---|
| 358 | + |
|---|
| 376 | 359 | if (len - offset < RXRPC_JUMBO_SUBPKTLEN) |
|---|
| 377 | 360 | goto protocol_error; |
|---|
| 378 | 361 | if (flags & RXRPC_LAST_PACKET) |
|---|
| .. | .. |
|---|
| 381 | 364 | if (skb_copy_bits(skb, offset, &flags, 1) < 0) |
|---|
| 382 | 365 | goto protocol_error; |
|---|
| 383 | 366 | offset += sizeof(struct rxrpc_jumbo_header); |
|---|
| 384 | | - } while (flags & RXRPC_JUMBO_PACKET); |
|---|
| 367 | + } |
|---|
| 385 | 368 | |
|---|
| 386 | | - sp->nr_jumbo = nr_jumbo; |
|---|
| 369 | + if (flags & RXRPC_LAST_PACKET) |
|---|
| 370 | + sp->rx_flags |= RXRPC_SKB_INCL_LAST; |
|---|
| 387 | 371 | return true; |
|---|
| 388 | 372 | |
|---|
| 389 | 373 | protocol_error: |
|---|
| .. | .. |
|---|
| 404 | 388 | * (that information is encoded in the ACK packet). |
|---|
| 405 | 389 | */ |
|---|
| 406 | 390 | static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq, |
|---|
| 407 | | - u8 annotation, bool *_jumbo_bad) |
|---|
| 391 | + bool is_jumbo, bool *_jumbo_bad) |
|---|
| 408 | 392 | { |
|---|
| 409 | 393 | /* Discard normal packets that are duplicates. */ |
|---|
| 410 | | - if (annotation == 0) |
|---|
| 394 | + if (is_jumbo) |
|---|
| 411 | 395 | return; |
|---|
| 412 | 396 | |
|---|
| 413 | 397 | /* Skip jumbo subpackets that are duplicates. When we've had three or |
|---|
| .. | .. |
|---|
| 421 | 405 | } |
|---|
| 422 | 406 | |
|---|
| 423 | 407 | /* |
|---|
| 424 | | - * Process a DATA packet, adding the packet to the Rx ring. |
|---|
| 408 | + * Process a DATA packet, adding the packet to the Rx ring. The caller's |
|---|
| 409 | + * packet ref must be passed on or discarded. |
|---|
| 425 | 410 | */ |
|---|
| 426 | | -static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb, |
|---|
| 427 | | - u16 skew) |
|---|
| 411 | +static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) |
|---|
| 428 | 412 | { |
|---|
| 429 | 413 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
|---|
| 430 | 414 | enum rxrpc_call_state state; |
|---|
| 431 | | - unsigned int offset = sizeof(struct rxrpc_wire_header); |
|---|
| 432 | | - unsigned int ix; |
|---|
| 433 | | - rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0; |
|---|
| 434 | | - rxrpc_seq_t seq = sp->hdr.seq, hard_ack; |
|---|
| 435 | | - bool immediate_ack = false, jumbo_bad = false, queued; |
|---|
| 436 | | - u16 len; |
|---|
| 437 | | - u8 ack = 0, flags, annotation = 0; |
|---|
| 415 | + unsigned int j, nr_subpackets, nr_unacked = 0; |
|---|
| 416 | + rxrpc_serial_t serial = sp->hdr.serial, ack_serial = serial; |
|---|
| 417 | + rxrpc_seq_t seq0 = sp->hdr.seq, hard_ack; |
|---|
| 418 | + bool immediate_ack = false, jumbo_bad = false; |
|---|
| 419 | + u8 ack = 0; |
|---|
| 438 | 420 | |
|---|
| 439 | 421 | _enter("{%u,%u},{%u,%u}", |
|---|
| 440 | | - call->rx_hard_ack, call->rx_top, skb->len, seq); |
|---|
| 422 | + call->rx_hard_ack, call->rx_top, skb->len, seq0); |
|---|
| 441 | 423 | |
|---|
| 442 | | - _proto("Rx DATA %%%u { #%u f=%02x }", |
|---|
| 443 | | - sp->hdr.serial, seq, sp->hdr.flags); |
|---|
| 424 | + _proto("Rx DATA %%%u { #%u f=%02x n=%u }", |
|---|
| 425 | + sp->hdr.serial, seq0, sp->hdr.flags, sp->nr_subpackets); |
|---|
| 444 | 426 | |
|---|
| 445 | 427 | state = READ_ONCE(call->state); |
|---|
| 446 | | - if (state >= RXRPC_CALL_COMPLETE) |
|---|
| 428 | + if (state >= RXRPC_CALL_COMPLETE) { |
|---|
| 429 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 447 | 430 | return; |
|---|
| 431 | + } |
|---|
| 448 | 432 | |
|---|
| 449 | 433 | if (state == RXRPC_CALL_SERVER_RECV_REQUEST) { |
|---|
| 450 | 434 | unsigned long timo = READ_ONCE(call->next_req_timo); |
|---|
| .. | .. |
|---|
| 469 | 453 | !rxrpc_receiving_reply(call)) |
|---|
| 470 | 454 | goto unlock; |
|---|
| 471 | 455 | |
|---|
| 472 | | - call->ackr_prev_seq = seq; |
|---|
| 473 | | - |
|---|
| 474 | 456 | hard_ack = READ_ONCE(call->rx_hard_ack); |
|---|
| 475 | | - if (after(seq, hard_ack + call->rx_winsize)) { |
|---|
| 476 | | - ack = RXRPC_ACK_EXCEEDS_WINDOW; |
|---|
| 477 | | - ack_serial = serial; |
|---|
| 478 | | - goto ack; |
|---|
| 479 | | - } |
|---|
| 480 | 457 | |
|---|
| 481 | | - flags = sp->hdr.flags; |
|---|
| 482 | | - if (flags & RXRPC_JUMBO_PACKET) { |
|---|
| 458 | + nr_subpackets = sp->nr_subpackets; |
|---|
| 459 | + if (nr_subpackets > 1) { |
|---|
| 483 | 460 | if (call->nr_jumbo_bad > 3) { |
|---|
| 484 | 461 | ack = RXRPC_ACK_NOSPACE; |
|---|
| 485 | 462 | ack_serial = serial; |
|---|
| 486 | 463 | goto ack; |
|---|
| 487 | 464 | } |
|---|
| 488 | | - annotation = 1; |
|---|
| 489 | 465 | } |
|---|
| 490 | 466 | |
|---|
| 491 | | -next_subpacket: |
|---|
| 492 | | - queued = false; |
|---|
| 493 | | - ix = seq & RXRPC_RXTX_BUFF_MASK; |
|---|
| 494 | | - len = skb->len; |
|---|
| 495 | | - if (flags & RXRPC_JUMBO_PACKET) |
|---|
| 496 | | - len = RXRPC_JUMBO_DATALEN; |
|---|
| 467 | + for (j = 0; j < nr_subpackets; j++) { |
|---|
| 468 | + rxrpc_serial_t serial = sp->hdr.serial + j; |
|---|
| 469 | + rxrpc_seq_t seq = seq0 + j; |
|---|
| 470 | + unsigned int ix = seq & RXRPC_RXTX_BUFF_MASK; |
|---|
| 471 | + bool terminal = (j == nr_subpackets - 1); |
|---|
| 472 | + bool last = terminal && (sp->rx_flags & RXRPC_SKB_INCL_LAST); |
|---|
| 473 | + u8 flags, annotation = j; |
|---|
| 497 | 474 | |
|---|
| 498 | | - if (flags & RXRPC_LAST_PACKET) { |
|---|
| 499 | | - if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) && |
|---|
| 500 | | - seq != call->rx_top) { |
|---|
| 501 | | - rxrpc_proto_abort("LSN", call, seq); |
|---|
| 502 | | - goto unlock; |
|---|
| 475 | + _proto("Rx DATA+%u %%%u { #%x t=%u l=%u }", |
|---|
| 476 | + j, serial, seq, terminal, last); |
|---|
| 477 | + |
|---|
| 478 | + if (last) { |
|---|
| 479 | + if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) && |
|---|
| 480 | + seq != call->rx_top) { |
|---|
| 481 | + rxrpc_proto_abort("LSN", call, seq); |
|---|
| 482 | + goto unlock; |
|---|
| 483 | + } |
|---|
| 484 | + } else { |
|---|
| 485 | + if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) && |
|---|
| 486 | + after_eq(seq, call->rx_top)) { |
|---|
| 487 | + rxrpc_proto_abort("LSA", call, seq); |
|---|
| 488 | + goto unlock; |
|---|
| 489 | + } |
|---|
| 503 | 490 | } |
|---|
| 504 | | - } else { |
|---|
| 505 | | - if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) && |
|---|
| 506 | | - after_eq(seq, call->rx_top)) { |
|---|
| 507 | | - rxrpc_proto_abort("LSA", call, seq); |
|---|
| 508 | | - goto unlock; |
|---|
| 509 | | - } |
|---|
| 510 | | - } |
|---|
| 511 | 491 | |
|---|
| 512 | | - trace_rxrpc_rx_data(call->debug_id, seq, serial, flags, annotation); |
|---|
| 513 | | - if (before_eq(seq, hard_ack)) { |
|---|
| 514 | | - ack = RXRPC_ACK_DUPLICATE; |
|---|
| 515 | | - ack_serial = serial; |
|---|
| 516 | | - goto skip; |
|---|
| 517 | | - } |
|---|
| 492 | + flags = 0; |
|---|
| 493 | + if (last) |
|---|
| 494 | + flags |= RXRPC_LAST_PACKET; |
|---|
| 495 | + if (!terminal) |
|---|
| 496 | + flags |= RXRPC_JUMBO_PACKET; |
|---|
| 497 | + if (test_bit(j, sp->rx_req_ack)) |
|---|
| 498 | + flags |= RXRPC_REQUEST_ACK; |
|---|
| 499 | + trace_rxrpc_rx_data(call->debug_id, seq, serial, flags, annotation); |
|---|
| 518 | 500 | |
|---|
| 519 | | - if (flags & RXRPC_REQUEST_ACK && !ack) { |
|---|
| 520 | | - ack = RXRPC_ACK_REQUESTED; |
|---|
| 521 | | - ack_serial = serial; |
|---|
| 522 | | - } |
|---|
| 523 | | - |
|---|
| 524 | | - if (call->rxtx_buffer[ix]) { |
|---|
| 525 | | - rxrpc_input_dup_data(call, seq, annotation, &jumbo_bad); |
|---|
| 526 | | - if (ack != RXRPC_ACK_DUPLICATE) { |
|---|
| 501 | + if (before_eq(seq, hard_ack)) { |
|---|
| 527 | 502 | ack = RXRPC_ACK_DUPLICATE; |
|---|
| 528 | 503 | ack_serial = serial; |
|---|
| 504 | + continue; |
|---|
| 529 | 505 | } |
|---|
| 530 | | - immediate_ack = true; |
|---|
| 531 | | - goto skip; |
|---|
| 532 | | - } |
|---|
| 533 | 506 | |
|---|
| 534 | | - /* Queue the packet. We use a couple of memory barriers here as need |
|---|
| 535 | | - * to make sure that rx_top is perceived to be set after the buffer |
|---|
| 536 | | - * pointer and that the buffer pointer is set after the annotation and |
|---|
| 537 | | - * the skb data. |
|---|
| 538 | | - * |
|---|
| 539 | | - * Barriers against rxrpc_recvmsg_data() and rxrpc_rotate_rx_window() |
|---|
| 540 | | - * and also rxrpc_fill_out_ack(). |
|---|
| 541 | | - */ |
|---|
| 542 | | - rxrpc_get_skb(skb, rxrpc_skb_rx_got); |
|---|
| 543 | | - call->rxtx_annotations[ix] = annotation; |
|---|
| 544 | | - smp_wmb(); |
|---|
| 545 | | - call->rxtx_buffer[ix] = skb; |
|---|
| 546 | | - if (after(seq, call->rx_top)) { |
|---|
| 547 | | - smp_store_release(&call->rx_top, seq); |
|---|
| 548 | | - } else if (before(seq, call->rx_top)) { |
|---|
| 549 | | - /* Send an immediate ACK if we fill in a hole */ |
|---|
| 550 | | - if (!ack) { |
|---|
| 551 | | - ack = RXRPC_ACK_DELAY; |
|---|
| 552 | | - ack_serial = serial; |
|---|
| 507 | + if (call->rxtx_buffer[ix]) { |
|---|
| 508 | + rxrpc_input_dup_data(call, seq, nr_subpackets > 1, |
|---|
| 509 | + &jumbo_bad); |
|---|
| 510 | + if (ack != RXRPC_ACK_DUPLICATE) { |
|---|
| 511 | + ack = RXRPC_ACK_DUPLICATE; |
|---|
| 512 | + ack_serial = serial; |
|---|
| 513 | + } |
|---|
| 514 | + immediate_ack = true; |
|---|
| 515 | + continue; |
|---|
| 553 | 516 | } |
|---|
| 554 | | - immediate_ack = true; |
|---|
| 555 | | - } |
|---|
| 556 | | - if (flags & RXRPC_LAST_PACKET) { |
|---|
| 557 | | - set_bit(RXRPC_CALL_RX_LAST, &call->flags); |
|---|
| 558 | | - trace_rxrpc_receive(call, rxrpc_receive_queue_last, serial, seq); |
|---|
| 559 | | - } else { |
|---|
| 560 | | - trace_rxrpc_receive(call, rxrpc_receive_queue, serial, seq); |
|---|
| 561 | | - } |
|---|
| 562 | | - queued = true; |
|---|
| 563 | 517 | |
|---|
| 564 | | - if (after_eq(seq, call->rx_expect_next)) { |
|---|
| 565 | | - if (after(seq, call->rx_expect_next)) { |
|---|
| 566 | | - _net("OOS %u > %u", seq, call->rx_expect_next); |
|---|
| 567 | | - ack = RXRPC_ACK_OUT_OF_SEQUENCE; |
|---|
| 568 | | - ack_serial = serial; |
|---|
| 569 | | - } |
|---|
| 570 | | - call->rx_expect_next = seq + 1; |
|---|
| 571 | | - } |
|---|
| 572 | | - |
|---|
| 573 | | -skip: |
|---|
| 574 | | - offset += len; |
|---|
| 575 | | - if (flags & RXRPC_JUMBO_PACKET) { |
|---|
| 576 | | - if (skb_copy_bits(skb, offset, &flags, 1) < 0) { |
|---|
| 577 | | - rxrpc_proto_abort("XJF", call, seq); |
|---|
| 578 | | - goto unlock; |
|---|
| 579 | | - } |
|---|
| 580 | | - offset += sizeof(struct rxrpc_jumbo_header); |
|---|
| 581 | | - seq++; |
|---|
| 582 | | - serial++; |
|---|
| 583 | | - annotation++; |
|---|
| 584 | | - if (flags & RXRPC_JUMBO_PACKET) |
|---|
| 585 | | - annotation |= RXRPC_RX_ANNO_JLAST; |
|---|
| 586 | 518 | if (after(seq, hard_ack + call->rx_winsize)) { |
|---|
| 587 | 519 | ack = RXRPC_ACK_EXCEEDS_WINDOW; |
|---|
| 588 | 520 | ack_serial = serial; |
|---|
| 589 | | - if (!jumbo_bad) { |
|---|
| 590 | | - call->nr_jumbo_bad++; |
|---|
| 591 | | - jumbo_bad = true; |
|---|
| 521 | + if (flags & RXRPC_JUMBO_PACKET) { |
|---|
| 522 | + if (!jumbo_bad) { |
|---|
| 523 | + call->nr_jumbo_bad++; |
|---|
| 524 | + jumbo_bad = true; |
|---|
| 525 | + } |
|---|
| 592 | 526 | } |
|---|
| 527 | + |
|---|
| 593 | 528 | goto ack; |
|---|
| 594 | 529 | } |
|---|
| 595 | 530 | |
|---|
| 596 | | - _proto("Rx DATA Jumbo %%%u", serial); |
|---|
| 597 | | - goto next_subpacket; |
|---|
| 598 | | - } |
|---|
| 531 | + if (flags & RXRPC_REQUEST_ACK && !ack) { |
|---|
| 532 | + ack = RXRPC_ACK_REQUESTED; |
|---|
| 533 | + ack_serial = serial; |
|---|
| 534 | + } |
|---|
| 599 | 535 | |
|---|
| 600 | | - if (queued && flags & RXRPC_LAST_PACKET && !ack) { |
|---|
| 601 | | - ack = RXRPC_ACK_DELAY; |
|---|
| 602 | | - ack_serial = serial; |
|---|
| 536 | + if (after(seq0, call->ackr_highest_seq)) |
|---|
| 537 | + call->ackr_highest_seq = seq0; |
|---|
| 538 | + |
|---|
| 539 | + /* Queue the packet. We use a couple of memory barriers here as need |
|---|
| 540 | + * to make sure that rx_top is perceived to be set after the buffer |
|---|
| 541 | + * pointer and that the buffer pointer is set after the annotation and |
|---|
| 542 | + * the skb data. |
|---|
| 543 | + * |
|---|
| 544 | + * Barriers against rxrpc_recvmsg_data() and rxrpc_rotate_rx_window() |
|---|
| 545 | + * and also rxrpc_fill_out_ack(). |
|---|
| 546 | + */ |
|---|
| 547 | + if (!terminal) |
|---|
| 548 | + rxrpc_get_skb(skb, rxrpc_skb_got); |
|---|
| 549 | + call->rxtx_annotations[ix] = annotation; |
|---|
| 550 | + smp_wmb(); |
|---|
| 551 | + call->rxtx_buffer[ix] = skb; |
|---|
| 552 | + if (after(seq, call->rx_top)) { |
|---|
| 553 | + smp_store_release(&call->rx_top, seq); |
|---|
| 554 | + } else if (before(seq, call->rx_top)) { |
|---|
| 555 | + /* Send an immediate ACK if we fill in a hole */ |
|---|
| 556 | + if (!ack) { |
|---|
| 557 | + ack = RXRPC_ACK_DELAY; |
|---|
| 558 | + ack_serial = serial; |
|---|
| 559 | + } |
|---|
| 560 | + immediate_ack = true; |
|---|
| 561 | + } |
|---|
| 562 | + |
|---|
| 563 | + if (terminal) { |
|---|
| 564 | + /* From this point on, we're not allowed to touch the |
|---|
| 565 | + * packet any longer as its ref now belongs to the Rx |
|---|
| 566 | + * ring. |
|---|
| 567 | + */ |
|---|
| 568 | + skb = NULL; |
|---|
| 569 | + sp = NULL; |
|---|
| 570 | + } |
|---|
| 571 | + |
|---|
| 572 | + nr_unacked++; |
|---|
| 573 | + |
|---|
| 574 | + if (last) { |
|---|
| 575 | + set_bit(RXRPC_CALL_RX_LAST, &call->flags); |
|---|
| 576 | + if (!ack) { |
|---|
| 577 | + ack = RXRPC_ACK_DELAY; |
|---|
| 578 | + ack_serial = serial; |
|---|
| 579 | + } |
|---|
| 580 | + trace_rxrpc_receive(call, rxrpc_receive_queue_last, serial, seq); |
|---|
| 581 | + } else { |
|---|
| 582 | + trace_rxrpc_receive(call, rxrpc_receive_queue, serial, seq); |
|---|
| 583 | + } |
|---|
| 584 | + |
|---|
| 585 | + if (after_eq(seq, call->rx_expect_next)) { |
|---|
| 586 | + if (after(seq, call->rx_expect_next)) { |
|---|
| 587 | + _net("OOS %u > %u", seq, call->rx_expect_next); |
|---|
| 588 | + ack = RXRPC_ACK_OUT_OF_SEQUENCE; |
|---|
| 589 | + ack_serial = serial; |
|---|
| 590 | + } |
|---|
| 591 | + call->rx_expect_next = seq + 1; |
|---|
| 592 | + } |
|---|
| 593 | + if (!ack) |
|---|
| 594 | + ack_serial = serial; |
|---|
| 603 | 595 | } |
|---|
| 604 | 596 | |
|---|
| 605 | 597 | ack: |
|---|
| 598 | + if (atomic_add_return(nr_unacked, &call->ackr_nr_unacked) > 2 && !ack) |
|---|
| 599 | + ack = RXRPC_ACK_IDLE; |
|---|
| 600 | + |
|---|
| 606 | 601 | if (ack) |
|---|
| 607 | | - rxrpc_propose_ACK(call, ack, skew, ack_serial, |
|---|
| 602 | + rxrpc_propose_ACK(call, ack, ack_serial, |
|---|
| 608 | 603 | immediate_ack, true, |
|---|
| 609 | 604 | rxrpc_propose_ack_input_data); |
|---|
| 610 | 605 | else |
|---|
| 611 | | - rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, skew, serial, |
|---|
| 606 | + rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, serial, |
|---|
| 612 | 607 | false, true, |
|---|
| 613 | 608 | rxrpc_propose_ack_input_data); |
|---|
| 614 | 609 | |
|---|
| .. | .. |
|---|
| 617 | 612 | |
|---|
| 618 | 613 | unlock: |
|---|
| 619 | 614 | spin_unlock(&call->input_lock); |
|---|
| 615 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 620 | 616 | _leave(" [queued]"); |
|---|
| 621 | 617 | } |
|---|
| 622 | 618 | |
|---|
| 623 | 619 | /* |
|---|
| 624 | | - * Process a requested ACK. |
|---|
| 620 | + * See if there's a cached RTT probe to complete. |
|---|
| 625 | 621 | */ |
|---|
| 626 | | -static void rxrpc_input_requested_ack(struct rxrpc_call *call, |
|---|
| 627 | | - ktime_t resp_time, |
|---|
| 628 | | - rxrpc_serial_t orig_serial, |
|---|
| 629 | | - rxrpc_serial_t ack_serial) |
|---|
| 622 | +static void rxrpc_complete_rtt_probe(struct rxrpc_call *call, |
|---|
| 623 | + ktime_t resp_time, |
|---|
| 624 | + rxrpc_serial_t acked_serial, |
|---|
| 625 | + rxrpc_serial_t ack_serial, |
|---|
| 626 | + enum rxrpc_rtt_rx_trace type) |
|---|
| 630 | 627 | { |
|---|
| 631 | | - struct rxrpc_skb_priv *sp; |
|---|
| 632 | | - struct sk_buff *skb; |
|---|
| 628 | + rxrpc_serial_t orig_serial; |
|---|
| 629 | + unsigned long avail; |
|---|
| 633 | 630 | ktime_t sent_at; |
|---|
| 634 | | - int ix; |
|---|
| 631 | + bool matched = false; |
|---|
| 632 | + int i; |
|---|
| 635 | 633 | |
|---|
| 636 | | - for (ix = 0; ix < RXRPC_RXTX_BUFF_SIZE; ix++) { |
|---|
| 637 | | - skb = call->rxtx_buffer[ix]; |
|---|
| 638 | | - if (!skb) |
|---|
| 634 | + avail = READ_ONCE(call->rtt_avail); |
|---|
| 635 | + smp_rmb(); /* Read avail bits before accessing data. */ |
|---|
| 636 | + |
|---|
| 637 | + for (i = 0; i < ARRAY_SIZE(call->rtt_serial); i++) { |
|---|
| 638 | + if (!test_bit(i + RXRPC_CALL_RTT_PEND_SHIFT, &avail)) |
|---|
| 639 | 639 | continue; |
|---|
| 640 | 640 | |
|---|
| 641 | | - sent_at = skb->tstamp; |
|---|
| 642 | | - smp_rmb(); /* Read timestamp before serial. */ |
|---|
| 643 | | - sp = rxrpc_skb(skb); |
|---|
| 644 | | - if (sp->hdr.serial != orig_serial) |
|---|
| 645 | | - continue; |
|---|
| 646 | | - goto found; |
|---|
| 641 | + sent_at = call->rtt_sent_at[i]; |
|---|
| 642 | + orig_serial = call->rtt_serial[i]; |
|---|
| 643 | + |
|---|
| 644 | + if (orig_serial == acked_serial) { |
|---|
| 645 | + clear_bit(i + RXRPC_CALL_RTT_PEND_SHIFT, &call->rtt_avail); |
|---|
| 646 | + smp_mb(); /* Read data before setting avail bit */ |
|---|
| 647 | + set_bit(i, &call->rtt_avail); |
|---|
| 648 | + if (type != rxrpc_rtt_rx_cancel) |
|---|
| 649 | + rxrpc_peer_add_rtt(call, type, i, acked_serial, ack_serial, |
|---|
| 650 | + sent_at, resp_time); |
|---|
| 651 | + else |
|---|
| 652 | + trace_rxrpc_rtt_rx(call, rxrpc_rtt_rx_cancel, i, |
|---|
| 653 | + orig_serial, acked_serial, 0, 0); |
|---|
| 654 | + matched = true; |
|---|
| 655 | + } |
|---|
| 656 | + |
|---|
| 657 | + /* If a later serial is being acked, then mark this slot as |
|---|
| 658 | + * being available. |
|---|
| 659 | + */ |
|---|
| 660 | + if (after(acked_serial, orig_serial)) { |
|---|
| 661 | + trace_rxrpc_rtt_rx(call, rxrpc_rtt_rx_obsolete, i, |
|---|
| 662 | + orig_serial, acked_serial, 0, 0); |
|---|
| 663 | + clear_bit(i + RXRPC_CALL_RTT_PEND_SHIFT, &call->rtt_avail); |
|---|
| 664 | + smp_wmb(); |
|---|
| 665 | + set_bit(i, &call->rtt_avail); |
|---|
| 666 | + } |
|---|
| 647 | 667 | } |
|---|
| 648 | 668 | |
|---|
| 649 | | - return; |
|---|
| 650 | | - |
|---|
| 651 | | -found: |
|---|
| 652 | | - rxrpc_peer_add_rtt(call, rxrpc_rtt_rx_requested_ack, |
|---|
| 653 | | - orig_serial, ack_serial, sent_at, resp_time); |
|---|
| 669 | + if (!matched) |
|---|
| 670 | + trace_rxrpc_rtt_rx(call, rxrpc_rtt_rx_lost, 9, 0, acked_serial, 0, 0); |
|---|
| 654 | 671 | } |
|---|
| 655 | 672 | |
|---|
| 656 | 673 | /* |
|---|
| .. | .. |
|---|
| 695 | 712 | */ |
|---|
| 696 | 713 | static void rxrpc_input_ping_response(struct rxrpc_call *call, |
|---|
| 697 | 714 | ktime_t resp_time, |
|---|
| 698 | | - rxrpc_serial_t orig_serial, |
|---|
| 715 | + rxrpc_serial_t acked_serial, |
|---|
| 699 | 716 | rxrpc_serial_t ack_serial) |
|---|
| 700 | 717 | { |
|---|
| 701 | | - rxrpc_serial_t ping_serial; |
|---|
| 702 | | - ktime_t ping_time; |
|---|
| 703 | | - |
|---|
| 704 | | - ping_time = call->ping_time; |
|---|
| 705 | | - smp_rmb(); |
|---|
| 706 | | - ping_serial = READ_ONCE(call->ping_serial); |
|---|
| 707 | | - |
|---|
| 708 | | - if (orig_serial == call->acks_lost_ping) |
|---|
| 718 | + if (acked_serial == call->acks_lost_ping) |
|---|
| 709 | 719 | rxrpc_input_check_for_lost_ack(call); |
|---|
| 710 | | - |
|---|
| 711 | | - if (before(orig_serial, ping_serial) || |
|---|
| 712 | | - !test_and_clear_bit(RXRPC_CALL_PINGING, &call->flags)) |
|---|
| 713 | | - return; |
|---|
| 714 | | - if (after(orig_serial, ping_serial)) |
|---|
| 715 | | - return; |
|---|
| 716 | | - |
|---|
| 717 | | - rxrpc_peer_add_rtt(call, rxrpc_rtt_rx_ping_response, |
|---|
| 718 | | - orig_serial, ack_serial, ping_time, resp_time); |
|---|
| 719 | 720 | } |
|---|
| 720 | 721 | |
|---|
| 721 | 722 | /* |
|---|
| .. | .. |
|---|
| 820 | 821 | static bool rxrpc_is_ack_valid(struct rxrpc_call *call, |
|---|
| 821 | 822 | rxrpc_seq_t first_pkt, rxrpc_seq_t prev_pkt) |
|---|
| 822 | 823 | { |
|---|
| 823 | | - rxrpc_seq_t base = READ_ONCE(call->ackr_first_seq); |
|---|
| 824 | + rxrpc_seq_t base = READ_ONCE(call->acks_first_seq); |
|---|
| 824 | 825 | |
|---|
| 825 | 826 | if (after(first_pkt, base)) |
|---|
| 826 | 827 | return true; /* The window advanced */ |
|---|
| .. | .. |
|---|
| 828 | 829 | if (before(first_pkt, base)) |
|---|
| 829 | 830 | return false; /* firstPacket regressed */ |
|---|
| 830 | 831 | |
|---|
| 831 | | - if (after_eq(prev_pkt, call->ackr_prev_seq)) |
|---|
| 832 | + if (after_eq(prev_pkt, call->acks_prev_seq)) |
|---|
| 832 | 833 | return true; /* previousPacket hasn't regressed. */ |
|---|
| 833 | 834 | |
|---|
| 834 | 835 | /* Some rx implementations put a serial number in previousPacket. */ |
|---|
| .. | .. |
|---|
| 847 | 848 | * soft-ACK means that the packet may be discarded and retransmission |
|---|
| 848 | 849 | * requested. A phase is complete when all packets are hard-ACK'd. |
|---|
| 849 | 850 | */ |
|---|
| 850 | | -static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, |
|---|
| 851 | | - u16 skew) |
|---|
| 851 | +static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) |
|---|
| 852 | 852 | { |
|---|
| 853 | 853 | struct rxrpc_ack_summary summary = { 0 }; |
|---|
| 854 | 854 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
|---|
| .. | .. |
|---|
| 857 | 857 | struct rxrpc_ackinfo info; |
|---|
| 858 | 858 | u8 acks[RXRPC_MAXACKS]; |
|---|
| 859 | 859 | } buf; |
|---|
| 860 | | - rxrpc_serial_t acked_serial; |
|---|
| 860 | + rxrpc_serial_t ack_serial, acked_serial; |
|---|
| 861 | 861 | rxrpc_seq_t first_soft_ack, hard_ack, prev_pkt; |
|---|
| 862 | 862 | int nr_acks, offset, ioffset; |
|---|
| 863 | 863 | |
|---|
| .. | .. |
|---|
| 870 | 870 | } |
|---|
| 871 | 871 | offset += sizeof(buf.ack); |
|---|
| 872 | 872 | |
|---|
| 873 | + ack_serial = sp->hdr.serial; |
|---|
| 873 | 874 | acked_serial = ntohl(buf.ack.serial); |
|---|
| 874 | 875 | first_soft_ack = ntohl(buf.ack.firstPacket); |
|---|
| 875 | 876 | prev_pkt = ntohl(buf.ack.previousPacket); |
|---|
| .. | .. |
|---|
| 878 | 879 | summary.ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ? |
|---|
| 879 | 880 | buf.ack.reason : RXRPC_ACK__INVALID); |
|---|
| 880 | 881 | |
|---|
| 881 | | - trace_rxrpc_rx_ack(call, sp->hdr.serial, acked_serial, |
|---|
| 882 | + trace_rxrpc_rx_ack(call, ack_serial, acked_serial, |
|---|
| 882 | 883 | first_soft_ack, prev_pkt, |
|---|
| 883 | 884 | summary.ack_reason, nr_acks); |
|---|
| 884 | 885 | |
|---|
| 885 | | - if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE) |
|---|
| 886 | + switch (buf.ack.reason) { |
|---|
| 887 | + case RXRPC_ACK_PING_RESPONSE: |
|---|
| 886 | 888 | rxrpc_input_ping_response(call, skb->tstamp, acked_serial, |
|---|
| 887 | | - sp->hdr.serial); |
|---|
| 888 | | - if (buf.ack.reason == RXRPC_ACK_REQUESTED) |
|---|
| 889 | | - rxrpc_input_requested_ack(call, skb->tstamp, acked_serial, |
|---|
| 890 | | - sp->hdr.serial); |
|---|
| 889 | + ack_serial); |
|---|
| 890 | + rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial, |
|---|
| 891 | + rxrpc_rtt_rx_ping_response); |
|---|
| 892 | + break; |
|---|
| 893 | + case RXRPC_ACK_REQUESTED: |
|---|
| 894 | + rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial, |
|---|
| 895 | + rxrpc_rtt_rx_requested_ack); |
|---|
| 896 | + break; |
|---|
| 897 | + default: |
|---|
| 898 | + if (acked_serial != 0) |
|---|
| 899 | + rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial, |
|---|
| 900 | + rxrpc_rtt_rx_cancel); |
|---|
| 901 | + break; |
|---|
| 902 | + } |
|---|
| 891 | 903 | |
|---|
| 892 | 904 | if (buf.ack.reason == RXRPC_ACK_PING) { |
|---|
| 893 | | - _proto("Rx ACK %%%u PING Request", sp->hdr.serial); |
|---|
| 905 | + _proto("Rx ACK %%%u PING Request", ack_serial); |
|---|
| 894 | 906 | rxrpc_propose_ACK(call, RXRPC_ACK_PING_RESPONSE, |
|---|
| 895 | | - skew, sp->hdr.serial, true, true, |
|---|
| 907 | + ack_serial, true, true, |
|---|
| 896 | 908 | rxrpc_propose_ack_respond_to_ping); |
|---|
| 897 | 909 | } else if (sp->hdr.flags & RXRPC_REQUEST_ACK) { |
|---|
| 898 | 910 | rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, |
|---|
| 899 | | - skew, sp->hdr.serial, true, true, |
|---|
| 911 | + ack_serial, true, true, |
|---|
| 900 | 912 | rxrpc_propose_ack_respond_to_ack); |
|---|
| 901 | 913 | } |
|---|
| 902 | 914 | |
|---|
| 903 | 915 | /* Discard any out-of-order or duplicate ACKs (outside lock). */ |
|---|
| 904 | 916 | if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { |
|---|
| 905 | | - trace_rxrpc_rx_discard_ack(call->debug_id, sp->hdr.serial, |
|---|
| 906 | | - first_soft_ack, call->ackr_first_seq, |
|---|
| 907 | | - prev_pkt, call->ackr_prev_seq); |
|---|
| 917 | + trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial, |
|---|
| 918 | + first_soft_ack, call->acks_first_seq, |
|---|
| 919 | + prev_pkt, call->acks_prev_seq); |
|---|
| 908 | 920 | return; |
|---|
| 909 | 921 | } |
|---|
| 910 | 922 | |
|---|
| .. | .. |
|---|
| 918 | 930 | |
|---|
| 919 | 931 | /* Discard any out-of-order or duplicate ACKs (inside lock). */ |
|---|
| 920 | 932 | if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { |
|---|
| 921 | | - trace_rxrpc_rx_discard_ack(call->debug_id, sp->hdr.serial, |
|---|
| 922 | | - first_soft_ack, call->ackr_first_seq, |
|---|
| 923 | | - prev_pkt, call->ackr_prev_seq); |
|---|
| 933 | + trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial, |
|---|
| 934 | + first_soft_ack, call->acks_first_seq, |
|---|
| 935 | + prev_pkt, call->acks_prev_seq); |
|---|
| 924 | 936 | goto out; |
|---|
| 925 | 937 | } |
|---|
| 926 | 938 | call->acks_latest_ts = skb->tstamp; |
|---|
| 927 | | - call->acks_latest = sp->hdr.serial; |
|---|
| 928 | 939 | |
|---|
| 929 | | - call->ackr_first_seq = first_soft_ack; |
|---|
| 930 | | - call->ackr_prev_seq = prev_pkt; |
|---|
| 940 | + call->acks_first_seq = first_soft_ack; |
|---|
| 941 | + call->acks_prev_seq = prev_pkt; |
|---|
| 931 | 942 | |
|---|
| 932 | 943 | /* Parse rwind and mtu sizes if provided. */ |
|---|
| 933 | 944 | if (buf.info.rxMTU) |
|---|
| .. | .. |
|---|
| 979 | 990 | RXRPC_TX_ANNO_LAST && |
|---|
| 980 | 991 | summary.nr_acks == call->tx_top - hard_ack && |
|---|
| 981 | 992 | rxrpc_is_client_call(call)) |
|---|
| 982 | | - rxrpc_propose_ACK(call, RXRPC_ACK_PING, skew, sp->hdr.serial, |
|---|
| 993 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, ack_serial, |
|---|
| 983 | 994 | false, true, |
|---|
| 984 | 995 | rxrpc_propose_ack_ping_for_lost_reply); |
|---|
| 985 | 996 | |
|---|
| .. | .. |
|---|
| 1026 | 1037 | |
|---|
| 1027 | 1038 | _proto("Rx ABORT %%%u { %x }", sp->hdr.serial, abort_code); |
|---|
| 1028 | 1039 | |
|---|
| 1029 | | - if (rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED, |
|---|
| 1030 | | - abort_code, -ECONNABORTED)) |
|---|
| 1031 | | - rxrpc_notify_socket(call); |
|---|
| 1040 | + rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED, |
|---|
| 1041 | + abort_code, -ECONNABORTED); |
|---|
| 1032 | 1042 | } |
|---|
| 1033 | 1043 | |
|---|
| 1034 | 1044 | /* |
|---|
| 1035 | 1045 | * Process an incoming call packet. |
|---|
| 1036 | 1046 | */ |
|---|
| 1037 | 1047 | static void rxrpc_input_call_packet(struct rxrpc_call *call, |
|---|
| 1038 | | - struct sk_buff *skb, u16 skew) |
|---|
| 1048 | + struct sk_buff *skb) |
|---|
| 1039 | 1049 | { |
|---|
| 1040 | 1050 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
|---|
| 1041 | 1051 | unsigned long timo; |
|---|
| .. | .. |
|---|
| 1054 | 1064 | |
|---|
| 1055 | 1065 | switch (sp->hdr.type) { |
|---|
| 1056 | 1066 | case RXRPC_PACKET_TYPE_DATA: |
|---|
| 1057 | | - rxrpc_input_data(call, skb, skew); |
|---|
| 1058 | | - break; |
|---|
| 1067 | + rxrpc_input_data(call, skb); |
|---|
| 1068 | + goto no_free; |
|---|
| 1059 | 1069 | |
|---|
| 1060 | 1070 | case RXRPC_PACKET_TYPE_ACK: |
|---|
| 1061 | | - rxrpc_input_ack(call, skb, skew); |
|---|
| 1071 | + rxrpc_input_ack(call, skb); |
|---|
| 1062 | 1072 | break; |
|---|
| 1063 | 1073 | |
|---|
| 1064 | 1074 | case RXRPC_PACKET_TYPE_BUSY: |
|---|
| .. | .. |
|---|
| 1082 | 1092 | break; |
|---|
| 1083 | 1093 | } |
|---|
| 1084 | 1094 | |
|---|
| 1095 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 1096 | +no_free: |
|---|
| 1085 | 1097 | _leave(""); |
|---|
| 1086 | 1098 | } |
|---|
| 1087 | 1099 | |
|---|
| .. | .. |
|---|
| 1098 | 1110 | switch (READ_ONCE(call->state)) { |
|---|
| 1099 | 1111 | case RXRPC_CALL_SERVER_AWAIT_ACK: |
|---|
| 1100 | 1112 | rxrpc_call_completed(call); |
|---|
| 1101 | | - /* Fall through */ |
|---|
| 1113 | + fallthrough; |
|---|
| 1102 | 1114 | case RXRPC_CALL_COMPLETE: |
|---|
| 1103 | 1115 | break; |
|---|
| 1104 | 1116 | default: |
|---|
| .. | .. |
|---|
| 1113 | 1125 | spin_lock(&rx->incoming_lock); |
|---|
| 1114 | 1126 | __rxrpc_disconnect_call(conn, call); |
|---|
| 1115 | 1127 | spin_unlock(&rx->incoming_lock); |
|---|
| 1116 | | - rxrpc_notify_socket(call); |
|---|
| 1117 | 1128 | } |
|---|
| 1118 | 1129 | |
|---|
| 1119 | 1130 | /* |
|---|
| .. | .. |
|---|
| 1143 | 1154 | skb_queue_tail(&local->event_queue, skb); |
|---|
| 1144 | 1155 | rxrpc_queue_local(local); |
|---|
| 1145 | 1156 | } else { |
|---|
| 1146 | | - rxrpc_free_skb(skb, rxrpc_skb_rx_freed); |
|---|
| 1157 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 1147 | 1158 | } |
|---|
| 1148 | 1159 | } |
|---|
| 1149 | 1160 | |
|---|
| .. | .. |
|---|
| 1152 | 1163 | */ |
|---|
| 1153 | 1164 | static void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb) |
|---|
| 1154 | 1165 | { |
|---|
| 1155 | | - CHECK_SLAB_OKAY(&local->usage); |
|---|
| 1156 | | - |
|---|
| 1157 | 1166 | if (rxrpc_get_local_maybe(local)) { |
|---|
| 1158 | 1167 | skb_queue_tail(&local->reject_queue, skb); |
|---|
| 1159 | 1168 | rxrpc_queue_local(local); |
|---|
| 1160 | 1169 | } else { |
|---|
| 1161 | | - rxrpc_free_skb(skb, rxrpc_skb_rx_freed); |
|---|
| 1170 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 1162 | 1171 | } |
|---|
| 1163 | 1172 | } |
|---|
| 1164 | 1173 | |
|---|
| .. | .. |
|---|
| 1212 | 1221 | struct rxrpc_peer *peer = NULL; |
|---|
| 1213 | 1222 | struct rxrpc_sock *rx = NULL; |
|---|
| 1214 | 1223 | unsigned int channel; |
|---|
| 1215 | | - int skew = 0; |
|---|
| 1216 | 1224 | |
|---|
| 1217 | 1225 | _enter("%p", udp_sk); |
|---|
| 1218 | 1226 | |
|---|
| .. | .. |
|---|
| 1223 | 1231 | if (skb->tstamp == 0) |
|---|
| 1224 | 1232 | skb->tstamp = ktime_get_real(); |
|---|
| 1225 | 1233 | |
|---|
| 1226 | | - rxrpc_new_skb(skb, rxrpc_skb_rx_received); |
|---|
| 1234 | + rxrpc_new_skb(skb, rxrpc_skb_received); |
|---|
| 1227 | 1235 | |
|---|
| 1228 | 1236 | skb_pull(skb, sizeof(struct udphdr)); |
|---|
| 1229 | 1237 | |
|---|
| .. | .. |
|---|
| 1240 | 1248 | static int lose; |
|---|
| 1241 | 1249 | if ((lose++ & 7) == 7) { |
|---|
| 1242 | 1250 | trace_rxrpc_rx_lose(sp); |
|---|
| 1243 | | - rxrpc_free_skb(skb, rxrpc_skb_rx_lost); |
|---|
| 1251 | + rxrpc_free_skb(skb, rxrpc_skb_lost); |
|---|
| 1244 | 1252 | return 0; |
|---|
| 1245 | 1253 | } |
|---|
| 1246 | 1254 | } |
|---|
| .. | .. |
|---|
| 1259 | 1267 | case RXRPC_PACKET_TYPE_BUSY: |
|---|
| 1260 | 1268 | if (rxrpc_to_server(sp)) |
|---|
| 1261 | 1269 | goto discard; |
|---|
| 1262 | | - /* Fall through */ |
|---|
| 1270 | + fallthrough; |
|---|
| 1263 | 1271 | case RXRPC_PACKET_TYPE_ACK: |
|---|
| 1264 | 1272 | case RXRPC_PACKET_TYPE_ACKALL: |
|---|
| 1265 | 1273 | if (sp->hdr.callNumber == 0) |
|---|
| 1266 | 1274 | goto bad_message; |
|---|
| 1267 | | - /* Fall through */ |
|---|
| 1275 | + fallthrough; |
|---|
| 1268 | 1276 | case RXRPC_PACKET_TYPE_ABORT: |
|---|
| 1269 | 1277 | break; |
|---|
| 1270 | 1278 | |
|---|
| .. | .. |
|---|
| 1272 | 1280 | if (sp->hdr.callNumber == 0 || |
|---|
| 1273 | 1281 | sp->hdr.seq == 0) |
|---|
| 1274 | 1282 | goto bad_message; |
|---|
| 1275 | | - if (sp->hdr.flags & RXRPC_JUMBO_PACKET && |
|---|
| 1276 | | - !rxrpc_validate_jumbo(skb)) |
|---|
| 1283 | + if (!rxrpc_validate_data(skb)) |
|---|
| 1277 | 1284 | goto bad_message; |
|---|
| 1285 | + |
|---|
| 1286 | + /* Unshare the packet so that it can be modified for in-place |
|---|
| 1287 | + * decryption. |
|---|
| 1288 | + */ |
|---|
| 1289 | + if (sp->hdr.securityIndex != 0) { |
|---|
| 1290 | + struct sk_buff *nskb = skb_unshare(skb, GFP_ATOMIC); |
|---|
| 1291 | + if (!nskb) { |
|---|
| 1292 | + rxrpc_eaten_skb(skb, rxrpc_skb_unshared_nomem); |
|---|
| 1293 | + goto out; |
|---|
| 1294 | + } |
|---|
| 1295 | + |
|---|
| 1296 | + if (nskb != skb) { |
|---|
| 1297 | + rxrpc_eaten_skb(skb, rxrpc_skb_received); |
|---|
| 1298 | + skb = nskb; |
|---|
| 1299 | + rxrpc_new_skb(skb, rxrpc_skb_unshared); |
|---|
| 1300 | + sp = rxrpc_skb(skb); |
|---|
| 1301 | + } |
|---|
| 1302 | + } |
|---|
| 1278 | 1303 | break; |
|---|
| 1279 | 1304 | |
|---|
| 1280 | 1305 | case RXRPC_PACKET_TYPE_CHALLENGE: |
|---|
| .. | .. |
|---|
| 1340 | 1365 | goto out; |
|---|
| 1341 | 1366 | } |
|---|
| 1342 | 1367 | |
|---|
| 1343 | | - /* Note the serial number skew here */ |
|---|
| 1344 | | - skew = (int)sp->hdr.serial - (int)conn->hi_serial; |
|---|
| 1345 | | - if (skew >= 0) { |
|---|
| 1346 | | - if (skew > 0) |
|---|
| 1347 | | - conn->hi_serial = sp->hdr.serial; |
|---|
| 1348 | | - } else { |
|---|
| 1349 | | - skew = -skew; |
|---|
| 1350 | | - skew = min(skew, 65535); |
|---|
| 1351 | | - } |
|---|
| 1368 | + if ((int)sp->hdr.serial - (int)conn->hi_serial > 0) |
|---|
| 1369 | + conn->hi_serial = sp->hdr.serial; |
|---|
| 1352 | 1370 | |
|---|
| 1353 | 1371 | /* Call-bound packets are routed by connection channel. */ |
|---|
| 1354 | 1372 | channel = sp->hdr.cid & RXRPC_CHANNELMASK; |
|---|
| .. | .. |
|---|
| 1402 | 1420 | } |
|---|
| 1403 | 1421 | } |
|---|
| 1404 | 1422 | |
|---|
| 1405 | | - if (!call || atomic_read(&call->usage) == 0) { |
|---|
| 1423 | + if (!call || refcount_read(&call->ref) == 0) { |
|---|
| 1406 | 1424 | if (rxrpc_to_client(sp) || |
|---|
| 1407 | 1425 | sp->hdr.type != RXRPC_PACKET_TYPE_DATA) |
|---|
| 1408 | 1426 | goto bad_message; |
|---|
| .. | .. |
|---|
| 1411 | 1429 | call = rxrpc_new_incoming_call(local, rx, skb); |
|---|
| 1412 | 1430 | if (!call) |
|---|
| 1413 | 1431 | goto reject_packet; |
|---|
| 1414 | | - rxrpc_send_ping(call, skb, skew); |
|---|
| 1415 | | - mutex_unlock(&call->user_mutex); |
|---|
| 1416 | 1432 | } |
|---|
| 1417 | 1433 | |
|---|
| 1418 | | - rxrpc_input_call_packet(call, skb, skew); |
|---|
| 1419 | | - goto discard; |
|---|
| 1434 | + /* Process a call packet; this either discards or passes on the ref |
|---|
| 1435 | + * elsewhere. |
|---|
| 1436 | + */ |
|---|
| 1437 | + rxrpc_input_call_packet(call, skb); |
|---|
| 1438 | + goto out; |
|---|
| 1420 | 1439 | |
|---|
| 1421 | 1440 | discard: |
|---|
| 1422 | | - rxrpc_free_skb(skb, rxrpc_skb_rx_freed); |
|---|
| 1441 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 1423 | 1442 | out: |
|---|
| 1424 | 1443 | trace_rxrpc_rx_done(0, 0); |
|---|
| 1425 | 1444 | return 0; |
|---|