Thread (2 messages) 2 messages, 2 authors, 10d ago

Re: [BUG] atlantic: resume from S3 fails with -ENOMEM in aq_ring_alloc(), leaves unusable netdev

flat view

From: Jonas Gorski <jonas.gorski@gmail.com>
Date: 2026-09-28 07:24:13

Hi,

On 26/09/2026 21:49, Stephan Hauser wrote:
Hi,

The atlantic driver intermittently fails to resume an AQC107 from suspend-to-RAM.
aq_nic_init() reallocates its per-ring software buffer arrays from the PM resume
path, where the PM core has restricted allocations to GFP_NOIO. With the default
ring sizes these are order-5 and order-6 requests (128 KiB and 256 KiB), which
cannot reliably be satisfied in a context that can neither reclaim, compact, nor
dip into reserves.

Resume then returns -ENOMEM and the device is left half-initialised: the netdev
still exists and is still marked IFF_UP, but has no rings and no vectors. It
passes no traffic, DHCP never completes, and bringing the link down hangs.

I have 3 occurrences in 60 suspend/resume cycles (5%) over 5.5 weeks of journal,
across kernels 7.1.4 and 7.2.2. What makes this worth reporting rather than
filing under "memory was tight": the three failures have three *different*
proximate causes in the allocator, detailed below. The allocation is fragile in
several independent ways at once, which is why no amount of tuning fixes it.

Two distinct problems:

  1. A >PAGE_ALLOC_COSTLY_ORDER kmalloc() on the resume path, for memory that
     never needs to be physically contiguous.
  2. atl_resume_common() does not unwind when aq_nic_init() fails, so an
     allocation failure is converted into a wedged interface.


Disclosure
----------

The analysis in this report, and the text of the report itself, were produced
with the assistance of Claude (Anthropic). Please weigh it accordingly.

What is directly evidenced: the hardware is real and in front of me, and every
log line, zone dump and free-page histogram quoted below is verbatim from my
journal. The failure counts come from scanning all boots in that journal.

What is inference rather than measurement, and where I would welcome a second
opinion:

  - The 64-byte element size is derived from the two reported allocation
    orders, not read out of the source.
  - The TX-before-RX ordering in aq_vec_ring_alloc(), and the claim that
    aq_nic_init() aborts on first failure, are inferred from the backtrace and
    from only ever seeing a single warning per event.
  - The ZONE_DMA32 lowmem_reserve arithmetic in case 3 is hand-computed from
    the zone dump.
  - The aq_nic_stop() attribution for the link-down hang is a guess; I say so
    again where it appears.
  - The suggested fixes were not compiled or tested, and were written without
    the source tree to hand. Treat them as a direction, not a patch.

I have read the whole thing and stand behind reporting it, but I have not
personally verified the driver internals against the code.


System
------

  Kernel:    7.1.4 and 7.2.2 (also running 7.2.7), x86_64, PREEMPT(lazy)
  Hardware:  Micro-Star International Co., Ltd. MEG X570 UNIFY (MS-7C35),
             BIOS A.80 01/22/2021
  NIC:       Aquantia AQC107 NBase-T/IEEE 802.3an [Atlantic 10G] (rev 02)
             PCI 0000:24:00.0, [1d6a:07b1], subsystem [1d6a:0001]
  Driver:    atlantic, firmware-version 3.1.100
  Rings:     rx 2048 / tx 4096 (driver defaults; maximum 8184), 8 vectors
  Memory:    64 GB, no swap configured
This is also happening to me, at least since 6.18 (where I first noticed it)
with an AQC113 [1d6a:04c0 / sub 1043:889a]. Currently running 7.2(.4).

Looking at older boot logs I see the exact same allocation failures, then
(later) hangs.

For me the hang often happens at suspend. I don't use the card as an uplink
port, so most of the time it has no connection, and the issue only shows up
when trying to tear down the interface on suspend after the allocation
failed at the previous resume.

Best regards,
Jonas
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help