On 5/13/19 2:44 PM, Oleksij Rempel wrote: > If retry timeout is equal for all systems and/or sockets, it will > collide at some point. In this case, one sender will always have > a chance to send some thing and make the CAN queue full, the other > one will always get -ENOBUS response. > Even if we would implement a scheduler for local system, we can't solve > same problem for multiple identical systems on same bus. > > Since the protocol has no other way to avoid this kind of collisions, > we can use random number for retry timer and reduce probability of > colliding retries. > > Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> > --- > net/can/j1939/transport.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c > index f469d9e131c7..978f2e194f32 100644 > --- a/net/can/j1939/transport.c > +++ b/net/can/j1939/transport.c > @@ -116,7 +116,6 @@ enum j1939_xtp_abort { > }; > > static unsigned int j1939_tp_block = 255; > -static unsigned int j1939_tp_retry_ms = 20; > static unsigned int j1939_tp_packet_delay; > static unsigned int j1939_tp_padding = 1; > > @@ -873,8 +872,12 @@ static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer) > int ret; > > ret = j1939_tp_txnext(session); > - if (ret < 0) > - j1939_tp_schedule_txtimer(session, j1939_tp_retry_ms ?: 20); > + if (ret < 0) { > + u32 random = get_random_u32(); It's probably save to use prandom_u32_max(): https://elixir.bootlin.com/linux/v5.1/source/include/linux/random.h#L137 > + > + j1939_tp_schedule_txtimer(session, 10 + (random & 0xf)); > + > + } > j1939_session_put(session); > > return HRTIMER_NORESTART; > Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Attachment:
signature.asc
Description: OpenPGP digital signature