On Tue, 08 May 2001 08:21:55 -0700 (PDT),
John Baldwin <[EMAIL PROTECTED]> said:
John> On 08-May-01 Seigo Tanimura wrote:
>> Here is another issue. PROC_LOCK may block to acquire a process lock,
>> during which an event of interest may occur or the remaining time of
>> select(2)/poll(2) may run out. Thus if the remaining time runs out
>> during locking a process, we should first rescan file descriptors to
>> avoid missing an event, followed by returning the result.
John> Hmmm. Actually, can the nb_poll, ncp_poll, pollscan, or selscan functions call
John> tsleep/msleep? If they don't, then we are just better off holding proc lock
John> while we call them rather than releasing it just to call that function and
John> acquiring it later. Then we don't have to work around the race you describe.
Poling functions called via fo_poll in a file descriptor should not
call msleep(9) in theory.
That does not, however, necessarily imply that we can scan file
descriptors with holding a process lock. Another process can release a
reference to a file descriptor via closef() during polling the
descriptor by calling its fo_poll. In this case, fdrop() subsequent to
the call of fo_poll may result the reference count of the descriptor
to be zero.
Now the problem is whether it is easy or difficult to free a file
descriptor with holding a process lock. At the level of the file
descriptor layer, we can convert the memory allocator of a file
descriptor from malloc(9) to the zone allocator, which locks only the
zone state for file descriptors by a mutex.
It is a crucial issue to release an object underlying a file
descriptor. Releasing a vnode can result in calling msleep(9) for
locking the vnode in vrele(). Releasing a socket may end up with
calling tsleep(9) for draining data if SO_LINGER is set. Hence we
cannot scan file descriptors with holding a process lock for now.
John> Also, in the done_noproclock: case (might want to use 'unlock:' and 'done:'
John> instead of 'done:' and 'done_noproclock:' for label names instead) are you
John> always sure that when you go to that label you don't need to clear P_SELECT?
select(2) and poll(2) set P_SELECT below retry: and clear P_SELECT
upon occurrence of an event or timeout. There are no other places than
them for a process to set P_SELECT in its p_flag. Thus we can assume
at the entry of select(2) and poll(2) that P_SELECT is not set.
We go to done_noproclock if and only if either copyin() or sanity
check of arguments fails. As we do not poll any descriptors in this
case, it is not necessary to clear P_SELECT.
--
Seigo Tanimura <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message