2007-08-31 12:13:37

by anon... anon.al

[permalink] [raw]
Subject: Nonblocking call may block in a mutex? Nonblocking call after poll may fail?

Hi!

This is a driver-related question on non-blocking writes and poll.

Setup:
there is a single output-buffer (in kernel-space) of 24 bytes for
writes from all processes A, B, and C: each process is restricted to
use at most 8 bytes: 8*3 = 24
(until that data is handled (interrupt-handler...))

Question:
If this output-buffer has "4-bytes space remaining for process A",
then a non-blocking write of process A could still encounter a locked
mutex, if process B is busy writing to the output-buffer.

Should process A now block/sleep until that mutex is free and it can
access the output-buffer (and it's 4 bytes space)?

What about a non-blocking (write-) poll of process A: if the poll call
succeeds (the output buffer has space remaining for process A), and
process A now performs a non-blocking write: what happens if A
encounters a blocked mutex, since process B is busy writing to the
output-buffer.
a) Should A block until the mutex is available?
b) Should A return -EAGAIN, even though the poll call succeeded?
c) Should it be impossible for this to happen! i.e. -> should process
A already "have" the mutex in question, when the poll call succeeds
(thus preventing B from writing to the output buffer)

For c) What if process A "has" the mutex, but never does the
non-blocking write. Then no process can write, since the mutex is held
by process A...


I'll appreciate any answer, or pointer to relevant information.

Thanks Albert


2007-08-31 14:25:30

by anon... anon.al

[permalink] [raw]
Subject: Re: Nonblocking call may block in a mutex? Nonblocking call after poll may fail?

On Aug 31, 2:20 pm, "anon... anon.al" <[email protected]> wrote:
> Setup:
> there is a single output-buffer (in kernel-space) of 24 bytes for
> writes from all processes A, B, and C: each process is restricted to
> use at most 8 bytes: 8*3 = 24
> (until that data is handled (interrupt-handler...))
>
> Question:
> If this output-buffer has "4-bytes space remaining for process A",
> then a non-blocking write of process A could still encounter a locked
> mutex, if process B is busy writing to the output-buffer.
>
> Should process A now block/sleep until that mutex is free and it can
> access the output-buffer (and it's 4 bytes space)?

Yes, it should sleep until the mutex is free.

This can be seen from a code snippet in LDD3 (Linux Device Drivers,
3rd ed.), on page 153:

http://lwn.net/images/pdf/LDD3/ch06.pdf#page=19&zoom=80,0,450


The code snippet in LDD3 does not contain the following before the while loop:

if (filp->f_flags & O_NONBLOCK) {
if (down_trylock(&dev->sem)) {
return -EAGAIN;
}
}

So a non-blocking process can also sleep (in down) if this type of
mutex is locked. It may however not block if the output-queue is full.

>
> What about a non-blocking (write-) poll of process A: if the poll call
> succeeds (the output buffer has space remaining for process A), and
> process A now performs a non-blocking write: what happens if A
> encounters a blocked mutex, since process B is busy writing to the
> output-buffer.
> a) Should A block until the mutex is available?
> b) Should A return -EAGAIN, even though the poll call succeeded?
> c) Should it be impossible for this to happen! i.e. -> should process
> A already "have" the mutex in question, when the poll call succeeds
> (thus preventing B from writing to the output buffer)
>
> For c) What if process A "has" the mutex, but never does the
> non-blocking write. Then no process can write, since the mutex is held
> by process A...
>

It cannot be b) (same reasoning as above).
But is it a) or c)...?

Regards,
Albert

2007-08-31 14:33:18

by Denys Vlasenko

[permalink] [raw]
Subject: Re: Nonblocking call may block in a mutex? Nonblocking call after poll may fail?

On Friday 31 August 2007 13:13, anon... anon.al wrote:
> Hi!
>
> This is a driver-related question on non-blocking writes and poll.
>
> Setup:
> there is a single output-buffer (in kernel-space) of 24 bytes for
> writes from all processes A, B, and C: each process is restricted to
> use at most 8 bytes: 8*3 = 24
> (until that data is handled (interrupt-handler...))
>
> Question:
> If this output-buffer has "4-bytes space remaining for process A",
> then a non-blocking write of process A could still encounter a locked
> mutex, if process B is busy writing to the output-buffer.
>
> Should process A now block/sleep until that mutex is free and it can
> access the output-buffer (and it's 4 bytes space)?
>
> What about a non-blocking (write-) poll of process A: if the poll call
> succeeds (the output buffer has space remaining for process A), and
> process A now performs a non-blocking write: what happens if A
> encounters a blocked mutex, since process B is busy writing to the
> output-buffer.
> a) Should A block until the mutex is available?

If mutex cannot be locked by B indefinitely, yes.
If it can be locked indefinitely, then obviosly no.

> b) Should A return -EAGAIN, even though the poll call succeeded?

Succeeding poll is no guarantee against getting EAGAIN.
When poll succeeds, it means "you _maybe_ can write now".

> c) Should it be impossible for this to happen! i.e. -> should process
> A already "have" the mutex in question, when the poll call succeeds
> (thus preventing B from writing to the output buffer)

No. Kernel cannot know whether A will do the write at all.

> For c) What if process A "has" the mutex, but never does the
> non-blocking write. Then no process can write, since the mutex is held
> by process A...

Exactly. (c) would be kernel bug.
--
vda

2007-08-31 21:34:18

by David Schwartz

[permalink] [raw]
Subject: RE: Nonblocking call may block in a mutex? Nonblocking call after poll may fail?


> If this output-buffer has "4-bytes space remaining for process A",
> then a non-blocking write of process A could still encounter a locked
> mutex, if process B is busy writing to the output-buffer.

Of course.

> Should process A now block/sleep until that mutex is free and it can
> access the output-buffer (and it's 4 bytes space)?

That depends on how long the other process might hold the mutex. If it's
just the time it takes to copy the buffer and do fast things, then it should
wait. If it might be a long time, then it's probably better not to block, as
the process requested.

> What about a non-blocking (write-) poll of process A: if the poll call
> succeeds (the output buffer has space remaining for process A), and
> process A now performs a non-blocking write: what happens if A
> encounters a blocked mutex, since process B is busy writing to the
> output-buffer.
> a) Should A block until the mutex is available?

Probably, unless the mutex is one that could be held for a very long time.
It really depends upon what semantics make sense with your driver. Is the
wait so short it should be considered not blocking or is it potentially long
enough that it should be avoided?

A non-blocking call does not mean it must never ever lose the CPU at all
under any circumstances. It just means no waits for "too long".

> b) Should A return -EAGAIN, even though the poll call succeeded?

If the wait would be for too long, then yes.

> c) Should it be impossible for this to happen! i.e. -> should process
> A already "have" the mutex in question, when the poll call succeeds
> (thus preventing B from writing to the output buffer)

No. Functions like 'poll' and 'select' are just status-reporting functions.
They should not change the semantics of other operations unless that's
unavoidable.

> For c) What if process A "has" the mutex, but never does the
> non-blocking write. Then no process can write, since the mutex is held
> by process A...

Right. That's why return values from 'poll' and 'select' don't guarantee
future behavior.

DS