Skip to content

Commit

Permalink
Merge tag 'rxrpc-devel-20140304' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/dhowells/linux-fs

David Howells says:

====================
net-next: AF_RXRPC fixes and development

Here are some AF_RXRPC fixes:

 (1) Fix to remove incorrect checksum calculation made during recvmsg().  It's
     unnecessary to try to do this there since we check the checksum before
     reading the RxRPC header from the packet.

 (2) Fix to prevent the sending of an ABORT packet in response to another
     ABORT packet and inducing a storm.

 (3) Fix UDP MTU calculation from parsing ICMP_FRAG_NEEDED packets where we
     don't handle the ICMP packet not specifying an MTU size.

And development patches:

 (4) Add sysctls for configuring RxRPC parameters, specifically various delays
     pertaining to ACK generation, the time before we resend a packet for
     which we don't receive an ACK, the maximum time a call is permitted to
     live and the amount of time transport, connection and dead call
     information is cached.

 (5) Improve ACK packet production by adjusting the handling of ACK_REQUESTED
     packets, ignoring the MORE_PACKETS flag, delaying the production of
     otherwise immediate ACK_IDLE packets and delaying all ACK_IDLE production
     (barring the call termination) to half a second.

 (6) Add more sysctl parameters to expose the Rx window size, the maximum
     packet size that we're willing to receive and the number of jumbo rxrpc
     packets we're willing to handle in a single UDP packet.

 (7) Request ACKs on alternate DATA packets so that the other side doesn't
     wait till we fill up the Tx window.

 (8) Use a RCU hash table to look up the rxrpc_call for an incoming packet
     rather than stepping through a hierarchy involving several spinlocks.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 7, 2014
2 parents 4caeccb + 7727640 commit 3894004
Show file tree
Hide file tree
Showing 14 changed files with 645 additions and 168 deletions.
81 changes: 81 additions & 0 deletions Documentation/networking/rxrpc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Contents of this document:

(*) AF_RXRPC kernel interface.

(*) Configurable parameters.


========
OVERVIEW
Expand Down Expand Up @@ -864,3 +866,82 @@ The kernel interface functions are as follows:

This is used to allocate a null RxRPC key that can be used to indicate
anonymous security for a particular domain.


=======================
CONFIGURABLE PARAMETERS
=======================

The RxRPC protocol driver has a number of configurable parameters that can be
adjusted through sysctls in /proc/net/rxrpc/:

(*) req_ack_delay

The amount of time in milliseconds after receiving a packet with the
request-ack flag set before we honour the flag and actually send the
requested ack.

Usually the other side won't stop sending packets until the advertised
reception window is full (to a maximum of 255 packets), so delaying the
ACK permits several packets to be ACK'd in one go.

(*) soft_ack_delay

The amount of time in milliseconds after receiving a new packet before we
generate a soft-ACK to tell the sender that it doesn't need to resend.

(*) idle_ack_delay

The amount of time in milliseconds after all the packets currently in the
received queue have been consumed before we generate a hard-ACK to tell
the sender it can free its buffers, assuming no other reason occurs that
we would send an ACK.

(*) resend_timeout

The amount of time in milliseconds after transmitting a packet before we
transmit it again, assuming no ACK is received from the receiver telling
us they got it.

(*) max_call_lifetime

The maximum amount of time in seconds that a call may be in progress
before we preemptively kill it.

(*) dead_call_expiry

The amount of time in seconds before we remove a dead call from the call
list. Dead calls are kept around for a little while for the purpose of
repeating ACK and ABORT packets.

(*) connection_expiry

The amount of time in seconds after a connection was last used before we
remove it from the connection list. Whilst a connection is in existence,
it serves as a placeholder for negotiated security; when it is deleted,
the security must be renegotiated.

(*) transport_expiry

The amount of time in seconds after a transport was last used before we
remove it from the transport list. Whilst a transport is in existence, it
serves to anchor the peer data and keeps the connection ID counter.

(*) rxrpc_rx_window_size

The size of the receive window in packets. This is the maximum number of
unconsumed received packets we're willing to hold in memory for any
particular call.

(*) rxrpc_rx_mtu

The maximum packet MTU size that we're willing to receive in bytes. This
indicates to the peer whether we're willing to accept jumbo packets.

(*) rxrpc_rx_jumbo_max

The maximum number of packets that we're willing to accept in a jumbo
packet. Non-terminal packets in a jumbo packet must contain a four byte
header plus exactly 1412 bytes of data. The terminal packet must contain
a four byte header plus any amount of data. In any event, a jumbo packet
may not exceed rxrpc_rx_mtu in size.
5 changes: 2 additions & 3 deletions net/rxrpc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ af-rxrpc-y := \
ar-skbuff.o \
ar-transport.o

ifeq ($(CONFIG_PROC_FS),y)
af-rxrpc-y += ar-proc.o
endif
af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o
af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o

obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o

Expand Down
9 changes: 9 additions & 0 deletions net/rxrpc/af_rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,13 +838,21 @@ static int __init af_rxrpc_init(void)
goto error_key_type_s;
}

ret = rxrpc_sysctl_init();
if (ret < 0) {
printk(KERN_CRIT "RxRPC: Cannot register sysctls\n");
goto error_sysctls;
}

#ifdef CONFIG_PROC_FS
proc_create("rxrpc_calls", 0, init_net.proc_net, &rxrpc_call_seq_fops);
proc_create("rxrpc_conns", 0, init_net.proc_net,
&rxrpc_connection_seq_fops);
#endif
return 0;

error_sysctls:
unregister_key_type(&key_type_rxrpc_s);
error_key_type_s:
unregister_key_type(&key_type_rxrpc);
error_key_type:
Expand All @@ -865,6 +873,7 @@ static int __init af_rxrpc_init(void)
static void __exit af_rxrpc_exit(void)
{
_enter("");
rxrpc_sysctl_exit();
unregister_key_type(&key_type_rxrpc_s);
unregister_key_type(&key_type_rxrpc);
sock_unregister(PF_RXRPC);
Expand Down
61 changes: 51 additions & 10 deletions net/rxrpc/ar-ack.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,49 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"

static unsigned int rxrpc_ack_defer = 1;
/*
* How long to wait before scheduling ACK generation after seeing a
* packet with RXRPC_REQUEST_ACK set (in jiffies).
*/
unsigned rxrpc_requested_ack_delay = 1;

/*
* How long to wait before scheduling an ACK with subtype DELAY (in jiffies).
*
* We use this when we've received new data packets. If those packets aren't
* all consumed within this time we will send a DELAY ACK if an ACK was not
* requested to let the sender know it doesn't need to resend.
*/
unsigned rxrpc_soft_ack_delay = 1 * HZ;

/*
* How long to wait before scheduling an ACK with subtype IDLE (in jiffies).
*
* We use this when we've consumed some previously soft-ACK'd packets when
* further packets aren't immediately received to decide when to send an IDLE
* ACK let the other end know that it can free up its Tx buffer space.
*/
unsigned rxrpc_idle_ack_delay = 0.5 * HZ;

/*
* Receive window size in packets. This indicates the maximum number of
* unconsumed received packets we're willing to retain in memory. Once this
* limit is hit, we should generate an EXCEEDS_WINDOW ACK and discard further
* packets.
*/
unsigned rxrpc_rx_window_size = 32;

/*
* Maximum Rx MTU size. This indicates to the sender the size of jumbo packet
* made by gluing normal packets together that we're willing to handle.
*/
unsigned rxrpc_rx_mtu = 5692;

/*
* The maximum number of fragments in a received jumbo packet that we tell the
* sender that we're willing to handle.
*/
unsigned rxrpc_rx_jumbo_max = 4;

static const char *rxrpc_acks(u8 reason)
{
Expand Down Expand Up @@ -82,24 +124,23 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
switch (ack_reason) {
case RXRPC_ACK_DELAY:
_debug("run delay timer");
call->ack_timer.expires = jiffies + rxrpc_ack_timeout * HZ;
add_timer(&call->ack_timer);
return;
expiry = rxrpc_soft_ack_delay;
goto run_timer;

case RXRPC_ACK_IDLE:
if (!immediate) {
_debug("run defer timer");
expiry = 1;
expiry = rxrpc_idle_ack_delay;
goto run_timer;
}
goto cancel_timer;

case RXRPC_ACK_REQUESTED:
if (!rxrpc_ack_defer)
expiry = rxrpc_requested_ack_delay;
if (!expiry)
goto cancel_timer;
if (!immediate || serial == cpu_to_be32(1)) {
_debug("run defer timer");
expiry = rxrpc_ack_defer;
goto run_timer;
}

Expand Down Expand Up @@ -1174,11 +1215,11 @@ void rxrpc_process_call(struct work_struct *work)
mtu = call->conn->trans->peer->if_mtu;
mtu -= call->conn->trans->peer->hdrsize;
ackinfo.maxMTU = htonl(mtu);
ackinfo.rwind = htonl(32);
ackinfo.rwind = htonl(rxrpc_rx_window_size);

/* permit the peer to send us jumbo packets if it wants to */
ackinfo.rxMTU = htonl(5692);
ackinfo.jumbo_max = htonl(4);
ackinfo.rxMTU = htonl(rxrpc_rx_mtu);
ackinfo.jumbo_max = htonl(rxrpc_rx_jumbo_max);

hdr.serial = htonl(atomic_inc_return(&call->conn->serial));
_proto("Tx ACK %%%u { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
Expand Down
Loading

0 comments on commit 3894004

Please sign in to comment.