* [PATCH] can: j1939: fix potential race condition in BAM segmentation
@ 2026-06-10 9:06 Alexander Hölzl
2026-10-01 10:42 ` Markus Koeniger
0 siblings, 1 reply; 6+ messages in thread
From: Alexander Hölzl @ 2026-06-10 9:06 UTC (permalink / raw)
To: o.rempel; +Cc: robin, linux-kernel, kernel, linux-can, Alexander Hölzl
There is a potential race condition in segmented messages using
the BAM protocol. When initiating a tx BAM session, first
the BAM itself is sent and then the txtimer is scheduled.
The tx timeout for BAM is currently hardcoded to 50ms.
As soon as the loopbacked BAM frame, acting as a tx
acknowledgment is received, the session->last_cmd field
is set to J1939_TP_CMD_BAM.
When the txtimer elapses the function j1939_xtp_txnext_transmiter
is called, which checks session->last_cmd and continues with
sending a data frame only if session->last_cmd is set to J1939_TP_CMD_BAM.
If there is a high busload and the BAM frame is stuck in the controller
for some time, the txtimer might elapse before the looped back frame is
received and the session will stall.
This problem becomes very obvious when changing the tx timeout
for BAMs to the lowest value allowed by the specification of 10ms.
This patch fixes the problem by moving the tx timer scheduling for
BAM transmissions such that the timer is scheduled when the tx ack
is received. This also fixes the problem that when consecutive
data frames are stuck in the controller they will be sent
without any delay.
Signed-off-by: Alexander Hölzl <alexander.hoelzl@gmx.net>
---
net/can/j1939/transport.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index df93d57907da..d00f0c158bb8 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -7,7 +7,6 @@
// Marc Kleine-Budde <kernel@pengutronix.de>
// Copyright (c) 2017-2019 Pengutronix,
// Oleksij Rempel <kernel@pengutronix.de>
-
#include <linux/can/skb.h>
#include <net/can.h>
@@ -26,6 +25,9 @@
#define J1939_TP_CMD_BAM 0x20
#define J1939_TP_CMD_ABORT 0xff
+#define J1939_TP_BAM_FRAME_SPACING_MS 50
+#define J1939_TP_BAM_ECHO_TIMEOUT_MS 250
+
#define J1939_ETP_CMD_RTS 0x14
#define J1939_ETP_CMD_CTS 0x15
#define J1939_ETP_CMD_DPO 0x16
@@ -754,7 +756,6 @@ static int j1939_session_tx_rts(struct j1939_session *session)
session->last_txcmd = dat[0];
if (dat[0] == J1939_TP_CMD_BAM) {
- j1939_tp_schedule_txtimer(session, 50);
j1939_tp_set_rxtimeout(session, 250);
} else {
j1939_tp_set_rxtimeout(session, 1250);
@@ -854,12 +855,19 @@ static int j1939_session_tx_dat(struct j1939_session *session)
session->last_txcmd = 0xff;
pkt_done++;
session->pkt.tx++;
- pdelay = j1939_cb_is_broadcast(&session->skcb) ? 50 :
- j1939_tp_packet_delay;
- if (session->pkt.tx < session->pkt.total && pdelay) {
- j1939_tp_schedule_txtimer(session, pdelay);
+ /* For BAM transfer the tx timer is scheduled after receiving
+ * the looped back frame as a tx ack. This means that here the
+ * timer is only scheduled for directed transfers.
+ */
+ pdelay = j1939_tp_packet_delay;
+ if (j1939_cb_is_broadcast(&session->skcb)) {
break;
+ } else {
+ if (session->pkt.tx < session->pkt.total && pdelay) {
+ j1939_tp_schedule_txtimer(session, j1939_tp_packet_delay);
+ break;
+ }
}
}
@@ -1793,8 +1801,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
session->last_cmd = cmd;
if (cmd == J1939_TP_CMD_BAM) {
- if (!session->transmission)
+ if (!session->transmission) {
j1939_tp_set_rxtimeout(session, 750);
+ } else {
+ j1939_tp_schedule_txtimer(session, J1939_TP_BAM_FRAME_SPACING_MS);
+ j1939_tp_set_rxtimeout(session, J1939_TP_BAM_ECHO_TIMEOUT_MS);
+ }
} else {
if (!session->transmission) {
j1939_session_txtimer_cancel(session);
@@ -1948,6 +1960,10 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
} else if (remain) {
if (!session->transmission)
j1939_tp_set_rxtimeout(session, 750);
+ else if (j1939_cb_is_broadcast(&session->skcb)) {
+ j1939_tp_schedule_txtimer(session, J1939_TP_BAM_FRAME_SPACING_MS);
+ j1939_tp_set_rxtimeout(session, J1939_TP_BAM_ECHO_TIMEOUT_MS);
+ }
} else if (do_cts_eoma) {
j1939_tp_set_rxtimeout(session, 1250);
if (!session->transmission)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] can: j1939: fix potential race condition in BAM segmentation
2026-06-10 9:06 [PATCH] can: j1939: fix potential race condition in BAM segmentation Alexander Hölzl
@ 2026-10-01 10:42 ` Markus Koeniger
2026-10-01 10:57 ` Marc Kleine-Budde
0 siblings, 1 reply; 6+ messages in thread
From: Markus Koeniger @ 2026-10-01 10:42 UTC (permalink / raw)
To: Alexander Hölzl
Cc: o.rempel, robin, linux-kernel, kernel, linux-can, markus.koeniger87
Hi Alexander,
I really appreciate your solution to schedule the TX timer for a BAM transfer after receiving the looped-back frame.
We use external CAN controllers in our system, which introduce some jitter into the transmit path. As a result, messages were sent from time to time too quickly and violated the 50 ms minimum interval. Your patch solves this problem.
Tested-by: Markus Koeniger markus.koeniger@liebherr.com
Best regards,
Markus
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] can: j1939: fix potential race condition in BAM segmentation
2026-10-01 10:42 ` Markus Koeniger
@ 2026-10-01 10:57 ` Marc Kleine-Budde
2026-10-01 11:18 ` Hölzl, Alexander
0 siblings, 1 reply; 6+ messages in thread
From: Marc Kleine-Budde @ 2026-10-01 10:57 UTC (permalink / raw)
To: Markus Koeniger
Cc: Alexander Hölzl, o.rempel, robin, linux-kernel, kernel, linux-can
[-- Attachment #1: Type: text/plain, Size: 877 bytes --]
On 01.10.2026 12:42:21, Markus Koeniger wrote:
> I really appreciate your solution to schedule the TX timer for a BAM
> transfer after receiving the looped-back frame.
> We use external CAN controllers in our system, which introduce some
> jitter into the transmit path. As a result, messages were sent from
> time to time too quickly and violated the 50 ms minimum interval. Your
> patch solves this problem.
>
> Tested-by: Markus Koeniger markus.koeniger@liebherr.com
Thanks for testing, however I'm not sure if we can get this patch
upstream if sashiko complains about it.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] can: j1939: fix potential race condition in BAM segmentation
2026-10-01 10:57 ` Marc Kleine-Budde
@ 2026-10-01 11:18 ` Hölzl, Alexander
2026-10-01 11:37 ` Oleksij Rempel
0 siblings, 1 reply; 6+ messages in thread
From: Hölzl, Alexander @ 2026-10-01 11:18 UTC (permalink / raw)
To: Marc Kleine-Budde, Markus Koeniger
Cc: o.rempel, robin, linux-kernel, kernel, linux-can
Hello,
Am 01.10.2026 um 12:57 schrieb Marc Kleine-Budde:
> On 01.10.2026 12:42:21, Markus Koeniger wrote:
>> I really appreciate your solution to schedule the TX timer for a BAM
>> transfer after receiving the looped-back frame.
>
Glad that I could help.
>> We use external CAN controllers in our system, which introduce some
>> jitter into the transmit path. As a result, messages were sent from
>> time to time too quickly and violated the 50 ms minimum interval. Your
>> patch solves this problem.
>>
>> Tested-by: Markus Koeniger markus.koeniger@liebherr.com
>
> Thanks for testing, however I'm not sure if we can get this patch
> upstream if sashiko complains about it.
>
I wasn't planning on letting this patch stall. Next week I'll try to
address sashiko comment's as well as the other patch I still have open.
Additionally while I'm at it I just wanted to ask, is it intended
behavior that the kernel implementation strictly serializes all J1939
sessions. E.g when sending a segmented message directed to destination
address A it is not possible to have a second session open targeting
destination address B. According to the standard this is allowed and not
being able to do so can result in very low performance in some
use-cases. This especially true if one of the sessions is a BAM session
transmitting a longer message, as there are 50ms pauses between each frame.
> regards,
> Marc
>
regards,
Alexander
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] can: j1939: fix potential race condition in BAM segmentation
2026-10-01 11:18 ` Hölzl, Alexander
@ 2026-10-01 11:37 ` Oleksij Rempel
2026-10-01 11:54 ` Hölzl, Alexander
0 siblings, 1 reply; 6+ messages in thread
From: Oleksij Rempel @ 2026-10-01 11:37 UTC (permalink / raw)
To: Hölzl, Alexander
Cc: Marc Kleine-Budde, Markus Koeniger, robin, linux-kernel, kernel,
linux-can
Hi,
On Thu, Oct 01, 2026 at 01:18:27PM +0200, Hölzl, Alexander wrote:
> Hello,
> Am 01.10.2026 um 12:57 schrieb Marc Kleine-Budde:
> > On 01.10.2026 12:42:21, Markus Koeniger wrote:
> > > I really appreciate your solution to schedule the TX timer for a BAM
> > > transfer after receiving the looped-back frame.
> >
> Glad that I could help.
>
> > > We use external CAN controllers in our system, which introduce some
> > > jitter into the transmit path. As a result, messages were sent from
> > > time to time too quickly and violated the 50 ms minimum interval. Your
> > > patch solves this problem.
> > >
> > > Tested-by: Markus Koeniger markus.koeniger@liebherr.com
> >
> > Thanks for testing, however I'm not sure if we can get this patch
> > upstream if sashiko complains about it.
> >
> I wasn't planning on letting this patch stall. Next week I'll try to address
> sashiko comment's as well as the other patch I still have open.
Nice, thx.
I'm working right now on j1939 selftests for core functionality. Hope
it will be ready this week. If not, next week i'll be in Prag on E-OSS
conference...
> Additionally while I'm at it I just wanted to ask, is it intended behavior
> that the kernel implementation strictly serializes all J1939 sessions. E.g
> when sending a segmented message directed to destination address A it is not
> possible to have a second session open targeting destination address B.
> According to the standard this is allowed and not
> being able to do so can result in very low performance in some use-cases.
> This especially true if one of the sessions is a BAM session transmitting a
> longer message, as there are 50ms pauses between each frame.
Is it not working with a separate socket? If I remember it correctly,
this behavior should be supported if two sockets send to separate
addresses. Withing one socket, frames should be serialized.
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] can: j1939: fix potential race condition in BAM segmentation
2026-10-01 11:37 ` Oleksij Rempel
@ 2026-10-01 11:54 ` Hölzl, Alexander
0 siblings, 0 replies; 6+ messages in thread
From: Hölzl, Alexander @ 2026-10-01 11:54 UTC (permalink / raw)
To: Oleksij Rempel
Cc: Marc Kleine-Budde, Markus Koeniger, robin, linux-kernel, kernel,
linux-can
Am 01.10.2026 um 13:37 schrieb Oleksij Rempel:
> Hi,
>
> On Thu, Oct 01, 2026 at 01:18:27PM +0200, Hölzl, Alexander wrote:
>> Hello,
>> Am 01.10.2026 um 12:57 schrieb Marc Kleine-Budde:
>>> On 01.10.2026 12:42:21, Markus Koeniger wrote:
>>>> I really appreciate your solution to schedule the TX timer for a BAM
>>>> transfer after receiving the looped-back frame.
>>>
>> Glad that I could help.
>>
>>>> We use external CAN controllers in our system, which introduce some
>>>> jitter into the transmit path. As a result, messages were sent from
>>>> time to time too quickly and violated the 50 ms minimum interval. Your
>>>> patch solves this problem.
>>>>
>>>> Tested-by: Markus Koeniger markus.koeniger@liebherr.com
>>>
>>> Thanks for testing, however I'm not sure if we can get this patch
>>> upstream if sashiko complains about it.
>>>
>> I wasn't planning on letting this patch stall. Next week I'll try to address
>> sashiko comment's as well as the other patch I still have open.
>
> Nice, thx.
>
> I'm working right now on j1939 selftests for core functionality. Hope
> it will be ready this week. If not, next week i'll be in Prag on E-OSS
> conference...
>
Ah that's good to know. In the CTS hold patch I've also implemented
some tests (https://lkml.org/lkml/2026/7/7/85) but I guess they'll
mostly be superfluous then?>> Additionally while I'm at it I just wanted
to ask, is it intended behavior
>> that the kernel implementation strictly serializes all J1939 sessions. E.g
>> when sending a segmented message directed to destination address A it is not
>> possible to have a second session open targeting destination address B.
>> According to the standard this is allowed and not
>> being able to do so can result in very low performance in some use-cases.
>> This especially true if one of the sessions is a BAM session transmitting a
>> longer message, as there are 50ms pauses between each frame.
>
> Is it not working with a separate socket? If I remember it correctly,
> this behavior should be supported if two sockets send to separate
> addresses. Withing one socket, frames should be serialized.
>
I've never tried it with multiple sockets but if you say so I'm sure
it'll work :). For my use case specifically this quite inconvenient
behavior but I guess I might be abusing the stack a little bit :).
I've written a patch which allows interleaved tx-sessions per socket but
if the kernel behaves as designed then that's probably not something
which I should try to get into the mainline.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-01 11:55 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-10 9:06 [PATCH] can: j1939: fix potential race condition in BAM segmentation Alexander Hölzl
2026-10-01 10:42 ` Markus Koeniger
2026-10-01 10:57 ` Marc Kleine-Budde
2026-10-01 11:18 ` Hölzl, Alexander
2026-10-01 11:37 ` Oleksij Rempel
2026-10-01 11:54 ` Hölzl, Alexander
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®