Skip to content

coherence.h: daxfs_cas64() does not byte-swap, so CAS loops never terminate on big-endian #20

Description

@congwang-mk

daxfs/coherence.h mixes converted and raw access to the same fields.

daxfs_load_once64() (line 50) and daxfs_store_once64() convert:

return le64_to_cpu(READ_ONCE(*(const __le64 *)ptr));

daxfs_cas64() (line 31) does not:

return cmpxchg((u64 *)ptr, old, new);

On a big-endian host the value read through daxfs_load_once64() is byte-swapped relative to the raw word in memory, so the comparison inside cmpxchg can never match. Every retry loop of this shape spins forever:

do {
        old_alloc = daxfs_load_once64(ovl->mem_model, &hdr->pool_alloc);
        ...
} while (daxfs_cas64(ovl->mem_model, &hdr->pool_alloc, old_alloc, new_alloc) != old_alloc);

That covers overlay_pool_bump(), overlay_pool_alloc_free(), overlay_pool_free(), pcache_inc_pending(), the value-update loop in overlay_insert(), and the inode allocator. The result is a hang in uninterruptible context, not an error.

The header comment already acknowledges this: "this matches the historical behavior and is correct on little-endian hosts". So it is a known, deliberate limitation rather than an oversight, and it costs nothing today on x86 and riscv64.

Filing it so it is tracked rather than rediscovered. Either make daxfs_cas64() convert consistently, or add a build-time guard so a big-endian build fails loudly instead of hanging at runtime.

Found during the review in #15.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions