Don't free specificdata in lwp_exit2(); it's not safe to block there.
Instead, free an LWP's specificdata from lwp_exit() (if it is not the last LWP) or exit1() (if it is the last LWP). For consistency, free the proc's specificdata from exit1() as well. Add lwp_finispecific() and proc_finispecific() functions to make this more convenient.
This commit is contained in:
parent
42951eac01
commit
12e8bb915e
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_exit.c,v 1.159 2006/09/23 15:36:12 xtraeme Exp $ */
|
||||
/* $NetBSD: kern_exit.c,v 1.160 2006/10/11 04:51:06 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
@ -74,7 +74,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.159 2006/09/23 15:36:12 xtraeme Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.160 2006/10/11 04:51:06 thorpej Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_perfctrs.h"
|
||||
@ -342,6 +342,13 @@ exit1(struct lwp *l, int rv)
|
||||
if (p->p_emul->e_proc_exit)
|
||||
(*p->p_emul->e_proc_exit)(p);
|
||||
|
||||
/*
|
||||
* Finalize the last LWP's specificdata, as well as the
|
||||
* specificdata for the proc itself.
|
||||
*/
|
||||
lwp_finispecific(l);
|
||||
proc_finispecific(p);
|
||||
|
||||
/*
|
||||
* Free the VM resources we're still holding on to.
|
||||
* We must do this from a valid thread because doing
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_lwp.c,v 1.44 2006/10/11 03:46:42 thorpej Exp $ */
|
||||
/* $NetBSD: kern_lwp.c,v 1.45 2006/10/11 04:51:06 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.44 2006/10/11 03:46:42 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.45 2006/10/11 04:51:06 thorpej Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
@ -435,8 +435,6 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lwpid_t *departed, int flags)
|
||||
simple_unlock(&p->p_lock);
|
||||
/* XXX decrement limits */
|
||||
|
||||
specificdata_fini(lwp_specificdata_domain,
|
||||
&l->l_specdataref);
|
||||
pool_put(&lwp_pool, l2);
|
||||
|
||||
return (0);
|
||||
@ -579,6 +577,8 @@ lwp_exit(struct lwp *l)
|
||||
* the entire process (if that's not already going on). We do
|
||||
* so with an exit status of zero, because it's a "controlled"
|
||||
* exit, and because that's what Solaris does.
|
||||
*
|
||||
* Note: the last LWP's specificdata will be deleted here.
|
||||
*/
|
||||
if (((p->p_nlwps - p->p_nzlwps) == 1) && ((p->p_flag & P_WEXIT) == 0)) {
|
||||
DPRINTF(("lwp_exit: %d.%d calling exit1()\n",
|
||||
@ -587,6 +587,9 @@ lwp_exit(struct lwp *l)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Delete the specificdata while it's still safe to sleep. */
|
||||
specificdata_fini(lwp_specificdata_domain, &l->l_specdataref);
|
||||
|
||||
s = proclist_lock_write();
|
||||
LIST_REMOVE(l, l_list);
|
||||
proclist_unlock_write(s);
|
||||
@ -650,7 +653,6 @@ lwp_exit2(struct lwp *l)
|
||||
|
||||
if (l->l_flag & L_DETACHED) {
|
||||
/* Nobody waits for detached LWPs. */
|
||||
specificdata_fini(lwp_specificdata_domain, &l->l_specdataref);
|
||||
pool_put(&lwp_pool, l);
|
||||
KERNEL_UNLOCK();
|
||||
} else {
|
||||
@ -772,8 +774,7 @@ int
|
||||
lwp_specific_key_create(specificdata_key_t *keyp, specificdata_dtor_t dtor)
|
||||
{
|
||||
|
||||
return (specificdata_key_create(lwp_specificdata_domain,
|
||||
keyp, dtor));
|
||||
return (specificdata_key_create(lwp_specificdata_domain, keyp, dtor));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -787,14 +788,30 @@ lwp_specific_key_delete(specificdata_key_t key)
|
||||
specificdata_key_delete(lwp_specificdata_domain, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* lwp_initspecific --
|
||||
* Initialize an LWP's specificdata container.
|
||||
*/
|
||||
void
|
||||
lwp_initspecific(struct lwp *l)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = specificdata_init(lwp_specificdata_domain, &l->l_specdataref);
|
||||
KASSERT(error == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* lwp_finispecific --
|
||||
* Finalize an LWP's specificdata container.
|
||||
*/
|
||||
void
|
||||
lwp_finispecific(struct lwp *l)
|
||||
{
|
||||
|
||||
specificdata_fini(lwp_specificdata_domain, &l->l_specdataref);
|
||||
}
|
||||
|
||||
/*
|
||||
* lwp_getspecific --
|
||||
* Return lwp-specific data corresponding to the specified key.
|
||||
@ -819,7 +836,7 @@ lwp_getspecific(specificdata_key_t key)
|
||||
* Set lwp-specific data corresponding to the specified key.
|
||||
*/
|
||||
void
|
||||
lwp_setspecific(struct lwp *l, specificdata_key_t key, void *data)
|
||||
lwp_setspecific(specificdata_key_t key, void *data)
|
||||
{
|
||||
|
||||
specificdata_setspecific(lwp_specificdata_domain,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_proc.c,v 1.97 2006/10/09 00:39:06 martin Exp $ */
|
||||
/* $NetBSD: kern_proc.c,v 1.98 2006/10/11 04:51:06 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
@ -69,7 +69,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.97 2006/10/09 00:39:06 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.98 2006/10/11 04:51:06 thorpej Exp $");
|
||||
|
||||
#include "opt_kstack.h"
|
||||
#include "opt_maxuprc.h"
|
||||
@ -664,8 +664,6 @@ proc_free_mem(struct proc *p)
|
||||
pid_t pid = p->p_pid;
|
||||
struct pid_table *pt;
|
||||
|
||||
specificdata_fini(proc_specificdata_domain, &p->p_specdataref);
|
||||
|
||||
s = proclist_lock_write();
|
||||
|
||||
pt = &pid_table[pid & pid_tbl_mask];
|
||||
@ -1295,8 +1293,7 @@ int
|
||||
proc_specific_key_create(specificdata_key_t *keyp, specificdata_dtor_t dtor)
|
||||
{
|
||||
|
||||
return (specificdata_key_create(proc_specificdata_domain,
|
||||
keyp, dtor));
|
||||
return (specificdata_key_create(proc_specificdata_domain, keyp, dtor));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1310,14 +1307,30 @@ proc_specific_key_delete(specificdata_key_t key)
|
||||
specificdata_key_delete(proc_specificdata_domain, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* proc_initspecific --
|
||||
* Initialize a proc's specificdata container.
|
||||
*/
|
||||
void
|
||||
proc_initspecific(struct proc *p)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = specificdata_init(proc_specificdata_domain, &p->p_specdataref);
|
||||
KASSERT(error == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* proc_finispecific --
|
||||
* Finalize a proc's specificdata container.
|
||||
*/
|
||||
void
|
||||
proc_finispecific(struct proc *p)
|
||||
{
|
||||
|
||||
specificdata_fini(proc_specificdata_domain, &p->p_specdataref);
|
||||
}
|
||||
|
||||
/*
|
||||
* proc_getspecific --
|
||||
* Return proc-specific data corresponding to the specified key.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lwp.h,v 1.44 2006/10/11 03:46:42 thorpej Exp $ */
|
||||
/* $NetBSD: lwp.h,v 1.45 2006/10/11 04:51:06 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -205,6 +205,7 @@ void lwp_update_creds(struct lwp *);
|
||||
int lwp_specific_key_create(specificdata_key_t *, specificdata_dtor_t);
|
||||
void lwp_specific_key_delete(specificdata_key_t);
|
||||
void lwp_initspecific(struct lwp *);
|
||||
void lwp_finispecific(struct lwp *);
|
||||
void * lwp_getspecific(specificdata_key_t);
|
||||
void lwp_setspecific(specificdata_key_t, void *);
|
||||
#endif /* _KERNEL */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: proc.h,v 1.229 2006/10/08 22:57:11 christos Exp $ */
|
||||
/* $NetBSD: proc.h,v 1.230 2006/10/11 04:51:06 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1986, 1989, 1991, 1993
|
||||
@ -520,6 +520,7 @@ void proc_crmod_enter(struct proc *);
|
||||
int proc_specific_key_create(specificdata_key_t *, specificdata_dtor_t);
|
||||
void proc_specific_key_delete(specificdata_key_t);
|
||||
void proc_initspecific(struct proc *);
|
||||
void proc_finispecific(struct proc *);
|
||||
void * proc_getspecific(struct proc *, specificdata_key_t);
|
||||
void proc_setspecific(struct proc *, specificdata_key_t, void *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user