Module Name:    src
Committed By:   matt
Date:           Wed Apr  8 18:10:08 UTC 2015

Modified Files:
        src/sys/arch/arm/arm: arm_machdep.c ast.c
        src/sys/arch/arm/include/arm32: frame.h
        src/sys/arch/arm/pic: pic.c

Log Message:
Don't clear CI_ASTPENDING in exception return, do it in ast() instead.
Add basic support for __HAVE_PREEMPTION.
Use atomic ops for ci_astpending if __HAVE_PREEMPTION is defined.
Use kpreempt_disable/kpreempt_enable


To generate a diff of this commit:
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/arm/arm/arm_machdep.c
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/arm/arm/ast.c
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/arm/include/arm32/frame.h
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/arm/pic/pic.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/arm/arm/arm_machdep.c
diff -u src/sys/arch/arm/arm/arm_machdep.c:1.45 src/sys/arch/arm/arm/arm_machdep.c:1.46
--- src/sys/arch/arm/arm/arm_machdep.c:1.45	Wed Apr  8 16:37:32 2015
+++ src/sys/arch/arm/arm/arm_machdep.c	Wed Apr  8 18:10:08 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm_machdep.c,v 1.45 2015/04/08 16:37:32 matt Exp $	*/
+/*	$NetBSD: arm_machdep.c,v 1.46 2015/04/08 18:10:08 matt Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.45 2015/04/08 16:37:32 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.46 2015/04/08 18:10:08 matt Exp $");
 
 #include <sys/exec.h>
 #include <sys/proc.h>
@@ -266,7 +266,7 @@ cpu_need_resched(struct cpu_info *ci, in
 #ifdef __HAVE_PREEMPTION
 		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
 		if (ci == cur_ci) {
-			ci->ci_astpending |= 2;
+			atomic_or_uint(&ci->ci_astpending, __BIT(1));
 		} else {
 			ipi = IPI_KPREEMPT;
 			goto send_ipi;
@@ -274,7 +274,11 @@ cpu_need_resched(struct cpu_info *ci, in
 #endif /* __HAVE_PREEMPTION */
 		return;
 	}
-	ci->ci_astpending |= 1;
+#ifdef __HAVE_PREEMPTION
+	atomic_or_uint(&ci->ci_astpending, __BIT(0));
+#else
+	ci->ci_astpending = __BIT(0);
+#endif
 #ifdef MULTIPROCESSOR
 	if (ci == curcpu() || !immed)
 		return;
@@ -321,3 +325,31 @@ arm_curcpu(void)
 	return curcpu();
 }
 #endif
+
+#ifdef __HAVE_PREEMPTION
+void
+cpu_set_curpri(int pri)
+{
+	kpreempt_disable();
+	curcpu()->ci_schedstate.spc_curpriority = pri;
+	kpreempt_enable();
+}
+
+bool
+cpu_kpreempt_enter(uintptr_t where, int s)
+{
+	return s == IPL_NONE;
+}
+
+void
+cpu_kpreempt_exit(uintptr_t where)
+{
+	atomic_and_uint(&curcpu()->ci_astpending, (unsigned int)~__BIT(1));
+}
+
+bool
+cpu_kpreempt_disabled(void)
+{
+	return curcpu()->ci_cpl != IPL_NONE;
+}
+#endif /* __HAVE_PREEMPTION */

Index: src/sys/arch/arm/arm/ast.c
diff -u src/sys/arch/arm/arm/ast.c:1.25 src/sys/arch/arm/arm/ast.c:1.26
--- src/sys/arch/arm/arm/ast.c:1.25	Wed Oct 29 10:56:19 2014
+++ src/sys/arch/arm/arm/ast.c	Wed Apr  8 18:10:08 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ast.c,v 1.25 2014/10/29 10:56:19 skrll Exp $	*/
+/*	$NetBSD: ast.c,v 1.26 2015/04/08 18:10:08 matt Exp $	*/
 
 /*
  * Copyright (c) 1994,1995 Mark Brinicombe
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ast.c,v 1.25 2014/10/29 10:56:19 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ast.c,v 1.26 2015/04/08 18:10:08 matt Exp $");
 
 #include "opt_ddb.h"
 
@@ -50,10 +50,11 @@ __KERNEL_RCSID(0, "$NetBSD: ast.c,v 1.25
 #include <sys/proc.h>
 #include <sys/acct.h>
 #include <sys/systm.h>
+#include <sys/atomic.h>
 #include <sys/kernel.h>
 #include <sys/signal.h>
-#include <sys/vmmeter.h>
 #include <sys/userret.h>
+#include <sys/vmmeter.h>
 
 #include <arm/locore.h>
 
@@ -76,11 +77,17 @@ userret(struct lwp *l)
 	 * If our ASID got released, access via TTBR0 will have been disabled.
 	 * So if it is disabled, activate the lwp again to get a new ASID.
 	 */
+#ifdef __HAVE_PREEMPTION
+	kpreempt_disable();
+#endif
 	KASSERT(curcpu()->ci_pmap_cur == l->l_proc->p_vmspace->vm_map.pmap);
-	if (armreg_ttbcr_read() & TTBCR_S_PD0) {
+	if (__predict_false(armreg_ttbcr_read() & TTBCR_S_PD0)) {
 		pmap_activate(l);
 	}
 	KASSERT(!(armreg_ttbcr_read() & TTBCR_S_PD0));
+#ifdef __HAVE_PREEMPTION
+	kpreempt_enable();
+#endif
 #endif
 
 	/* Invoke MI userret code */
@@ -116,12 +123,23 @@ ast(struct trapframe *tf)
 	KASSERT(VALID_R15_PSR(tf->tf_pc, tf->tf_spsr));
 #endif
 
-	curcpu()->ci_data.cpu_ntrap++;
-	//curcpu()->ci_data.cpu_nast++;
+#ifdef __HAVE_PREEEMPTION
+	kpreempt_disable();
+#endif
+	struct cpu_info * const ci = curcpu();
+
+	ci->ci_data.cpu_ntrap++;
 
-#ifdef DEBUG
-	KDASSERT(curcpu()->ci_cpl == IPL_NONE);
-#endif	
+	KDASSERT(ci->ci_cpl == IPL_NONE);
+#ifdef __HAVE_PREEEMPTION
+	atomic_and_uint(&ci->ci_astpending, ~__BIT(0));
+#else
+	ci->ci_astpending = 0;
+#endif
+	const int want_resched = ci->ci_want_resched;
+#ifdef __HAVE_PREEEMPTION
+	kpreempt_enable();
+#endif
 
 	if (l->l_pflag & LP_OWEUPC) {
 		l->l_pflag &= ~LP_OWEUPC;
@@ -129,8 +147,7 @@ ast(struct trapframe *tf)
 	}
 
 	/* Allow a forced task switch. */
-	if (l->l_cpu->ci_want_resched)
+	if (want_resched)
 		preempt();
-
 	userret(l);
 }

Index: src/sys/arch/arm/include/arm32/frame.h
diff -u src/sys/arch/arm/include/arm32/frame.h:1.40 src/sys/arch/arm/include/arm32/frame.h:1.41
--- src/sys/arch/arm/include/arm32/frame.h:1.40	Wed Apr  8 16:38:42 2015
+++ src/sys/arch/arm/include/arm32/frame.h	Wed Apr  8 18:10:08 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: frame.h,v 1.40 2015/04/08 16:38:42 matt Exp $	*/
+/*	$NetBSD: frame.h,v 1.41 2015/04/08 18:10:08 matt Exp $	*/
 
 /*
  * Copyright (c) 1994-1997 Mark Brinicombe.
@@ -213,9 +213,7 @@ void validate_trapframe(trapframe_t *, i
 	adr	lr, 3f							;\
 	B_CF_CONTROL(r2)		/* Set new CTRL reg value */	;\
 	/* NOTREACHED */						\
-2:	bic	r1, r1, #0x00000001					;\
-	str	r1, [r4, #CI_ASTPENDING] /* Clear astpending */		;\
-	CPSIE_I(r5, r5)			/* Restore interrupts */	;\
+2:	CPSIE_I(r5, r5)			/* Restore interrupts */	;\
 	mov	r0, sp							;\
 	bl	_C_LABEL(ast)		/* ast(frame) */		;\
 	CPSID_I(r0, r5)			/* Disable interrupts */	;\
@@ -240,8 +238,6 @@ void validate_trapframe(trapframe_t *, i
 1:	ldr	r1, [r4, #CI_ASTPENDING] /* Pending AST? */		;\
 	tst	r1, #0x00000001						;\
 	beq	2f			/* Nope. Just bail */		;\
-	bic	r1, r1, #0x00000001					;\
-	str	r1, [r4, #CI_ASTPENDING] /* Clear astpending */		;\
 	CPSIE_I(r5, r5)			/* Restore interrupts */	;\
 	mov	r0, sp							;\
 	bl	_C_LABEL(ast)		/* ast(frame) */		;\

Index: src/sys/arch/arm/pic/pic.c
diff -u src/sys/arch/arm/pic/pic.c:1.26 src/sys/arch/arm/pic/pic.c:1.27
--- src/sys/arch/arm/pic/pic.c:1.26	Sun Mar 29 00:31:30 2015
+++ src/sys/arch/arm/pic/pic.c	Wed Apr  8 18:10:08 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: pic.c,v 1.26 2015/03/29 00:31:30 matt Exp $	*/
+/*	$NetBSD: pic.c,v 1.27 2015/04/08 18:10:08 matt Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -33,7 +33,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.26 2015/03/29 00:31:30 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.27 2015/04/08 18:10:08 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -505,6 +505,12 @@ pic_do_pending_ints(register_t psw, int 
 			pic_list_unblock_irqs();
 		}
 	}
+#ifdef __HAVE_PREEEMPTION
+	if (newipl == IPL_NONE && (ci->ci_astpending & __BIT(1))) {
+		pic_set_priority(ci, IPL_SCHED);
+		kpreempt(0);
+	}
+#endif
 	if (ci->ci_cpl != newipl)
 		pic_set_priority(ci, newipl);
 }

Reply via email to