Subject: locking p_children, p_sibling and p_pptr
To: None <tech-smp@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: tech-smp
Date: 11/05/2003 14:19:51
I was trying to sort of an SMP safe method of locking the pointers
that link parent and child processes together.  

My initial thought was that I could use the p_lock field of the
parent to control the p_children/p_sibling list.  However I couldn't
decide whether to allow the p_lock to be grabbed parent then child or v.v.
Some code needed it one way, and some the other.

However digging deeper I realised that p_pptr cannot be followed unless
the same lock is held.  This makes it very tricky [1] to code proc_reparent()
unless a global lock is used.

The real 'fun' starts when you realise that a process, its real parent,
and a process tracing it could all be in sys_exit1() at the same time
(given the big_lock has been killed).

Although a separate spinlock could be used, the proclist_lock could be used.
(Actually everything except the 'allproc' and 'alllwp' lists would be
better with a simplelock.)

I also notice that schedcpu() does:
	LIST_FOREACH(l, &p->p_lwps, l_sibling)
without holding p->p_lock (was p->p_lwplock before I renamed it!).
So maybe the l_sibling list should be locked with proclist_lock.

The other option is to note that schedcpu() is really only interested
in runnable processes - so it could traverse the runqueues while holding
SCHED_LOCK().  This will give better scaling for systems with large numbers
of idle LWPs.

	David

[1] foul schemes with trylock and backoff-retry might work...

-- 
David Laight: david@l8s.co.uk