Re: [PATCH] Describe race of direct read and fork for unaligned buffers

From: Michael Kerrisk (man-pages)
Date: Wed May 09 2012 - 03:18:34 EST


On Wed, May 9, 2012 at 7:01 PM, Nick Piggin <npiggin@xxxxxxxxx> wrote:
> On 9 May 2012 15:35, Michael Kerrisk (man-pages) <mtk.manpages@xxxxxxxxx> wrote:
>> On Wed, May 9, 2012 at 11:10 AM, Nick Piggin <npiggin@xxxxxxxxx> wrote:
>>> On 6 May 2012 01:29, KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxx> wrote:
>>>>> So, am I correct to assume that right text to add to the page is as below?
>>>>>
>>>>> Nick, can you clarify what you mean by "quiesced"?
>>>>
>>>> finished?
>>>
>>> Yes exactly. That might be a simpler word. Thanks!
>>
>> Thanks.
>>
>> But see below. I realize the text is still ambiguous.
>>
>>>>> [[
>>>>> O_DIRECT IOs should never be run concurrently with fork(2) system call,
>>>>> when the memory buffer is anonymous memory, or comes from mmap(2)
>>>>> with MAP_PRIVATE.
>>>>>
>>>>> Any such IOs, whether submitted with asynchronous IO interface or from
>>>>> another thread in the process, should be quiesced before fork(2) is called.
>>>>> Failure to do so can result in data corruption and undefined behavior in
>>>>> parent and child processes.
>>>>>
>>>>> This restriction does not apply when the memory buffer for the O_DIRECT
>>>>> IOs comes from mmap(2) with MAP_SHARED or from shmat(2).
>>>>> Nor does this restriction apply when the memory buffer has been advised
>>>>> as MADV_DONTFORK with madvise(2), ensuring that it will not be available
>>>>> to the child after fork(2).
>>>>> ]]
>>
>> In the above, the status of a MAP_SHARED MAP_ANONYMOUS buffer is
>> unclear. The first paragraph implies that such a buffer is unsafe,
>> while the third paragraph implies that it *is* safe, thus
>> contradicting the first paragraph. Which is correct?
>
> Yes I see. It's because MAP_SHARED | MAP_ANONYMOUS isn't *really*
> anonymous from the virtual memory subsystem's point of view. But that
> just serves to confuse userspace I guess.
>
> Anything with MAP_SHARED, shmat, or MADV_DONTFORK is OK.
>
> Anything else (MAP_PRIVATE, brk, without MADV_DONTFORK) is
> dangerous. These type are used by standard heap allocators malloc,
> new, etc.

So, would the following text be okay:

O_DIRECT I/Os should never be run concurrently with the fork(2)
system call, if the memory buffer is a private mapping (i.e.,
any mapping created with the mmap(2) MAP_PRIVATE flag; this
includes memory allocated on the heap and statically allocated
buffers). Any such I/Os, whether submitted via an asynchronous
I/O interface or from another thread in the process, should be
completed before fork(2) is called. Failure to do so can
result in data corruption and undefined behavior in parent and
child processes. This restriction does not apply when the memâ
ory buffer for the O_DIRECT I/Os was created using shmat(2) or
mmap(2) with the MAP_SHARED flag. Nor does this restriction
apply when the memory buffer has been advised as MADV_DONTFORK
with madvise(2), ensuring that it will not be available to the
child after fork(2).

Thanks,

Michael

--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/