Skip to content

Commit

Permalink
rxrpc: Allow a delay to be injected into packet reception
Browse files Browse the repository at this point in the history
If CONFIG_AF_RXRPC_DEBUG_RX_DELAY=y, then a delay is injected between
packets and errors being received and them being made available to the
processing code, thereby allowing the RTT to be artificially increased.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
dhowells committed Nov 2, 2022
1 parent 76ba79b commit e4d4990
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 2 deletions.
9 changes: 9 additions & 0 deletions net/rxrpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ config AF_RXRPC_INJECT_LOSS
Say Y here to inject packet loss by discarding some received and some
transmitted packets.

config AF_RXRPC_INJECT_RX_DELAY
bool "Inject delay into packet reception"
depends on SYSCTL
help
Say Y here to inject a delay into packet reception, allowing an
extended RTT time to be modelled. The delay can be configured using
/proc/sys/net/rxrpc/rxrpc_inject_rx_delay, setting a number of
milliseconds up to 0.5s (note that the granularity is actually in
jiffies).

config AF_RXRPC_DEBUG
bool "RxRPC dynamic debugging"
Expand Down
6 changes: 6 additions & 0 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ struct rxrpc_local {
struct task_struct *io_thread;
struct rxrpc_sock __rcu *service; /* Service(s) listening on this endpoint */
struct rw_semaphore defrag_sem; /* control re-enablement of IP DF bit */
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
struct sk_buff_head rx_delay_queue; /* Delay injection queue */
#endif
struct sk_buff_head rx_queue; /* Received packets */
struct list_head call_attend_q; /* Calls requiring immediate attention */
struct rb_root client_bundles; /* Client connection bundles by socket params */
Expand Down Expand Up @@ -1009,6 +1012,9 @@ extern unsigned long rxrpc_idle_ack_delay;
extern unsigned int rxrpc_rx_window_size;
extern unsigned int rxrpc_rx_mtu;
extern unsigned int rxrpc_rx_jumbo_max;
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
extern unsigned long rxrpc_inject_rx_delay;
#endif

/*
* net_ns.c
Expand Down
41 changes: 40 additions & 1 deletion net/rxrpc/io_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ int rxrpc_encap_rcv(struct sock *udp_sk, struct sk_buff *skb)

skb->mark = RXRPC_SKB_MARK_PACKET;
rxrpc_new_skb(skb, rxrpc_skb_received);
skb_queue_tail(&local->rx_queue, skb);
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
if (rxrpc_inject_rx_delay ||
!skb_queue_empty(&local->rx_delay_queue)) {
skb->tstamp = ktime_add_ms(skb->tstamp, rxrpc_inject_rx_delay);
skb_queue_tail(&local->rx_delay_queue, skb);
} else
#endif
skb_queue_tail(&local->rx_queue, skb);
rxrpc_wake_up_io_thread(local);
return 0;
}
Expand Down Expand Up @@ -415,6 +422,17 @@ int rxrpc_io_thread(void *data)
continue;
}

/* Inject a delay into packets if requested. */
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
now = ktime_get_real();
while ((skb = skb_peek(&local->rx_delay_queue))) {
if (ktime_before(now, skb->tstamp))
break;
skb = skb_dequeue(&local->rx_delay_queue);
skb_queue_tail(&local->rx_queue, skb);
}
#endif

if (!skb_queue_empty(&local->rx_queue)) {
spin_lock_irq(&local->rx_queue.lock);
skb_queue_splice_tail_init(&local->rx_queue, &rx_queue);
Expand All @@ -431,6 +449,27 @@ int rxrpc_io_thread(void *data)

if (kthread_should_stop())
break;

#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
if ((skb = skb_peek(&local->rx_delay_queue))) {
unsigned long timeout;
ktime_t tstamp = skb->tstamp;
ktime_t now = ktime_get_real();
s64 delay_ns = ktime_to_ns(ktime_sub(tstamp, now));

if (delay_ns <= 0) {
__set_current_state(TASK_RUNNING);
continue;
}

timeout = nsecs_to_jiffies(delay_ns);
timeout = max(timeout, 1UL);
schedule_timeout(timeout);
__set_current_state(TASK_RUNNING);
continue;
}
#endif

schedule();
}

Expand Down
6 changes: 6 additions & 0 deletions net/rxrpc/local_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
local->rxnet = rxnet;
INIT_HLIST_NODE(&local->link);
init_rwsem(&local->defrag_sem);
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
skb_queue_head_init(&local->rx_delay_queue);
#endif
skb_queue_head_init(&local->rx_queue);
INIT_LIST_HEAD(&local->call_attend_q);
local->client_bundles = RB_ROOT;
Expand Down Expand Up @@ -400,6 +403,9 @@ void rxrpc_destroy_local(struct rxrpc_local *local)
/* At this point, there should be no more packets coming in to the
* local endpoint.
*/
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
rxrpc_purge_queue(&local->rx_delay_queue);
#endif
rxrpc_purge_queue(&local->rx_queue);
}

Expand Down
7 changes: 7 additions & 0 deletions net/rxrpc/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,10 @@ unsigned int rxrpc_rx_mtu = 5692;
* sender that we're willing to handle.
*/
unsigned int rxrpc_rx_jumbo_max = 4;

#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
/*
* The delay to inject into packet reception.
*/
unsigned long rxrpc_inject_rx_delay = 0;
#endif
17 changes: 16 additions & 1 deletion net/rxrpc/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ static const unsigned int n_65535 = 65535;
static const unsigned int n_max_acks = 255;
static const unsigned long one_jiffy = 1;
static const unsigned long max_jiffies = MAX_JIFFY_OFFSET;
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
static const unsigned long max_500 = 500;
#endif

/*
* RxRPC operating parameters.
Expand Down Expand Up @@ -63,6 +66,19 @@ static struct ctl_table rxrpc_sysctl_table[] = {
.extra2 = (void *)&max_jiffies,
},

/* Values used in milliseconds */
#ifdef CONFIG_AF_RXRPC_INJECT_RX_DELAY
{
.procname = "inject_rx_delay",
.data = &rxrpc_inject_rx_delay,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_doulongvec_minmax,
.extra1 = (void *)SYSCTL_LONG_ZERO,
.extra2 = (void *)&max_500,
},
#endif

/* Non-time values */
{
.procname = "reap_client_conns",
Expand Down Expand Up @@ -109,7 +125,6 @@ static struct ctl_table rxrpc_sysctl_table[] = {
.extra1 = (void *)SYSCTL_ONE,
.extra2 = (void *)&four,
},

{ }
};

Expand Down

0 comments on commit e4d4990

Please sign in to comment.