函数源码 |
Source File:fs\coredump.c |
Create Date:2022-07-29 11:06:11 |
首页 | Copyright©Brick |
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | static int zap_threads( struct task_struct *tsk, struct mm_struct *mm, struct core_state *core_state, int exit_code) { struct task_struct *g, *p; unsigned long flags; int nr = -EAGAIN; spin_lock_irq(&tsk->sighand->siglock); if (!signal_group_exit(tsk-> signal )) { mm->core_state = core_state; tsk-> signal ->group_exit_task = tsk; nr = zap_process(tsk, exit_code, 0); clear_tsk_thread_flag(tsk, TIF_SIGPENDING); } spin_unlock_irq(&tsk->sighand->siglock); if (unlikely(nr < 0)) return nr; tsk->flags |= PF_DUMPCORE; if (atomic_read(&mm->mm_users) == nr + 1) goto done; /* * We should find and kill all tasks which use this mm, and we should * count them correctly into ->nr_threads. We don't take tasklist * lock, but this is safe wrt: * * fork: * None of sub-threads can fork after zap_process(leader). All * processes which were created before this point should be * visible to zap_threads() because copy_process() adds the new * process to the tail of init_task.tasks list, and lock/unlock * of ->siglock provides a memory barrier. * * do_exit: * The caller holds mm->mmap_sem. This means that the task which * uses this mm can't pass exit_mm(), so it can't exit or clear * its ->mm. * * de_thread: * It does list_replace_rcu(&leader->tasks, ¤t->tasks), * we must see either old or new leader, this does not matter. * However, it can change p->sighand, so lock_task_sighand(p) * must be used. Since p->mm != NULL and we hold ->mmap_sem * it can't fail. * * Note also that "g" can be the old leader with ->mm == NULL * and already unhashed and thus removed from ->thread_group. * This is OK, __unhash_process()->list_del_rcu() does not * clear the ->next pointer, we will find the new leader via * next_thread(). */ rcu_read_lock(); for_each_process(g) { if (g == tsk->group_leader) continue ; if (g->flags & PF_KTHREAD) continue ; for_each_thread(g, p) { if (unlikely(!p->mm)) continue ; if (unlikely(p->mm == mm)) { lock_task_sighand(p, &flags); nr += zap_process(p, exit_code, SIGNAL_GROUP_EXIT); unlock_task_sighand(p, &flags); } break ; } } rcu_read_unlock(); done: atomic_set(&core_state->nr_threads, nr); return nr; } |