- Configuring LinuxCNC
- Advanced Configuration
- EtherCAT
- J1900 L2 sibling: pin Qt HMI to CPUs 0-1, keep the 1 ms EtherCAT thread on CPU3
J1900 L2 sibling: pin Qt HMI to CPUs 0-1, keep the 1 ms EtherCAT thread on CPU3
- tietouwa
-
Topic Author
- Offline
- New Member
-
Less
More
- Posts: 6
- Thank you received: 2
16 Sep 2026 02:27 #349668
by tietouwa
J1900 L2 sibling: pin Qt HMI to CPUs 0-1, keep the 1 ms EtherCAT thread on CPU3 was created by tietouwa
Not a LinuxCNC install. Same class of box as the earlier J1900 eglfs vs Xorg thread.Posting because the useful knob was not another kernel cmdline flag.
Intel Celeron J1900 has 2 MiB L2 as two 1 MiB slices:
CPUs 0-1 share one L2
CPUs 2-3 share the other L2
We already isolated the EtherCAT loop on CPU3 (SCHED_FIFO 80, 1 kHz).
That is not enough if the fullscreen Qt/eglfs HMI is still allowed on CPU2.
The UI then sits on the L2 sibling of the RT core and contends for the same 1 MiB.
Change (HMI only, not a whole-system cgroup):
before: Qt main / touch / QML / render / GPU worker allowed on CPUs 0-2
after: those threads allowed on CPUs 0-1 only
RT thread stayed on CPU3 both times
Same binary, same recipe, same 1 ms period, 20 automatic press cycles each side.
Jitter = wake-to-wake CLOCK_MONOTONIC minus 1 ms, integer microseconds.
0 us means |error| < 1 us. This is period error, not latency-test / cyclictest.
All numbers below are the full captures (approach + press + retract), not a PID subset.
Absolute jitter, nearest-rank, all samples
UI on 0-2 (20 runs) UI on 0-1 (20 runs)
n 119159 119254
P50 0 us 0 us
P95 6 us 1 us
P99 13 us 1 us
P99.9 21 us 2 us
signed min/max -42 / +46 us -13 / +14 us
|j| >= 10 us 2983 8
|j| >= 20 us 198 0
|j| >= 30 us 22 0
|j|
Per-run P50 / P95 / P99 / P99.9 (|jitter|, us)
# UI 0-2 UI 0-1
1 1 / 9 / 14 / 23 0 / 1 / 1 / 2
2 0 / 2 / 9 / 19 0 / 1 / 1 / 2
3 0 / 5 / 12 / 21 0 / 1 / 1 / 2
4 0 / 6 / 15 / 20 0 / 1 / 1 / 2
5 0 / 7 / 15 / 20 0 / 1 / 1 / 2
6 0 / 1 / 1 / 2 0 / 1 / 1 / 2
7 0 / 6 / 14 / 20 0 / 1 / 1 / 2
8 0 / 7 / 15 / 20 0 / 1 / 1 / 2
9 0 / 4 / 13 / 19 0 / 1 / 1 / 2
10 0 / 6 / 16 / 26 0 / 1 / 1 / 2
11 0 / 3 / 11 / 22 0 / 1 / 1 / 3
12 1 / 9 / 15 / 23 0 / 1 / 1 / 2
13 1 / 9 / 14 / 26 0 / 1 / 1 / 2
14 1 / 9 / 15 / 32 0 / 1 / 1 / 2
15 0 / 8 / 14 / 19 0 / 1 / 1 / 2
16 1 / 9 / 14 / 26 0 / 1 / 1 / 2
17 0 / 1 / 6 / 13 0 / 1 / 1 / 2
18 0 / 6 / 13 / 19 0 / 1 / 1 / 2
19 0 / 1 / 5 / 15 0 / 1 / 1 / 2
20 0 / 1 / 1 / 2 0 / 1 / 1 / 2
After the pin, every run has P99 = 1 us. 15/20 runs have max |j|
The 8 remaining >=10 us samples are two ticks each in runs 1, 8, 15, 16.
Point of the numbers
- P50 was already 0 us. The HMI was not ruining the median.
- The L2 sibling shows up in the tail: P95 6->1, P99 13->1, P99.9 21->2.
- Moving i915 IRQ off CPU2 was not sufficient by itself. User-space Qt
render can still land on CPU2 and thrash the RT core's L2.
- Do not set a cgroup AllowedCPUs=0-1 on the whole process: the FIFO
thread must still be able to bind to CPU3.
- Do not park every system thread on 0-1. This was only the HMI/render path.
Box (for context, not the variable under test)
- Debian 13 PREEMPT_RT 6.12, Qt eglfs_kms, no X
- IgH EtherCAT, 1 kHz, Lost frames = 0
- isolcpus / rcu_nocbs on CPU3, i915 IRQ on CPU0
Happy to hear if anyone running a GL HMI on Bay Trail saw the same
CPU2/CPU3 L2 pairing.
Intel Celeron J1900 has 2 MiB L2 as two 1 MiB slices:
CPUs 0-1 share one L2
CPUs 2-3 share the other L2
We already isolated the EtherCAT loop on CPU3 (SCHED_FIFO 80, 1 kHz).
That is not enough if the fullscreen Qt/eglfs HMI is still allowed on CPU2.
The UI then sits on the L2 sibling of the RT core and contends for the same 1 MiB.
Change (HMI only, not a whole-system cgroup):
before: Qt main / touch / QML / render / GPU worker allowed on CPUs 0-2
after: those threads allowed on CPUs 0-1 only
RT thread stayed on CPU3 both times
Same binary, same recipe, same 1 ms period, 20 automatic press cycles each side.
Jitter = wake-to-wake CLOCK_MONOTONIC minus 1 ms, integer microseconds.
0 us means |error| < 1 us. This is period error, not latency-test / cyclictest.
All numbers below are the full captures (approach + press + retract), not a PID subset.
Absolute jitter, nearest-rank, all samples
UI on 0-2 (20 runs) UI on 0-1 (20 runs)
n 119159 119254
P50 0 us 0 us
P95 6 us 1 us
P99 13 us 1 us
P99.9 21 us 2 us
signed min/max -42 / +46 us -13 / +14 us
|j| >= 10 us 2983 8
|j| >= 20 us 198 0
|j| >= 30 us 22 0
|j|
Per-run P50 / P95 / P99 / P99.9 (|jitter|, us)
# UI 0-2 UI 0-1
1 1 / 9 / 14 / 23 0 / 1 / 1 / 2
2 0 / 2 / 9 / 19 0 / 1 / 1 / 2
3 0 / 5 / 12 / 21 0 / 1 / 1 / 2
4 0 / 6 / 15 / 20 0 / 1 / 1 / 2
5 0 / 7 / 15 / 20 0 / 1 / 1 / 2
6 0 / 1 / 1 / 2 0 / 1 / 1 / 2
7 0 / 6 / 14 / 20 0 / 1 / 1 / 2
8 0 / 7 / 15 / 20 0 / 1 / 1 / 2
9 0 / 4 / 13 / 19 0 / 1 / 1 / 2
10 0 / 6 / 16 / 26 0 / 1 / 1 / 2
11 0 / 3 / 11 / 22 0 / 1 / 1 / 3
12 1 / 9 / 15 / 23 0 / 1 / 1 / 2
13 1 / 9 / 14 / 26 0 / 1 / 1 / 2
14 1 / 9 / 15 / 32 0 / 1 / 1 / 2
15 0 / 8 / 14 / 19 0 / 1 / 1 / 2
16 1 / 9 / 14 / 26 0 / 1 / 1 / 2
17 0 / 1 / 6 / 13 0 / 1 / 1 / 2
18 0 / 6 / 13 / 19 0 / 1 / 1 / 2
19 0 / 1 / 5 / 15 0 / 1 / 1 / 2
20 0 / 1 / 1 / 2 0 / 1 / 1 / 2
After the pin, every run has P99 = 1 us. 15/20 runs have max |j|
The 8 remaining >=10 us samples are two ticks each in runs 1, 8, 15, 16.
Point of the numbers
- P50 was already 0 us. The HMI was not ruining the median.
- The L2 sibling shows up in the tail: P95 6->1, P99 13->1, P99.9 21->2.
- Moving i915 IRQ off CPU2 was not sufficient by itself. User-space Qt
render can still land on CPU2 and thrash the RT core's L2.
- Do not set a cgroup AllowedCPUs=0-1 on the whole process: the FIFO
thread must still be able to bind to CPU3.
- Do not park every system thread on 0-1. This was only the HMI/render path.
Box (for context, not the variable under test)
- Debian 13 PREEMPT_RT 6.12, Qt eglfs_kms, no X
- IgH EtherCAT, 1 kHz, Lost frames = 0
- isolcpus / rcu_nocbs on CPU3, i915 IRQ on CPU0
Happy to hear if anyone running a GL HMI on Bay Trail saw the same
CPU2/CPU3 L2 pairing.
The following user(s) said Thank You: NWE
Please Log in or Create an account to join the conversation.
- rodw
-
- Offline
- Platinum Member
-
Less
More
- Posts: 12156
- Thank you received: 4149
17 Sep 2026 06:41 #349693
by rodw
Replied by rodw on topic J1900 L2 sibling: pin Qt HMI to CPUs 0-1, keep the 1 ms EtherCAT thread on CPU3
Well you got further than me years ago, you were able to boot the Baytrail PC (but mine was a J1850).
Isolating the sibling core is recommended. If you are using a NIC with an RT app that uses networking, its recommended to pin the NIC IRQ to the same core as the RT thread. Latency may be worse but the network latency becomes the bottleneck. I could not see what you were pinning.
Isolating the sibling core is recommended. If you are using a NIC with an RT app that uses networking, its recommended to pin the NIC IRQ to the same core as the RT thread. Latency may be worse but the network latency becomes the bottleneck. I could not see what you were pinning.
The following user(s) said Thank You: tietouwa
Please Log in or Create an account to join the conversation.
- tietouwa
-
Topic Author
- Offline
- New Member
-
Less
More
- Posts: 6
- Thank you received: 2
25 Sep 2026 13:48 #349866
by tietouwa
Replied by tietouwa on topic J1900 L2 sibling: pin Qt HMI to CPUs 0-1, keep the 1 ms EtherCAT thread on CPU3
Thanks rodw. I'm not using ec_generic. The EtherCAT port runs on IgH's native ec_r8169 driver, which is polled from the RT thread on CPU3, so there is no NIC IRQ to pin. What I pinned: the 1 ms thread on CPU3 (SCHED_FIFO 80), and the Qt HMI threads on CPUs 0-1 via taskset. Isolating CPU2 is a good idea. I'll try it next.
The following user(s) said Thank You: rodw
Please Log in or Create an account to join the conversation.
- Configuring LinuxCNC
- Advanced Configuration
- EtherCAT
- J1900 L2 sibling: pin Qt HMI to CPUs 0-1, keep the 1 ms EtherCAT thread on CPU3
Time to create page: 0.183 seconds