Skip to content

fix(cmrpc): release session when resend exhaustion aborts the AR - #601

Open
acrews42 wants to merge 1 commit into
rtlabs-com:publicfrom
acrews42:fix-cmrpc-session-leak-on-resend-exhaustion
Open

fix(cmrpc): release session when resend exhaustion aborts the AR#601
acrews42 wants to merge 1 commit into
rtlabs-com:publicfrom
acrews42:fix-cmrpc-session-leak-on-resend-exhaustion

Conversation

@acrews42

Copy link
Copy Markdown

Symptom

After a few AR churn cycles (controller connects, then aborts or disappears without answering the device's CControl/ApplicationReady request), a p-net device starts logging

CMRPC(4331): Out of session resources for incoming frame.

for every incoming RPC frame and never recovers. New Connects are still accepted, but record writes and PrmEnd stall until the controller's RPC timeout, and the AR then aborts with CMSM: Timeout for communication start up (0xFD/0x06). The device is effectively wedged until restart. A stale scheduler handle from the leaked session also produces SCHEDULER: Invalid value 0 for timeout "(null)". No removal.

Root cause

In pf_cmrpc_send_with_timeout, when resend_counter is exhausted:

  • the from_me == true branch (CControl request, no response) aborts the AR and closes the socket, but never calls pf_session_release;
  • the fragment-timeout branch aborts the AR and releases nothing at all.

The session stays in_use forever. With PF_MAX_SESSION = 2 * PNET_MAX_AR + 1 — three sessions in the default single-AR configuration — a handful of unanswered CControls exhausts the pool permanently.

Fix

Call pf_session_release in both exhaustion branches, after the AR abort (mirroring the release the normal completion paths perform).

Testing

Reproduced with a PROFINET controller performing repeated connect/abort cycles against 32 p-net-based simulated devices (Linux, default options):

  • Before: each device wedged after ~3 unanswered CControls; subsequent establish attempts crawled (30 s RPC recv timeouts per step) and a 32-device reconnect train that normally takes ~45 s blew past 480 s.
  • After: three consecutive full 32-device reconnect cycles completed with flat establish times (40/41/40 s) and zero session-exhaustion log lines on sampled devices.

Happy to sign a CLA or rework the patch to your conventions if needed — this is also offered under the project's GPLv3 terms for the dual-license arrangement at your discretion.

When pf_cmrpc_send_with_timeout exhausts its resend counter — a
CControl request that never got a response, or a fragment that timed
out — it aborts the AR (and, in the CControl branch, closes the
socket) but never calls pf_session_release. The session stays
in_use forever.

With PF_MAX_SESSION = 2 * PNET_MAX_AR + 1 (three sessions in the
default single-AR configuration), a handful of unanswered CControl
requests permanently exhausts the pool. From then on the device logs
"CMRPC: Out of session resources for incoming frame" for every
incoming RPC frame: new Connects are still accepted (they reuse the
recovered connect session) but record writes and PrmEnd stall until
the controller's RPC timeout, and the AR eventually aborts with a
CMSM startup timeout. The device is wedged until restart.

Reproduced with a PROFINET controller repeatedly connecting/aborting
against p-net sample devices: before this change a device wedged
after ~3 unanswered CControls; after it, 3 consecutive full
reconnect cycles across 32 simulated devices completed with flat
establish times and zero session-exhaustion errors.

Release the session in both exhaustion branches, after the AR abort.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Aug 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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.

2 participants