Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5873c083 authored by David Howells's avatar David Howells
Browse files

af_rxrpc: Add sysctls for configuring RxRPC parameters



Add sysctls for configuring RxRPC protocol handling, specifically controls on
delays before ack generation, the delay before resending a packet, the maximum
lifetime of a call and the expiration times of calls, connections and
transports that haven't been recently used.

More info added in Documentation/networking/rxrpc.txt.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 6c9a2d32
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ Contents of this document:

 (*) AF_RXRPC kernel interface.

 (*) Configurable parameters.


========
OVERVIEW
@@ -864,3 +866,63 @@ 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.
+2 −3
Original line number Diff line number Diff line
@@ -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

+9 −0
Original line number Diff line number Diff line
@@ -838,6 +838,12 @@ 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,
@@ -845,6 +851,8 @@ static int __init af_rxrpc_init(void)
#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:
@@ -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);
+28 −7
Original line number Diff line number Diff line
@@ -19,7 +19,29 @@
#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 = 1;

static const char *rxrpc_acks(u8 reason)
{
@@ -82,24 +104,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;
		}

+13 −5
Original line number Diff line number Diff line
@@ -16,6 +16,16 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"

/*
 * Maximum lifetime of a call (in jiffies).
 */
unsigned rxrpc_max_call_lifetime = 60 * HZ;

/*
 * Time till dead call expires after last use (in jiffies).
 */
unsigned rxrpc_dead_call_expiry = 2 * HZ;

const char *const rxrpc_call_states[] = {
	[RXRPC_CALL_CLIENT_SEND_REQUEST]	= "ClSndReq",
	[RXRPC_CALL_CLIENT_AWAIT_REPLY]		= "ClAwtRpl",
@@ -38,8 +48,6 @@ const char *const rxrpc_call_states[] = {
struct kmem_cache *rxrpc_call_jar;
LIST_HEAD(rxrpc_calls);
DEFINE_RWLOCK(rxrpc_call_lock);
static unsigned int rxrpc_call_max_lifetime = 60;
static unsigned int rxrpc_dead_call_timeout = 2;

static void rxrpc_destroy_call(struct work_struct *work);
static void rxrpc_call_life_expired(unsigned long _call);
@@ -132,7 +140,7 @@ static struct rxrpc_call *rxrpc_alloc_client_call(
	list_add(&call->error_link, &call->conn->trans->peer->error_targets);
	spin_unlock(&call->conn->trans->peer->lock);

	call->lifetimer.expires = jiffies + rxrpc_call_max_lifetime * HZ;
	call->lifetimer.expires = jiffies + rxrpc_max_call_lifetime;
	add_timer(&call->lifetimer);

	_leave(" = %p", call);
@@ -349,7 +357,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,

	_net("CALL incoming %d on CONN %d", call->debug_id, call->conn->debug_id);

	call->lifetimer.expires = jiffies + rxrpc_call_max_lifetime * HZ;
	call->lifetimer.expires = jiffies + rxrpc_max_call_lifetime;
	add_timer(&call->lifetimer);
	_leave(" = %p {%d} [new]", call, call->debug_id);
	return call;
@@ -533,7 +541,7 @@ void rxrpc_release_call(struct rxrpc_call *call)
	del_timer_sync(&call->resend_timer);
	del_timer_sync(&call->ack_timer);
	del_timer_sync(&call->lifetimer);
	call->deadspan.expires = jiffies + rxrpc_dead_call_timeout * HZ;
	call->deadspan.expires = jiffies + rxrpc_dead_call_expiry;
	add_timer(&call->deadspan);

	_leave("");
Loading