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);
}