unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Florian Weimer <fweimer@redhat.com>
To: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Carlos O'Donell <carlos@redhat.com>,  libc-alpha@sourceware.org
Subject: Re: [PATCH] nptl: Fix deadlock on atfork handler which calls dlclose (BZ#24595)
Date: Thu, 23 May 2019 19:31:20 +0200	[thread overview]
Message-ID: <87blztulg7.fsf@oldenburg2.str.redhat.com> (raw)
In-Reply-To: <77021a69-c1a9-b41a-4396-5201915e3fa3@linaro.org> (Adhemerval Zanella's message of "Thu, 23 May 2019 11:53:44 -0300")

* Adhemerval Zanella:

> We can go back to old behaviour of using a lock-free registration on the
> atfork lists, make a lock-free copy on fork, and handle the synchronization
> with __unregister_atfork using locks plus futexes.  It would require all the
> old complexity of mixing lock-free algorithms with locks accesses plus using 
> an unbounded alloca on fork (maybe we could just use malloc to allocate
> the backup list, my understanding it is avoid to to add another issue to
> make fork async-signal-safe).

I think we can avoid the async-signal-safety issue (for now) by not
using locks in single-threaded mode.  pthread_atfork is not required to
be async-signal-safe, so we need not worry about fork/pthread_at_fork
interactions in single-threaded processes, beyond the modification of
the handler list from the handler itself.

Maybe we can avoid making the copy for every fork call, using some sort
of copy-on-write list?  On the reader side, the protocol would look like
this:

  lock the fork handler mutex
    get pointer to the dynlist head from a global variable
    increment the reference counter next to the dynlist head
  unlock the fork handler mutex

  perform all the fork work, traversing the list as needed
  (without any locking)

  lock the fork handler mutex
    decrement the reference counter
    if the counter is zero, delocate the entire data structure
      (list and struct containing list head plus reference counter)
  unlock the fork handler mutex

On the registration/unregistration side (pthread_atfork,
__unregister_atfork), we would do this:

  lock the fork handler mutex
    get pointer to the dynlist head from the global variable
    if the reference counter is 1:
      modify the list in place
    else:
      make a modified copy of the list
      update the global variable to point to it
      decrement the reference counter in the original list
  unlock the fork handler mutex

(The reference counter in the quiet state would have to be 1, because
the list is referenced from the global variable.)

I think this is still simpler than the original scheme.  It also ensures
that we are not modifying the list during the traversal in fork.
Instead, we update a list that will be used for future forks.

What do you think?

Thanks,
Florian

  reply	other threads:[~2019-05-23 17:31 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-23 13:30 [PATCH] nptl: Fix deadlock on atfork handler which calls dlclose (BZ#24595) Adhemerval Zanella
2019-05-23 14:36 ` Carlos O'Donell
2019-05-23 14:53   ` Adhemerval Zanella
2019-05-23 17:31     ` Florian Weimer [this message]
2019-05-23 18:33       ` Adhemerval Zanella
2019-05-23 19:50         ` Florian Weimer
2019-05-23 23:46           ` Adhemerval Zanella
2019-05-24 11:06             ` Florian Weimer
2019-05-24 13:24               ` Adhemerval Zanella
2019-05-24 14:42                 ` Florian Weimer
2019-05-24 14:49                   ` Adhemerval Zanella
2019-07-08 13:11                     ` Florian Weimer
2019-07-12 18:05                       ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/libc/involved.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87blztulg7.fsf@oldenburg2.str.redhat.com \
    --to=fweimer@redhat.com \
    --cc=adhemerval.zanella@linaro.org \
    --cc=carlos@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).