All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Wilck <mwilck@suse.com>
To: Benjamin Marzinski <bmarzins@redhat.com>
Cc: lixiaokeng@huawei.com, dm-devel@redhat.com,
	Zdenek Kabelac <zkabelac@redhat.com>
Subject: Re: [PATCH 10/19] libmultipath: devmapper: refactor libdm version determination
Date: Mon, 21 Sep 2020 10:35:34 +0200	[thread overview]
Message-ID: <1cb705785cf5d77b89002135b9411900fb82b630.camel@suse.com> (raw)
In-Reply-To: <20200919221422.GW11108@octiron.msp.redhat.com>

On Sat, 2020-09-19 at 17:14 -0500, Benjamin Marzinski wrote:
> On Wed, Sep 16, 2020 at 05:37:09PM +0200, mwilck@suse.com wrote:
> > From: Martin Wilck <mwilck@suse.com>
> > 
> > As one step towards bundling all possibly racy libdm init calls
> > into a single
> > function, split the code for determining and checking versions of
> > libdm and kernel components. Provide a generic helper
> > libmp_get_version() that makes sure the versions are "lazily"
> > initialized.
> > Note that retrieving the versions requires libdm calls, thus the
> > version initialization calls libdm initialization, which might call
> > version initialization recursively. But that's not an issue, as
> > the initialization is protected by pthread_once().
> 
> This is confusing me. dm_tgt_version will call
> DM_DEVICE_LIST_VERSIONS,
> but it doesn't call libmp_dm_task_create(), so I don't see the
> recursion
> possiblity. 

You are right, I was confused. 
The callstack for "lazy" initialization looks like this:

libmp_dm_task_create
  pthread_once(&dm_initialized, libmp_dm_init);
    libmp_dm_init()
=>    dm_prereq()
        init_versions
          pthread_once(&versions_initialized, _init_versions);
            _init_versions()
              init_dm_library_version()
              init_dm_drv_version()
              init_dm_mpath_version()
                dm_tgt_version
**                dm_task_create
                  libmp_task_run()
                    pthread_mutex_lock(&libmp_dm_lock);
                    dm_task_run()

(If an application called dm_prereq() explicitly, it would enter
the stack at "=>", which would be less of a problem).

I suppose I should add a comment at "**" saying that we must not call
libmp_dm_task_create() there to avoid recursion. I also notice that my
function naming I used is inconsistent; it should be
libmp_dm_task_run() rather than just libmp_task_run().

> That's good because according to the man page:
> 
> "If you specify a routine that directly or indirectly results in a
> recursive call to pthread_once(3) and that specifies the same routine
> argument, the recursive call can result in a deadlock."

Thanks for pointing this out. I had missed that indeed.

I see this paragraph only in some old DECThreads man pages on the web.
There's a slighly different "APPLICATION USAGE" statement under 
https://pubs.opengroup.org/onlinepubs/9699919799/. The pragraph is
missing in https://man7.org/linux/man-pages/man3/pthread_once.3p.html,
which is still based on POSIX.1-2008, 2013 edition - that's why I
missed it.

Anyway, it makes sense, because pthread_once() guarantees that the init
routine has _finished_ when it returns, which can't work with recursive
calls.

Anyway, I'll send a v2.

Regards
Martin

  reply	other threads:[~2020-09-21  8:35 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-16 15:36 [PATCH 00/19] multipath-tools: shutdown, libdevmapper races, globals mwilck
2020-09-16 15:37 ` [PATCH 01/19] multipathd: allow shutdown during configure() mwilck
2020-09-16 15:37 ` [PATCH 02/19] multipathd: avoid sending "READY=1" to systemd on early shutdown mwilck
2020-09-16 15:37 ` [PATCH 03/19] multipathd: send "STOPPING=1" to systemd on shutdown mwilck
2020-09-16 15:37 ` [PATCH 04/19] multipathd: send "RELOADING=1" to systemd on DAEMON_CONFIGURE state mwilck
2020-09-16 15:37 ` [PATCH 05/19] multipathd: use volatile qualifier for running_state mwilck
2020-09-16 15:37 ` [PATCH 06/19] multipathd: generalize and fix wait_for_state_change_if() mwilck
2020-09-16 15:37 ` [PATCH 07/19] multipathd: set_config_state(): avoid code duplication mwilck
2020-09-19 19:01   ` Benjamin Marzinski
2020-09-16 15:37 ` [PATCH 08/19] multipathd: cancel threads early during shutdown mwilck
2020-09-16 15:37 ` [PATCH 09/19] multipath-tools: don't call dm_lib_release() any more mwilck
2020-09-16 15:37 ` [PATCH 10/19] libmultipath: devmapper: refactor libdm version determination mwilck
2020-09-19 22:14   ` Benjamin Marzinski
2020-09-21  8:35     ` Martin Wilck [this message]
2020-09-16 15:37 ` [PATCH 11/19] libmultipath: protect racy libdevmapper calls with a mutex mwilck
2020-09-16 15:37 ` [PATCH 12/19] libmultipath: constify file argument in config parser mwilck
2020-09-16 15:37 ` [PATCH 13/19] libmultipath: provide defaults for {get, put}_multipath_config mwilck
2020-09-21 19:08   ` Benjamin Marzinski
2020-09-21 19:42     ` Martin Wilck
2020-09-16 15:37 ` [PATCH 14/19] libmpathpersist: allow using libmultipath " mwilck
2020-09-16 15:37 ` [PATCH 15/19] multipath: use {get_put}_multipath_config from libmultipath mwilck
2020-09-16 15:37 ` [PATCH 16/19] mpathpersist: use {get, put}_multipath_config() " mwilck
2020-09-16 15:37 ` [PATCH 17/19] libmultipath: add udev and logsink symbols mwilck
2020-09-21 20:10   ` Benjamin Marzinski
2020-09-23  8:16     ` Martin Wilck
2020-09-23 16:05       ` Benjamin Marzinski
2020-09-16 15:37 ` [PATCH 18/19] multipath: remove logsink and udev mwilck
2020-09-16 15:37 ` [PATCH 19/19] mpathpersist: " mwilck
2020-09-21 20:15   ` Benjamin Marzinski
2020-09-22 11:32     ` Martin Wilck
2020-09-21 20:20 ` [PATCH 00/19] multipath-tools: shutdown, libdevmapper races, globals Benjamin Marzinski

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

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

  git send-email \
    --in-reply-to=1cb705785cf5d77b89002135b9411900fb82b630.camel@suse.com \
    --to=mwilck@suse.com \
    --cc=bmarzins@redhat.com \
    --cc=dm-devel@redhat.com \
    --cc=lixiaokeng@huawei.com \
    --cc=zkabelac@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.