All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Warren <swarren@wwwdotorg.org>
To: Linus Walleij <linus.walleij@stericsson.com>
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Stephen Warren <swarren@nvidia.com>,
	Anmar Oueja <anmar.oueja@linaro.org>,
	Patrice Chotard <patrice.chotard@st.com>,
	Linus Walleij <linus.walleij@linaro.org>
Subject: Re: [PATCH] pinctrl: move subsystem mutex to pinctrl_dev struct
Date: Wed, 13 Mar 2013 12:22:45 -0600	[thread overview]
Message-ID: <5140C3F5.9030406@wwwdotorg.org> (raw)
In-Reply-To: <1363189479-11240-1-git-send-email-linus.walleij@stericsson.com>

On 03/13/2013 09:44 AM, Linus Walleij wrote:
> From: Patrice Chotard <patrice.chotard@st.com>
> 
> This mutex avoids deadlock in case of use of multiple pin
> controllers. Before this modification, by using a global
> mutex, deadlock appeared when, for example, a call to
> pinctrl_pins_show() locked the pinctrl_mutex, called the
> ops->pin_dbg_show of a particular pin controller. If this
> pin controller needs I2C access to retrieve configuration
> information and I2C driver is using pinctrl to drive its
> pins, a call to pinctrl_select_state() try to lock again
> pinctrl_mutex which leads to a deadlock.
> 
> Notice that the mutex grab from the two direction functions
> was moved into pinctrl_gpio_direction().
> 
> For two cases, we can't replace pinctrl_mutex by
> pctldev->mutex, because at this stage, pctldev is
> not accessible :
> 	- pinctrl_get()/pinctrl_put()
> 	- pinctrl_register_maps()
> 
> So add respectively pinctrl_list_mutex and
> pinctrl_maps_mutex in order to protect
> pinctrl_list and pinctrl_maps list instead.

I can't see how this would be safe, or even how it would solve the
problem (and still be safe).

In the scenario described above, pinctrl_pins_show() would need to lock
the list mutex since it's interacting with the list of pinctrl devices.
Then, the I2C drivers'c pinctrl_select() also needs to acquire that same
lock, since it's interacting with another entry in that same list in
order to re-program the other pinctrl device to route I2C to the correct
location.

So, I can't see how separating out the map lock would make any difference.

Also, why is the map lock relevant here at all anyway? The I2C mux's
probe() should have executed pinctrl_get(), and isn't the map parsed at
that time, and converted to a struct pinctrl, and hence any later call
to pinctrl_select() doesn't touch the map?

Is there a recursive lock type that could be used instead? I'm not sure
if that'd still be safe though.

Finally, a long while ago when I removed these separate locks and
created the single lock, I raised a slew of complex points re: why it
was extremely hard to split up the locking. I talked about a number of
AB/BA deadlock cases IIRC mostly w.r.t pinctrl device registration. Were
those considered when writing this patch? What's the solution?

WARNING: multiple messages have this Message-ID (diff)
From: swarren@wwwdotorg.org (Stephen Warren)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] pinctrl: move subsystem mutex to pinctrl_dev struct
Date: Wed, 13 Mar 2013 12:22:45 -0600	[thread overview]
Message-ID: <5140C3F5.9030406@wwwdotorg.org> (raw)
In-Reply-To: <1363189479-11240-1-git-send-email-linus.walleij@stericsson.com>

On 03/13/2013 09:44 AM, Linus Walleij wrote:
> From: Patrice Chotard <patrice.chotard@st.com>
> 
> This mutex avoids deadlock in case of use of multiple pin
> controllers. Before this modification, by using a global
> mutex, deadlock appeared when, for example, a call to
> pinctrl_pins_show() locked the pinctrl_mutex, called the
> ops->pin_dbg_show of a particular pin controller. If this
> pin controller needs I2C access to retrieve configuration
> information and I2C driver is using pinctrl to drive its
> pins, a call to pinctrl_select_state() try to lock again
> pinctrl_mutex which leads to a deadlock.
> 
> Notice that the mutex grab from the two direction functions
> was moved into pinctrl_gpio_direction().
> 
> For two cases, we can't replace pinctrl_mutex by
> pctldev->mutex, because at this stage, pctldev is
> not accessible :
> 	- pinctrl_get()/pinctrl_put()
> 	- pinctrl_register_maps()
> 
> So add respectively pinctrl_list_mutex and
> pinctrl_maps_mutex in order to protect
> pinctrl_list and pinctrl_maps list instead.

I can't see how this would be safe, or even how it would solve the
problem (and still be safe).

In the scenario described above, pinctrl_pins_show() would need to lock
the list mutex since it's interacting with the list of pinctrl devices.
Then, the I2C drivers'c pinctrl_select() also needs to acquire that same
lock, since it's interacting with another entry in that same list in
order to re-program the other pinctrl device to route I2C to the correct
location.

So, I can't see how separating out the map lock would make any difference.

Also, why is the map lock relevant here at all anyway? The I2C mux's
probe() should have executed pinctrl_get(), and isn't the map parsed at
that time, and converted to a struct pinctrl, and hence any later call
to pinctrl_select() doesn't touch the map?

Is there a recursive lock type that could be used instead? I'm not sure
if that'd still be safe though.

Finally, a long while ago when I removed these separate locks and
created the single lock, I raised a slew of complex points re: why it
was extremely hard to split up the locking. I talked about a number of
AB/BA deadlock cases IIRC mostly w.r.t pinctrl device registration. Were
those considered when writing this patch? What's the solution?

  reply	other threads:[~2013-03-13 18:30 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-13 15:44 [PATCH] pinctrl: move subsystem mutex to pinctrl_dev struct Linus Walleij
2013-03-13 15:44 ` Linus Walleij
2013-03-13 18:22 ` Stephen Warren [this message]
2013-03-13 18:22   ` Stephen Warren
2013-03-14 16:59   ` Patrice CHOTARD
2013-03-14 16:59     ` Patrice CHOTARD
2013-03-27 21:45     ` Linus Walleij
2013-03-27 21:45       ` Linus Walleij
2013-03-27 23:33       ` Stephen Warren
2013-03-27 23:33         ` Stephen Warren
2013-04-10 13:04         ` Patrice CHOTARD
2013-04-10 13:04           ` Patrice CHOTARD
2013-04-24  8:58           ` Linus Walleij
2013-04-24  8:58             ` Linus Walleij

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=5140C3F5.9030406@wwwdotorg.org \
    --to=swarren@wwwdotorg.org \
    --cc=anmar.oueja@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linus.walleij@stericsson.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patrice.chotard@st.com \
    --cc=swarren@nvidia.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.