Skip to content

Commit 5b0c6fc

Browse files
committed
Merge tag 'rxrpc-rewrite-20160917-1' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
David Howells says: ==================== rxrpc: Fixes & miscellany Here are some more AF_RXRPC fix patches with a couple of miscellaneous changes also. Fixes include: (1) Make RxRPC IPv6 support conditional on IPv6 being available. (2) Move the condition check in rxrpc_locate_data() into the caller and check the error return. (3) Fix the detection of the last received packet in recvmsg. (4) Account calls that need acceptance and clean up any unaccepted ones if the socket gets closed. (5) Fix the cleanup of client connections. (6) Fix the soft-ACK parsing and the retransmission of packets based on those ACKs. (7) Suppress transmission of an ACK when there's no pending ACK to transmit because another thread stole it. And some miscellany: (8) Whitespace removal. (9) Switch-value consistency in rxrpc_send_call_packet(). (10) Fix the basic transmission packet size to allow for spur-of-the-moment jumbo DATA packet production. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 029ac21 + 182f505 commit 5b0c6fc

File tree

8 files changed

+89
-70
lines changed

8 files changed

+89
-70
lines changed

net/rxrpc/call_accept.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local,
369369

370370
if (rx->notify_new_call)
371371
rx->notify_new_call(&rx->sk, call, call->user_call_ID);
372+
else
373+
sk_acceptq_added(&rx->sk);
372374

373375
spin_lock(&conn->state_lock);
374376
switch (conn->state) {

net/rxrpc/call_event.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static void rxrpc_set_timer(struct rxrpc_call *call)
3131
_enter("{%ld,%ld,%ld:%ld}",
3232
call->ack_at - now, call->resend_at - now, call->expire_at - now,
3333
call->timer.expires - now);
34-
34+
3535
read_lock_bh(&call->state_lock);
3636

3737
if (call->state < RXRPC_CALL_COMPLETE) {
@@ -163,8 +163,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
163163
*/
164164
now = jiffies;
165165
resend_at = now + rxrpc_resend_timeout;
166-
seq = cursor + 1;
167-
do {
166+
for (seq = cursor + 1; before_eq(seq, top); seq++) {
168167
ix = seq & RXRPC_RXTX_BUFF_MASK;
169168
annotation = call->rxtx_annotations[ix];
170169
if (annotation == RXRPC_TX_ANNO_ACK)
@@ -184,8 +183,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
184183

185184
/* Okay, we need to retransmit a packet. */
186185
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS;
187-
seq++;
188-
} while (before_eq(seq, top));
186+
}
189187

190188
call->resend_at = resend_at;
191189

@@ -194,8 +192,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
194192
* lock is dropped, it may clear some of the retransmission markers for
195193
* packets that it soft-ACKs.
196194
*/
197-
seq = cursor + 1;
198-
do {
195+
for (seq = cursor + 1; before_eq(seq, top); seq++) {
199196
ix = seq & RXRPC_RXTX_BUFF_MASK;
200197
annotation = call->rxtx_annotations[ix];
201198
if (annotation != RXRPC_TX_ANNO_RETRANS)
@@ -237,8 +234,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
237234

238235
if (after(call->tx_hard_ack, seq))
239236
seq = call->tx_hard_ack;
240-
seq++;
241-
} while (before_eq(seq, top));
237+
}
242238

243239
out_unlock:
244240
spin_unlock_bh(&call->lock);

net/rxrpc/call_object.c

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,6 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
226226
(const void *)user_call_ID);
227227

228228
/* Publish the call, even though it is incompletely set up as yet */
229-
call->user_call_ID = user_call_ID;
230-
__set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
231-
232229
write_lock(&rx->call_lock);
233230

234231
pp = &rx->calls.rb_node;
@@ -242,10 +239,12 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
242239
else if (user_call_ID > xcall->user_call_ID)
243240
pp = &(*pp)->rb_right;
244241
else
245-
goto found_user_ID_now_present;
242+
goto error_dup_user_ID;
246243
}
247244

248245
rcu_assign_pointer(call->socket, rx);
246+
call->user_call_ID = user_call_ID;
247+
__set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
249248
rxrpc_get_call(call, rxrpc_call_got_userid);
250249
rb_link_node(&call->sock_node, parent, pp);
251250
rb_insert_color(&call->sock_node, &rx->calls);
@@ -276,33 +275,22 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
276275
_leave(" = %p [new]", call);
277276
return call;
278277

279-
error:
280-
write_lock(&rx->call_lock);
281-
rb_erase(&call->sock_node, &rx->calls);
282-
write_unlock(&rx->call_lock);
283-
rxrpc_put_call(call, rxrpc_call_put_userid);
284-
285-
write_lock(&rxrpc_call_lock);
286-
list_del_init(&call->link);
287-
write_unlock(&rxrpc_call_lock);
288-
289-
error_out:
290-
__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
291-
RX_CALL_DEAD, ret);
292-
set_bit(RXRPC_CALL_RELEASED, &call->flags);
293-
rxrpc_put_call(call, rxrpc_call_put);
294-
_leave(" = %d", ret);
295-
return ERR_PTR(ret);
296-
297278
/* We unexpectedly found the user ID in the list after taking
298279
* the call_lock. This shouldn't happen unless the user races
299280
* with itself and tries to add the same user ID twice at the
300281
* same time in different threads.
301282
*/
302-
found_user_ID_now_present:
283+
error_dup_user_ID:
303284
write_unlock(&rx->call_lock);
304285
ret = -EEXIST;
305-
goto error_out;
286+
287+
error:
288+
__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
289+
RX_CALL_DEAD, ret);
290+
rxrpc_release_call(rx, call);
291+
rxrpc_put_call(call, rxrpc_call_put);
292+
_leave(" = %d", ret);
293+
return ERR_PTR(ret);
306294
}
307295

308296
/*
@@ -476,6 +464,16 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
476464

477465
_enter("%p", rx);
478466

467+
while (!list_empty(&rx->to_be_accepted)) {
468+
call = list_entry(rx->to_be_accepted.next,
469+
struct rxrpc_call, accept_link);
470+
list_del(&call->accept_link);
471+
rxrpc_abort_call("SKR", call, 0, RX_CALL_DEAD, ECONNRESET);
472+
rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT);
473+
rxrpc_release_call(rx, call);
474+
rxrpc_put_call(call, rxrpc_call_put);
475+
}
476+
479477
while (!list_empty(&rx->sock_calls)) {
480478
call = list_entry(rx->sock_calls.next,
481479
struct rxrpc_call, sock_link);

net/rxrpc/conn_client.c

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *call)
721721
}
722722

723723
ASSERTCMP(rcu_access_pointer(chan->call), ==, call);
724-
ASSERTCMP(atomic_read(&conn->usage), >=, 2);
725724

726725
/* If a client call was exposed to the world, we save the result for
727726
* retransmission.
@@ -818,7 +817,7 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *call)
818817
static struct rxrpc_connection *
819818
rxrpc_put_one_client_conn(struct rxrpc_connection *conn)
820819
{
821-
struct rxrpc_connection *next;
820+
struct rxrpc_connection *next = NULL;
822821
struct rxrpc_local *local = conn->params.local;
823822
unsigned int nr_conns;
824823

@@ -834,24 +833,22 @@ rxrpc_put_one_client_conn(struct rxrpc_connection *conn)
834833

835834
ASSERTCMP(conn->cache_state, ==, RXRPC_CONN_CLIENT_INACTIVE);
836835

837-
if (!test_bit(RXRPC_CONN_COUNTED, &conn->flags))
838-
return NULL;
839-
840-
spin_lock(&rxrpc_client_conn_cache_lock);
841-
nr_conns = --rxrpc_nr_client_conns;
836+
if (test_bit(RXRPC_CONN_COUNTED, &conn->flags)) {
837+
spin_lock(&rxrpc_client_conn_cache_lock);
838+
nr_conns = --rxrpc_nr_client_conns;
839+
840+
if (nr_conns < rxrpc_max_client_connections &&
841+
!list_empty(&rxrpc_waiting_client_conns)) {
842+
next = list_entry(rxrpc_waiting_client_conns.next,
843+
struct rxrpc_connection, cache_link);
844+
rxrpc_get_connection(next);
845+
rxrpc_activate_conn(next);
846+
}
842847

843-
next = NULL;
844-
if (nr_conns < rxrpc_max_client_connections &&
845-
!list_empty(&rxrpc_waiting_client_conns)) {
846-
next = list_entry(rxrpc_waiting_client_conns.next,
847-
struct rxrpc_connection, cache_link);
848-
rxrpc_get_connection(next);
849-
rxrpc_activate_conn(next);
848+
spin_unlock(&rxrpc_client_conn_cache_lock);
850849
}
851850

852-
spin_unlock(&rxrpc_client_conn_cache_lock);
853851
rxrpc_kill_connection(conn);
854-
855852
if (next)
856853
rxrpc_activate_channels(next);
857854

net/rxrpc/input.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb,
238238
len = RXRPC_JUMBO_DATALEN;
239239

240240
if (flags & RXRPC_LAST_PACKET) {
241-
if (test_and_set_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
241+
if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
242242
seq != call->rx_top)
243243
return rxrpc_proto_abort("LSN", call, seq);
244244
} else {
@@ -282,6 +282,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb,
282282
call->rxtx_buffer[ix] = skb;
283283
if (after(seq, call->rx_top))
284284
smp_store_release(&call->rx_top, seq);
285+
if (flags & RXRPC_LAST_PACKET)
286+
set_bit(RXRPC_CALL_RX_LAST, &call->flags);
285287
queued = true;
286288

287289
if (after_eq(seq, call->rx_expect_next)) {
@@ -382,7 +384,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,
382384

383385
for (; nr_acks > 0; nr_acks--, seq++) {
384386
ix = seq & RXRPC_RXTX_BUFF_MASK;
385-
switch (*acks) {
387+
switch (*acks++) {
386388
case RXRPC_ACK_TYPE_ACK:
387389
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_ACK;
388390
break;

net/rxrpc/output.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type)
137137
switch (type) {
138138
case RXRPC_PACKET_TYPE_ACK:
139139
spin_lock_bh(&call->lock);
140+
if (!call->ackr_reason) {
141+
spin_unlock_bh(&call->lock);
142+
ret = 0;
143+
goto out;
144+
}
140145
n = rxrpc_fill_out_ack(call, pkt);
141146
call->ackr_reason = 0;
142147

@@ -177,7 +182,7 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type)
177182
&msg, iov, ioc, len);
178183

179184
if (ret < 0 && call->state < RXRPC_CALL_COMPLETE) {
180-
switch (pkt->whdr.type) {
185+
switch (type) {
181186
case RXRPC_PACKET_TYPE_ACK:
182187
rxrpc_propose_ACK(call, pkt->ack.reason,
183188
ntohs(pkt->ack.maxSkew),

net/rxrpc/recvmsg.c

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call)
134134
{
135135
_enter("%d,%s", call->debug_id, rxrpc_call_states[call->state]);
136136

137+
ASSERTCMP(call->rx_hard_ack, ==, call->rx_top);
138+
137139
if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) {
138140
rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, true, false);
139141
rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK);
@@ -163,8 +165,10 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call)
163165
*/
164166
static void rxrpc_rotate_rx_window(struct rxrpc_call *call)
165167
{
168+
struct rxrpc_skb_priv *sp;
166169
struct sk_buff *skb;
167170
rxrpc_seq_t hard_ack, top;
171+
u8 flags;
168172
int ix;
169173

170174
_enter("%d", call->debug_id);
@@ -177,15 +181,17 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call)
177181
ix = hard_ack & RXRPC_RXTX_BUFF_MASK;
178182
skb = call->rxtx_buffer[ix];
179183
rxrpc_see_skb(skb);
184+
sp = rxrpc_skb(skb);
185+
flags = sp->hdr.flags;
180186
call->rxtx_buffer[ix] = NULL;
181187
call->rxtx_annotations[ix] = 0;
182188
/* Barrier against rxrpc_input_data(). */
183189
smp_store_release(&call->rx_hard_ack, hard_ack);
184190

185191
rxrpc_free_skb(skb);
186192

187-
_debug("%u,%u,%lx", hard_ack, top, call->flags);
188-
if (hard_ack == top && test_bit(RXRPC_CALL_RX_LAST, &call->flags))
193+
_debug("%u,%u,%02x", hard_ack, top, flags);
194+
if (flags & RXRPC_LAST_PACKET)
189195
rxrpc_end_rx_phase(call);
190196
}
191197

@@ -240,9 +246,6 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb,
240246
int ret;
241247
u8 annotation = *_annotation;
242248

243-
if (offset > 0)
244-
return 0;
245-
246249
/* Locate the subpacket */
247250
offset = sp->offset;
248251
len = skb->len - sp->offset;
@@ -281,13 +284,19 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
281284
size_t remain;
282285
bool last;
283286
unsigned int rx_pkt_offset, rx_pkt_len;
284-
int ix, copy, ret = 0;
287+
int ix, copy, ret = -EAGAIN, ret2;
285288

286289
_enter("");
287290

288291
rx_pkt_offset = call->rx_pkt_offset;
289292
rx_pkt_len = call->rx_pkt_len;
290293

294+
if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) {
295+
seq = call->rx_hard_ack;
296+
ret = 1;
297+
goto done;
298+
}
299+
291300
/* Barriers against rxrpc_input_data(). */
292301
hard_ack = call->rx_hard_ack;
293302
top = smp_load_acquire(&call->rx_top);
@@ -303,8 +312,15 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
303312
if (msg)
304313
sock_recv_timestamp(msg, sock->sk, skb);
305314

306-
ret = rxrpc_locate_data(call, skb, &call->rxtx_annotations[ix],
307-
&rx_pkt_offset, &rx_pkt_len);
315+
if (rx_pkt_offset == 0) {
316+
ret2 = rxrpc_locate_data(call, skb,
317+
&call->rxtx_annotations[ix],
318+
&rx_pkt_offset, &rx_pkt_len);
319+
if (ret2 < 0) {
320+
ret = ret2;
321+
goto out;
322+
}
323+
}
308324
_debug("recvmsg %x DATA #%u { %d, %d }",
309325
sp->hdr.callNumber, seq, rx_pkt_offset, rx_pkt_len);
310326

@@ -314,10 +330,12 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
314330
if (copy > remain)
315331
copy = remain;
316332
if (copy > 0) {
317-
ret = skb_copy_datagram_iter(skb, rx_pkt_offset, iter,
318-
copy);
319-
if (ret < 0)
333+
ret2 = skb_copy_datagram_iter(skb, rx_pkt_offset, iter,
334+
copy);
335+
if (ret2 < 0) {
336+
ret = ret2;
320337
goto out;
338+
}
321339

322340
/* handle piecemeal consumption of data packets */
323341
_debug("copied %d @%zu", copy, *_offset);
@@ -330,6 +348,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
330348
if (rx_pkt_len > 0) {
331349
_debug("buffer full");
332350
ASSERTCMP(*_offset, ==, len);
351+
ret = 0;
333352
break;
334353
}
335354

@@ -340,19 +359,19 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
340359
rx_pkt_offset = 0;
341360
rx_pkt_len = 0;
342361

343-
ASSERTIFCMP(last, seq, ==, top);
344-
}
345-
346-
if (after(seq, top)) {
347-
ret = -EAGAIN;
348-
if (test_bit(RXRPC_CALL_RX_LAST, &call->flags))
362+
if (last) {
363+
ASSERTCMP(seq, ==, READ_ONCE(call->rx_top));
349364
ret = 1;
365+
goto out;
366+
}
350367
}
368+
351369
out:
352370
if (!(flags & MSG_PEEK)) {
353371
call->rx_pkt_offset = rx_pkt_offset;
354372
call->rx_pkt_len = rx_pkt_len;
355373
}
374+
done:
356375
_leave(" = %d [%u/%u]", ret, seq, top);
357376
return ret;
358377
}

net/rxrpc/sendmsg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
214214
goto maybe_error;
215215
}
216216

217-
max = call->conn->params.peer->maxdata;
217+
max = RXRPC_JUMBO_DATALEN;
218218
max -= call->conn->security_size;
219219
max &= ~(call->conn->size_align - 1UL);
220220

0 commit comments

Comments
 (0)