diff options
Diffstat (limited to 'net/rxrpc/input.c')
| -rw-r--r-- | net/rxrpc/input.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 991a20d25093..70bb77818dea 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
| @@ -55,9 +55,6 @@ int rxrpc_queue_rcv_skb(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 55 | if (test_bit(RXRPC_CALL_TERMINAL_MSG, &call->flags)) { | 55 | if (test_bit(RXRPC_CALL_TERMINAL_MSG, &call->flags)) { |
| 56 | _debug("already terminated"); | 56 | _debug("already terminated"); |
| 57 | ASSERTCMP(call->state, >=, RXRPC_CALL_COMPLETE); | 57 | ASSERTCMP(call->state, >=, RXRPC_CALL_COMPLETE); |
| 58 | skb->destructor = NULL; | ||
| 59 | sp->call = NULL; | ||
| 60 | rxrpc_put_call(call); | ||
| 61 | rxrpc_free_skb(skb); | 58 | rxrpc_free_skb(skb); |
| 62 | return 0; | 59 | return 0; |
| 63 | } | 60 | } |
| @@ -111,13 +108,7 @@ int rxrpc_queue_rcv_skb(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 111 | ret = 0; | 108 | ret = 0; |
| 112 | 109 | ||
| 113 | out: | 110 | out: |
| 114 | /* release the socket buffer */ | 111 | rxrpc_free_skb(skb); |
| 115 | if (skb) { | ||
| 116 | skb->destructor = NULL; | ||
| 117 | sp->call = NULL; | ||
| 118 | rxrpc_put_call(call); | ||
| 119 | rxrpc_free_skb(skb); | ||
| 120 | } | ||
| 121 | 112 | ||
| 122 | _leave(" = %d", ret); | 113 | _leave(" = %d", ret); |
| 123 | return ret; | 114 | return ret; |
| @@ -133,11 +124,15 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call, | |||
| 133 | struct rxrpc_skb_priv *sp; | 124 | struct rxrpc_skb_priv *sp; |
| 134 | bool terminal; | 125 | bool terminal; |
| 135 | int ret, ackbit, ack; | 126 | int ret, ackbit, ack; |
| 127 | u32 serial; | ||
| 128 | u8 flags; | ||
| 136 | 129 | ||
| 137 | _enter("{%u,%u},,{%u}", call->rx_data_post, call->rx_first_oos, seq); | 130 | _enter("{%u,%u},,{%u}", call->rx_data_post, call->rx_first_oos, seq); |
| 138 | 131 | ||
| 139 | sp = rxrpc_skb(skb); | 132 | sp = rxrpc_skb(skb); |
| 140 | ASSERTCMP(sp->call, ==, NULL); | 133 | ASSERTCMP(sp->call, ==, NULL); |
| 134 | flags = sp->hdr.flags; | ||
| 135 | serial = sp->hdr.serial; | ||
| 141 | 136 | ||
| 142 | spin_lock(&call->lock); | 137 | spin_lock(&call->lock); |
| 143 | 138 | ||
| @@ -200,8 +195,9 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call, | |||
| 200 | 195 | ||
| 201 | sp->call = call; | 196 | sp->call = call; |
| 202 | rxrpc_get_call(call); | 197 | rxrpc_get_call(call); |
| 203 | terminal = ((sp->hdr.flags & RXRPC_LAST_PACKET) && | 198 | atomic_inc(&call->skb_count); |
| 204 | !(sp->hdr.flags & RXRPC_CLIENT_INITIATED)); | 199 | terminal = ((flags & RXRPC_LAST_PACKET) && |
| 200 | !(flags & RXRPC_CLIENT_INITIATED)); | ||
| 205 | ret = rxrpc_queue_rcv_skb(call, skb, false, terminal); | 201 | ret = rxrpc_queue_rcv_skb(call, skb, false, terminal); |
| 206 | if (ret < 0) { | 202 | if (ret < 0) { |
| 207 | if (ret == -ENOMEM || ret == -ENOBUFS) { | 203 | if (ret == -ENOMEM || ret == -ENOBUFS) { |
| @@ -213,12 +209,13 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call, | |||
| 213 | } | 209 | } |
| 214 | 210 | ||
| 215 | skb = NULL; | 211 | skb = NULL; |
| 212 | sp = NULL; | ||
| 216 | 213 | ||
| 217 | _debug("post #%u", seq); | 214 | _debug("post #%u", seq); |
| 218 | ASSERTCMP(call->rx_data_post, ==, seq); | 215 | ASSERTCMP(call->rx_data_post, ==, seq); |
| 219 | call->rx_data_post++; | 216 | call->rx_data_post++; |
| 220 | 217 | ||
| 221 | if (sp->hdr.flags & RXRPC_LAST_PACKET) | 218 | if (flags & RXRPC_LAST_PACKET) |
| 222 | set_bit(RXRPC_CALL_RCVD_LAST, &call->flags); | 219 | set_bit(RXRPC_CALL_RCVD_LAST, &call->flags); |
| 223 | 220 | ||
| 224 | /* if we've reached an out of sequence packet then we need to drain | 221 | /* if we've reached an out of sequence packet then we need to drain |
| @@ -234,7 +231,7 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call, | |||
| 234 | 231 | ||
| 235 | spin_unlock(&call->lock); | 232 | spin_unlock(&call->lock); |
| 236 | atomic_inc(&call->ackr_not_idle); | 233 | atomic_inc(&call->ackr_not_idle); |
| 237 | rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, sp->hdr.serial, false); | 234 | rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, serial, false); |
| 238 | _leave(" = 0 [posted]"); | 235 | _leave(" = 0 [posted]"); |
| 239 | return 0; | 236 | return 0; |
| 240 | 237 | ||
| @@ -247,7 +244,7 @@ out: | |||
| 247 | 244 | ||
| 248 | discard_and_ack: | 245 | discard_and_ack: |
| 249 | _debug("discard and ACK packet %p", skb); | 246 | _debug("discard and ACK packet %p", skb); |
| 250 | __rxrpc_propose_ACK(call, ack, sp->hdr.serial, true); | 247 | __rxrpc_propose_ACK(call, ack, serial, true); |
| 251 | discard: | 248 | discard: |
| 252 | spin_unlock(&call->lock); | 249 | spin_unlock(&call->lock); |
| 253 | rxrpc_free_skb(skb); | 250 | rxrpc_free_skb(skb); |
| @@ -255,7 +252,7 @@ discard: | |||
| 255 | return 0; | 252 | return 0; |
| 256 | 253 | ||
| 257 | enqueue_and_ack: | 254 | enqueue_and_ack: |
| 258 | __rxrpc_propose_ACK(call, ack, sp->hdr.serial, true); | 255 | __rxrpc_propose_ACK(call, ack, serial, true); |
| 259 | enqueue_packet: | 256 | enqueue_packet: |
| 260 | _net("defer skb %p", skb); | 257 | _net("defer skb %p", skb); |
| 261 | spin_unlock(&call->lock); | 258 | spin_unlock(&call->lock); |
| @@ -575,13 +572,13 @@ done: | |||
| 575 | * post connection-level events to the connection | 572 | * post connection-level events to the connection |
| 576 | * - this includes challenges, responses and some aborts | 573 | * - this includes challenges, responses and some aborts |
| 577 | */ | 574 | */ |
| 578 | static bool rxrpc_post_packet_to_conn(struct rxrpc_connection *conn, | 575 | static void rxrpc_post_packet_to_conn(struct rxrpc_connection *conn, |
| 579 | struct sk_buff *skb) | 576 | struct sk_buff *skb) |
| 580 | { | 577 | { |
| 581 | _enter("%p,%p", conn, skb); | 578 | _enter("%p,%p", conn, skb); |
| 582 | 579 | ||
| 583 | skb_queue_tail(&conn->rx_queue, skb); | 580 | skb_queue_tail(&conn->rx_queue, skb); |
| 584 | return rxrpc_queue_conn(conn); | 581 | rxrpc_queue_conn(conn); |
| 585 | } | 582 | } |
| 586 | 583 | ||
| 587 | /* | 584 | /* |
| @@ -702,7 +699,6 @@ void rxrpc_data_ready(struct sock *sk) | |||
| 702 | 699 | ||
| 703 | rcu_read_lock(); | 700 | rcu_read_lock(); |
| 704 | 701 | ||
| 705 | retry_find_conn: | ||
| 706 | conn = rxrpc_find_connection_rcu(local, skb); | 702 | conn = rxrpc_find_connection_rcu(local, skb); |
| 707 | if (!conn) | 703 | if (!conn) |
| 708 | goto cant_route_call; | 704 | goto cant_route_call; |
| @@ -710,8 +706,7 @@ retry_find_conn: | |||
| 710 | if (sp->hdr.callNumber == 0) { | 706 | if (sp->hdr.callNumber == 0) { |
| 711 | /* Connection-level packet */ | 707 | /* Connection-level packet */ |
| 712 | _debug("CONN %p {%d}", conn, conn->debug_id); | 708 | _debug("CONN %p {%d}", conn, conn->debug_id); |
| 713 | if (!rxrpc_post_packet_to_conn(conn, skb)) | 709 | rxrpc_post_packet_to_conn(conn, skb); |
| 714 | goto retry_find_conn; | ||
| 715 | } else { | 710 | } else { |
| 716 | /* Call-bound packets are routed by connection channel. */ | 711 | /* Call-bound packets are routed by connection channel. */ |
| 717 | unsigned int channel = sp->hdr.cid & RXRPC_CHANNELMASK; | 712 | unsigned int channel = sp->hdr.cid & RXRPC_CHANNELMASK; |
| @@ -749,6 +744,8 @@ cant_route_call: | |||
| 749 | if (sp->hdr.type != RXRPC_PACKET_TYPE_ABORT) { | 744 | if (sp->hdr.type != RXRPC_PACKET_TYPE_ABORT) { |
| 750 | _debug("reject type %d",sp->hdr.type); | 745 | _debug("reject type %d",sp->hdr.type); |
| 751 | rxrpc_reject_packet(local, skb); | 746 | rxrpc_reject_packet(local, skb); |
| 747 | } else { | ||
| 748 | rxrpc_free_skb(skb); | ||
| 752 | } | 749 | } |
| 753 | _leave(" [no call]"); | 750 | _leave(" [no call]"); |
| 754 | return; | 751 | return; |
