Module Name: src
Committed By: reinoud
Date: Fri Jan 6 12:54:59 UTC 2012
Modified Files:
src/sys/arch/usermode/dev: cpu.c
src/sys/arch/usermode/include: pcb.h
Log Message:
Cleanup stack allocation and freeing. This means the memory leak on lwp
destruction ought to be solved.
To generate a diff of this commit:
cvs rdiff -u -r1.61 -r1.62 src/sys/arch/usermode/dev/cpu.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/usermode/include/pcb.h
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/usermode/dev/cpu.c
diff -u src/sys/arch/usermode/dev/cpu.c:1.61 src/sys/arch/usermode/dev/cpu.c:1.62
--- src/sys/arch/usermode/dev/cpu.c:1.61 Wed Jan 4 15:18:57 2012
+++ src/sys/arch/usermode/dev/cpu.c Fri Jan 6 12:54:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.61 2012/01/04 15:18:57 reinoud Exp $ */
+/* $NetBSD: cpu.c,v 1.62 2012/01/06 12:54:59 reinoud Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <[email protected]>
@@ -30,7 +30,7 @@
#include "opt_hz.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.61 2012/01/04 15:18:57 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.62 2012/01/06 12:54:59 reinoud Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -278,22 +278,23 @@ cpu_lwp_free2(struct lwp *l)
if (pcb == NULL)
return;
- if (pcb->pcb_needfree) {
-#if 0
- free(pcb->pcb_ucp.uc_stack.ss_sp, M_TEMP);
+ if (pcb->pcb_stack_userland) {
+ free(pcb->pcb_stack_userland, M_TEMP);
+ pcb->pcb_stack_userland = NULL;
pcb->pcb_ucp.uc_stack.ss_sp = NULL;
pcb->pcb_ucp.uc_stack.ss_size = 0;
-#endif
+ }
- free(pcb->pcb_syscall_ucp.uc_stack.ss_sp, M_TEMP);
+ if (pcb->pcb_stack_syscall) {
+ free(pcb->pcb_stack_syscall, M_TEMP);
pcb->pcb_syscall_ucp.uc_stack.ss_sp = NULL;
pcb->pcb_syscall_ucp.uc_stack.ss_size = 0;
+ }
- free(pcb->pcb_pagefault_ucp.uc_stack.ss_sp, M_TEMP);
+ if (pcb->pcb_stack_pagefault) {
+ free(pcb->pcb_stack_pagefault, M_TEMP);
pcb->pcb_pagefault_ucp.uc_stack.ss_sp = NULL;
pcb->pcb_pagefault_ucp.uc_stack.ss_size = 0;
-
- pcb->pcb_needfree = false;
}
}
@@ -317,7 +318,6 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
{
struct pcb *pcb1 = lwp_getpcb(l1);
struct pcb *pcb2 = lwp_getpcb(l2);
- void *stack_ucp, *stack_syscall_ucp, *stack_pagefault_ucp;
#ifdef CPU_DEBUG
thunk_printf_debug("cpu_lwp_fork [%s/%p] -> [%s/%p] stack=%p stacksize=%d\n",
@@ -333,21 +333,20 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
memcpy(pcb2, pcb1, sizeof(struct pcb));
stacksize = 2*PAGE_SIZE;
- stack_ucp = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
- stack_syscall_ucp = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
- stack_pagefault_ucp = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
- pcb2->pcb_needfree = true;
-
- KASSERT(stack_ucp);
- KASSERT(stack_syscall_ucp);
- KASSERT(stack_pagefault_ucp);
+ pcb2->pcb_stack_userland = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
+ pcb2->pcb_stack_syscall = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
+ pcb2->pcb_stack_pagefault = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
+
+ KASSERT(pcb2->pcb_stack_userland);
+ KASSERT(pcb2->pcb_stack_syscall);
+ KASSERT(pcb2->pcb_stack_pagefault);
if (thunk_getcontext(&pcb2->pcb_ucp))
panic("getcontext failed");
/* set up the ucontext for the userland switch */
/* XXX BUG TODO when is this stack space freed? */
- pcb2->pcb_ucp.uc_stack.ss_sp = stack_ucp;
+ pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->pcb_stack_userland;
pcb2->pcb_ucp.uc_stack.ss_size = stacksize;
pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU;
pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp;
@@ -356,7 +355,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
3, &pcb2->pcb_ucp, func, arg);
/* set up the ucontext for the syscall */
- pcb2->pcb_syscall_ucp.uc_stack.ss_sp = stack_syscall_ucp;
+ pcb2->pcb_syscall_ucp.uc_stack.ss_sp = pcb2->pcb_stack_syscall;
pcb2->pcb_syscall_ucp.uc_stack.ss_size = stacksize;
pcb2->pcb_syscall_ucp.uc_flags = _UC_STACK | _UC_CPU;
pcb2->pcb_syscall_ucp.uc_link = &pcb2->pcb_userret_ucp;
@@ -364,7 +363,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
0, NULL, NULL, NULL);
/* set up the ucontext for the pagefault */
- pcb2->pcb_pagefault_ucp.uc_stack.ss_sp = stack_pagefault_ucp;
+ pcb2->pcb_pagefault_ucp.uc_stack.ss_sp = pcb2->pcb_stack_pagefault;
pcb2->pcb_pagefault_ucp.uc_stack.ss_size = stacksize;
pcb2->pcb_pagefault_ucp.uc_flags = _UC_STACK | _UC_CPU;
pcb2->pcb_pagefault_ucp.uc_link = &pcb2->pcb_trapret_ucp;
@@ -385,7 +384,6 @@ cpu_startup(void)
{
vaddr_t minaddr, maxaddr;
size_t stacksize, msgbufsize = 32 * 1024;
- void *stack_pagefault_ucp;
/* get ourself a message buffer */
um_msgbuf = kmem_zalloc(msgbufsize, KM_SLEEP);
@@ -415,9 +413,9 @@ cpu_startup(void)
/* set up the ucontext for the pagefault */
stacksize = 2*PAGE_SIZE;
- stack_pagefault_ucp = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
+ lwp0pcb.pcb_stack_pagefault = malloc(stacksize, M_TEMP, M_WAITOK | M_ZERO);
- lwp0pcb.pcb_pagefault_ucp.uc_stack.ss_sp = stack_pagefault_ucp;
+ lwp0pcb.pcb_pagefault_ucp.uc_stack.ss_sp = lwp0pcb.pcb_stack_pagefault;
lwp0pcb.pcb_pagefault_ucp.uc_stack.ss_size = stacksize;
lwp0pcb.pcb_pagefault_ucp.uc_flags = _UC_STACK | _UC_CPU;
lwp0pcb.pcb_pagefault_ucp.uc_link = &lwp0pcb.pcb_userret_ucp;
Index: src/sys/arch/usermode/include/pcb.h
diff -u src/sys/arch/usermode/include/pcb.h:1.15 src/sys/arch/usermode/include/pcb.h:1.16
--- src/sys/arch/usermode/include/pcb.h:1.15 Tue Jan 3 10:53:46 2012
+++ src/sys/arch/usermode/include/pcb.h Fri Jan 6 12:54:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.15 2012/01/03 10:53:46 reinoud Exp $ */
+/* $NetBSD: pcb.h,v 1.16 2012/01/06 12:54:59 reinoud Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <[email protected]>
@@ -40,13 +40,16 @@
//typedef ucontext_t trapframe;
struct pcb {
+ void *pcb_stack_userland;
+ void *pcb_stack_syscall;
+ void *pcb_stack_pagefault;
+
ucontext_t pcb_ucp; /* lwp switchframe */
ucontext_t pcb_syscall_ucp; /* syscall context */
ucontext_t pcb_userret_ucp; /* return to userland context */
ucontext_t pcb_pagefault_ucp; /* pagefault context */
ucontext_t pcb_trapret_ucp;
- bool pcb_needfree;
void * pcb_onfault; /* on fault handler */
int pcb_errno; /* save/restore place */