[PATCH 16/16] signal: Always call do_notify_parent_cldstop with siglock held

kernel test robot lkp at intel.com
Fri May 20 09:19:05 PDT 2022


Hi "Eric,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on next-20220518]
[cannot apply to linux/master powerpc/next wireless-next/main wireless/main linus/master v5.18-rc7 v5.18-rc6 v5.18-rc5 v5.18-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Eric-W-Biederman/signal-alpha-Remove-unused-definition-of-TASK_REAL_PARENT/20220519-065947
base:    736ee37e2e8eed7fe48d0a37ee5a709514d478b3
config: parisc-randconfig-s032-20220519 (https://download.01.org/0day-ci/archive/20220521/202205210010.E4Hyn2kD-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 11.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/intel-lab-lkp/linux/commit/4b66a617bf6d095d33fe43e9dbcfdf2e0de9fb29
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Eric-W-Biederman/signal-alpha-Remove-unused-definition-of-TASK_REAL_PARENT/20220519-065947
        git checkout 4b66a617bf6d095d33fe43e9dbcfdf2e0de9fb29
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=parisc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp at intel.com>


sparse warnings: (new ones prefixed by >>)
   kernel/signal.c: note: in included file (through arch/parisc/include/uapi/asm/signal.h, arch/parisc/include/asm/signal.h, include/uapi/linux/signal.h, ...):
   include/uapi/asm-generic/signal-defs.h:83:29: sparse: sparse: multiple address spaces given
   kernel/signal.c:195:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:195:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:195:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:198:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:198:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:198:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:480:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:480:9: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:480:9: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:484:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:484:34: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:484:34: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:542:53: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct k_sigaction *ka @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/signal.c:542:53: sparse:     expected struct k_sigaction *ka
   kernel/signal.c:542:53: sparse:     got struct k_sigaction [noderef] __rcu *
   include/uapi/asm-generic/signal-defs.h:83:29: sparse: sparse: multiple address spaces given
   kernel/signal.c:1261:9: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: cannot dereference this type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: cannot dereference this type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: cannot dereference this type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: cannot dereference this type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: cannot dereference this type
   kernel/signal.c:1267:29: sparse: sparse: no member 'ip' in struct pt_regs
   kernel/signal.c:1267:29: sparse: sparse: cast from unknown type
   kernel/signal.c:1267:29: sparse: sparse: incompatible types for 'case' statement
   kernel/signal.c:1267:29: sparse: sparse: incompatible types for 'case' statement
   kernel/signal.c:1267:29: sparse: sparse: incompatible types for 'case' statement
   kernel/signal.c:1267:29: sparse: sparse: incompatible types for 'case' statement
   kernel/signal.c:1328:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:1328:9: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:1328:9: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:1329:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct k_sigaction *action @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/signal.c:1329:16: sparse:     expected struct k_sigaction *action
   kernel/signal.c:1329:16: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/signal.c:1349:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:1349:34: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:1349:34: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:1938:36: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:1938:36: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:1938:36: sparse:     got struct spinlock [noderef] __rcu *
>> kernel/signal.c:2048:46: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *m_sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/signal.c:2048:46: sparse:     expected struct sighand_struct *m_sighand
   kernel/signal.c:2048:46: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/signal.c:2057:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/signal.c:2057:24: sparse:     expected struct task_struct *parent
   kernel/signal.c:2057:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/signal.c:2087:21: sparse: sparse: incompatible types in comparison expression (different address spaces):
>> kernel/signal.c:2087:21: sparse:    struct task_struct [noderef] __rcu *
>> kernel/signal.c:2087:21: sparse:    struct task_struct *
>> kernel/signal.c:2117:40: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/signal.c:2117:40: sparse:     expected struct task_struct *parent
   kernel/signal.c:2117:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/signal.c:2119:46: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *m_sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/signal.c:2119:46: sparse:     expected struct sighand_struct *m_sighand
   kernel/signal.c:2119:46: sparse:     got struct sighand_struct [noderef] __rcu *sighand
>> kernel/signal.c:2120:50: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *p_sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/signal.c:2120:50: sparse:     expected struct sighand_struct *p_sighand
   kernel/signal.c:2120:50: sparse:     got struct sighand_struct [noderef] __rcu *sighand
>> kernel/signal.c:2125:58: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *t_sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/signal.c:2125:58: sparse:     expected struct sighand_struct *t_sighand
   kernel/signal.c:2125:58: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/signal.c:2171:44: sparse: sparse: cast removes address space '__rcu' of expression
   kernel/signal.c:2190:65: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/signal.c:2190:65: sparse:     expected struct task_struct *tsk
   kernel/signal.c:2190:65: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/signal.c:2191:40: sparse: sparse: cast removes address space '__rcu' of expression
   kernel/signal.c:2209:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sighand_struct *psig @@     got struct sighand_struct [noderef] __rcu *[noderef] __rcu sighand @@
   kernel/signal.c:2209:14: sparse:     expected struct sighand_struct *psig
   kernel/signal.c:2209:14: sparse:     got struct sighand_struct [noderef] __rcu *[noderef] __rcu sighand
   kernel/signal.c:2238:53: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected struct task_struct *t @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/signal.c:2238:53: sparse:     expected struct task_struct *t
   kernel/signal.c:2238:53: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/signal.c:2239:34: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/signal.c:2239:34: sparse:     expected struct task_struct *parent
   kernel/signal.c:2239:34: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/signal.c:2269:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/signal.c:2269:24: sparse:     expected struct task_struct *parent
   kernel/signal.c:2269:24: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/signal.c:2272:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/signal.c:2272:24: sparse:     expected struct task_struct *parent
   kernel/signal.c:2272:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/signal.c:2307:17: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/signal.c:2307:17: sparse:     expected struct sighand_struct *sighand
   kernel/signal.c:2307:17: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/signal.c:2341:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2341:41: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2341:41: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2343:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2343:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2343:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2428:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2428:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2428:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2440:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2440:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2440:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2479:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2479:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2479:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2481:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2481:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2481:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2584:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2584:41: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2584:41: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2599:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2599:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2599:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2656:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2656:41: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2656:41: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2668:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:2668:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:2668:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:2726:49: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/signal.c:2726:49: sparse:     expected struct sighand_struct *sighand
   kernel/signal.c:2726:49: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/signal.c:3052:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3052:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3052:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3081:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3081:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3081:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3138:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3138:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3138:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3140:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3140:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3140:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3291:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3291:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3291:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3294:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3294:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3294:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3683:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3683:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3683:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3695:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3695:37: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3695:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3700:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3700:35: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3700:35: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:3705:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:3705:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:3705:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:4159:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:4159:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:4159:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:4171:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:4171:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:4171:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/signal.c:4189:11: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct k_sigaction *k @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/signal.c:4189:11: sparse:     expected struct k_sigaction *k
   kernel/signal.c:4189:11: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/signal.c:4191:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/signal.c:4191:25: sparse:     expected struct spinlock [usertype] *lock
   kernel/signal.c:4191:25: sparse:     got struct spinlock [noderef] __rcu *

vim +2048 kernel/signal.c

  1934	
  1935	void sigqueue_free(struct sigqueue *q)
  1936	{
  1937		unsigned long flags;
> 1938		spinlock_t *lock = &current->sighand->siglock;
  1939	
  1940		BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
  1941		/*
  1942		 * We must hold ->siglock while testing q->list
  1943		 * to serialize with collect_signal() or with
  1944		 * __exit_signal()->flush_sigqueue().
  1945		 */
  1946		spin_lock_irqsave(lock, flags);
  1947		q->flags &= ~SIGQUEUE_PREALLOC;
  1948		/*
  1949		 * If it is queued it will be freed when dequeued,
  1950		 * like the "regular" sigqueue.
  1951		 */
  1952		if (!list_empty(&q->list))
  1953			q = NULL;
  1954		spin_unlock_irqrestore(lock, flags);
  1955	
  1956		if (q)
  1957			__sigqueue_free(q);
  1958	}
  1959	
  1960	int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
  1961	{
  1962		int sig = q->info.si_signo;
  1963		struct sigpending *pending;
  1964		struct task_struct *t;
  1965		unsigned long flags;
  1966		int ret, result;
  1967	
  1968		BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
  1969	
  1970		ret = -1;
  1971		rcu_read_lock();
  1972		t = pid_task(pid, type);
  1973		if (!t || !likely(lock_task_sighand(t, &flags)))
  1974			goto ret;
  1975	
  1976		ret = 1; /* the signal is ignored */
  1977		result = TRACE_SIGNAL_IGNORED;
  1978		if (!prepare_signal(sig, t, false))
  1979			goto out;
  1980	
  1981		ret = 0;
  1982		if (unlikely(!list_empty(&q->list))) {
  1983			/*
  1984			 * If an SI_TIMER entry is already queue just increment
  1985			 * the overrun count.
  1986			 */
  1987			BUG_ON(q->info.si_code != SI_TIMER);
  1988			q->info.si_overrun++;
  1989			result = TRACE_SIGNAL_ALREADY_PENDING;
  1990			goto out;
  1991		}
  1992		q->info.si_overrun = 0;
  1993	
  1994		signalfd_notify(t, sig);
  1995		pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
  1996		list_add_tail(&q->list, &pending->list);
  1997		sigaddset(&pending->signal, sig);
  1998		complete_signal(sig, t, type);
  1999		result = TRACE_SIGNAL_DELIVERED;
  2000	out:
  2001		trace_signal_generate(sig, &q->info, t, type != PIDTYPE_PID, result);
  2002		unlock_task_sighand(t, &flags);
  2003	ret:
  2004		rcu_read_unlock();
  2005		return ret;
  2006	}
  2007	
  2008	/**
  2009	 * lock_parents_siglocks - Take current, real_parent, and parent's siglock
  2010	 * @lock_tracer: The tracers siglock is needed.
  2011	 *
  2012	 * There is no natural ordering to these locks so they must be sorted
  2013	 * before being taken.
  2014	 *
  2015	 * There are two complicating factors here:
  2016	 * - The locks live in sighand and sighand can be arbitrarily shared
  2017	 * - parent and real_parent can change when current's siglock is unlocked.
  2018	 *
  2019	 * To deal with this first the all of the sighand pointers are
  2020	 * gathered under current's siglock, and the sighand pointers are
  2021	 * sorted.  As siglock lives inside of sighand this also sorts the
  2022	 * siglock's by address.
  2023	 *
  2024	 * Then the siglocks are taken in order dropping current's siglock if
  2025	 * necessary.
  2026	 *
  2027	 * Finally if parent and real_parent have not changed return.
  2028	 * If they either parent has changed drop their locks and try again.
  2029	 *
  2030	 * Changing sighand is an infrequent and somewhat expensive operation
  2031	 * (unshare or exec) and so even in the worst case this loop
  2032	 * should not loop too many times before all of the proper locks are
  2033	 * taken in order.
  2034	 *
  2035	 * CONTEXT:
  2036	 * Must be called with @current->sighand->siglock held
  2037	 *
  2038	 * RETURNS:
  2039	 * current's, real_parent's, and parent's siglock held.
  2040	 */
  2041	static void lock_parents_siglocks(bool lock_tracer)
  2042		__releases(&current->sighand->siglock)
  2043		__acquires(&current->sighand->siglock)
  2044		__acquires(&current->real_parent->sighand->siglock)
  2045		__acquires(&current->parent->sighand->siglock)
  2046	{
  2047		struct task_struct *me = current;
> 2048		struct sighand_struct *m_sighand = me->sighand;
  2049	
  2050		lockdep_assert_held(&m_sighand->siglock);
  2051	
  2052		rcu_read_lock();
  2053		for (;;) {
  2054			struct task_struct *parent, *tracer;
  2055			struct sighand_struct *p_sighand, *t_sighand, *s1, *s2, *s3;
  2056	
  2057			parent = me->real_parent;
  2058			tracer = ptrace_parent(me);
  2059			if (!tracer || !lock_tracer)
  2060				tracer = parent;
  2061	
  2062			p_sighand = rcu_dereference(parent->sighand);
  2063			t_sighand = rcu_dereference(tracer->sighand);
  2064	
  2065			/* Sort the sighands so that s1 >= s2 >= s3 */
  2066			s1 = m_sighand;
  2067			s2 = p_sighand;
  2068			s3 = t_sighand;
  2069			if (s1 > s2)
  2070				swap(s1, s2);
  2071			if (s1 > s3)
  2072				swap(s1, s3);
  2073			if (s2 > s3)
  2074				swap(s2, s3);
  2075	
  2076			/* Take the locks in order */
  2077			if (s1 != m_sighand) {
  2078				spin_unlock(&m_sighand->siglock);
  2079				spin_lock(&s1->siglock);
  2080			}
  2081			if (s1 != s2)
  2082				spin_lock_nested(&s2->siglock, 1);
  2083			if (s2 != s3)
  2084				spin_lock_nested(&s3->siglock, 2);
  2085	
  2086			/* Verify the proper locks are held */
> 2087			if (likely((s1 == m_sighand) ||
  2088				   ((me->real_parent == parent) &&
  2089				    (me->parent == tracer) &&
  2090				    (parent->sighand == p_sighand) &&
  2091				    (tracer->sighand == t_sighand)))) {
  2092				break;
  2093			}
  2094	
  2095			/* Drop all but current's siglock */
  2096			if (p_sighand != m_sighand)
  2097				spin_unlock(&p_sighand->siglock);
  2098			if (t_sighand != p_sighand)
  2099				spin_unlock(&t_sighand->siglock);
  2100	
  2101			/*
  2102			 * Since [pt]_sighand will likely change if we go
  2103			 * around, and m_sighand is the only one held, make sure
  2104			 * it is subclass-0, since the above 's1 != m_sighand'
  2105			 * clause very much relies on that.
  2106			 */
  2107			lock_set_subclass(&m_sighand->siglock.dep_map, 0, _RET_IP_);
  2108		}
  2109		rcu_read_unlock();
  2110	}
  2111	
  2112	static void unlock_parents_siglocks(bool unlock_tracer)
  2113		__releases(&current->real_parent->sighand->siglock)
  2114		__releases(&current->parent->sighand->siglock)
  2115	{
  2116		struct task_struct *me = current;
> 2117		struct task_struct *parent = me->real_parent;
  2118		struct task_struct *tracer = ptrace_parent(me);
  2119		struct sighand_struct *m_sighand = me->sighand;
> 2120		struct sighand_struct *p_sighand = parent->sighand;
  2121	
  2122		if (p_sighand != m_sighand)
  2123			spin_unlock(&p_sighand->siglock);
  2124		if (tracer && unlock_tracer) {
> 2125			struct sighand_struct *t_sighand = tracer->sighand;
  2126			if (t_sighand != p_sighand)
  2127				spin_unlock(&t_sighand->siglock);
  2128		}
  2129	}
  2130	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp



More information about the linux-um mailing list