Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 May 2001 20:23:30 +0900
From:      Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp>
To:        jhb@FreeBSD.org
Cc:        tanimura@r.dl.itc.u-tokyo.ac.jp, current@FreeBSD.org
Subject:   RE: New strategy of locking a process group
Message-ID:  <200105231123.f4NBNUD33639@rina.r.dl.itc.u-tokyo.ac.jp>
In-Reply-To: In your message of "Tue, 22 May 2001 07:56:52 -0700 (PDT)" <XFMail.010522075652.jhb@FreeBSD.org>
References:  <200105221258.f4MCwAD85296@rina.r.dl.itc.u-tokyo.ac.jp> <XFMail.010522075652.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 22 May 2001 07:56:52 -0700 (PDT),
  John Baldwin <jhb@FreeBSD.org> said:

John> On 22-May-01 Seigo Tanimura wrote:
>> On Tue, 22 May 2001 04:48:38 -0700 (PDT),
>> John Baldwin <jhb@FreeBSD.org> said:
>> 
John> On 22-May-01 Seigo Tanimura wrote:
>>>> For now, p_mtx protects p_pgrp in struct proc. This is quite
>>>> troublesome for the following reason:
>> 
John> Err, it doesn't really.  It's mostly undecided at this point.  Also, have you
John> looked at the BSD/OS code on builder?  They have process groups and sessions
John> already locked not using global locks but using per-data structure locks.
>> 
>> If you do not protect both p_pgrp and p_pglist in struct proc by an
>> identical lock, you end up with breaking either setpgid(2) or kill(2)
>> for a process group. The following scenario depicts an example of the
>> breakage:

John> I'll have to look over the code in more detail, but I would encourage you
John> to check the BSD/OS code.

I did that last night, and figured out that there are two problems in
FreeBSD under the scenario shown below:

1. Lock a process and obtain a process group via p_pgrp.
2. Lock the process list of the process group and traverse the list
   via p_pglist, locking each process in the list.
3. Lock each process in the list.

That scenario induces the following problems:

A. We have to lock two processes at once in order to traverse the
   list, namely p and LIST_NEXT(p, p_pglist) where p is a process in
   the list.

B. We have to lock a process in 1 and 3 while locking a process group
   in 2, resulting in lock order reversal.

BSD/OS solves the problem A by locking not a process but a process
group to traverse the list. It should be worth implementing that
solution in FreeBSD.

In order to solve the problem B, a lock other than the process lock
should protect p_pgrp. BSD/OS adopts the lock of a session accessible
via p_session embedded in struct proc, while I attempt to apply a
global lock. In any case, the aim of the p_pgrp lock is essentially
for protecting *only* p_pgrp. Once we lock p_pgrp, we can compare
pg_session (which requires no locks), lock a process group, a session
or etc. until unlocking p_pgrp.

The issue of both of the solutions briefed above is that the p_pgrp
lock protects *excess* data. It might be another solution to introduce
a new mutex (p_pgrpmtx) into struct proc to lock p_pgrp. Although
memory size costs per process, contention for p_pgrp lock should occur
much less than to adopt a session lock or a global lock.

As psignal() and some other functions also read p_pgrp, p_mtx should
also lock p_pgrp. You lock either p_pgrpmtx or p_mtx to read p_pgrp,
and both of the locks to modify p_pgrp.

-- 
Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp> <tanimura@FreeBSD.org>

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200105231123.f4NBNUD33639>