releng/13.1 amd64 atomic_fcmpset_long parameter order and dst,expect,src (source) vs. src,dst,expect (crash dump report)

From: Mark Millard <marklmi_at_yahoo.com>
Date: Wed, 22 Mar 2023 02:19:49 UTC
Anyone know what to make of the below mismatch between the source
and what  crash log is reporting about the atomic_fcmpset_long
parameter order?

A releng/13.1 sys/amd64/include/atomic.h has the likes of:

int     atomic_fcmpset_long(volatile u_long *dst, u_long *expect, u_long src);

Note the order: dst, expect, src. Later it has the implementation:

/*
 * Atomic compare and set, used by the mutex functions.
 *
 * cmpset:
 *      if (*dst == expect)
 *              *dst = src
 *
 * fcmpset:
 *      if (*dst == *expect)
 *              *dst = src
 *      else
 *              *expect = *dst
 *
 * Returns 0 on failure, non-zero on success.
 */
#define ATOMIC_CMPSET(TYPE)                             \
static __inline int                                     \
atomic_cmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE expect, u_##TYPE src) \
{                                                       \
        u_char res;                                     \
                                                        \
        __asm __volatile(                               \
        " lock; cmpxchg %3,%1 ; "                       \
        "# atomic_cmpset_" #TYPE "      "               \
        : "=@cce" (res),                /* 0 */         \
          "+m" (*dst),                  /* 1 */         \
          "+a" (expect)                 /* 2 */         \
        : "r" (src)                     /* 3 */         \
        : "memory", "cc");                              \
        return (res);                                   \
}                                                       \
                                                        \
static __inline int                                     \
atomic_fcmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE *expect, u_##TYPE src) \
{                                                       \
        u_char res;                                     \
                                                        \
        __asm __volatile(                               \
        " lock; cmpxchg %3,%1 ;         "               \
        "# atomic_fcmpset_" #TYPE "     "               \
        : "=@cce" (res),                /* 0 */         \
          "+m" (*dst),                  /* 1 */         \
          "+a" (*expect)                /* 2 */         \
        : "r" (src)                     /* 3 */         \
        : "memory", "cc");                              \
        return (res);                                   \
}

ATOMIC_CMPSET(char);
ATOMIC_CMPSET(short);
ATOMIC_CMPSET(int);
ATOMIC_CMPSET(long);

which still shows dst,expect,src for the order.


But a releng/13.1 crash dump log shows the name order: src, dst, expect
(in #7 below):

#4 0xffffffff80c1ba63 in panic (fmt=<unavailable>)
at /usr/src/sys/kern/kern_shutdown.c:844
#5 0xffffffff810addf5 in trap_fatal (frame=0xfffffe00b555dae0, eva=0)
at /usr/src/sys/amd64/amd64/trap.c:944
#6 <signal handler called>
#7 0xffffffff80c895cb in atomic_fcmpset_long (src=18446741877726026240, 
dst=<optimized out>, expect=<optimized out>)
at /usr/src/sys/amd64/include/atomic.h:225

The atomic_fcmpset_long (from a mtx_lock(?) use) got a:

Fatal trap 9: general protection fault while in kernel mode

crash. The code was inside nfsd.

( Note: 18446741877726026240 == 0xfffffe00b52e9a00 )

The crash is not mine. It is a new type of example from
an ongoing crash-evidence gathering session. See:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267028#c147
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267028#c148

===
Mark Millard
marklmi at yahoo.com