mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-19 15:33:56 +00:00
Remove un-needed code.
Don't copyin() data we are about to overwrite. Add a flag to tell userland that KSE is officially "DONE" with the mailbox and has gone away. Obtained from: davidxu@
This commit is contained in:
parent
de7f8045e0
commit
2b035cbe5a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=115790
@ -422,21 +422,36 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
|
||||
struct proc *p;
|
||||
struct ksegrp *kg;
|
||||
struct kse *ke;
|
||||
struct kse_upcall *ku, *ku2;
|
||||
int error, count;
|
||||
|
||||
p = td->td_proc;
|
||||
if (td->td_upcall == NULL || TD_CAN_UNBIND(td))
|
||||
if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td))
|
||||
return (EINVAL);
|
||||
kg = td->td_ksegrp;
|
||||
/* Serialize removing upcall */
|
||||
count = 0;
|
||||
PROC_LOCK(p);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if ((kg->kg_numupcalls == 1) && (kg->kg_numthreads > 1)) {
|
||||
FOREACH_UPCALL_IN_GROUP(kg, ku2) {
|
||||
if (ku2->ku_flags & KUF_EXITING)
|
||||
count++;
|
||||
}
|
||||
if ((kg->kg_numupcalls - count) == 1 &&
|
||||
(kg->kg_numthreads > 1)) {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
return (EDEADLK);
|
||||
}
|
||||
ke = td->td_kse;
|
||||
ku->ku_flags |= KUF_EXITING;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
error = suword(&ku->ku_mailbox->km_flags, ku->ku_mflags|KMF_DONE);
|
||||
PROC_LOCK(p);
|
||||
if (error)
|
||||
psignal(p, SIGSEGV);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
upcall_remove(td);
|
||||
ke = td->td_kse;
|
||||
if (p->p_numthreads == 1) {
|
||||
kse_purge(p, td);
|
||||
p->p_flag &= ~P_THREADED;
|
||||
@ -720,41 +735,6 @@ kse_create(struct thread *td, struct kse_create_args *uap)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill a ucontext_t with a thread's context information.
|
||||
*
|
||||
* This is an analogue to getcontext(3).
|
||||
*/
|
||||
void
|
||||
thread_getcontext(struct thread *td, ucontext_t *uc)
|
||||
{
|
||||
|
||||
get_mcontext(td, &uc->uc_mcontext, 0);
|
||||
PROC_LOCK(td->td_proc);
|
||||
uc->uc_sigmask = td->td_sigmask;
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a thread's context from a ucontext_t.
|
||||
*
|
||||
* This is an analogue to setcontext(3).
|
||||
*/
|
||||
int
|
||||
thread_setcontext(struct thread *td, ucontext_t *uc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = set_mcontext(td, &uc->uc_mcontext);
|
||||
if (ret == 0) {
|
||||
SIG_CANTMASK(uc->uc_sigmask);
|
||||
PROC_LOCK(td->td_proc);
|
||||
td->td_sigmask = uc->uc_sigmask;
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize global thread allocation resources.
|
||||
*/
|
||||
@ -948,27 +928,25 @@ thread_export_context(struct thread *td)
|
||||
uintptr_t mbx;
|
||||
void *addr;
|
||||
int error,temp;
|
||||
ucontext_t uc;
|
||||
mcontext_t mc;
|
||||
|
||||
p = td->td_proc;
|
||||
kg = td->td_ksegrp;
|
||||
|
||||
/* Export the user/machine context. */
|
||||
addr = (void *)(&td->td_mailbox->tm_context);
|
||||
error = copyin(addr, &uc, sizeof(ucontext_t));
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
thread_getcontext(td, &uc);
|
||||
error = copyout(&uc, addr, sizeof(ucontext_t));
|
||||
if (error)
|
||||
get_mcontext(td, &mc, 0);
|
||||
addr = (void *)(&td->td_mailbox->tm_context.uc_mcontext);
|
||||
error = copyout(&mc, addr, sizeof(mcontext_t));
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
/* Exports clock ticks in kernel mode */
|
||||
addr = (caddr_t)(&td->td_mailbox->tm_sticks);
|
||||
temp = fuword(addr) + td->td_usticks;
|
||||
if (suword(addr, temp))
|
||||
if (suword(addr, temp)) {
|
||||
error = EFAULT;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Get address in latest mbox of list pointer */
|
||||
addr = (void *)(&td->td_mailbox->tm_next);
|
||||
|
@ -422,21 +422,36 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
|
||||
struct proc *p;
|
||||
struct ksegrp *kg;
|
||||
struct kse *ke;
|
||||
struct kse_upcall *ku, *ku2;
|
||||
int error, count;
|
||||
|
||||
p = td->td_proc;
|
||||
if (td->td_upcall == NULL || TD_CAN_UNBIND(td))
|
||||
if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td))
|
||||
return (EINVAL);
|
||||
kg = td->td_ksegrp;
|
||||
/* Serialize removing upcall */
|
||||
count = 0;
|
||||
PROC_LOCK(p);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if ((kg->kg_numupcalls == 1) && (kg->kg_numthreads > 1)) {
|
||||
FOREACH_UPCALL_IN_GROUP(kg, ku2) {
|
||||
if (ku2->ku_flags & KUF_EXITING)
|
||||
count++;
|
||||
}
|
||||
if ((kg->kg_numupcalls - count) == 1 &&
|
||||
(kg->kg_numthreads > 1)) {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
return (EDEADLK);
|
||||
}
|
||||
ke = td->td_kse;
|
||||
ku->ku_flags |= KUF_EXITING;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
error = suword(&ku->ku_mailbox->km_flags, ku->ku_mflags|KMF_DONE);
|
||||
PROC_LOCK(p);
|
||||
if (error)
|
||||
psignal(p, SIGSEGV);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
upcall_remove(td);
|
||||
ke = td->td_kse;
|
||||
if (p->p_numthreads == 1) {
|
||||
kse_purge(p, td);
|
||||
p->p_flag &= ~P_THREADED;
|
||||
@ -720,41 +735,6 @@ kse_create(struct thread *td, struct kse_create_args *uap)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill a ucontext_t with a thread's context information.
|
||||
*
|
||||
* This is an analogue to getcontext(3).
|
||||
*/
|
||||
void
|
||||
thread_getcontext(struct thread *td, ucontext_t *uc)
|
||||
{
|
||||
|
||||
get_mcontext(td, &uc->uc_mcontext, 0);
|
||||
PROC_LOCK(td->td_proc);
|
||||
uc->uc_sigmask = td->td_sigmask;
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a thread's context from a ucontext_t.
|
||||
*
|
||||
* This is an analogue to setcontext(3).
|
||||
*/
|
||||
int
|
||||
thread_setcontext(struct thread *td, ucontext_t *uc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = set_mcontext(td, &uc->uc_mcontext);
|
||||
if (ret == 0) {
|
||||
SIG_CANTMASK(uc->uc_sigmask);
|
||||
PROC_LOCK(td->td_proc);
|
||||
td->td_sigmask = uc->uc_sigmask;
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize global thread allocation resources.
|
||||
*/
|
||||
@ -948,27 +928,25 @@ thread_export_context(struct thread *td)
|
||||
uintptr_t mbx;
|
||||
void *addr;
|
||||
int error,temp;
|
||||
ucontext_t uc;
|
||||
mcontext_t mc;
|
||||
|
||||
p = td->td_proc;
|
||||
kg = td->td_ksegrp;
|
||||
|
||||
/* Export the user/machine context. */
|
||||
addr = (void *)(&td->td_mailbox->tm_context);
|
||||
error = copyin(addr, &uc, sizeof(ucontext_t));
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
thread_getcontext(td, &uc);
|
||||
error = copyout(&uc, addr, sizeof(ucontext_t));
|
||||
if (error)
|
||||
get_mcontext(td, &mc, 0);
|
||||
addr = (void *)(&td->td_mailbox->tm_context.uc_mcontext);
|
||||
error = copyout(&mc, addr, sizeof(mcontext_t));
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
/* Exports clock ticks in kernel mode */
|
||||
addr = (caddr_t)(&td->td_mailbox->tm_sticks);
|
||||
temp = fuword(addr) + td->td_usticks;
|
||||
if (suword(addr, temp))
|
||||
if (suword(addr, temp)) {
|
||||
error = EFAULT;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Get address in latest mbox of list pointer */
|
||||
addr = (void *)(&td->td_mailbox->tm_next);
|
||||
|
@ -88,6 +88,7 @@ struct kse_mailbox {
|
||||
/* These flags are kept in km_flags */
|
||||
#define KMF_NOUPCALL 0x01
|
||||
#define KMF_NOCOMPLETED 0x02
|
||||
#define KMF_DONE 0x04
|
||||
|
||||
#ifndef _KERNEL
|
||||
int kse_create(struct kse_mailbox *, int);
|
||||
|
@ -459,6 +459,7 @@ struct kse_upcall {
|
||||
};
|
||||
|
||||
#define KUF_DOUPCALL 0x00001 /* Do upcall now, don't wait */
|
||||
#define KUF_EXITING 0x00002 /* Upcall structure is exiting */
|
||||
|
||||
/*
|
||||
* Kernel-scheduled entity group (KSEG). The scheduler considers each KSEG to
|
||||
@ -900,11 +901,9 @@ struct thread *thread_alloc(void);
|
||||
void thread_exit(void) __dead2;
|
||||
int thread_export_context(struct thread *td);
|
||||
void thread_free(struct thread *td);
|
||||
void thread_getcontext(struct thread *td, ucontext_t *uc);
|
||||
void thread_link(struct thread *td, struct ksegrp *kg);
|
||||
void thread_reap(void);
|
||||
struct thread *thread_schedule_upcall(struct thread *td, struct kse_upcall *ku);
|
||||
int thread_setcontext(struct thread *td, ucontext_t *uc);
|
||||
int thread_single(int how);
|
||||
#define SINGLE_NO_EXIT 0 /* values for 'how' */
|
||||
#define SINGLE_EXIT 1
|
||||
|
Loading…
Reference in New Issue
Block a user