summaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2026-05-29 11:03:10 -0700
committerNiklas Cassel <cassel@kernel.org>2026-06-01 19:09:08 +0200
commit7725c45682abd7a6590676c33c35a7bdfdec6db5 (patch)
treedead5ede72b813e5557f8c036c32c2e44eda823d /drivers/ata
parent4b3c2ca268b0a66093793466e02d8566d642f19c (diff)
downloadlinux-next-7725c45682abd7a6590676c33c35a7bdfdec6db5.tar.gz
linux-next-7725c45682abd7a6590676c33c35a7bdfdec6db5.zip
ata: libata: Document when host->eh_mutex should be held
Annotate the following functions with __must_hold(&host->eh_mutex): * All ata_port_operations.error_handler() implementations. * ata_eh_reset() and ata_eh_recover() because these functions call ata_eh_release() and ata_eh_acquire(). * All callers of ata_eh_reset() and ata_eh_recover(). Enable Clang's context analysis. This will cause the build to fail if e.g. a locking bug would be introduced in an error path. This patch should not affect the generated assembler code. Signed-off-by: Bart Van Assche <bvanassche@acm.org> [cassel: drop note about clang 23 from commit log] Signed-off-by: Niklas Cassel <cassel@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/ata/ahci.h3
-rw-r--r--drivers/ata/ahci_imx.c1
-rw-r--r--drivers/ata/libahci.c1
-rw-r--r--drivers/ata/libata-core.c2
-rw-r--r--drivers/ata/libata-eh.c5
-rw-r--r--drivers/ata/libata-pmp.c3
-rw-r--r--drivers/ata/libata-sff.c2
-rw-r--r--drivers/ata/libata.h12
-rw-r--r--drivers/ata/pata_arasan_cf.c1
-rw-r--r--drivers/ata/sata_dwc_460ex.c1
-rw-r--r--drivers/ata/sata_fsl.c1
-rw-r--r--drivers/ata/sata_inic162x.c1
-rw-r--r--drivers/ata/sata_mv.c1
-rw-r--r--drivers/ata/sata_nv.c2
-rw-r--r--drivers/ata/sata_promise.c1
-rw-r--r--drivers/ata/sata_qstor.c1
-rw-r--r--drivers/ata/sata_sil24.c1
-rw-r--r--drivers/ata/sata_sx4.c1
-rw-r--r--drivers/ata/sata_via.c1
20 files changed, 38 insertions, 5 deletions
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 20e6645ab737..b96025abd45e 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
+CONTEXT_ANALYSIS := y
+
obj-$(CONFIG_ATA) += libata.o
# non-SFF interface
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 9e8b6319025c..b57cca352faa 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -448,7 +448,8 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
int ahci_reset_em(struct ata_host *host);
void ahci_print_info(struct ata_host *host, const char *scc_s);
int ahci_host_activate(struct ata_host *host, const struct scsi_host_template *sht);
-void ahci_error_handler(struct ata_port *ap);
+void ahci_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex);
u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked);
static inline void __iomem *__ahci_port_base(struct ahci_host_priv *hpriv,
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 3d26595524d3..6aaa18e29abc 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -598,6 +598,7 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
}
static void ahci_imx_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
u32 reg_val;
struct ata_device *dev;
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index e0af4b5716b3..6d72eb017b49 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -2208,6 +2208,7 @@ static void ahci_thaw(struct ata_port *ap)
}
void ahci_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct ahci_host_priv *hpriv = ap->host->private_data;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3e19a00a9239..f68882706fdc 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6835,6 +6835,7 @@ EXPORT_SYMBOL_GPL(ata_ratelimit);
* Might sleep.
*/
void ata_msleep(struct ata_port *ap, unsigned int msecs)
+ __context_unsafe(conditional locking)
{
bool owns_eh = ap && ap->host->eh_owner == current;
@@ -6909,6 +6910,7 @@ static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
}
static void ata_dummy_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
/* truly dummy */
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ecfb9d96249f..05df7ea6954a 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -469,6 +469,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
* EH context.
*/
void ata_eh_acquire(struct ata_port *ap)
+ __acquires(&ap->host->eh_mutex)
{
mutex_lock(&ap->host->eh_mutex);
WARN_ON_ONCE(ap->host->eh_owner);
@@ -486,6 +487,7 @@ void ata_eh_acquire(struct ata_port *ap)
* EH context.
*/
void ata_eh_release(struct ata_port *ap)
+ __releases(&ap->host->eh_mutex)
{
WARN_ON_ONCE(ap->host->eh_owner != current);
ap->host->eh_owner = NULL;
@@ -2833,6 +2835,7 @@ static bool ata_eh_followup_srst_needed(struct ata_link *link, int rc)
int ata_eh_reset(struct ata_port *ap, struct ata_link *link, int classify,
struct ata_reset_operations *reset_ops)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_link *slave = ap->slave_link;
struct ata_eh_context *ehc = &link->eh_context;
@@ -3815,6 +3818,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
*/
int ata_eh_recover(struct ata_port *ap, struct ata_reset_operations *reset_ops,
struct ata_link **r_failed_link)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_link *link;
struct ata_device *dev;
@@ -4112,6 +4116,7 @@ void ata_eh_finish(struct ata_port *ap)
* Kernel thread context (may sleep).
*/
void ata_std_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_reset_operations *reset_ops = &ap->ops->reset;
struct ata_link *link = &ap->link;
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index ffd654996067..736eaf0586f7 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -756,6 +756,7 @@ static int sata_pmp_revalidate_quick(struct ata_device *dev)
*/
static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
struct ata_reset_operations *reset_ops)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_link *link = &ap->link;
struct ata_eh_context *ehc = &link->eh_context;
@@ -921,6 +922,7 @@ static int sata_pmp_handle_link_fail(struct ata_link *link, int *link_tries)
* 0 on success, -errno on failure.
*/
static int sata_pmp_eh_recover(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_port_operations *ops = ap->ops;
int pmp_tries, link_tries[SATA_PMP_MAX_PORTS];
@@ -1098,6 +1100,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
* Kernel thread context (may sleep).
*/
void sata_pmp_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
ata_eh_autopsy(ap);
ata_eh_report(ap);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 785b6e371abf..734e7c88439a 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2053,6 +2053,7 @@ EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
* Kernel thread context (may sleep)
*/
void ata_sff_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_queued_cmd *qc;
unsigned long flags;
@@ -2769,6 +2770,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_interrupt);
* Kernel thread context (may sleep)
*/
void ata_bmdma_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_queued_cmd *qc;
unsigned long flags;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index a5920c10aaca..d0b0ecd3d086 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -173,8 +173,10 @@ void ata_scsi_requeue_deferred_qc(struct ata_port *ap);
/* libata-eh.c */
extern unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
extern void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd);
-extern void ata_eh_acquire(struct ata_port *ap);
-extern void ata_eh_release(struct ata_port *ap);
+extern void ata_eh_acquire(struct ata_port *ap)
+ __acquires(&ap->host->eh_mutex);
+extern void ata_eh_release(struct ata_port *ap)
+ __releases(&ap->host->eh_mutex);
extern void ata_scsi_error(struct Scsi_Host *host);
extern void ata_eh_fastdrain_timerfn(struct timer_list *t);
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
@@ -188,10 +190,12 @@ extern void ata_eh_autopsy(struct ata_port *ap);
const char *ata_get_cmd_name(u8 command);
extern void ata_eh_report(struct ata_port *ap);
extern int ata_eh_reset(struct ata_port *ap, struct ata_link *link,
- int classify, struct ata_reset_operations *reset_ops);
+ int classify, struct ata_reset_operations *reset_ops)
+ __must_hold(&ap->host->eh_mutex);
extern int ata_eh_recover(struct ata_port *ap,
struct ata_reset_operations *reset_ops,
- struct ata_link **r_failed_disk);
+ struct ata_link **r_failed_disk)
+ __must_hold(&ap->host->eh_mutex);
extern void ata_eh_finish(struct ata_port *ap);
extern int ata_ering_map(struct ata_ering *ering,
int (*map_fn)(struct ata_ering_entry *, void *),
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index a77fefd320c2..e05a4847e037 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -658,6 +658,7 @@ static void arasan_cf_freeze(struct ata_port *ap)
}
static void arasan_cf_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct arasan_cf_dev *acdev = ap->host->private_data;
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
index 64cb544903d8..4fc22ce4bd9a 100644
--- a/drivers/ata/sata_dwc_460ex.c
+++ b/drivers/ata/sata_dwc_460ex.c
@@ -1041,6 +1041,7 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
}
static void sata_dwc_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
ata_sff_error_handler(ap);
}
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index be829fcc584d..70b210afd291 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1035,6 +1035,7 @@ err:
}
static void sata_fsl_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
sata_pmp_error_handler(ap);
}
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 46a8c20daf18..065408975f5b 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -660,6 +660,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
}
static void inic_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
void __iomem *port_base = inic_port_base(ap);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index ffb396f61731..f6942fd80bae 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2398,6 +2398,7 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
}
static void mv_pmp_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
unsigned int pmp, pmp_map;
struct mv_port_priv *pp = ap->private_data;
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 841e7de2bba6..19b927065868 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1626,6 +1626,7 @@ static void nv_mcp55_thaw(struct ata_port *ap)
}
static void nv_adma_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct nv_adma_port_priv *pp = ap->private_data;
if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
@@ -1795,6 +1796,7 @@ static void nv_swncq_ncq_stop(struct ata_port *ap)
}
static void nv_swncq_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct ata_eh_context *ehc = &ap->link.eh_context;
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 2a005aede123..c5fad448bafc 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -816,6 +816,7 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
}
static void pdc_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
if (!ata_port_is_frozen(ap))
pdc_reset_port(ap);
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index cfb9b5b61cd7..1add7a7d5ff6 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -220,6 +220,7 @@ static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
}
static void qs_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
qs_enter_reg_mode(ap);
ata_sff_error_handler(ap);
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 57f1081b86db..b4549ba968a4 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -1171,6 +1171,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
}
static void sil24_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct sil24_port_priv *pp = ap->private_data;
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 0986ebd1eb4e..227dc1d4e85b 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -853,6 +853,7 @@ static int pdc_softreset(struct ata_link *link, unsigned int *class,
}
static void pdc_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
if (!ata_port_is_frozen(ap))
pdc_reset_port(ap);
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 68e9003ec2d4..b672a1e05867 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -573,6 +573,7 @@ static irqreturn_t vt642x_interrupt(int irq, void *dev_instance)
}
static void vt6421_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
struct svia_priv *hpriv = ap->host->private_data;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);