Skip to content

Mesa Hostmot2 Xenomai4 OOB networking support#4199

Draft
hdiethelm wants to merge 8 commits into
LinuxCNC:masterfrom
hdiethelm:hm2_eth_oob_v5
Draft

Mesa Hostmot2 Xenomai4 OOB networking support#4199
hdiethelm wants to merge 8 commits into
LinuxCNC:masterfrom
hdiethelm:hm2_eth_oob_v5

Conversation

@hdiethelm

@hdiethelm hdiethelm commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This PR adds Xenomai4 EVL out of band networking support for Mesa Hostmot2.

Out of band networking is basically a fast path inside the xenomai real time kernel that enables networking without involving the normal kernel.

Due to some users might want to use Xenomai4 with the standard kernel networking, I decided to create a new component called hm2_eth_evl while hm2_eth behaves exactly like before.

Common code is left in hm2_eth.c and network specific code is moved to hm2_eth_net.c and hm2_eth_net_evl.c.
The linker is used to link hm2_eth_evl and hm2_eth with two different network implementations and the same common code.

To select the mode, you can use: board_rtnet=posix or board_rtnet=evl, where the default is posix, so it is a non-breaking change.

With board_rtnet=evl, initf hm2_eth.realtime-init servo-thread needs to be added to the .ini file to initialize the realtime network inside the realtime context.

A few changes in the existing code where performed:

  • Fix a bug in src/rtapi/uspace_xenomai_evl.cc. This resulted in a while(true) error message when the kernel and the userspace library did not match.
  • Pass board instead of board->fd to network functions.
  • Don't use a cumbersome void pointer casting one line function for SIOCSARP
  • The ifname is fetched in init_board() and stored in board, so the install_firewall_perinterface() loop is simplifyed and I can reuse the name inside the evl implementation
  • The ip address is stored in board because I need it later
  • Print which board is connected, nice if you have more than one board and it throws an error

Things still open:

  • I have to set the Xenomai4 C and LD flags to all modules, I did not find a way to only set it for a specific module in the Makefile. It will only change anything if you have libevl installed.
  • There are more global symbols. Would it make sense to rename fetch_hwaddr to hm2_fetch_hwaddr for example to avoid conflicts?
  • Loading hm2_eth_evl and hm2_eth at the same time would probably create a runtime linker issue which generates undefined behavior.

It's a bit hard to review due to moved code. git diff master:src/hal/drivers/mesa-hostmot2/hm2_eth.c hm2_eth_oob_v5:src/hal/drivers/mesa-hostmot2/hm2_eth_net_posix.c helps.

This two PR's need to be merged first:
#4217
#4218

@hdiethelm

Copy link
Copy Markdown
Contributor Author

BTW: I know, rootless xenomai is still todo. I will do that after #4132 is in. It will conflict otherwhise.

@zz912

zz912 commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

@pcw-mesa What do you think aboat this PR? Do we want two drivers? hm2_eth.c and hm2_eth_net.c? Shouldnt be better implement OOB to hm2_eth.c?

To @hdiethelm : I can help with testing 7i96s.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

@pcw-mesa What do you think aboat this PR? Do we want two drivers? hm2_eth.c and hm2_eth_net.c? Shouldnt be better implement OOB to hm2_eth.c?

This way, I can cleanly separate the two Ethernet implementations and not break the existing one by accident. Also hm2_eth.c is already quite big and I did not want to blow it up even more.

But you are right, having one module and instead using for example rt_eth_type=evl,posix,..., similar to board_ip=ip[,ip…​] would be an alternative and it would even allow to only use one xenomai capable network card if you have a second board that is not that important and connected to a non-xenomai capable NIC. I will look into it.

To @hdiethelm : I can help with testing 7i96s.

Thanks! I have also a 7i96s, this PR is already tested both with posix and evl networking. But a second test is always good to have, not all configs behave the same.

@zz912

zz912 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

But you are right, having one module and instead using for example rt_eth_type=evl,posix,..., similar to board_ip=ip[,ip…​] would be an alternative and it would even allow to only use one xenomai capable network card if you have a second board that is not that important and connected to a non-xenomai capable NIC. I will look into it.

This variant will be easier for switching "posix and evl". If you want evl to be used normally, you will need to add it to PNCconf. For most Mesa card users, installing a LinuxCNC distribution is the best they can do.

@zz912

zz912 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

ChatGPT is helping me with this PR. We have these questions:

Before I start preparing the environment, I have a few questions:

  1. Which Linux kernel version are you currently using for development and testing (e.g. 6.12.x)?
  2. Which Dovetail branch/tag or commit should be used with this PR?
  3. Which EVL version (or commit) do you recommend?
  4. Is there a reference build environment or set of repositories that you use, so testers can reproduce your setup as closely as possible?
  5. Which Ethernet drivers have you actually tested with the OOB implementation? Only igb, or also e1000e?
  6. Are there any known limitations or unsupported NICs at the moment?
  7. Is there anything specific you would like testers to measure or report (latency, jitter, missed frames, CPU load, etc.)?

@hdiethelm

Copy link
Copy Markdown
Contributor Author

You will find most information here:
#3878

For PREEMPT_RT, i use Debian Trixie, stock preempt kernel.

Intel I350 uses the igb driver. For e1000e, you need quite an old card.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

So, I went back to having one component with two network backends:
Posix (Normal mode):

  • loadrt board_ip=192.168.1.121 config=...
  • loadrt board_ip=192.168.1.121 board_rtnet=posix config=...

Xenomai4 EVL mode:
loadrt board_ip=192.168.1.121 board_rtnet=evl config=...

@zz912

zz912 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

I'm currently stuck on getting the EVL kernel working:
hdiethelm/xenomai4-linuxcnc#1
so I can't test anything yet.

The "board_rtnet" parameter looks good. Do you think it would be possible to add:
board_rtnet=auto
?
Would that make sense?

board_rtnet=evl - this configuration doesn't make sense when:
zdenek@cnc:~$ uname -a
Linux cnc 6.12.94+deb13-rt-amd64 #1 SMP PREEMPT_RT Debian 6.12.94-1 (2026-06-20) x86_64 GNU/Linux
?

board_rtnet=posix - does this configuration make sense when:
zdenek@cnc:~$ uname -a
Linux 6.12.85-cip22-xenomai4-efed61 #1 SMP PREEMPT_RT EVL
?

The less the user has to configure, the better.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

I'm currently stuck on getting the EVL kernel working: hdiethelm/xenomai4-linuxcnc#1 so I can't test anything yet.

I uploaded a non-rt variant and the matching config. See: hdiethelm/xenomai4-linuxcnc#1 Thanks for the good description.

The "board_rtnet" parameter looks good. Do you think it would be possible to add:
board_rtnet=auto

board_rtnet=auto is not that simple: I would also have to check if your network card supports OOB networking. And I generally don't like auto, it does often exactly what you don't want and often breaks. Windows style... ;-)

However, I have to check if LinuxCNC is running in Xenomai4 mode when you configure board_rtnet=evl and throw an error otherwise.

@zz912

zz912 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

board_rtnet=auto is not that simple: I would also have to check if your network card supports OOB networking. And I generally don't like auto, it does often exactly what you don't want and often breaks. Windows style... ;-)

I respect your opinion, but I think LinuxCNC should be friendly. Should be possible check if Linux is running in Xenomai4 mode and check network card supports OOB networking in PNCconf? For example pressbutton next checkbutton "EVL mode"

I know it's too early to ask this. EVL needs to be tested first. But I'm interested.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

board_rtnet=auto is not that simple: I would also have to check if your network card supports OOB networking. And I generally don't like auto, it does often exactly what you don't want and often breaks. Windows style... ;-)

I respect your opinion, but I think LinuxCNC should be friendly. Should be possible check if Linux is running in Xenomai4 mode and check network card supports OOB networking in PNCconf? For example pressbutton next checkbutton "EVL mode"

I know it's too early to ask this. EVL needs to be tested first. But I'm interested.

I believe if you invest the effort to get xenimai4 running, setting board_rtnet=evl instead board_rtnet=auto should not be to complex, at least for now. However, having "auto" as default might generate issues if a detection fails for whatever reason.

That said, if we discover that Xenimai4 really performs better than PREEMPT_RT for many users, then we can still invest some time in:

  • Add it to PNCconf
  • Might be autodetect
  • A good doc how to set it up with the kernel parameters
  • Add support to the Debian package (For now, you have to compile from source)
  • Add support for the Ethercat Project
  • ...

For now, it's mostly a toy project for me to learn Xenimai4. At least on my setup, it doesn't perform much better than PREEMPT_RT but this old PC anyway runs nearly perfect, max latency of 20us including Ethernet is absolutely unnecessary for a Mesa card but still fun... ;-)

It will be nice to have a report from you if it works well on your setup.

Never the less, having this part also merged to master makes it testable for many people. I will update the hm2_eth doc in this PR after testing, I don't like to change it many times based on feedback about the implementation.

@pcw-mesa

Copy link
Copy Markdown
Collaborator

I think options like OS detection belong more in the configuration utilities or maybe startup scripts
(so they can be done once for all drivers/utilities that need to know) not duplicated in the low level drivers
themselves.

I am really curious what Ethernet performance is possible with Xenomai/OOB networking, as trying to get higher
than say 1 KHz thread rates with Preempt-RT and Ethernet gets really picky about the precise hardware used.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

I think options like OS detection belong more in the configuration utilities or maybe startup scripts (so they can be done once for all drivers/utilities that need to know) not duplicated in the low level drivers themselves.

Agreed.

I am really curious what Ethernet performance is possible with Xenomai/OOB networking, as trying to get higher than say 1 KHz thread rates with Preempt-RT and Ethernet gets really picky about the precise hardware used.

I have to check tomorrow, but as I remember, I have a loop time of 50us avg / 70us max. with a well tuned PC and an Intel I350.
Only issue: The GPU sometimes generates ~ 100us latency spikes when I do stupid stuff like browsing / watching youtube in the CNC PC.
So being careful,10kHz shold work and with some reserve 5kHz.

BTW: For a long time, the HAL time measurements where in cycles. This PR changed all to ns: #4082

@zz912

zz912 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Here are my first results:

Latency with Preempt:
Latency_test_preempt

Latency with EVL:
Latency_test_EVL
Is it OK? It is still PREEMPT.

I was interested mainly aboat Mesa tests:
Mesa_test_screen
I had problems with Bokkworm. Unfortunately I didnt measure it before upgrade to Trixie.

CPU test with Preempt:
cpu_test_preempt

CPU test with EVL:
cpu_test_evl

NIC test with Preempt:
nic_test_preempt

NIC test with EVL:
nic_test_evl

Copy terminal:

zdenek@cnc:~/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5$ linuxcnc
LINUXCNC - 2.10.0~pre1
Machine configuration directory is '/home/zdenek/linuxcnc/configs/DedaCNC-012'
Machine configuration file is 'DedaCNC-012.ini'
Starting LinuxCNC...
linuxcnc TPMOD=tpmod HOMEMOD=homemod EMCMOT=motmod
Note: Using XENOMAI4 EVL realtime
Found file(REL): ./DedaCNC-012.hal
linuxcnc-task:19345
hm2: loading Mesa HostMot2 driver version 0.15
hm2_eth: loading Mesa AnyIO HostMot2 ethernet driver version 0.2
hm2_eth: 10.10.10.10: INFO: init board (Xenomai EVL)
hm2_eth: 10.10.10.10: INFO: Hardware address (MAC): 00:60:1b:16:80:30
hm2_eth: discovered 7I96S
hm2/hm2_7i96s.0: Low Level init 0.15
hm2/hm2_7i96s.0: created PktUART Interface function hm2_7i96s.0.pktuart.0.
hm2/hm2_7i96s.0: 51 I/O Pins used:
hm2/hm2_7i96s.0:     IO Pin 000 (TB3-01): InM Input Module #0, pin in0,enca0 (Input)
hm2/hm2_7i96s.0:     IO Pin 001 (TB3-02): InM Input Module #0, pin in1,encb0 (Input)
hm2/hm2_7i96s.0:     IO Pin 002 (TB3-03): InM Input Module #0, pin in2,enca1 (Input)
hm2/hm2_7i96s.0:     IO Pin 003 (TB3-04): InM Input Module #0, pin in3,encb1 (Input)
hm2/hm2_7i96s.0:     IO Pin 004 (TB3-05): InM Input Module #0, pin in4,enca2 (Input)
hm2/hm2_7i96s.0:     IO Pin 005 (TB3-06): InM Input Module #0, pin in5,encb2 (Input)
hm2/hm2_7i96s.0:     IO Pin 006 (TB3-07): InM Input Module #0, pin in6,enca3 (Input)
hm2/hm2_7i96s.0:     IO Pin 007 (TB3-08): InM Input Module #0, pin in7,encb3 (Input)
hm2/hm2_7i96s.0:     IO Pin 008 (TB3-09): InM Input Module #0, pin in8 (Input)
hm2/hm2_7i96s.0:     IO Pin 009 (TB3-10): InM Input Module #0, pin in9 (Input)
hm2/hm2_7i96s.0:     IO Pin 010 (TB3-11): InM Input Module #0, pin in10 (Input)
hm2/hm2_7i96s.0:     IO Pin 011 (TB3-13/TB3-14): SSR #0, pin Out-00 (Output)
hm2/hm2_7i96s.0:     IO Pin 012 (TB3-15/TB3-16): SSR #0, pin Out-01 (Output)
hm2/hm2_7i96s.0:     IO Pin 013 (TB3-17/TB3-18): SSR #0, pin Out-02 (Output)
hm2/hm2_7i96s.0:     IO Pin 014 (TB3-19/TB3-20): SSR #0, pin Out-03 (Output)
hm2/hm2_7i96s.0:     IO Pin 015 (TB3-21/TB3-22): OutM Output Module #0, pin Out-04 (Output)
hm2/hm2_7i96s.0:     IO Pin 016 (TB3-23/TB3-24): OutM Output Module #0, pin Out-05 (Output)
hm2/hm2_7i96s.0:     IO Pin 017 (TB1-02/TB1-03): StepGen #0, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 018 (TB1-04/TB1-05): StepGen #0, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 019 (TB1-08/TB1-09): StepGen #1, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 020 (TB1-10/TB1-11): StepGen #1, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 021 (TB1-14/TB1-15): StepGen #2, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 022 (TB1-16/TB1-17): StepGen #2, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 023 (TB1-20/TB1-21): StepGen #3, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 024 (TB1-22-TB1-23): StepGen #3, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 025 (TB2-02/TB2-03): StepGen #4, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 026 (TB2-04/TB2-05): StepGen #4, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 027 (TB2-07/TB2-08): Encoder #0, pin A (Input)
hm2/hm2_7i96s.0:     IO Pin 028 (TB2-10/TB2-11): Encoder #0, pin B (Input)
hm2/hm2_7i96s.0:     IO Pin 029 (TB2-13/TB2-14): Encoder #0, pin Index (Input)
hm2/hm2_7i96s.0:     IO Pin 030 (TB2-16/TB2-17): PktUART Receive Channel #0, pin RX Data (Input)
hm2/hm2_7i96s.0:     IO Pin 031 (TB2-18/TB2-19): PktUART Transmit Channel #0, pin TX Data (Output)
hm2/hm2_7i96s.0:     IO Pin 032 (internal): PktUART Transmit Channel #0, pin Drv Enable low (Output)
hm2/hm2_7i96s.0:     IO Pin 033 (internal): SSR #0, pin AC Ref (internal) (Output)
hm2/hm2_7i96s.0:     IO Pin 034 (P1-01/DB25-01): IOPort
hm2/hm2_7i96s.0:     IO Pin 035 (P1-02/DB25-14): IOPort
hm2/hm2_7i96s.0:     IO Pin 036 (P1-03/DB25-02): IOPort
hm2/hm2_7i96s.0:     IO Pin 037 (P1-04/DB25-15): IOPort
hm2/hm2_7i96s.0:     IO Pin 038 (P1-05/DB25-03): IOPort
hm2/hm2_7i96s.0:     IO Pin 039 (P1-06/DB25-16): IOPort
hm2/hm2_7i96s.0:     IO Pin 040 (P1-07/DB25-04): IOPort
hm2/hm2_7i96s.0:     IO Pin 041 (P1-08/DB25-17): IOPort
hm2/hm2_7i96s.0:     IO Pin 042 (P1-09/DB25-05): IOPort
hm2/hm2_7i96s.0:     IO Pin 043 (P1-11/DB25-06): IOPort
hm2/hm2_7i96s.0:     IO Pin 044 (P1-13/DB25-07): IOPort
hm2/hm2_7i96s.0:     IO Pin 045 (P1-15/DB25-08): IOPort
hm2/hm2_7i96s.0:     IO Pin 046 (P1-17/DB25-09): IOPort
hm2/hm2_7i96s.0:     IO Pin 047 (P1-19/DB25-10): IOPort
hm2/hm2_7i96s.0:     IO Pin 048 (P1-21/DB25-11): IOPort
hm2/hm2_7i96s.0:     IO Pin 049 (P1-23/DB25-12): IOPort
hm2/hm2_7i96s.0:     IO Pin 050 (P1-25/DB25-13): IOPort
hm2/hm2_7i96s.0: registered
hm2_eth: 10.10.10.10: INFO: enable OOB for board on if eno1
hm2_modbus.0: warning: PktUART version is less than 3 (Rx=2 Tx=2). Please consider upgrading.
hm2_modbus.0: inst->name     : hm2_modbus.0
hm2_modbus.0: inst->uart     : hm2_7i96s.0.pktuart.0
hm2_modbus.0: inst->mbccbsize: 320
hm2_modbus.0: inst->ninit    : 0
hm2_modbus.0: inst->ncmds    : 5
hm2_modbus.0: inst->npins    : 5
hm2_modbus.0: inst->icdelay  : 0
hm2_modbus.0: inst->rxdelay  : 34
hm2_modbus.0: inst->txdelay  : 36
hm2_modbus.0: inst->drvdelay : 1
hm2_modbus.0: PktUART serial port 'hm2_7i96s.0.pktuart.0' configured to 8N1@9600
hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
PID: installed 4 PID loops
Found file(REL): ./custom.hal
hm2_modbus.0: warning: Out-of-band data received. Might not belong to current command 0
MOTION: setting Traj cycle time to 1000000 nsecs
MOTION: setting Servo cycle time to 1000000 nsecs
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No DEFAULT_SPINDLE_0_SPEED Entry in DISPLAY, Using: 200 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_SPEED Entry in DISPLAY, Using: 100 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_SPEED Entry in DISPLAY, Using: 2500 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 1 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 0.5 (iniinfo.py:715)
[Gmoccapy.GMOCCAPY.GETINIINFO][WARNING]  No DEFAULT_SPINDLE_SPEED entry found in [DISPLAY] of INI file (getiniinfo.py:276)
[DEFAULT.COMMON.INIINFO][DEBUG]  INI Path: /home/zdenek/linuxcnc/configs/DedaCNC-012/DedaCNC-012.ini (iniinfo.py:36)
[DEFAULT.COMMON.INIINFO][DEBUG]  Linuxcnc Run-In-Place (RIP) flag true (iniinfo.py:1013)
[DEFAULT.COMMON.INIINFO][DEBUG]  Machine is METRIC based. unit Conversion constant=0.03937007874015748 (iniinfo.py:145)
[DEFAULT.COMMON.INIINFO][DEBUG]  TRAJ COORDINATES: XYZ (iniinfo.py:166)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_LINEAR_VELOCITY = 360.0 (iniinfo.py:349)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_LINEAR_VELOCITY = 30.0 (iniinfo.py:350)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_LINEAR_VELOCITY = 1500.0 (iniinfo.py:351)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_ANGULAR_VELOCITY = 720.0 (iniinfo.py:356)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_ANGULAR_VELOCITY = 100.00001999999999 (iniinfo.py:357)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_ANGULAR_VELOCITY = 10800.0 (iniinfo.py:358)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No DEFAULT_SPINDLE_0_SPEED Entry in DISPLAY, Using: 200 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_SPEED Entry in DISPLAY, Using: 100 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_SPEED Entry in DISPLAY, Using: 2500 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 1 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 0.5 (iniinfo.py:715)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib write socket not available: Adresa je užívána (addr='tcp://127.0.0.1:5690') (hal_glib.py:365)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib read socket available: tcp://127.0.0.1:5691 (hal_glib.py:393)
[DEFAULT.COMMON.INIINFO][DEBUG]  INI Path: /home/zdenek/linuxcnc/configs/DedaCNC-012/DedaCNC-012.ini (iniinfo.py:36)
[DEFAULT.COMMON.INIINFO][DEBUG]  Linuxcnc Run-In-Place (RIP) flag true (iniinfo.py:1013)
[DEFAULT.COMMON.INIINFO][DEBUG]  Machine is METRIC based. unit Conversion constant=0.03937007874015748 (iniinfo.py:145)
[DEFAULT.COMMON.INIINFO][DEBUG]  TRAJ COORDINATES: XYZ (iniinfo.py:166)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_LINEAR_VELOCITY = 360.0 (iniinfo.py:349)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_LINEAR_VELOCITY = 30.0 (iniinfo.py:350)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_LINEAR_VELOCITY = 1500.0 (iniinfo.py:351)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_ANGULAR_VELOCITY = 720.0 (iniinfo.py:356)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_ANGULAR_VELOCITY = 100.00001999999999 (iniinfo.py:357)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_ANGULAR_VELOCITY = 10800.0 (iniinfo.py:358)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No DEFAULT_SPINDLE_0_SPEED Entry in DISPLAY, Using: 200 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_SPEED Entry in DISPLAY, Using: 100 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_SPEED Entry in DISPLAY, Using: 2500 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 1 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 0.5 (iniinfo.py:715)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib write socket not available: Adresa je užívána (addr='tcp://127.0.0.1:5690') (hal_glib.py:365)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib read socket available: tcp://127.0.0.1:5691 (hal_glib.py:393)
23:31:27.982 WARNING Config: mousetweaks GSettings schema not found, mousetweaks integration disabled.

(onboard:19450): Gdk-CRITICAL **: 23:31:28.237: gdk_window_thaw_toplevel_updates: assertion 'window->update_and_descendants_freeze_count > 0' failed
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_mesa_tests, BASENAME=gtk_mesa_tests BASEPATH=gtk_mesa_tests (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_mesa_tests.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.glade (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .glade file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.glade (gladevcppath.py:62)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_little_probe, BASENAME=gtk_little_probe BASEPATH=gtk_little_probe (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_little_probe.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.glade (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .glade file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.glade (gladevcppath.py:62)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_mesa_tests, BASENAME=gtk_mesa_tests BASEPATH=gtk_mesa_tests (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_mesa_tests.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.py (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .py file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.py (gladevcppath.py:62)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_little_probe, BASENAME=gtk_little_probe BASEPATH=gtk_little_probe (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_little_probe.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.py (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .py file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.py (gladevcppath.py:62)
****  probe_screen GETINIINFO **** 
 Preference file path: /home/zdenek/linuxcnc/configs/DedaCNC-012/DedaCNC-012.pref
1 2

DedaCNC-012.zip

This is wierd. Machine worked as usualy:

hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1
hm2_eth: ERROR: sending packet: Operation not permitted
zdenek@cnc:~$ evl ps -l
CPU   PID   SCHED   PRIO  ISW     CTXSW     SYS       RWA       STAT     TIMEOUT      %CPU      CPUTIME       WCHAN                 NAME
  3   22116  fifo    98   2       2855392   5904449   1          D       715            6.7      6:458.335    (null)                linuxcnc-thread:22116
  1   22137  fifo    50   0       193868    0         193867     W          -           0.9      0:850.197    (null)                [eno1.rx]
  0   22138  fifo    50   0       193819    0         193818     W          -           0.0      0:769.740    (null)                [eno1.tx]
zdenek@cnc:~$ evl ps -l
CPU   PID   SCHED   PRIO  ISW     CTXSW     SYS       RWA       STAT     TIMEOUT      %CPU      CPUTIME       WCHAN                 NAME
  3   22116  fifo    98   2       3438642   7110545   1          D       004            6.4      7:731.816    (null)                linuxcnc-thread:22116
  1   22137  fifo    50   0       233473    0         233472     W          -           0.8      1:013.128    (null)                [eno1.rx]
  0   22138  fifo    50   0       233415    0         233414     W          -           0.8      0:921.849    (null)                [eno1.tx]
zdenek@cnc:~$ evl ps -l
CPU   PID   SCHED   PRIO  ISW     CTXSW     SYS       RWA       STAT     TIMEOUT      %CPU      CPUTIME       WCHAN                 NAME
  3   22116  fifo    98   2       3766993   7789552   1          D       020            6.3      8:435.762    (null)                linuxcnc-thread:22116
  1   22137  fifo    50   0       255785    0         255784     W          -           0.8      1:101.958    (null)                [eno1.rx]
  0   22138  fifo    50   0       255721    0         255720     W          -           0.8      1:006.113    (null)                [eno1.tx]
zdenek@cnc:~$ evl ps -l
CPU   PID   SCHED   PRIO  ISW     CTXSW     SYS       RWA       STAT     TIMEOUT      %CPU      CPUTIME       WCHAN                 NAME
  3   22116  fifo    98   2       4156006   8593978   1          D       228            6.3      9:267.835    (null)                linuxcnc-thread:22116
  1   22137  fifo    50   0       282192    0         282191     W          -           0.8      1:206.582    (null)                [eno1.rx]
  0   22138  fifo    50   0       282121    0         282120     W          -           0.8      1:106.821    (null)                [eno1.tx]
zdenek@cnc:~$ evl ps -l
CPU   PID   SCHED   PRIO  ISW     CTXSW     SYS       RWA       STAT     TIMEOUT      %CPU      CPUTIME       WCHAN                 NAME
  3   22116  fifo    98   2       4291791   8874762   1          D       008            6.3      9:559.317    (null)                linuxcnc-thread:22116
  1   22137  fifo    50   0       291410    0         291409     W          -           0.8      1:243.498    (null)                [eno1.rx]
  0   22138  fifo    50   0       291337    0         291336     W          -           0.8      1:142.261    (null)                [eno1.tx]

I made this tests quickly. For big machine I am makeing 24 hour tests.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

Thanks already for testing. I will look into it in detail tomorrow.
Can you post the output of cat /proc/cmdline, cat /proc/cpuinfo and cat /proc/interrupts? Looks like something is off, the nic and linuxcnc thread should be on the same CPU (evl ps -l) for min. latency. At least this was the case for my setup.

@zz912

zz912 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor
zdenek@cnc:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.12.90-cip24-xenomai4 root=UUID=9406517e-7912-433c-9aa9-35a17c54fa0c ro isolcpus=3
zdenek@cnc:~$ cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 58
model name	: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
stepping	: 9
microcode	: 0x21
cpu MHz		: 3392.100
cache size	: 6144 KB
physical id	: 0
siblings	: 4
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts vnmi md_clear flush_l1d
vmx flags	: vnmi preemption_timer invvpid ept_x_only flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown vmscape
bogomips	: 6385.13
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 6
model		: 58
model name	: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
stepping	: 9
microcode	: 0x21
cpu MHz		: 3392.100
cache size	: 6144 KB
physical id	: 0
siblings	: 4
core id		: 1
cpu cores	: 4
apicid		: 2
initial apicid	: 2
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts vnmi md_clear flush_l1d
vmx flags	: vnmi preemption_timer invvpid ept_x_only flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown vmscape
bogomips	: 6385.13
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

processor	: 2
vendor_id	: GenuineIntel
cpu family	: 6
model		: 58
model name	: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
stepping	: 9
microcode	: 0x21
cpu MHz		: 3392.101
cache size	: 6144 KB
physical id	: 0
siblings	: 4
core id		: 2
cpu cores	: 4
apicid		: 4
initial apicid	: 4
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts vnmi md_clear flush_l1d
vmx flags	: vnmi preemption_timer invvpid ept_x_only flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown vmscape
bogomips	: 6385.13
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

processor	: 3
vendor_id	: GenuineIntel
cpu family	: 6
model		: 58
model name	: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
stepping	: 9
microcode	: 0x21
cpu MHz		: 3392.099
cache size	: 6144 KB
physical id	: 0
siblings	: 4
core id		: 3
cpu cores	: 4
apicid		: 6
initial apicid	: 6
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts vnmi md_clear flush_l1d
vmx flags	: vnmi preemption_timer invvpid ept_x_only flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown vmscape
bogomips	: 6385.13
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

zdenek@cnc:~$ cat /proc/interrupts
              CPU0       CPU1       CPU2       CPU3       
     0:          9          0          0          0  IR-IO-APIC      2    -edge      timer
     1:          0          0          0          4  IR-IO-APIC      1    -edge      i8042
     8:          1          0          0          0  IR-IO-APIC      8    -edge      rtc0
     9:          0          3          0          0  IR-IO-APIC      9    -fasteoi   acpi
    12:          0          0          6          0  IR-IO-APIC     12    -edge      i8042
    16:          0          0          0      17019  IR-IO-APIC     16    -fasteoi   ehci_hcd:usb1
    18:          0         16          0          0  IR-IO-APIC     18    -fasteoi   i801_smbus
    23:         35          0          0          0  IR-IO-APIC     23    -fasteoi   ehci_hcd:usb2
    24:       2954       2670     408790      18042     SIRQC     24      in-band irq work
    25:     109600     109737      98626      57532     SIRQC     25      proxy tick
    26:          0          0     406066          0  IR-PCI-MSI-0000:00:19.0      0 oob-edge      eno1
    27:          0       5972          0          0  IR-PCI-MSI-0000:00:14.0      0    -edge      xhci_hcd
    32:          0          0      26265          0  IR-PCI-MSI-0000:00:1f.2      0    -edge      ahci[0000:00:1f.2]
    33:          0          0          0      21173  IR-PCI-MSI-0000:00:02.0      0    -edge      i915
    34:         31          0          0          0  IR-PCI-MSI-0000:00:16.0      0    -edge      mei_me
    35:          0        392          0          0  IR-PCI-MSI-0000:00:1b.0      0    -edge      snd_hda_intel:card0
524544:          0          0          0          0     SIPIC      0 oob  out-of-band function call IPI
524545:          0     405980          0          0     SIPIC      1 oob  EVL reschedule
524546:          0          0          0          0     SIPIC      2 oob  EVL timer IPI
524548:     113686     115707     103734    6081121     SIPIC      4 oob  Out-of-band LAPIC timer interrupt
   NMI:         22         22         22         21   Non-maskable interrupts
   LOC:         44         44         43         42   Local timer interrupts
   SPU:          0          0          0          0   Spurious interrupts
   PMI:         22         22         22         21   Performance monitoring interrupts
   IWI:          0          0          0          0   IRQ work interrupts
   RTR:          0          0          0          0   APIC ICR read retries
   RES:       8886       8750       9279          4   Rescheduling interrupts
   CAL:      31662      32307      28593      17139   Function call interrupts
   TLB:      11840      21280      14573          0   TLB shootdowns
   TRM:          0          0          0          0   Thermal event interrupts
   THR:          0          0          0          0   Threshold APIC interrupts
   DFR:          0          0          0          0   Deferred Error APIC interrupts
   MCE:          0          0          0          0   Machine check exceptions
   MCP:          1          2          2          2   Machine check polls
   ERR:          0
   MIS:          0
   PIN:          0          0          0          0   Posted-interrupt notification event
   NPI:          0          0          0          0   Nested posted-interrupt event
   PIW:          0          0          0          0   Posted-interrupt wakeup event
zdenek@cnc:~$ 

@hdiethelm

Copy link
Copy Markdown
Contributor Author

So, what I can tell so far:

  • It looks like the latency-test is not better with Xenomai4 but the ethernet IO time is reduced by nearly a factor of two: tmax total 634us to 387us. But it can still be improved.
  • hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1 is a bug from my side. Basically, i initialize everything in normal networking mode in hm2_eth rtapi_app_main() and then switch over to OOB networking mode. In this mode, you can only send data from a realtime thread. However, looks like hm2_modbus also sends data at init. I will fix this.
  • PC Mesa: With Remove rtapi_get_clocks() #4082, Time and Max-Time are changed from clocks to ns. I tried to find all references but I obviously missed your PC Mesa GUI, sorry. Can you correct this or should I do it? I see your name in this file, so you might know better how it works but of course I can also fix it. As an advantage: The CPU speed is not needed any more.
  • You should be able to improve your timings quite a lot by modifying your kernel command line.
    • Minimum is: evl.oobcpus=3 isolcpus=3
    • After ^, you should see all threads in evl ps -l on CPU3
    • Due to your CPU is similar to mine, you can try the full blown: isolcpus=managed_irq,domain,2-3 irqaffinity=0-1 rcu_nocbs=2-3 rcu_nocb_poll intel_idle.max_cstate=1 cpufreq.off=1 nosoftlockup nowatchdog mce=off evl.oobcpus=3
    • After ^^, you should see no more increasing interrupts on CPU2 and 3 in cat /proc/interrupts as long as LinuxCNC is not running.
  • Locking the eno1 interrupt also to CPU3 might help additionally:
    • grep eno1 /proc/interrupts -> First number is the IRQ
    • echo 8 > /proc/irq/$IRQ/smp_affinity -> Use ^ instead of $IRQ
    • You can also try to use this script: eth-rt-affinity.txt sudo ./eth-rt-affinity eno1 8
    • Afterwards, you should see the eno1 interrupt counting up on CPU3 in cat /proc/interrupts as soon as LinuxCNC is running.

Reason why all this effort above: mesa sends a package and waits for the response. Due to the waiting, it is way more efficient latency wise to run all including the ethernet task and interrupt on one core. Otherwise, the data has to be copied from one core to main memory and back to the other. At least in my setup, the jitter got reduced by a lot doing this.

I use the eth-rt-affinity at startup in /etc/network/interfaces

auto eno1
iface eno1 inet static
  address 192.168.1.120/31
  post-up /usr/local/sbin/eth-rt-affinity eno1 8

I wanted to create a doc and might be even a tool to do it from my tuning experience since some time but a few other projects went between... ;-)

@pcw-mesa My timing info:
I can run stable at 125000ns / 8kHz servo thread. At least for a few minutes, I did not do long term testing. Me setup is a 7i96s with an Intel I350 (Chinese variant, really not expensive)

All short term tests, a few minutes:
Bildschirmfoto_2026-07-01_10-05-30
Bildschirmfoto_2026-07-01_10-07-38
Bildschirmfoto_2026-07-01_10-08-56

@hdiethelm

Copy link
Copy Markdown
Contributor Author

@zz912
So, I pushed the firs attempt in fixing hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1.
Downside:
You have to add initf hm2_eth.realtime-init servo-thread in your hal file before the addf block.
Can you test if this works also for you?

I don't like it that much but it seams that this is the only way I can run a long duration init function in the real time context.

I have a chicken and egg problem:

  • oob_enable_port() has to be called after all initialization is done and before any data is sent in realtime context
  • After this, you mus be inside realtime context to be able to send data but hm2_modbus sends also data at initialization, giving you this error
  • oob_enable_port() takes ~1ms, so I can not run it inside a thread or it is blocked for to long, even if I do it only once. There is the new function rtapi_task_self_resync() which allows to resync the thread but still, servo_thread.tmax will be ~1200000 after this.

This is based on:
#4012
#4036

@zz912

zz912 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

I works wrong:
It still repeat:
"hm2_eth: 10.10.10.10: INFO: enable OOB for board on if eno"

terminal

@hdiethelm hdiethelm force-pushed the hm2_eth_oob_v5 branch 2 times, most recently from 408596c to 1aade8f Compare July 1, 2026 11:50
@hdiethelm

Copy link
Copy Markdown
Contributor Author

I works wrong: It still repeat: "hm2_eth: 10.10.10.10: INFO: enable OOB for board on if eno"

Looks like you use addf hm2_eth.realtime-init servo-thread instead of initf hm2_eth.realtime-init servo-thread.
initf is a new command added lately.

@zz912

zz912 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

I works wrong: It still repeat: "hm2_eth: 10.10.10.10: INFO: enable OOB for board on if eno"

Looks like you use addf hm2_eth.realtime-init servo-thread instead of initf hm2_eth.realtime-init servo-thread. initf is a new command added lately.

You are right. Thanks. I work with ChatGPT and it(he) change initf => addf.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

I works wrong: It still repeat: "hm2_eth: 10.10.10.10: INFO: enable OOB for board on if eno"

Looks like you use addf hm2_eth.realtime-init servo-thread instead of initf hm2_eth.realtime-init servo-thread. initf is a new command added lately.

You are right. Thanks. I work with ChatGPT and it(he) change initf => addf.

ChatGPT lies all the time... :-D That's why I normally don't use AI stuff except for generating samples where I afterwards check the real doc and then integrate it by hand.

@zz912

zz912 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

On the other hand, without ChatGPT I wouldn't have a chance to test your PR. I use ChatGPT as a teacher to explain what you do, what you need, and how some things work.

I am mechanical designer. Programing is only my hobby.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

On the other hand, without ChatGPT I wouldn't have a chance to test your PR. I use ChatGPT as a teacher to explain what you do, what you need, and how some things work.

Yes for this it's not to bad.

Now it works, no hm2_eth: ERROR: oob_sendmsg Operation not permitted 1 -1 errors any more?

@zz912

zz912 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Actual terminal:

zdenek@cnc:~/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5$ linuxcnc
LINUXCNC - 2.10.0~pre1
Machine configuration directory is '/home/zdenek/linuxcnc/configs/DedaCNC-012'
Machine configuration file is 'DedaCNC-012.ini'
Starting LinuxCNC...
linuxcnc TPMOD=tpmod HOMEMOD=homemod EMCMOT=motmod
Note: Using XENOMAI4 EVL realtime
Found file(REL): ./DedaCNC-012.hal
linuxcnc-task:17092
hm2: loading Mesa HostMot2 driver version 0.15
hm2_eth: loading Mesa AnyIO HostMot2 ethernet driver version 0.2
hm2_eth: 10.10.10.10: INFO: init board (Xenomai EVL)
hm2_eth: 10.10.10.10: INFO: Hardware address (MAC): 00:60:1b:16:80:30
hm2_eth: discovered 7I96S
hm2/hm2_7i96s.0: Low Level init 0.15
hm2/hm2_7i96s.0: created PktUART Interface function hm2_7i96s.0.pktuart.0.
hm2/hm2_7i96s.0: 51 I/O Pins used:
hm2/hm2_7i96s.0:     IO Pin 000 (TB3-01): InM Input Module #0, pin in0,enca0 (Input)
hm2/hm2_7i96s.0:     IO Pin 001 (TB3-02): InM Input Module #0, pin in1,encb0 (Input)
hm2/hm2_7i96s.0:     IO Pin 002 (TB3-03): InM Input Module #0, pin in2,enca1 (Input)
hm2/hm2_7i96s.0:     IO Pin 003 (TB3-04): InM Input Module #0, pin in3,encb1 (Input)
hm2/hm2_7i96s.0:     IO Pin 004 (TB3-05): InM Input Module #0, pin in4,enca2 (Input)
hm2/hm2_7i96s.0:     IO Pin 005 (TB3-06): InM Input Module #0, pin in5,encb2 (Input)
hm2/hm2_7i96s.0:     IO Pin 006 (TB3-07): InM Input Module #0, pin in6,enca3 (Input)
hm2/hm2_7i96s.0:     IO Pin 007 (TB3-08): InM Input Module #0, pin in7,encb3 (Input)
hm2/hm2_7i96s.0:     IO Pin 008 (TB3-09): InM Input Module #0, pin in8 (Input)
hm2/hm2_7i96s.0:     IO Pin 009 (TB3-10): InM Input Module #0, pin in9 (Input)
hm2/hm2_7i96s.0:     IO Pin 010 (TB3-11): InM Input Module #0, pin in10 (Input)
hm2/hm2_7i96s.0:     IO Pin 011 (TB3-13/TB3-14): SSR #0, pin Out-00 (Output)
hm2/hm2_7i96s.0:     IO Pin 012 (TB3-15/TB3-16): SSR #0, pin Out-01 (Output)
hm2/hm2_7i96s.0:     IO Pin 013 (TB3-17/TB3-18): SSR #0, pin Out-02 (Output)
hm2/hm2_7i96s.0:     IO Pin 014 (TB3-19/TB3-20): SSR #0, pin Out-03 (Output)
hm2/hm2_7i96s.0:     IO Pin 015 (TB3-21/TB3-22): OutM Output Module #0, pin Out-04 (Output)
hm2/hm2_7i96s.0:     IO Pin 016 (TB3-23/TB3-24): OutM Output Module #0, pin Out-05 (Output)
hm2/hm2_7i96s.0:     IO Pin 017 (TB1-02/TB1-03): StepGen #0, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 018 (TB1-04/TB1-05): StepGen #0, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 019 (TB1-08/TB1-09): StepGen #1, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 020 (TB1-10/TB1-11): StepGen #1, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 021 (TB1-14/TB1-15): StepGen #2, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 022 (TB1-16/TB1-17): StepGen #2, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 023 (TB1-20/TB1-21): StepGen #3, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 024 (TB1-22-TB1-23): StepGen #3, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 025 (TB2-02/TB2-03): StepGen #4, pin Step (Output)
hm2/hm2_7i96s.0:     IO Pin 026 (TB2-04/TB2-05): StepGen #4, pin Direction (Output)
hm2/hm2_7i96s.0:     IO Pin 027 (TB2-07/TB2-08): Encoder #0, pin A (Input)
hm2/hm2_7i96s.0:     IO Pin 028 (TB2-10/TB2-11): Encoder #0, pin B (Input)
hm2/hm2_7i96s.0:     IO Pin 029 (TB2-13/TB2-14): Encoder #0, pin Index (Input)
hm2/hm2_7i96s.0:     IO Pin 030 (TB2-16/TB2-17): PktUART Receive Channel #0, pin RX Data (Input)
hm2/hm2_7i96s.0:     IO Pin 031 (TB2-18/TB2-19): PktUART Transmit Channel #0, pin TX Data (Output)
hm2/hm2_7i96s.0:     IO Pin 032 (internal): PktUART Transmit Channel #0, pin Drv Enable low (Output)
hm2/hm2_7i96s.0:     IO Pin 033 (internal): SSR #0, pin AC Ref (internal) (Output)
hm2/hm2_7i96s.0:     IO Pin 034 (P1-01/DB25-01): IOPort
hm2/hm2_7i96s.0:     IO Pin 035 (P1-02/DB25-14): IOPort
hm2/hm2_7i96s.0:     IO Pin 036 (P1-03/DB25-02): IOPort
hm2/hm2_7i96s.0:     IO Pin 037 (P1-04/DB25-15): IOPort
hm2/hm2_7i96s.0:     IO Pin 038 (P1-05/DB25-03): IOPort
hm2/hm2_7i96s.0:     IO Pin 039 (P1-06/DB25-16): IOPort
hm2/hm2_7i96s.0:     IO Pin 040 (P1-07/DB25-04): IOPort
hm2/hm2_7i96s.0:     IO Pin 041 (P1-08/DB25-17): IOPort
hm2/hm2_7i96s.0:     IO Pin 042 (P1-09/DB25-05): IOPort
hm2/hm2_7i96s.0:     IO Pin 043 (P1-11/DB25-06): IOPort
hm2/hm2_7i96s.0:     IO Pin 044 (P1-13/DB25-07): IOPort
hm2/hm2_7i96s.0:     IO Pin 045 (P1-15/DB25-08): IOPort
hm2/hm2_7i96s.0:     IO Pin 046 (P1-17/DB25-09): IOPort
hm2/hm2_7i96s.0:     IO Pin 047 (P1-19/DB25-10): IOPort
hm2/hm2_7i96s.0:     IO Pin 048 (P1-21/DB25-11): IOPort
hm2/hm2_7i96s.0:     IO Pin 049 (P1-23/DB25-12): IOPort
hm2/hm2_7i96s.0:     IO Pin 050 (P1-25/DB25-13): IOPort
hm2/hm2_7i96s.0: registered
hm2_modbus.0: warning: PktUART version is less than 3 (Rx=2 Tx=2). Please consider upgrading.
hm2_modbus.0: inst->name     : hm2_modbus.0
hm2_modbus.0: inst->uart     : hm2_7i96s.0.pktuart.0
hm2_modbus.0: inst->mbccbsize: 320
hm2_modbus.0: inst->ninit    : 0
hm2_modbus.0: inst->ncmds    : 5
hm2_modbus.0: inst->npins    : 5
hm2_modbus.0: inst->icdelay  : 0
hm2_modbus.0: inst->rxdelay  : 34
hm2_modbus.0: inst->txdelay  : 36
hm2_modbus.0: inst->drvdelay : 1
hm2_modbus.0: PktUART serial port 'hm2_7i96s.0.pktuart.0' configured to 8N1@9600
PID: installed 4 PID loops
Found file(REL): ./custom.hal
hm2_eth: 10.10.10.10: INFO: enable OOB for board on if eno1
MOTION: setting Traj cycle time to 1000000 nsecs
MOTION: setting Servo cycle time to 1000000 nsecs
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No DEFAULT_SPINDLE_0_SPEED Entry in DISPLAY, Using: 200 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_SPEED Entry in DISPLAY, Using: 100 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_SPEED Entry in DISPLAY, Using: 2500 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 1 (iniinfo.py:715)
[Gmoccapy.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 0.5 (iniinfo.py:715)
[Gmoccapy.GMOCCAPY.GETINIINFO][WARNING]  No DEFAULT_SPINDLE_SPEED entry found in [DISPLAY] of INI file (getiniinfo.py:276)
[DEFAULT.COMMON.INIINFO][DEBUG]  INI Path: /home/zdenek/linuxcnc/configs/DedaCNC-012/DedaCNC-012.ini (iniinfo.py:36)
[DEFAULT.COMMON.INIINFO][DEBUG]  Linuxcnc Run-In-Place (RIP) flag true (iniinfo.py:1013)
[DEFAULT.COMMON.INIINFO][DEBUG]  Machine is METRIC based. unit Conversion constant=0.03937007874015748 (iniinfo.py:145)
[DEFAULT.COMMON.INIINFO][DEBUG]  TRAJ COORDINATES: XYZ (iniinfo.py:166)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_LINEAR_VELOCITY = 360.0 (iniinfo.py:349)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_LINEAR_VELOCITY = 30.0 (iniinfo.py:350)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_LINEAR_VELOCITY = 1500.0 (iniinfo.py:351)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_ANGULAR_VELOCITY = 720.0 (iniinfo.py:356)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_ANGULAR_VELOCITY = 100.00001999999999 (iniinfo.py:357)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_ANGULAR_VELOCITY = 10800.0 (iniinfo.py:358)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No DEFAULT_SPINDLE_0_SPEED Entry in DISPLAY, Using: 200 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_SPEED Entry in DISPLAY, Using: 100 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_SPEED Entry in DISPLAY, Using: 2500 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 1 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 0.5 (iniinfo.py:715)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib write socket not available: Adresa je užívána (addr='tcp://127.0.0.1:5690') (hal_glib.py:365)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib read socket available: tcp://127.0.0.1:5691 (hal_glib.py:393)
[DEFAULT.COMMON.INIINFO][DEBUG]  INI Path: /home/zdenek/linuxcnc/configs/DedaCNC-012/DedaCNC-012.ini (iniinfo.py:36)
[DEFAULT.COMMON.INIINFO][DEBUG]  Linuxcnc Run-In-Place (RIP) flag true (iniinfo.py:1013)
[DEFAULT.COMMON.INIINFO][DEBUG]  Machine is METRIC based. unit Conversion constant=0.03937007874015748 (iniinfo.py:145)
[DEFAULT.COMMON.INIINFO][DEBUG]  TRAJ COORDINATES: XYZ (iniinfo.py:166)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_LINEAR_VELOCITY = 360.0 (iniinfo.py:349)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_LINEAR_VELOCITY = 30.0 (iniinfo.py:350)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_LINEAR_VELOCITY = 1500.0 (iniinfo.py:351)
[DEFAULT.COMMON.INIINFO][DEBUG]  DEFAULT_ANGULAR_VELOCITY = 720.0 (iniinfo.py:356)
[DEFAULT.COMMON.INIINFO][DEBUG]  MIN_ANGULAR_VELOCITY = 100.00001999999999 (iniinfo.py:357)
[DEFAULT.COMMON.INIINFO][DEBUG]  MAX_ANGULAR_VELOCITY = 10800.0 (iniinfo.py:358)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No DEFAULT_SPINDLE_0_SPEED Entry in DISPLAY, Using: 200 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_SPEED Entry in DISPLAY, Using: 100 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_SPEED Entry in DISPLAY, Using: 2500 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MAX_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 1 (iniinfo.py:715)
[DEFAULT.COMMON.INIINFO][WARNING]  INI Parsing Error, No MIN_SPINDLE_0_OVERRIDE Entry in DISPLAY, Using: 0.5 (iniinfo.py:715)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib write socket not available: Adresa je užívána (addr='tcp://127.0.0.1:5690') (hal_glib.py:365)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  hal_glib read socket available: tcp://127.0.0.1:5691 (hal_glib.py:393)
14:33:06.696 WARNING Config: mousetweaks GSettings schema not found, mousetweaks integration disabled.
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_little_probe, BASENAME=gtk_little_probe BASEPATH=gtk_little_probe (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_little_probe.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.glade (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .glade file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.glade (gladevcppath.py:62)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_mesa_tests, BASENAME=gtk_mesa_tests BASEPATH=gtk_mesa_tests (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_mesa_tests.glade (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .glade in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.glade (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .glade file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.glade (gladevcppath.py:62)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_little_probe, BASENAME=gtk_little_probe BASEPATH=gtk_little_probe (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_little_probe.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.py (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .py file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_little_probe/gtk_little_probe.py (gladevcppath.py:62)
****  probe_screen GETINIINFO **** 
 Preference file path: /home/zdenek/linuxcnc/configs/DedaCNC-012/DedaCNC-012.pref
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  RIP environmental variable flag: True (gladevcppath.py:19)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Linuxcnc Home directory found in environmental variable: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5 (gladevcppath.py:29)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Passed name=gtk_mesa_tests, BASENAME=gtk_mesa_tests BASEPATH=gtk_mesa_tests (gladevcppath.py:35)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/configs/DedaCNC-012/gtk_mesa_tests.py (gladevcppath.py:53)
[DEFAULT.GLADEVCP.GLADEVCPPATH][DEBUG]  Checking for .py in: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.py (gladevcppath.py:60)
[DEFAULT.GLADEVCP.GLADEVCPPATH][INFO]  Using DEFAULT .py file from: /home/zdenek/linuxcnc/linuxcnc-fork-hm2_eth_oob_v5/lib/python/gladevcp/builtin-panels/gtk_mesa_tests/gtk_mesa_tests.py (gladevcppath.py:62)
1 2

@hdiethelm

Copy link
Copy Markdown
Contributor Author

Nice, now there is no error any more from hm2_modbus, so one issue solved. :-)

Can you try to set the kernel command line suggested in #4199 (comment) and the rerun your timing tests just for Xenomai?

If you have issues, you can also just ask me.

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

wirrshark-zz912-2027-07-03.pcapng.gz
This is communication with Modbus.

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks. You also have the 3 packages in sequence. It was just hard to see due to you had set the time relative to the last package. You can switch that: View->Display Time Format->Seconds Since First Captured Package. Pretty similar to my setup except the timing:
image

Looks like the response is indeed ~250-300us. Mine is at 60-70us. It might still be the modbus part. I don't know exactly how that works, possibly commenting out addf hm2_modbus.0.process servo-thread is not enough.

Anyway, depends on your patience, we could try fully disable it or also just call it a day, good enough... ;-)

@pcw-mesa Do you have any insight? Is a modbus read blocking on the FPGA firmware? That could be the real culprit...
Additionally, I see: hm2_modbus.0: warning: PktUART version is less than 3 (Rx=2 Tx=2). Please consider upgrading. in the logs.

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

I made 24 hour test:
servo_test_24hour
nic_test_24hour
The result is not much.

I will try with ChatGPT tune ethernet card. Current settings:

zdenek@cnc:~$ sudo ethtool -k eno1
[sudo] heslo pro zdenek: 
Features for eno1:
rx-checksumming: on
tx-checksumming: on
	tx-checksum-ipv4: off [fixed]
	tx-checksum-ip-generic: on
	tx-checksum-ipv6: off [fixed]
	tx-checksum-fcoe-crc: off [fixed]
	tx-checksum-sctp: off [fixed]
scatter-gather: on
	tx-scatter-gather: on
	tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
	tx-tcp-segmentation: on
	tx-tcp-ecn-segmentation: off [fixed]
	tx-tcp-mangleid-segmentation: off
	tx-tcp6-segmentation: on
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off [fixed]
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: off [fixed]
vlan-challenged: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-gre-csum-segmentation: off [fixed]
tx-ipxip4-segmentation: off [fixed]
tx-ipxip6-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
tx-udp_tnl-csum-segmentation: off [fixed]
tx-gso-partial: off [fixed]
tx-tunnel-remcsum-segmentation: off [fixed]
tx-sctp-segmentation: off [fixed]
tx-esp-segmentation: off [fixed]
tx-udp-segmentation: off [fixed]
tx-gso-list: off [fixed]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
l2-fwd-offload: off [fixed]
hw-tc-offload: off [fixed]
esp-hw-offload: off [fixed]
esp-tx-csum-hw-offload: off [fixed]
rx-udp_tunnel-port-offload: off [fixed]
tls-hw-tx-offload: off [fixed]
tls-hw-rx-offload: off [fixed]
rx-gro-hw: off [fixed]
tls-hw-record: off [fixed]
rx-gro-list: off
macsec-hw-offload: off [fixed]
rx-udp-gro-forwarding: off
hsr-tag-ins-offload: off [fixed]
hsr-tag-rm-offload: off [fixed]
hsr-fwd-offload: off [fixed]
hsr-dup-offload: off [fixed]

@hdiethelm

Copy link
Copy Markdown
Contributor Author

The 24h test looks nice, not worse than the short test.

I am somehow assuming that the issue is the modbus part. So network tuning might not help. So if you want to go forward, I can try to remove it from your config, just to test.

Do you have a free PCI slot? You can get an I210 / I350 card for cheep: https://de.aliexpress.com/item/1005005999039768.html https://de.aliexpress.com/item/1005007037690648.html

Network card tuning:
#4199 (comment)

  • Locking the eno1 interrupt also to CPU3 might help additionally:
    • grep eno1 /proc/interrupts -> First number is the IRQ
    • echo 8 > /proc/irq/$IRQ/smp_affinity -> Use ^ instead of $IRQ
    • You can also try to use this script: eth-rt-affinity.txt sudo ./eth-rt-affinity eno1 8
    • Afterwards, you should see the eno1 interrupt counting up on CPU3 in cat /proc/interrupts as soon as LinuxCNC is running.

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

You can try this one, but you won't have spindle control any more. Just to test if the timing is still bad:
DedaCNC-012-no-modbus.zip

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Give me some time.
I will test the version without modbus later. I can also test the original firmware for Mesa without ptkuart. Buying a new ethernet card will not be a problem. I even have some ethernet cards. But I have to do things step by step :-)

Checking the ethernet card was the right choice.

I had coalising enabled.

I had in /etc/network/interfaces:

hardware-irq-coalesce-rx-usecs 0 # Intel Ethernet chip

This entry is also forbidden according to the "man interfaces" manual

It should be:

# Intel Ethernet chip
hardware-irq-coalesce-rx-usecs 0

@BsAtHome

BsAtHome commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

The hm2_modbus part will only change the time it takes for the all the functions in the servo thread to run. With the speed it runs at, 9600 Baud, it will only very periodically have something to do because the external communication is slow. But if you measure the servo thread activity, then that will (always) vary all the time.

Measuring thread active time is a very bad measure for stability. The data sent out over Ethernet will vary with the thread's activity as the packet write is the final stage of the cycle (see the addf sequence in the .hal file). More interesting is to see the timing of the packet read at the start of the thread cycle. That read says something about thread stability.

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Give me some time. I will test the version without modbus later. I can also test the original firmware for Mesa without ptkuart. Buying a new ethernet card will not be a problem. I even have some ethernet cards. But I have to do things step by step :-)

Shure, all fine.

Checking the ethernet card was the right choice.

I had coalising enabled.

I had in /etc/network/interfaces:

hardware-irq-coalesce-rx-usecs 0 # Intel Ethernet chip

There is also hardware-irq-coalesce-tx-usecs, at least for my card. Set this to 0 as well.

You can check the settings with: ethtool -c eno1

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

There is also hardware-irq-coalesce-tx-usecs, at least for my card. Set this to 0 as well.

It is not possible for me:

zdenek@cnc:~$ sudo ethtool -c eno1
[sudo] heslo pro zdenek: 
Coalesce parameters for eno1:
Adaptive RX: n/a  TX: n/a
stats-block-usecs:	n/a
sample-interval:	n/a
pkt-rate-low:		n/a
pkt-rate-high:		n/a

rx-usecs:	0
rx-frames:	n/a
rx-usecs-irq:	n/a
rx-frames-irq:	n/a

tx-usecs:	n/a
tx-frames:	n/a
tx-usecs-irq:	n/a
tx-frames-irq:	n/a

rx-usecs-low:	n/a
rx-frame-low:	n/a
tx-usecs-low:	n/a
tx-frame-low:	n/a

rx-usecs-high:	n/a
rx-frame-high:	n/a
tx-usecs-high:	n/a
tx-frame-high:	n/a

CQE mode RX: n/a  TX: n/a

tx-aggr-max-bytes:	n/a
tx-aggr-max-frames:	n/a
tx-aggr-time-usecs:	n/a

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Hi Hannes,

Thanks for sharing the eth-rt-affinity script.

I have a question about the intended long-term usage.

Is the script meant to be run manually before starting LinuxCNC, or do you recommend integrating it into the system startup (for example via systemd or /etc/network/interfaces)?

I'm trying to understand what you consider the preferred way for a permanent LinuxCNC installation.

Do you consider all parts of the script (rx-usecs, queue count, IRQ affinity and realtime priority) equally important, or are some of them just optional optimizations?

Here is my Wireshark after coalising turn off:
without_coalizing.pcapng.gz

@hdiethelm

Copy link
Copy Markdown
Contributor Author

There is also hardware-irq-coalesce-tx-usecs, at least for my card. Set this to 0 as well.

It is not possible for me:

That's depending on the network card.

I did the script for me to use it in /etc/network/interfaces: #4199 (comment)

All settings in the script improved it. Especially the IRQ affinity. It works in my setup for a realtec card and the I350.

Some of the settings are not available for all the cards but if they are not available, it is fine.

I might create one day a PR but not now, to many open projects... ;-)

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Here is my Wireshark after coalising turn off: without_coalizing.pcapng.gz

Seams to be better now. But can you post also a screenshot from Mesa PC test? Wireshark was just once to see if the timing from Wireshark matches the Mesa PC test. It does, so all fine there.

I think a proper tuning tool that sets the kernel parameter but also the ethernet card correctly would help a lot. Even thought I use linux since ages, it took me some time to set it all up and of course, I also missed the coalesce parameter in the manual... :-D Took me some time to figure that out.

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@BsAtHome

The hm2_modbus part will only change the time it takes for the all the functions in the servo thread to run. With the speed it runs at, 9600 Baud, it will only very periodically have something to do because the external communication is slow. But if you measure the servo thread activity, then that will (always) vary all the time.

That doesn't really answer the question. A few bytes more or less should not change a lot. I found it in the manual, looks like the communication happens in the background and should not block:
https://www.linuxcnc.org/docs/master/html/en/drivers/mesa_modbus.html
So all fine according to the manual. However, testing if it is really fine doesn't hurt, wouldn't be the first thing that wrongly described or broken... ;-)

I see the sporadic 112 byte packages in the wireshark, I guess these are the additional modbus packages.

Measuring thread active time is a very bad measure for stability. The data sent out over Ethernet will vary with the thread's activity as the packet write is the final stage of the cycle (see the addf sequence in the .hal file). More interesting is to see the timing of the packet read at the start of the thread cycle. That read says something about thread stability.

You mean servo-thread.tmax / servo-thread.time? It's not so bad, if its over 1000000, it fails. So you have to measure it to be below, right? Additionally a check for read.time/tmax and write.time/tmax helps to see if the issue is there or somewhere else.

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Hi Hannes,

I made 24 hour test yesterday. Then I made git pull of your repository. I dont remember what was upgraded. :-(
obrazek

Then I tuned ethernet card. Everything looked good. I made very short tests during tuning (abou 3 minutes). Servo and nic tests was about 20%. I was happy.

I made:

    hardware-irq-coalesce-rx-usecs 0 
    up ethtool -K eno1 gro off
+
    echo 8 | sudo tee /proc/irq/26/smp_affinity

After finish I wanted make another 24 hour test. But after 10 minutes Servo and nic tests jump from 20% to 80%.
I tried step by step back ethernet card settings. Nothing helped.

In case:

    hardware-irq-coalesce-rx-usecs 3
    up ethtool -K eno1 gro on
+
    echo 3 | sudo tee /proc/irq/26/smp_affinity

LCNC wrote:

hm2_modbus.0: error: hm2_pktuart_queue_read_data() returned an error: -1
hm2_modbus.0: error: Received PDU too small, size=0
hm2_modbus.0: warning: Out-of-band data received. Might not belong to current command 0

Is it possible that this has something to do with your recent edits? I don't want to accuse you of anything. Maybe I did something else that I forgot.

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Hmm, i have to check myself. I rebased to master, I dont remember if I tested it after. I would have to test it tomorrow.

Can you test withouth smp_affinity? Note: Interrupt numbers can change from boot to boot. If you take my script, this should work. If not, you have to do it manually if your PC has dynamic interrupt numbers. Took me by surprise too... ;-)

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Can you test withouth smp_affinity? Note: Interrupt numbers can change from boot to boot. If you take my script, this should work. If not, you have to do it manually if your PC has dynamic interrupt numbers. Took me by surprise too... ;-)

PC has dynamic interrupt numbers - ChatGPT warning me too. I did not reboot PC

Can you test withouth smp_affinity? - how?

ChatGPT helped me with git history. This is for you:

I checked my Git history. Before today's update I was on commit 76139c8c5d (which I had been testing since Wednesday). After updating I'm now on f2c224fd0a. Looking at the log, there are 19 commits between those revisions, including several related to hm2_eth and EVL networking. I haven't had time to bisect yet, but if it helps, the regression appeared somewhere between those two commits.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

Ah ChatGPT... ;-)

No smp_affinity:
Reboot and just dont do echo 8 | sudo tee /proc/irq/26/smp_affinity before the test.

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Original value for /proc/irq/26/smp_affinity was 3. So I made test with

echo 3 | sudo tee /proc/irq/26/smp_affinity

and it did not help.

ChatGPT wanted cat /proc/irq/26/smp_affinity before echo. :-)

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

ChatGPT has no clue. The only changes coming in from master where not related to this PR. It tested it again anyway, no difference.

Probably you did something wrong while tuning Ethernet. Or it was just a random glitch that hit.

While Tuning: Always reboot after setting random parameters. If you set something, it might get stuck until you reboot. Then set what worked again and test again.

Only set one parameter at a time, test, next parameter.

Question to ChatGPT: Why echo 3 ? ;-)

Did you try my eth-rt-affinity script and my recommendations for the kernel command line? At least for me, it reduced the jitter by a lot, but it might be hardware dependent.

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Question to ChatGPT: Why echo 3 ? ;-)

ChatGPT studied your script before we run it. ChatGPT explain me, how your script works.

I made cat /proc/irq/26/smp_affinity before we made anything. Results was 3.

Then I made:
echo 8 | sudo tee /proc/irq/26/smp_affinity

I made tests with:
echo 3 | sudo tee /proc/irq/26/smp_affinity
and
echo 8 | sudo tee /proc/irq/26/smp_affinity
Results was same above 80%

@hdiethelm

hdiethelm commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Here, it was 48%: #4199 (comment) So something must have changed. I don't think it's the rebase. But who knows, at least for me, it was no issue and looking at the changes, it is all fine.

You can try this branch, i restored the old version if you want to try: https://github.com/hdiethelm/linuxcnc-fork/tree/hm2_eth_oob_v5_before_rebase_2

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Do you have something with modbus? We should have similar conditions.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

Do you have something with modbus? We should have similar conditions.

Sadly no. But you can disable modbus for your setup, so it is also similar, a few messages before, I sent you something that should work, just without spindle.

As it looks to me, you changed something at the same time while pulling the new branch and that generated the issue you are having now. There was no change in modbus or OOB Networking, only some change in other code from other people, not really connected to latency.

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

I have to take a break from testing or my wife will divorce me. So I apologize for not responding right away. Maybe I'll get back to it on Monday.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

I need a break to, all fine... ;-)

@zz912

zz912 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Did you notice above?

hm2_modbus.0: error: hm2_pktuart_queue_read_data() returned an error: -1
hm2_modbus.0: error: Received PDU too small, size=0
hm2_modbus.0: warning: Out-of-band data received. Might not belong to current command 0

@hdiethelm

Copy link
Copy Markdown
Contributor Author

Yes, makes no sense to me. Do you had that only once after setting ethernet affinity? Did you reboot and it went away?
Might be a bug somewhere in the xenomai kernel that a package got lost or just something that happens from time to time with modbus. Could also happen with preempt_rt.

@zz912

zz912 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Would you be willing to buy this: https://a.aliexpress.com/_EHftnL8
?

24V 1ch variant
Screenshot_20260704-075053_AliExpress

I would buy the same for testing together.

@hdiethelm

Copy link
Copy Markdown
Contributor Author

The device itsself is cheep. But I would have to connect it to my CNC / flash a new firmware and revert it afterwards. I think my VFD even supports modbus but at the time I figured just adding a few wires and control it analog is easier.

Now I did not find the original firmware which was on the mesa card when I bought it. All available files have different pin info.

Best would be to just buy a new mesa card for testing so I don't brick my machine but that's not cheep.

At the end, the chances are high that it works well on my machine and it's a different issue...

Can you reproduce this hm2_modbus.0: error: hm2_pktuart_queue_read_data() returned an error: -1? Can you post the full logs including all active network card tweaks / cat /proc/cmdline cat /proc/interrupts?

Ideally as zip, so the thread doesn't explode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants