Skip to content

Mesa Hostmot2 Xenomai4 OOB networking support#4199

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

Mesa Hostmot2 Xenomai4 OOB networking support#4199
hdiethelm wants to merge 6 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.

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.

@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.

If this fails, everything beaks and there are a thon of error messages.
So better abort here
Split into two network implementations, one for posix and
one for evl.

There are now two modules: hm2_eth and hm2_eth_evl.
@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 added 4 commits July 1, 2026 13:50
Change back to one component that uses a "board_rtnet" argument to switch
between the types
Requres:
initf hm2_eth.realtime-init servo-thread
in .hal file
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.

3 participants