[PATCH] do_signal_stop: don't take tasklist_lock

do_signal_stop() does not need tasklist_lock anymore. So it does not need to
do misc re-checks, and we can simplify the code.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Oleg Nesterov and committed by
Linus Torvalds
a122b341 6108ccd3

+20 -55
+20 -55
kernel/signal.c
··· 1682 1682 * Returns nonzero if we've actually stopped and released the siglock. 1683 1683 * Returns zero if we didn't stop and still hold the siglock. 1684 1684 */ 1685 - static int 1686 - do_signal_stop(int signr) 1685 + static int do_signal_stop(int signr) 1687 1686 { 1688 1687 struct signal_struct *sig = current->signal; 1689 1688 struct sighand_struct *sighand = current->sighand; ··· 1702 1703 set_current_state(TASK_STOPPED); 1703 1704 if (stop_count == 0) 1704 1705 sig->flags = SIGNAL_STOP_STOPPED; 1705 - spin_unlock_irq(&sighand->siglock); 1706 1706 } 1707 1707 else if (thread_group_empty(current)) { 1708 1708 /* ··· 1710 1712 current->exit_code = current->signal->group_exit_code = signr; 1711 1713 set_current_state(TASK_STOPPED); 1712 1714 sig->flags = SIGNAL_STOP_STOPPED; 1713 - spin_unlock_irq(&sighand->siglock); 1714 1715 } 1715 1716 else { 1716 1717 /* 1718 + * (sig->group_stop_count == 0) 1717 1719 * There is no group stop already in progress. 1718 - * We must initiate one now, but that requires 1719 - * dropping siglock to get both the tasklist lock 1720 - * and siglock again in the proper order. Note that 1721 - * this allows an intervening SIGCONT to be posted. 1722 - * We need to check for that and bail out if necessary. 1720 + * We must initiate one now. 1723 1721 */ 1724 1722 struct task_struct *t; 1725 1723 1726 - spin_unlock_irq(&sighand->siglock); 1727 - 1728 - /* signals can be posted during this window */ 1729 - 1730 - read_lock(&tasklist_lock); 1731 - spin_lock_irq(&sighand->siglock); 1732 - 1733 - if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED)) { 1734 - /* 1735 - * Another stop or continue happened while we 1736 - * didn't have the lock. We can just swallow this 1737 - * signal now. If we raced with a SIGCONT, that 1738 - * should have just cleared it now. If we raced 1739 - * with another processor delivering a stop signal, 1740 - * then the SIGCONT that wakes us up should clear it. 1741 - */ 1742 - read_unlock(&tasklist_lock); 1743 - return 0; 1744 - } 1745 - 1746 - if (sig->group_stop_count == 0) { 1747 - sig->group_exit_code = signr; 1748 - stop_count = 0; 1749 - for (t = next_thread(current); t != current; 1750 - t = next_thread(t)) 1751 - /* 1752 - * Setting state to TASK_STOPPED for a group 1753 - * stop is always done with the siglock held, 1754 - * so this check has no races. 1755 - */ 1756 - if (!t->exit_state && 1757 - !(t->state & (TASK_STOPPED|TASK_TRACED))) { 1758 - stop_count++; 1759 - signal_wake_up(t, 0); 1760 - } 1761 - sig->group_stop_count = stop_count; 1762 - } 1763 - else { 1764 - /* A race with another thread while unlocked. */ 1765 - signr = sig->group_exit_code; 1766 - stop_count = --sig->group_stop_count; 1767 - } 1768 - 1769 1724 current->exit_code = signr; 1725 + sig->group_exit_code = signr; 1726 + 1727 + stop_count = 0; 1728 + for (t = next_thread(current); t != current; t = next_thread(t)) 1729 + /* 1730 + * Setting state to TASK_STOPPED for a group 1731 + * stop is always done with the siglock held, 1732 + * so this check has no races. 1733 + */ 1734 + if (!t->exit_state && 1735 + !(t->state & (TASK_STOPPED|TASK_TRACED))) { 1736 + stop_count++; 1737 + signal_wake_up(t, 0); 1738 + } 1739 + sig->group_stop_count = stop_count; 1740 + 1770 1741 set_current_state(TASK_STOPPED); 1771 1742 if (stop_count == 0) 1772 1743 sig->flags = SIGNAL_STOP_STOPPED; 1773 - 1774 - spin_unlock_irq(&sighand->siglock); 1775 - read_unlock(&tasklist_lock); 1776 1744 } 1777 1745 1746 + spin_unlock_irq(&sighand->siglock); 1778 1747 finish_stop(stop_count); 1779 1748 return 1; 1780 1749 }