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 <jmcne...@invisible.ca>
@@ -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 <jmcne...@invisible.ca>
@@ -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 */

Reply via email to