Prevent sa_newcachelwp() from creating new LWPs when the process is exiting.
This should fix PR 23418 which was also reported by Thomas Klausner and Ian Fry (who also provided core dumps for analysis - thanks!). Also g/c sa_yieldcall since it's now safe to put LWPs back into the cache. Also return stacks in failure case.
This commit is contained in:
parent
0342c9586a
commit
e2c29624f5
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: kern_sa.c,v 1.41 2003/11/07 18:37:41 cl Exp $ */
|
/* $NetBSD: kern_sa.c,v 1.42 2003/11/12 21:27:46 cl Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.41 2003/11/07 18:37:41 cl Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.42 2003/11/12 21:27:46 cl Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -750,31 +750,34 @@ sa_switch(struct lwp *l, int type)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa->sa_nstacks == 0) {
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
printf("sa_switch(%d.%d flag %x): Not enough stacks.\n",
|
||||||
|
p->p_pid, l->l_lid, l->l_flag);
|
||||||
|
#endif
|
||||||
|
sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
|
||||||
|
mi_switch(l, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX We need to allocate the sadata_upcall structure here,
|
* XXX We need to allocate the sadata_upcall structure here,
|
||||||
* XXX since we can't sleep while waiting for memory inside
|
* XXX since we can't sleep while waiting for memory inside
|
||||||
* XXX sa_upcall(). It would be nice if we could safely
|
* XXX sa_upcall(). It would be nice if we could safely
|
||||||
* XXX allocate the sadata_upcall structure on the stack, here.
|
* XXX allocate the sadata_upcall structure on the stack, here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (sa->sa_nstacks == 0) {
|
|
||||||
#ifdef DIAGNOSTIC
|
|
||||||
printf("sa_switch(%d.%d flag %x): Not enough stacks.\n",
|
|
||||||
p->p_pid, l->l_lid, l->l_flag);
|
|
||||||
#endif
|
|
||||||
goto sa_upcall_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
sau = sadata_upcall_alloc(0);
|
sau = sadata_upcall_alloc(0);
|
||||||
if (sau == NULL) {
|
if (sau == NULL) {
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
printf("sa_switch(%d.%d): "
|
printf("sa_switch(%d.%d): "
|
||||||
"couldn't allocate upcall data.\n",
|
"couldn't allocate upcall data.\n",
|
||||||
p->p_pid, l->l_lid);
|
p->p_pid, l->l_lid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
goto sa_upcall_failed;
|
sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
|
||||||
|
mi_switch(l, NULL);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
st = sa->sa_stacks[--sa->sa_nstacks];
|
st = sa->sa_stacks[--sa->sa_nstacks];
|
||||||
DPRINTFN(9,("sa_switch(%d.%d) nstacks-- = %2d\n",
|
DPRINTFN(9,("sa_switch(%d.%d) nstacks-- = %2d\n",
|
||||||
l->l_proc->p_pid, l->l_lid, sa->sa_nstacks));
|
l->l_proc->p_pid, l->l_lid, sa->sa_nstacks));
|
||||||
|
@ -787,7 +790,10 @@ sa_switch(struct lwp *l, int type)
|
||||||
printf("sa_switch(%d.%d): Error %d from sa_upcall()\n",
|
printf("sa_switch(%d.%d): Error %d from sa_upcall()\n",
|
||||||
p->p_pid, l->l_lid, error);
|
p->p_pid, l->l_lid, error);
|
||||||
#endif
|
#endif
|
||||||
goto sa_upcall_failed;
|
sa->sa_stacks[sa->sa_nstacks++] = st;
|
||||||
|
sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
|
||||||
|
mi_switch(l, NULL);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -842,13 +848,6 @@ sa_switch(struct lwp *l, int type)
|
||||||
} else {
|
} else {
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
panic("sa_vp empty");
|
panic("sa_vp empty");
|
||||||
|
|
||||||
sa_upcall_failed:
|
|
||||||
cpu_setfunc(l2, sa_yieldcall, l2);
|
|
||||||
|
|
||||||
l2->l_priority = l2->l_usrpri;
|
|
||||||
setrunnable(l2);
|
|
||||||
PRELE(l2); /* Remove the artificial hold-count */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTFN(4,("sa_switch(%d.%d) switching to LWP %d.\n",
|
DPRINTFN(4,("sa_switch(%d.%d) switching to LWP %d.\n",
|
||||||
|
@ -888,31 +887,6 @@ sa_switchcall(void *arg)
|
||||||
upcallret(l);
|
upcallret(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
sa_yieldcall(void *arg)
|
|
||||||
{
|
|
||||||
struct lwp *l;
|
|
||||||
struct proc *p;
|
|
||||||
struct sadata *sa;
|
|
||||||
|
|
||||||
l = arg;
|
|
||||||
p = l->l_proc;
|
|
||||||
sa = p->p_sa;
|
|
||||||
sa->sa_vp = l;
|
|
||||||
|
|
||||||
DPRINTFN(6,("sa_yieldcall(%d.%d)\n", p->p_pid, l->l_lid));
|
|
||||||
|
|
||||||
if (LIST_EMPTY(&sa->sa_lwpcache)) {
|
|
||||||
/* Allocate the next cache LWP */
|
|
||||||
DPRINTFN(6,("sa_yieldcall(%d.%d) allocating LWP\n",
|
|
||||||
p->p_pid, l->l_lid));
|
|
||||||
sa_newcachelwp(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
sa_yield(l);
|
|
||||||
upcallret(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sa_newcachelwp(struct lwp *l)
|
sa_newcachelwp(struct lwp *l)
|
||||||
{
|
{
|
||||||
|
@ -923,6 +897,8 @@ sa_newcachelwp(struct lwp *l)
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
p = l->l_proc;
|
p = l->l_proc;
|
||||||
|
if (p->p_flag & P_WEXIT)
|
||||||
|
return (0);
|
||||||
|
|
||||||
inmem = uvm_uarea_alloc(&uaddr);
|
inmem = uvm_uarea_alloc(&uaddr);
|
||||||
if (__predict_false(uaddr == 0)) {
|
if (__predict_false(uaddr == 0)) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: savar.h,v 1.11 2003/11/03 22:34:51 cl Exp $ */
|
/* $NetBSD: savar.h,v 1.12 2003/11/12 21:27:46 cl Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -116,7 +116,6 @@ void sa_switch(struct lwp *, int);
|
||||||
void sa_preempt(struct lwp *);
|
void sa_preempt(struct lwp *);
|
||||||
void sa_yield(struct lwp *);
|
void sa_yield(struct lwp *);
|
||||||
void sa_switchcall(void *);
|
void sa_switchcall(void *);
|
||||||
void sa_yieldcall(void *);
|
|
||||||
int sa_upcall(struct lwp *, int, struct lwp *, struct lwp *, size_t, void *);
|
int sa_upcall(struct lwp *, int, struct lwp *, struct lwp *, size_t, void *);
|
||||||
int sa_upcall0(struct lwp *, int, struct lwp *, struct lwp *,
|
int sa_upcall0(struct lwp *, int, struct lwp *, struct lwp *,
|
||||||
size_t, void *, struct sadata_upcall *, stack_t *);
|
size_t, void *, struct sadata_upcall *, stack_t *);
|
||||||
|
|
Loading…
Reference in New Issue