From b19d9defef17fd447813157b9e7fd8ad26a78cb2 Mon Sep 17 00:00:00 2001 From: Maxime Henrion Date: Fri, 22 Nov 2002 23:57:02 +0000 Subject: [PATCH] Under certain circumstances, we were calling kmem_free() from i386 cpu_thread_exit(). This resulted in a panic with WITNESS since we need to hold Giant to call kmem_free(), and we weren't helding it anymore in cpu_thread_exit(). We now do this from a new MD function, cpu_thread_dtor(), called by thread_dtor(). Approved by: re@ Suggested by: jhb --- sys/alpha/alpha/vm_machdep.c | 5 +++++ sys/amd64/amd64/vm_machdep.c | 30 +++++++++++++++++++----------- sys/i386/i386/vm_machdep.c | 30 +++++++++++++++++++----------- sys/ia64/ia64/vm_machdep.c | 5 +++++ sys/kern/kern_kse.c | 3 +++ sys/kern/kern_thread.c | 3 +++ sys/powerpc/aim/vm_machdep.c | 5 +++++ sys/powerpc/powerpc/vm_machdep.c | 5 +++++ sys/sparc64/sparc64/vm_machdep.c | 5 +++++ sys/sys/proc.h | 1 + 10 files changed, 70 insertions(+), 22 deletions(-) diff --git a/sys/alpha/alpha/vm_machdep.c b/sys/alpha/alpha/vm_machdep.c index 524daf51236..2f864388fc3 100644 --- a/sys/alpha/alpha/vm_machdep.c +++ b/sys/alpha/alpha/vm_machdep.c @@ -260,6 +260,11 @@ cpu_thread_exit(struct thread *td) return; } +void +cpu_thread_dtor(struct thread *td) +{ +} + void cpu_thread_setup(struct thread *td) { diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index ff991ef1bb1..14721f30603 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -272,17 +272,6 @@ cpu_thread_exit(struct thread *td) #ifdef DEV_NPX npxexit(td); #endif - if (pcb->pcb_ext != 0) { - /* XXXKSE XXXSMP not SMP SAFE.. what locks do we have? */ - /* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ - /* - * XXX do we need to move the TSS off the allocated pages - * before freeing them? (not done here) - */ - kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ext, - ctob(IOPAGES + 1)); - pcb->pcb_ext = 0; - } if (pcb->pcb_flags & PCB_DBREGS) { /* * disable all hardware breakpoints @@ -292,6 +281,25 @@ cpu_thread_exit(struct thread *td) } } +void +cpu_thread_dtor(struct thread *td) +{ + struct pcb *pcb; + + pcb = td->td_pcb; + if (pcb->pcb_ext != 0) { + /* XXXKSE XXXSMP not SMP SAFE.. what locks do we have? */ + /* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ + /* + * XXX do we need to move the TSS off the allocated pages + * before freeing them? (not done here) + */ + kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ext, + ctob(IOPAGES + 1)); + pcb->pcb_ext = 0; + } +} + void cpu_sched_exit(td) register struct thread *td; diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index ff991ef1bb1..14721f30603 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -272,17 +272,6 @@ cpu_thread_exit(struct thread *td) #ifdef DEV_NPX npxexit(td); #endif - if (pcb->pcb_ext != 0) { - /* XXXKSE XXXSMP not SMP SAFE.. what locks do we have? */ - /* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ - /* - * XXX do we need to move the TSS off the allocated pages - * before freeing them? (not done here) - */ - kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ext, - ctob(IOPAGES + 1)); - pcb->pcb_ext = 0; - } if (pcb->pcb_flags & PCB_DBREGS) { /* * disable all hardware breakpoints @@ -292,6 +281,25 @@ cpu_thread_exit(struct thread *td) } } +void +cpu_thread_dtor(struct thread *td) +{ + struct pcb *pcb; + + pcb = td->td_pcb; + if (pcb->pcb_ext != 0) { + /* XXXKSE XXXSMP not SMP SAFE.. what locks do we have? */ + /* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ + /* + * XXX do we need to move the TSS off the allocated pages + * before freeing them? (not done here) + */ + kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ext, + ctob(IOPAGES + 1)); + pcb->pcb_ext = 0; + } +} + void cpu_sched_exit(td) register struct thread *td; diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 6a634820c72..7bfdd76a98d 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -117,6 +117,11 @@ cpu_thread_exit(struct thread *td) { } +void +cpu_thread_dtor(struct thread *td) +{ +} + void cpu_thread_setup(struct thread *td) { diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 45ac5c09d29..cf17c08d0ed 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -115,6 +115,7 @@ thread_dtor(void *mem, int size, void *arg) { struct thread *td; + mtx_assert(&Giant, MA_OWNED); td = (struct thread *)mem; #ifdef INVARIANTS @@ -137,6 +138,8 @@ thread_dtor(void *mem, int size, void *arg) /* NOTREACHED */ } #endif + + cpu_thread_dtor(td); } /* diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 45ac5c09d29..cf17c08d0ed 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -115,6 +115,7 @@ thread_dtor(void *mem, int size, void *arg) { struct thread *td; + mtx_assert(&Giant, MA_OWNED); td = (struct thread *)mem; #ifdef INVARIANTS @@ -137,6 +138,8 @@ thread_dtor(void *mem, int size, void *arg) /* NOTREACHED */ } #endif + + cpu_thread_dtor(td); } /* diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 284a0317717..1e9d9bab817 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -353,6 +353,11 @@ cpu_thread_exit(struct thread *td) return; } +void +cpu_thread_dtor(struct thread *td) +{ +} + void cpu_thread_setup(struct thread *td) { diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index 284a0317717..1e9d9bab817 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -353,6 +353,11 @@ cpu_thread_exit(struct thread *td) return; } +void +cpu_thread_dtor(struct thread *td) +{ +} + void cpu_thread_setup(struct thread *td) { diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index ed011e3d32d..a3771d5ab83 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -113,6 +113,11 @@ cpu_thread_exit(struct thread *td) { } +void +cpu_thread_dtor(struct thread *td) +{ +} + void cpu_thread_setup(struct thread *td) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c04458ec744..04db3cdd411 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -905,6 +905,7 @@ void kse_free(struct kse *ke); void kse_stash(struct kse *ke); void cpu_set_upcall(struct thread *td, void *pcb); void cpu_set_upcall_kse(struct thread *td, struct kse *ke); +void cpu_thread_dtor(struct thread *); void cpu_thread_exit(struct thread *); void cpu_thread_setup(struct thread *td); void kse_reassign(struct kse *ke);