When loading model weights, FastFlowLM (FLM) calls mmap() followed by mlock() to pin host RAM, enabling the AMD NPU to perform direct DMA transfers without triggering page faults.

If the process exceeds its locked-memory resource limit (RLIMIT_MEMLOCK), mlock() fails with EAGAIN:

TEXT
mmap(err=-11)

For context, even a compact 1.2B parameter model requires ~1.6 GB of pinned memory. Systemd’s out-of-the-box DefaultLimitMEMLOCK is set to 8 MB (8388608 bytes), causing FLM model loading to fail immediately under default unit configurations.

Why /etc/security/limits.d Is Insufficient

A common, and recommended by FastFlowLM project, mitigation is dropping a memlock unlimited file into /etc/security/limits.d/. This is necessary for interactive user sessions, but insufficient for background processes and services.

limits.d configurations are enforced by pam_limits.so during PAM session initialization. Execution paths that bypass PAM will not inherit these limits:

Table
Execution Path Uses PAM? Enforced Limit Source
Interactive TTY / SSH login Yes /etc/security/limits.d/
systemd system service No Unit LimitMEMLOCK (defaults to 8 MB)
systemd --user unit No User manager ceiling (defaults to 8 MB)
Non-PAM shells / processes No Parent process limit (defaults to 8 MB)

Because systemctl --user and system services bypass PAM completely, FLM runtimes managed as systemd units inherit systemd’s default 8 MB limit regardless of /etc/security/limits.d/.

Additionally, a child user unit cannot exceed the resource ceiling set on its parent user@<UID>.service manager.

Resolution

To raise RLIMIT_MEMLOCK globally for systemd services and user-managed processes, apply two configuration drop-ins:

1. Set global systemd default

Create /etc/systemd/system.conf.d/10-memlock.conf:

INI
[Manager]
DefaultLimitMEMLOCK=infinity

2. Set user-manager ceiling override

Create /etc/systemd/system/user@.service.d/10-memlock.conf (applies to all user session managers):

INI
[Service]
LimitMEMLOCK=infinity
Tip

If you only want this apply to a specific user you can set this only for the user. For instance, if your user id is 1000, you would use /etc/systemd/system/user@1000.service.d/10-memlock.conf.

3. Reload configuration

BASH
sudo systemctl daemon-reload
Note

Existing services and user managers must be restarted (or the host rebooted) for the updated limit to take effect.

Verification

Verify the updated limits via systemd and the Linux kernel process interface:

Confirm global systemd default

BASH
systemctl show -p DefaultLimitMEMLOCK

Confirm user manager limit

BASH
systemctl show user@$(id -u).service -p LimitMEMLOCK

Confirm effective limit on the running FLM process

BASH
cat /proc/$(pgrep -f flm)/limits | grep 'Max locked'