Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Niklas Cassel <cassel@kernel.org>
To: Patrice Chotard <patrice.chotard@foss.st.com>,
	Damien Le Moal <dlemoal@kernel.org>,
	Niklas Cassel <cassel@kernel.org>,
	Hans de Goede <hansg@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>, Tejun Heo <tj@kernel.org>,
	Alexandre Torgue <alexandre.torgue@st.com>,
	Lee Jones <lee@kernel.org>,
	Brian Norris <computersforpeace@gmail.com>,
	Jeff Garzik <jgarzik@redhat.com>
Cc: linux-arm-kernel@lists.infradead.org, linux-ide@vger.kernel.org
Subject: [PATCH v3 0/3] ata: Do not release the host resources twice on probe() failure
Date: Thu, 10 Sep 2026 14:19:00 +0200	[thread overview]
Message-ID: <20260910121900.97676-5-cassel@kernel.org> (raw)

ata_host_start() registers ata_host_stop() as a devres action as soon as
it has succeeded:

	if (have_stop) {
		start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL);
	...
	if (start_dr)
		devres_add(host->dev, start_dr);
	host->flags |= ATA_HOST_STARTED;

From that point on, releasing the host resources is owned by devres: when
probe() fails, the driver core calls devres_release_all(), which calls
ata_host_stop(), which calls ->port_stop() and ->host_stop().

ata_host_activate() and ahci_host_activate_multi_irqs() can however fail
after ata_host_start() has succeeded - devm_kasprintf(),
devm_request_irq() (a shared IRQ conflict) and ata_host_register()
(scsi_add_host(), ata_tport_add()) can all fail - and they return the
error with the devres action still registered. Since the caller cannot
tell whether ata_host_start() succeeded, and since it has to release the
resources for the failures happening before that, all the ahci-platform
drivers release the host resources in their probe() error path, e.g.
ahci_probe() calls ahci_platform_disable_resources() while
ahci_host_stop() does the same through devres.

The clocks, regulators, resets and PHYs of the host are therefore
released twice, which gives refcount underflow warnings from the clk,
regulator and phy cores and, for shared resources, can disable resources
which are still in use by other devices.

Patch 2 adds ata_host_undo_start(), which stops the ports and drops the
devres action without calling ->host_stop(), and calls it from both
activation helpers when they fail, so that "on failure, the caller
releases what it acquired" holds for all of them. sata_qstor and sata_fsl
are the only drivers which implement ->host_stop() while having no error
handling at all for the activate host call, so they get some.

Patch 1 has to come first: ahci_st is the only ahci-platform driver whose
->host_stop() does more than its probe() error path, as it also asserts
the "pwr-dwn" reset. Without patch 1, patch 2 would silently stop that
reset from being asserted when activating the host fails.

Patch 3 is an unrelated kdoc fix that I noticed while documenting the
above.

Changes since v2:
- Do not take the host teardown back in ata_pci_sff_activate_host(), and
  drop the sata_nv change which went with it. None of its callers
  releases the host resources itself: ata_piix, pata_rdc and
  ata_pci_init_one() all rely on ->host_stop() being called through
  devres, ata_pci_init_one() by releasing the devres group of the host.
- Document who releases the host resources on failure in the kdoc of
  ata_host_activate(), ata_host_register(), ata_pci_sff_activate_host(),
  ahci_host_activate() and ahci_platform_init_host().
- New patch 1, so that patch 2 does not stop ahci_st from asserting its
  "pwr-dwn" reset on probe() failure.
- New patch 3.

Niklas Cassel (3):
  ata: ahci_st: Assert the power down reset in the probe() error path
  ata: libata: Do not leave ata_host_stop() registered when activation
    fails
  ata: libata-core: Fix the ata_host_register() kdoc

 drivers/ata/ahci_st.c          | 51 ++++++++++++---------
 drivers/ata/libahci.c          | 17 ++++++-
 drivers/ata/libahci_platform.c |  4 ++
 drivers/ata/libata-core.c      | 81 ++++++++++++++++++++++++++++++----
 drivers/ata/libata-sff.c       |  5 +++
 drivers/ata/sata_fsl.c         |  8 +++-
 drivers/ata/sata_qstor.c       |  8 +++-
 include/linux/libata.h         |  1 +
 8 files changed, 139 insertions(+), 36 deletions(-)

-- 
2.55.0



             reply	other threads:[~2026-09-10 12:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-10 12:19 Niklas Cassel [this message]
2026-09-10 12:19 ` [PATCH v3 1/3] ata: ahci_st: Assert the power down reset in the probe() error path Niklas Cassel

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=20260910121900.97676-5-cassel@kernel.org \
    --to=cassel@kernel.org \
    --cc=alexandre.torgue@st.com \
    --cc=computersforpeace@gmail.com \
    --cc=dlemoal@kernel.org \
    --cc=hansg@kernel.org \
    --cc=jgarzik@redhat.com \
    --cc=lee@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=patrice.chotard@foss.st.com \
    --cc=tj@kernel.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