Skip to content

Commit 3cad70b

Browse files
francoismichelkuba-moo
authored andcommitted
netem: use seeded PRNG for correlated loss events
Use prandom_u32_state() instead of get_random_u32() to generate the correlated loss events of netem. Signed-off-by: François Michel <francois.michel@uclouvain.be> Reviewed-by: Simon Horman <horms@kernel.org> Acked-by: Stephen Hemminger <stephen@networkplumber.org> Link: https://lore.kernel.org/r/20230815092348.1449179-4-francois.michel@uclouvain.be Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 9c87b2a commit 3cad70b

1 file changed

Lines changed: 12 additions & 10 deletions

File tree

net/sched/sch_netem.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,16 @@ static void init_crandom(struct crndstate *state, unsigned long rho)
184184
* Next number depends on last value.
185185
* rho is scaled to avoid floating point.
186186
*/
187-
static u32 get_crandom(struct crndstate *state)
187+
static u32 get_crandom(struct crndstate *state, struct prng *p)
188188
{
189189
u64 value, rho;
190190
unsigned long answer;
191+
struct rnd_state *s = &p->prng_state;
191192

192193
if (!state || state->rho == 0) /* no correlation */
193-
return get_random_u32();
194+
return prandom_u32_state(s);
194195

195-
value = get_random_u32();
196+
value = prandom_u32_state(s);
196197
rho = (u64)state->rho + 1;
197198
answer = (value * ((1ull<<32) - rho) + state->last * rho) >> 32;
198199
state->last = answer;
@@ -295,7 +296,7 @@ static bool loss_event(struct netem_sched_data *q)
295296
switch (q->loss_model) {
296297
case CLG_RANDOM:
297298
/* Random packet drop 0 => none, ~0 => all */
298-
return q->loss && q->loss >= get_crandom(&q->loss_cor);
299+
return q->loss && q->loss >= get_crandom(&q->loss_cor, &q->prng);
299300

300301
case CLG_4_STATES:
301302
/* 4state loss model algorithm (used also for GI model)
@@ -324,6 +325,7 @@ static bool loss_event(struct netem_sched_data *q)
324325
*/
325326
static s64 tabledist(s64 mu, s32 sigma,
326327
struct crndstate *state,
328+
struct prng *prng,
327329
const struct disttable *dist)
328330
{
329331
s64 x;
@@ -333,7 +335,7 @@ static s64 tabledist(s64 mu, s32 sigma,
333335
if (sigma == 0)
334336
return mu;
335337

336-
rnd = get_crandom(state);
338+
rnd = get_crandom(state, prng);
337339

338340
/* default uniform distribution */
339341
if (dist == NULL)
@@ -455,7 +457,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
455457
skb->prev = NULL;
456458

457459
/* Random duplication */
458-
if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor))
460+
if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor, &q->prng))
459461
++count;
460462

461463
/* Drop packet? */
@@ -498,7 +500,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
498500
* If packet is going to be hardware checksummed, then
499501
* do it now in software before we mangle it.
500502
*/
501-
if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
503+
if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor, &q->prng)) {
502504
if (skb_is_gso(skb)) {
503505
skb = netem_segment(skb, sch, to_free);
504506
if (!skb)
@@ -536,12 +538,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
536538
cb = netem_skb_cb(skb);
537539
if (q->gap == 0 || /* not doing reordering */
538540
q->counter < q->gap - 1 || /* inside last reordering gap */
539-
q->reorder < get_crandom(&q->reorder_cor)) {
541+
q->reorder < get_crandom(&q->reorder_cor, &q->prng)) {
540542
u64 now;
541543
s64 delay;
542544

543545
delay = tabledist(q->latency, q->jitter,
544-
&q->delay_cor, q->delay_dist);
546+
&q->delay_cor, &q->prng, q->delay_dist);
545547

546548
now = ktime_get_ns();
547549

@@ -645,7 +647,7 @@ static void get_slot_next(struct netem_sched_data *q, u64 now)
645647
else
646648
next_delay = tabledist(q->slot_config.dist_delay,
647649
(s32)(q->slot_config.dist_jitter),
648-
NULL, q->slot_dist);
650+
NULL, &q->prng, q->slot_dist);
649651

650652
q->slot.slot_next = now + next_delay;
651653
q->slot.packets_left = q->slot_config.max_packets;

0 commit comments

Comments
 (0)