Interestingly, the spinlock test works after I change tas() implementation
FROM
  __sync_lock_test_and_set(lock, 1);
TO
  __sync_val_compare_and_swap(lock, 0, 1);

## gcc (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)

====
__sync_lock_test_and_set(lock, 1) disassembly:

```
objdump -S a.out

000000000040073c <tas>:
  40073c:       d10043ff        sub     sp, sp, #0x10
  400740:       f90007e0        str     x0, [sp, #8]
  400744:       f94007e0        ldr     x0, [sp, #8]
  400748:       52800021        mov     w1, #0x1                        // #1
  40074c:       885f7c02        ldxr    w2, [x0]
  400750:       88037c01        stxr    w3, w1, [x0]
  400754:       35ffffc3        cbnz    w3, 40074c <tas+0x10>
  400758:       d5033bbf        dmb     ish
  40075c:       2a0203e0        mov     w0, w2
  400760:       910043ff        add     sp, sp, #0x10
  400764:       d65f03c0        ret
```

====
__sync_val_compare_and_swap(lock, 0, 1); disassembly:

```
objdump -S a.out

000000000040073c <tas>:
  40073c:       d10043ff        sub     sp, sp, #0x10
  400740:       f90007e0        str     x0, [sp, #8]
  400744:       f94007e0        ldr     x0, [sp, #8]
  400748:       52800021        mov     w1, #0x1                        // #1
  40074c:       885f7c02        ldxr    w2, [x0]
  400750:       35000062        cbnz    w2, 40075c <tas+0x20>
  400754:       8803fc01        stlxr   w3, w1, [x0]
  400758:       35ffffa3        cbnz    w3, 40074c <tas+0x10>
  40075c:       7100005f        cmp     w2, #0x0
  400760:       d5033bbf        dmb     ish
  400764:       2a0203e0        mov     w0, w2
  400768:       910043ff        add     sp, sp, #0x10
  40076c:       d65f03c0        ret
```

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1908626

Title:
  Atomic test-and-set instruction does not work on qemu-user

Status in QEMU:
  New

Bug description:
  I try to compile and run PostgreSQL/Greenplum database inside docker 
container/qemu-aarch64-static:
  ```
   host: CentOS7 x86_64
   container: centos:centos7.9.2009 --platform linux/arm64/v8
   qemu-user-static: https://github.com/multiarch/qemu-user-static/releases/
  ```

  However, GP/PG's spinlock always gets stuck and reports PANIC errors. It 
seems its spinlock
  has something wrong.
  ```
  https://github.com/greenplum-db/gpdb/blob/master/src/include/storage/s_lock.h
  
https://github.com/greenplum-db/gpdb/blob/master/src/backend/storage/lmgr/s_lock.c
  ```

  So I extract its spinlock implementation into one test C source file (see 
attachment file),
  and get reprodcued:

  ```
  $ gcc spinlock_qemu.c
  $ ./a.out 
  C -- slock inited, lock value is: 0
  parent 139642, child 139645
  P -- slock lock before, lock value is: 0
  P -- slock locked, lock value is: 1
  P -- slock unlock after, lock value is: 0
  C -- slock lock before, lock value is: 1
  P -- slock lock before, lock value is: 1
  C -- slock locked, lock value is: 1
  C -- slock unlock after, lock value is: 0
  C -- slock lock before, lock value is: 1
  P -- slock locked, lock value is: 1
  P -- slock unlock after, lock value is: 0
  P -- slock lock before, lock value is: 1
  C -- slock locked, lock value is: 1
  C -- slock unlock after, lock value is: 0
  P -- slock locked, lock value is: 1
  C -- slock lock before, lock value is: 1
  P -- slock unlock after, lock value is: 0
  C -- slock locked, lock value is: 1
  P -- slock lock before, lock value is: 1
  C -- slock unlock after, lock value is: 0
  P -- slock locked, lock value is: 1
  C -- slock lock before, lock value is: 1
  P -- slock unlock after, lock value is: 0
  C -- slock locked, lock value is: 1
  P -- slock lock before, lock value is: 1
  C -- slock unlock after, lock value is: 0
  P -- slock locked, lock value is: 1
  C -- slock lock before, lock value is: 1
  P -- slock unlock after, lock value is: 0
  P -- slock lock before, lock value is: 1
  spin timeout, lock value is 1 (pid 139642)
  spin timeout, lock value is 1 (pid 139645)
  spin timeout, lock value is 1 (pid 139645)
  spin timeout, lock value is 1 (pid 139642)
  spin timeout, lock value is 1 (pid 139645)
  spin timeout, lock value is 1 (pid 139642)
  ...
  ...
  ...
  ```

  NOTE: this code always works on PHYSICAL ARM64 server.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1908626/+subscriptions

Reply via email to