Hi,

This patch set tries to add loongarch64 native spin lock to postgresql.

- [PATCH 1/2] implements a loongarch64 native spin lock.
- [PATCH 2/2] fixes s_lock_test to make it runnable via `make check'.

The patch set is tested on my Loongson 3A5000 machine with Loong Arch Linux and GCC 13.1.0 with default ./configure with no options.

Output of `make check' in src/backend/storage/lmgr is attached.

See:
[1]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#atomic-memory-access-instructions [2]: https://github.com/torvalds/linux/blob/f1fcbaa18b28dec10281551dfe6ed3a3ed80e3d6/arch/loongarch/include/asm/cmpxchg.h#L12

----
YANG Xudong
From fe4fb3c9b8027a3e9664e8e99ac78dec4c4ef83d Mon Sep 17 00:00:00 2001
From: YANG Xudong <yangxud...@ymatrix.cn>
Date: Wed, 17 May 2023 16:21:45 +0800
Subject: [PATCH 1/2] Implement loongarch64 native spinlock with TAS.

---
 src/include/storage/s_lock.h | 39 ++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index c9fa84cc43..3656595270 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -596,6 +596,45 @@ tas(volatile slock_t *lock)
 #endif  /* __hppa || __hppa__ */
 
 
+#if defined(__loongarch__) && defined(__linux__)       /* loongarch64 */
+
+#define HAS_TEST_AND_SET
+
+typedef unsigned int slock_t;
+
+#define TAS(lock) tas(lock)
+
+static __inline__ int
+tas(volatile slock_t *lock)
+{
+       /*
+        * The following implementation is based on the implementation of 
cmpxchg
+        * in linux kernel source code tree.
+        * See: arch/loongarch/include/asm/cmpxchg.h in linux for more details.
+        */
+       register slock_t _res = 1;
+
+       __asm__ __volatile__ (        \
+       " amswap_db.w %1, %z2, %0 \n" \
+       : "+ZB" (*lock), "=&r" (_res) \
+       : "Jr" (_res)                 \
+       : "memory");
+
+       return (int) _res;
+}
+
+#define SPIN_DELAY() spin_delay()
+
+static __inline__ void
+spin_delay(void)
+{
+       __asm__ __volatile__(
+       " nop \n");
+}
+
+#endif /* __loongarch__ */
+
+
 /*
  * If we have no platform-specific knowledge, but we found that the compiler
  * provides __sync_lock_test_and_set(), use that.  Prefer the int-width
-- 
2.40.1

From 1e5d6ed9b54c264d539c84ead7513845ad1349ed Mon Sep 17 00:00:00 2001
From: YANG Xudong <yangxud...@ymatrix.cn>
Date: Wed, 17 May 2023 16:22:06 +0800
Subject: [PATCH 2/2] Make s_lock_test work.

---
 src/backend/storage/lmgr/Makefile | 2 +-
 src/backend/storage/lmgr/s_lock.c | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/backend/storage/lmgr/Makefile 
b/src/backend/storage/lmgr/Makefile
index b25b7ee421..3b04561d6f 100644
--- a/src/backend/storage/lmgr/Makefile
+++ b/src/backend/storage/lmgr/Makefile
@@ -33,7 +33,7 @@ endif
 s_lock_test: s_lock.c $(top_builddir)/src/common/libpgcommon.a 
$(top_builddir)/src/port/libpgport.a
        $(CC) $(CPPFLAGS) $(CFLAGS) -DS_LOCK_TEST=1 $(srcdir)/s_lock.c \
                $(TASPATH) -L $(top_builddir)/src/common -lpgcommon \
-               -L $(top_builddir)/src/port -lpgport -o s_lock_test
+               -L $(top_builddir)/src/port -lpgport -lm -o s_lock_test
 
 # see notes in src/backend/parser/Makefile
 lwlocknames.c: lwlocknames.h
diff --git a/src/backend/storage/lmgr/s_lock.c 
b/src/backend/storage/lmgr/s_lock.c
index 327ac64f7c..1d674840b4 100644
--- a/src/backend/storage/lmgr/s_lock.c
+++ b/src/backend/storage/lmgr/s_lock.c
@@ -145,9 +145,13 @@ perform_spin_delay(SpinDelayStatus *status)
                 * We might want to report something more granular at some 
point, but
                 * this is better than nothing.
                 */
+#if !defined(S_LOCK_TEST)
                pgstat_report_wait_start(WAIT_EVENT_SPIN_DELAY);
+#endif
                pg_usleep(status->cur_delay);
+#if !defined(S_LOCK_TEST)
                pgstat_report_wait_end();
+#endif
 
 #if defined(S_LOCK_TEST)
                fprintf(stdout, "*");
-- 
2.40.1

make -C ../../../../src/backend generated-headers
make[1]: Entering directory '/home/yxd/playspace/postgres/src/backend'
make -C catalog distprep generated-header-symlinks
make[2]: Entering directory '/home/yxd/playspace/postgres/src/backend/catalog'
make[2]: Nothing to be done for 'distprep'.
make[2]: Nothing to be done for 'generated-header-symlinks'.
make[2]: Leaving directory '/home/yxd/playspace/postgres/src/backend/catalog'
make -C nodes distprep generated-header-symlinks
make[2]: Entering directory '/home/yxd/playspace/postgres/src/backend/nodes'
make[2]: Nothing to be done for 'distprep'.
make[2]: Nothing to be done for 'generated-header-symlinks'.
make[2]: Leaving directory '/home/yxd/playspace/postgres/src/backend/nodes'
make -C utils distprep generated-header-symlinks
make[2]: Entering directory '/home/yxd/playspace/postgres/src/backend/utils'
make[2]: Nothing to be done for 'distprep'.
make[2]: Nothing to be done for 'generated-header-symlinks'.
make[2]: Leaving directory '/home/yxd/playspace/postgres/src/backend/utils'
make[1]: Leaving directory '/home/yxd/playspace/postgres/src/backend'
rm -rf '/home/yxd/playspace/postgres'/tmp_install
/usr/bin/mkdir -p '/home/yxd/playspace/postgres'/tmp_install/log
make -C '../../../..' DESTDIR='/home/yxd/playspace/postgres'/tmp_install 
install >'/home/yxd/playspace/postgres'/tmp_install/log/install.log 2>&1
make -j1  checkprep 
>>'/home/yxd/playspace/postgres'/tmp_install/log/install.log 2>&1
./s_lock_test
S_LOCK_TEST: this will print 1000 stars and then
             exit with a 'stuck spinlock' message
             if S_LOCK() and TAS() are working.
****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
Stuck spinlock detected at main, ./s_lock.c:322.
make: *** [Makefile:46: check] Error 1

Reply via email to