Module Name:    src
Committed By:   thorpej
Date:           Tue Jul 13 01:59:10 UTC 2021

Modified Files:
        src/sys/arch/alpha/alpha: lock_stubs.s patch.c

Log Message:
As with membar_producer() and membar_sync(), initialize the fast-path
lock stubs with "unop" isns where memory barriers need to be, and if
we detect a multiprocessor system, patch those locations with "mb" insns.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/alpha/alpha/lock_stubs.s \
    src/sys/arch/alpha/alpha/patch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/alpha/alpha/lock_stubs.s
diff -u src/sys/arch/alpha/alpha/lock_stubs.s:1.6 src/sys/arch/alpha/alpha/lock_stubs.s:1.7
--- src/sys/arch/alpha/alpha/lock_stubs.s:1.6	Mon Jul 12 15:21:51 2021
+++ src/sys/arch/alpha/alpha/lock_stubs.s	Tue Jul 13 01:59:10 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: lock_stubs.s,v 1.6 2021/07/12 15:21:51 thorpej Exp $	*/
+/*	$NetBSD: lock_stubs.s,v 1.7 2021/07/13 01:59:10 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2021 The NetBSD Foundation, Inc.
@@ -34,12 +34,16 @@
 
 #include <machine/asm.h>
 
-__KERNEL_RCSID(0, "$NetBSD: lock_stubs.s,v 1.6 2021/07/12 15:21:51 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lock_stubs.s,v 1.7 2021/07/13 01:59:10 thorpej Exp $");
 
 #include "assym.h"
 
 #if defined(MULTIPROCESSOR)
-#define	MB		mb
+/*
+ * These 'unop' insns will be patched with 'mb' insns at run-time if
+ * the system has more than one processor.
+ */
+#define	MB(label)	label: unop
 #else
 #define	MB		/* nothing */
 #endif
@@ -55,11 +59,11 @@ LEAF(_lock_cas, 3)
 	beq	t1, 2f
 	stq_c	v0, 0(a0)
 	beq	v0, 3f
-	MB	
+	MB(.L__lock_cas_mb_1)
 	RET
 2:
 	mov	zero, v0
-	MB
+	MB(.L__lock_cas_mb_2)
 	RET
 3:
 	br	1b
@@ -79,7 +83,7 @@ LEAF(mutex_enter, 1)
 	bne	t2, 2f
 	stq_c	t1, 0(a0)
 	beq	t1, 3f
-	MB
+	MB(.L_mutex_enter_mb_1)
 	RET
 2:
 	lda	t12, mutex_vector_enter
@@ -93,7 +97,7 @@ LEAF(mutex_enter, 1)
  */
 LEAF(mutex_exit, 1)
 	LDGP(pv)
-	MB
+	MB(.L_mutex_exit_mb_1)
 	GET_CURLWP	/* Note: GET_CURLWP clobbers v0, t0, t8...t11. */
 	mov	zero, t3
 1:
@@ -179,7 +183,7 @@ LEAF(mutex_spin_enter, 1);
 	bne	t0, 2f			/* contended */
 	stl_c	t1, MUTEX_SIMPLELOCK(a1)
 	beq	t1, 2f			/* STL_C failed; consider contended */
-	MB
+	MB(.L_mutex_spin_enter_mb_1)
 	RET
 2:
 	mov	a1, a0			/* restore first argument */
@@ -192,7 +196,7 @@ LEAF(mutex_spin_enter, 1);
  */
 LEAF(mutex_spin_exit, 1)
 	LDGP(pv);
-	MB
+	MB(.L_mutex_spin_exit_mb_1)
 
 	/*
 	 * STEP 1: __cpu_simple_unlock(&mtx->mtx_lock)
@@ -247,7 +251,7 @@ LEAF(rw_enter, 2)
 	bne	t1, 4f		/* contended */
 	stq_c	t2, 0(a0)
 	beq	t2, 2f		/* STQ_C failed; retry */
-	MB
+	MB(.L_rw_enter_mb_1)
 	RET
 
 2:	br	1b
@@ -259,7 +263,7 @@ LEAF(rw_enter, 2)
 	bne	t0, 4f		/* contended */
 	stq_c	t2, 0(a0)
 	beq	t2, 4f		/* STQ_C failed; consider it contended */
-	MB
+	MB(.L_rw_enter_mb_2)
 	RET
 
 4:	lda	pv, rw_vector_enter
@@ -284,7 +288,7 @@ LEAF(rw_tryenter, 2)
 	bne	t1, 4f		/* contended */
 	stq_c	v0, 0(a0)
 	beq	v0, 2f		/* STQ_C failed; retry */
-	MB
+	MB(.L_rw_tryenter_mb_1)
 	RET			/* v0 contains non-zero LOCK_FLAG from STQ_C */
 
 2:	br	1b
@@ -302,7 +306,7 @@ LEAF(rw_tryenter, 2)
 	 * in the failure case because we expect it to be rare and it saves
 	 * a branch-not-taken instruction in the success case.
 	 */
-	MB
+	MB(.L_rw_tryenter_mb_2)
 	RET
 
 4:	mov	zero, v0	/* return 0 (failure) */
@@ -316,7 +320,7 @@ LEAF(rw_tryenter, 2)
  */
 LEAF(rw_exit, 1)
 	LDGP(pv)
-	MB
+	MB(.L_rw_exit_mb_1)
 
 	/*
 	 * Check for write-lock release, and get the owner/count field
@@ -381,3 +385,27 @@ LEAF(rw_exit, 1)
 	END(rw_exit)
 
 #endif	/* !LOCKDEBUG */
+
+#if defined(MULTIPROCESSOR)
+/*
+ * Table of locations to patch with MB instructions on multiprocessor
+ * systems.
+ */
+	.section ".rodata"
+	.globl	lock_stub_patch_table
+lock_stub_patch_table:
+	.quad	.L__lock_cas_mb_1
+	.quad	.L__lock_cas_mb_2
+#if !defined(LOCKDEBUG)
+	.quad	.L_mutex_enter_mb_1
+	.quad	.L_mutex_exit_mb_1
+	.quad	.L_mutex_spin_enter_mb_1
+	.quad	.L_mutex_spin_exit_mb_1
+	.quad	.L_rw_enter_mb_1
+	.quad	.L_rw_enter_mb_2
+	.quad	.L_rw_tryenter_mb_1
+	.quad	.L_rw_tryenter_mb_2
+	.quad	.L_rw_exit_mb_1
+#endif /* ! LOCKDEBUG */
+	.quad	0		/* NULL terminator */
+#endif /* MULTIPROCESSOR */
Index: src/sys/arch/alpha/alpha/patch.c
diff -u src/sys/arch/alpha/alpha/patch.c:1.6 src/sys/arch/alpha/alpha/patch.c:1.7
--- src/sys/arch/alpha/alpha/patch.c:1.6	Wed Jul  7 03:30:35 2021
+++ src/sys/arch/alpha/alpha/patch.c	Tue Jul 13 01:59:10 2021
@@ -1,7 +1,7 @@
-/*	$NetBSD: patch.c,v 1.6 2021/07/07 03:30:35 thorpej Exp $	*/
+/*	$NetBSD: patch.c,v 1.7 2021/07/13 01:59:10 thorpej Exp $	*/
 
 /*-
- * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * Copyright (c) 2007, 2021 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.6 2021/07/07 03:30:35 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.7 2021/07/13 01:59:10 thorpej Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -47,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.
 #include <machine/alpha.h>
 #include <machine/intr.h>
 
+#include <alpha/alpha/db_instruction.h>
+
 void	_membar_producer(void);
 void	_membar_producer_end(void);
 void	_membar_producer_mp(void);
@@ -60,7 +62,32 @@ void	_membar_sync_mp_end(void);
 extern char alpha_copystr_bwx[], alpha_copystr_bwx_end[];
 extern char alpha_copystr[], alpha_copystr_end[];
 
-static void __attribute__((__unused__))
+#if defined(MULTIPROCESSOR)
+extern uint32_t *lock_stub_patch_table[];
+
+static void
+patch_lock_stubs(void)
+{
+	alpha_instruction insn = {
+		.mem_format = {
+			.opcode = op_special,
+			.displacement = op_mb,
+		},
+	};
+	int i, s;
+
+	s = splhigh();
+
+	for (i = 0; lock_stub_patch_table[i] != NULL; i++) {
+		*lock_stub_patch_table[i] = insn.bits;
+	}
+	alpha_pal_imb();
+
+	splx(s);
+}
+#endif /* MULTIPROCESSOR */
+
+static void
 patchfunc(void *from_s, void *from_e, void *to_s, void *to_e)
 {
 	int s;
@@ -98,6 +125,8 @@ alpha_patch(bool is_mp)
 		KASSERT(curcpu()->ci_flags & CPUF_PRIMARY);
 		KASSERT((cpus_running & ~(1UL << cpu_number())) == 0);
 
+		patch_lock_stubs();
+
 		patchfunc(_membar_producer_mp, _membar_producer_mp_end,
 			  _membar_producer, _membar_producer_end);
 		patchfunc(_membar_sync_mp, _membar_sync_mp_end,

Reply via email to