refactoring to send signal
This commit is contained in:
@ -804,19 +804,26 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
int ptracecont)
|
int ptracecont)
|
||||||
{
|
{
|
||||||
dkprintf("do_kill,pid=%d,tid=%d,sig=%d\n", pid, tid, sig);
|
dkprintf("do_kill,pid=%d,tid=%d,sig=%d\n", pid, tid, sig);
|
||||||
struct cpu_local_var *v;
|
|
||||||
struct thread *t;
|
struct thread *t;
|
||||||
|
struct process *tproc;
|
||||||
|
struct process *proc = thread? thread->proc: NULL;
|
||||||
struct thread *tthread = NULL;
|
struct thread *tthread = NULL;
|
||||||
int i;
|
int i;
|
||||||
__sigset_t mask;
|
__sigset_t mask;
|
||||||
struct list_head *head;
|
ihk_spinlock_t *savelock = NULL;
|
||||||
|
struct list_head *head = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
unsigned long irqstate = 0;
|
unsigned long irqstate = 0;
|
||||||
struct k_sigaction *k;
|
struct k_sigaction *k;
|
||||||
int doint;
|
int doint;
|
||||||
ihk_spinlock_t *savelock = NULL;
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
siginfo_t info0;
|
siginfo_t info0;
|
||||||
|
struct resource_set *rset = cpu_local_var(resource_set);
|
||||||
|
int hash;
|
||||||
|
struct thread_hash *thash = rset->thread_hash;
|
||||||
|
struct process_hash *phash = rset->process_hash;
|
||||||
|
struct mcs_rwlock_node lock;
|
||||||
|
struct mcs_rwlock_node updatelock;
|
||||||
|
|
||||||
if(sig > 64 || sig < 0)
|
if(sig > 64 || sig < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -829,10 +836,11 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(tid == -1 && pid <= 0){
|
if(tid == -1 && pid <= 0){
|
||||||
|
struct process *p;
|
||||||
|
struct mcs_rwlock_node_irqsave slock;
|
||||||
int pgid = -pid;
|
int pgid = -pid;
|
||||||
int rc = -ESRCH;
|
int rc = -ESRCH;
|
||||||
int *pids;
|
int *pids;
|
||||||
int i;
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int sendme = 0;
|
int sendme = 0;
|
||||||
|
|
||||||
@ -844,30 +852,21 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
pids = kmalloc(sizeof(int) * num_processors, IHK_MC_AP_NOWAIT);
|
pids = kmalloc(sizeof(int) * num_processors, IHK_MC_AP_NOWAIT);
|
||||||
if(!pids)
|
if(!pids)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
for(i = 0; i < num_processors; i++){
|
for(i = 0; i < HASH_SIZE; i++){
|
||||||
v = get_cpu_local_var(i);
|
mcs_rwlock_reader_lock(&phash->lock[i], &slock);
|
||||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
list_for_each_entry(p, &phash->list[i], hash_list){
|
||||||
list_for_each_entry(t, &(v->runq), sched_list){
|
if(pgid != 1 && p->pgid != pgid)
|
||||||
int j;
|
continue;
|
||||||
|
|
||||||
if(t->proc->pid <= 0)
|
if(thread && p->pid == thread->proc->pid){
|
||||||
continue;
|
|
||||||
if(pgid != 1 && t->proc->pgid != pgid)
|
|
||||||
continue;
|
|
||||||
if(thread && t->proc->pid == thread->proc->pid){
|
|
||||||
sendme = 1;
|
sendme = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(j = 0; j < n; j++)
|
pids[n] = p->pid;
|
||||||
if(pids[j] == t->proc->pid)
|
n++;
|
||||||
break;
|
|
||||||
if(j == n){
|
|
||||||
pids[n] = t->proc->pid;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
mcs_rwlock_reader_unlock(&phash->lock[i], &slock);
|
||||||
}
|
}
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
rc = do_kill(thread, pids[i], -1, sig, info, ptracecont);
|
rc = do_kill(thread, pids[i], -1, sig, info, ptracecont);
|
||||||
@ -877,130 +876,132 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
kfree(pids);
|
kfree(pids);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
irqstate = cpu_disable_interrupt_save();
|
irqstate = cpu_disable_interrupt_save();
|
||||||
mask = __sigmask(sig);
|
mask = __sigmask(sig);
|
||||||
if(tid == -1){
|
if(tid == -1){
|
||||||
struct thread *tthread0 = NULL;
|
struct thread *tthread0 = NULL;
|
||||||
ihk_spinlock_t *savelock0 = NULL;
|
struct mcs_rwlock_node plock;
|
||||||
|
struct mcs_rwlock_node updatelock;
|
||||||
|
|
||||||
for(i = 0; i < num_processors; i++){
|
found = 0;
|
||||||
v = get_cpu_local_var(i);
|
hash = process_hash(pid);
|
||||||
found = 0;
|
mcs_rwlock_reader_lock_noirq(&phash->lock[hash], &plock);
|
||||||
ihk_mc_spinlock_lock_noirq(&(v->runq_lock));
|
list_for_each_entry(tproc, &phash->list[hash], hash_list){
|
||||||
list_for_each_entry(t, &(v->runq), sched_list){
|
if(tproc->pid == pid){
|
||||||
if(t->proc->pid == pid){
|
found = 1;
|
||||||
if(t->tid == pid || tthread == NULL){
|
break;
|
||||||
if(!(mask & t->sigmask.__val[0])){
|
|
||||||
tthread = t;
|
|
||||||
if(!found && savelock) {
|
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
|
||||||
}
|
|
||||||
found = 1;
|
|
||||||
savelock = &(v->runq_lock);
|
|
||||||
if(savelock0 && savelock0 != savelock){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock0);
|
|
||||||
savelock0 = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(tthread == NULL && tthread0 == NULL){
|
|
||||||
tthread0 = t;
|
|
||||||
found = 1;
|
|
||||||
savelock0 = &(v->runq_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!(mask & t->sigmask.__val[0])){
|
|
||||||
if(t->tid == pid || tthread == NULL){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!found) {
|
}
|
||||||
ihk_mc_spinlock_unlock_noirq(&(v->runq_lock));
|
if(!found){
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&phash->lock[hash], &plock);
|
||||||
|
cpu_restore_interrupt(irqstate);
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
mcs_rwlock_reader_lock_noirq(&tproc->update_lock, &updatelock);
|
||||||
|
if(tproc->pstatus == PS_EXITED || tproc->pstatus == PS_ZOMBIE){
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
mcs_rwlock_reader_lock_noirq(&tproc->threads_lock, &lock);
|
||||||
|
list_for_each_entry(t, &tproc->threads_list, siblings_list){
|
||||||
|
if(t->tid == pid || tthread == NULL){
|
||||||
|
if(t->tstatus == PS_EXITED){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!(mask & t->sigmask.__val[0])){
|
||||||
|
tthread = t;
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
else if(tthread == NULL && tthread0 == NULL){
|
||||||
|
tthread0 = t;
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(tthread == NULL){
|
if(tthread == NULL){
|
||||||
tthread = tthread0;
|
tthread = tthread0;
|
||||||
savelock = savelock0;
|
|
||||||
}
|
}
|
||||||
}
|
if(tthread && tthread->tstatus != PS_EXITED){
|
||||||
else if(pid == -1){
|
savelock = &tthread->sigcommon->lock;
|
||||||
for(i = 0; i < num_processors; i++){
|
head = &tthread->sigcommon->sigpending;
|
||||||
v = get_cpu_local_var(i);
|
hold_thread(tthread);
|
||||||
found = 0;
|
|
||||||
ihk_mc_spinlock_lock_noirq(&(v->runq_lock));
|
|
||||||
list_for_each_entry(t, &(v->runq), sched_list){
|
|
||||||
if(t->proc->pid > 0 &&
|
|
||||||
t->tid == tid){
|
|
||||||
savelock = &(v->runq_lock);
|
|
||||||
found = 1;
|
|
||||||
tthread = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found)
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&(v->runq_lock));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
tthread = NULL;
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&tproc->threads_lock, &lock);
|
||||||
|
done:
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&tproc->update_lock, &updatelock);
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&phash->lock[hash], &plock);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
for(i = 0; i < num_processors; i++){
|
found = 0;
|
||||||
v = get_cpu_local_var(i);
|
hash = thread_hash(tid);
|
||||||
found = 0;
|
mcs_rwlock_reader_lock_noirq(&thash->lock[hash], &lock);
|
||||||
ihk_mc_spinlock_lock_noirq(&(v->runq_lock));
|
list_for_each_entry(tthread, &thash->list[hash], hash_list){
|
||||||
list_for_each_entry(t, &(v->runq), sched_list){
|
if(pid != -1 && tthread->proc->pid != pid){
|
||||||
if(t->proc->pid == pid &&
|
continue;
|
||||||
t->tid == tid){
|
|
||||||
savelock = &(v->runq_lock);
|
|
||||||
found = 1;
|
|
||||||
tthread = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(found)
|
if(tthread->tid == tid){
|
||||||
|
found = 1;
|
||||||
break;
|
break;
|
||||||
ihk_mc_spinlock_unlock_noirq(&(v->runq_lock));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!found){
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&thash->lock[hash], &lock);
|
||||||
|
cpu_restore_interrupt(irqstate);
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
tproc = tthread->proc;
|
||||||
|
mcs_rwlock_reader_lock_noirq(&tproc->update_lock, &updatelock);
|
||||||
|
savelock = &tthread->sigpendinglock;
|
||||||
|
head = &tthread->sigpending;
|
||||||
|
if(sig == SIGKILL ||
|
||||||
|
(tproc->pstatus != PS_EXITED &&
|
||||||
|
tproc->pstatus != PS_ZOMBIE &&
|
||||||
|
tthread->tstatus != PS_EXITED)){
|
||||||
|
hold_thread(tthread);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tthread = NULL;
|
||||||
|
}
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&tproc->update_lock, &updatelock);
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&thash->lock[hash], &lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tthread){
|
|
||||||
cpu_restore_interrupt(irqstate);
|
|
||||||
return -ESRCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sig != SIGCONT &&
|
if(sig != SIGCONT &&
|
||||||
thread &&
|
proc &&
|
||||||
thread->proc->euid != 0 &&
|
proc->euid != 0 &&
|
||||||
thread->proc->ruid != tthread->proc->ruid &&
|
proc->ruid != tproc->ruid &&
|
||||||
thread->proc->euid != tthread->proc->ruid &&
|
proc->euid != tproc->ruid &&
|
||||||
thread->proc->ruid != tthread->proc->suid &&
|
proc->ruid != tproc->suid &&
|
||||||
thread->proc->euid != tthread->proc->suid){
|
proc->euid != tproc->suid){
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
if(tthread)
|
||||||
|
release_thread(tthread);
|
||||||
cpu_restore_interrupt(irqstate);
|
cpu_restore_interrupt(irqstate);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sig == 0){
|
if(sig == 0 || tthread == NULL || tthread->tstatus == PS_EXITED){
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
if(tthread)
|
||||||
|
release_thread(tthread);
|
||||||
cpu_restore_interrupt(irqstate);
|
cpu_restore_interrupt(irqstate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
doint = 0;
|
doint = 0;
|
||||||
if(tid == -1){
|
|
||||||
ihk_mc_spinlock_lock_noirq(&tthread->sigcommon->lock);
|
ihk_mc_spinlock_lock_noirq(savelock);
|
||||||
head = &tthread->sigcommon->sigpending;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ihk_mc_spinlock_lock_noirq(&tthread->sigpendinglock);
|
|
||||||
head = &tthread->sigpending;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put signal event even when handler is SIG_IGN or SIG_DFL
|
/* Put signal event even when handler is SIG_IGN or SIG_DFL
|
||||||
because target ptraced thread must call ptrace_report_signal
|
because target ptraced thread must call ptrace_report_signal
|
||||||
in check_signal */
|
in check_signal */
|
||||||
rc = 0;
|
rc = 0;
|
||||||
k = tthread->sigcommon->action + sig - 1;
|
k = tthread->sigcommon->action + sig - 1;
|
||||||
if((sig != SIGKILL && (tthread->proc->ptrace & PT_TRACED)) ||
|
if((sig != SIGKILL && (tproc->ptrace & PT_TRACED)) ||
|
||||||
(k->sa.sa_handler != (void *)1 &&
|
(k->sa.sa_handler != (void *)1 &&
|
||||||
(k->sa.sa_handler != NULL ||
|
(k->sa.sa_handler != NULL ||
|
||||||
(sig != SIGCHLD && sig != SIGURG)))){
|
(sig != SIGCHLD && sig != SIGURG)))){
|
||||||
@ -1032,27 +1033,20 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ihk_mc_spinlock_unlock_noirq(savelock);
|
||||||
if(tid == -1){
|
cpu_restore_interrupt(irqstate);
|
||||||
ihk_mc_spinlock_unlock_noirq(&tthread->sigcommon->lock);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&tthread->sigpendinglock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doint && !(mask & tthread->sigmask.__val[0])) {
|
if (doint && !(mask & tthread->sigmask.__val[0])) {
|
||||||
int cpuid = tthread->cpu_id;
|
int cpuid = tthread->cpu_id;
|
||||||
int pid = tthread->proc->pid;
|
int pid = tproc->pid;
|
||||||
int status = tthread->tstatus;
|
int status = tthread->tstatus;
|
||||||
|
|
||||||
if (thread != tthread) {
|
if (thread != tthread) {
|
||||||
dkprintf("do_kill,ipi,pid=%d,cpu_id=%d\n",
|
dkprintf("do_kill,ipi,pid=%d,cpu_id=%d\n",
|
||||||
tthread->proc->pid, tthread->cpu_id);
|
tproc->pid, tthread->cpu_id);
|
||||||
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tthread->cpu_id)->apic_id, 0xd0);
|
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tthread->cpu_id)->apic_id, 0xd0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
|
||||||
cpu_restore_interrupt(irqstate);
|
|
||||||
if(!tthread->proc->nohost)
|
if(!tthread->proc->nohost)
|
||||||
interrupt_syscall(pid, cpuid);
|
interrupt_syscall(pid, cpuid);
|
||||||
|
|
||||||
@ -1067,10 +1061,7 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
release_thread(tthread);
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
|
||||||
cpu_restore_interrupt(irqstate);
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2090,7 +2090,7 @@ out:
|
|||||||
|
|
||||||
void hold_thread(struct thread *thread)
|
void hold_thread(struct thread *thread)
|
||||||
{
|
{
|
||||||
if (thread->proc->pstatus & (PS_ZOMBIE | PS_EXITED)) {
|
if (thread->tstatus == PS_EXITED) {
|
||||||
panic("hold_thread: already exited process");
|
panic("hold_thread: already exited process");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2130,15 +2130,15 @@ void destroy_thread(struct thread *thread)
|
|||||||
struct resource_set *resource_set = cpu_local_var(resource_set);
|
struct resource_set *resource_set = cpu_local_var(resource_set);
|
||||||
int hash;
|
int hash;
|
||||||
|
|
||||||
mcs_rwlock_writer_lock(&proc->threads_lock, &lock);
|
|
||||||
list_del(&thread->siblings_list);
|
|
||||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
|
||||||
|
|
||||||
hash = thread_hash(thread->tid);
|
hash = thread_hash(thread->tid);
|
||||||
mcs_rwlock_writer_lock(&resource_set->thread_hash->lock[hash], &lock);
|
mcs_rwlock_writer_lock(&resource_set->thread_hash->lock[hash], &lock);
|
||||||
list_del(&thread->hash_list);
|
list_del(&thread->hash_list);
|
||||||
mcs_rwlock_writer_unlock(&resource_set->thread_hash->lock[hash], &lock);
|
mcs_rwlock_writer_unlock(&resource_set->thread_hash->lock[hash], &lock);
|
||||||
|
|
||||||
|
mcs_rwlock_writer_lock(&proc->threads_lock, &lock);
|
||||||
|
list_del(&thread->siblings_list);
|
||||||
|
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||||
|
|
||||||
cpu_clear(thread->cpu_id, &thread->vm->cpu_set, &thread->vm->cpu_set_lock);
|
cpu_clear(thread->cpu_id, &thread->vm->cpu_set, &thread->vm->cpu_set_lock);
|
||||||
list_for_each_entry_safe(pending, signext, &thread->sigpending, list){
|
list_for_each_entry_safe(pending, signext, &thread->sigpending, list){
|
||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
@ -2801,7 +2801,7 @@ find_thread(int pid, int tid, struct mcs_rwlock_node_irqsave *lock)
|
|||||||
if(thread->tid == tid){
|
if(thread->tid == tid){
|
||||||
if(pid <= 0)
|
if(pid <= 0)
|
||||||
return thread;
|
return thread;
|
||||||
if(pid == thread->proc->pid)
|
if(thread->proc->pid == pid)
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2833,8 +2833,7 @@ find_process(int pid, struct mcs_rwlock_node_irqsave *lock)
|
|||||||
mcs_rwlock_reader_lock(&phash->lock[hash], lock);
|
mcs_rwlock_reader_lock(&phash->lock[hash], lock);
|
||||||
list_for_each_entry(proc, &phash->list[hash], hash_list){
|
list_for_each_entry(proc, &phash->list[hash], hash_list){
|
||||||
if(proc->pid == pid){
|
if(proc->pid == pid){
|
||||||
if(pid == proc->pid)
|
return proc;
|
||||||
return proc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mcs_rwlock_reader_unlock(&phash->lock[hash], lock);
|
mcs_rwlock_reader_unlock(&phash->lock[hash], lock);
|
||||||
|
|||||||
@ -606,6 +606,7 @@ terminate(int rc, int sig)
|
|||||||
do_kill(mythread, proc->pid, ids[i], SIGKILL, NULL, 0);
|
do_kill(mythread, proc->pid, ids[i], SIGKILL, NULL, 0);
|
||||||
}
|
}
|
||||||
kfree(ids);
|
kfree(ids);
|
||||||
|
ids = NULL;
|
||||||
}
|
}
|
||||||
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||||
|
|
||||||
@ -3527,7 +3528,14 @@ SYSCALL_DECLARE(exit)
|
|||||||
FUTEX_WAKE, 1, 0, NULL, 0, 0);
|
FUTEX_WAKE, 1, 0, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mcs_rwlock_reader_lock(&proc->threads_lock, &lock);
|
||||||
|
if(proc->pstatus == PS_EXITED){
|
||||||
|
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||||
|
terminate(exit_status, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
thread->tstatus = PS_EXITED;
|
thread->tstatus = PS_EXITED;
|
||||||
|
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||||
release_thread(thread);
|
release_thread(thread);
|
||||||
|
|
||||||
schedule();
|
schedule();
|
||||||
|
|||||||
Reference in New Issue
Block a user