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; |