This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/20372] New: New AIO request in child process after fork does not work


https://sourceware.org/bugzilla/show_bug.cgi?id=20372

            Bug ID: 20372
           Summary: New AIO request in child process after fork does not
                    work
           Product: glibc
           Version: 2.23
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: rkateja at cmu dot edu
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

Created attachment 9391
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9391&action=edit
Minimal C code to recreate the bug

One line description: Doing AIO concurrently before and after a fork
causes the IOs after the fork to be never queued.

Full Description: Consider the scenario.

1. A program issues an aio_read/aio_write
2. After the completion of the aio, the program forks
3. The child process issues an aio_read/aio_write

The aio code (from aio_misc.c) maintains a global variable
idle_thread_count. Also, aio threads idle for a period of 1 second (by
default) after completing the IO operation. During this one second,
the parent forks and the child gets the copy of the idle_thread_count
from the global data segment. When the child issues a fresh aio
request, the code sees that the idle_thread_count is greater than one
and signals a condition variable to wake up the thread. But of course,
there if no thread in the child process. Hence the AIO stays in the
EINPROGRESS state forever.

I think this might be fixed if the return value form the conditional
signalling is checked. Doing an aio_init in the child also doesn't
help because that function is basically a no-op if a global pointer
(pool) is not null. In the above scenario, since the parent had also
done some AIO, the global pointer is not null, and aio_init in the
child does not help. Moreover, the aio_init does not reset the
idle_thread_count, even if the global pool pointer is NULL. Another
possible solution is to improve the aio_init function and specify in
the man page that doing AIO with fork requires calling the aio_init
function in the child. Yet another solution is to allow the user to
set 0 as the aio_idle_timeout in the aio_init function. Then the
parent process can do the aio_init and no thread would ever be idle.

Keyword: AIO system, fork

Kernel: Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version
5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18
18:33:37 UTC 2016

Please find a minimal program to recreate the error attached. It first creates
and reads from a file in the parent, then it spawns a child which does the
same thing for a different file. The child's aio never completes. I had also
tried doing aio_init in the child to reset the context but that does not help
(not provided in the example).

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]