mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
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>
This commit is contained in:
committed by
Niklas Cassel
parent
4b3c2ca268
commit
7725c45682
@@ -1,5 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
CONTEXT_ANALYSIS := y
|
||||
|
||||
obj-$(CONFIG_ATA) += libata.o
|
||||
|
||||
# non-SFF interface
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1035,6 +1035,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
|
||||
}
|
||||
|
||||
static void sata_fsl_error_handler(struct ata_port *ap)
|
||||
__must_hold(&ap->host->eh_mutex)
|
||||
{
|
||||
sata_pmp_error_handler(ap);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -984,7 +984,8 @@ struct ata_port_operations {
|
||||
void (*thaw)(struct ata_port *ap);
|
||||
struct ata_reset_operations reset;
|
||||
struct ata_reset_operations pmp_reset;
|
||||
void (*error_handler)(struct ata_port *ap);
|
||||
void (*error_handler)(struct ata_port *ap)
|
||||
__must_hold(&ap->host->eh_mutex);
|
||||
void (*lost_interrupt)(struct ata_port *ap);
|
||||
void (*post_internal_cmd)(struct ata_queued_cmd *qc);
|
||||
void (*sched_eh)(struct ata_port *ap);
|
||||
@@ -1419,7 +1420,8 @@ extern void ata_eh_thaw_port(struct ata_port *ap);
|
||||
extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
|
||||
extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
|
||||
|
||||
extern void ata_std_error_handler(struct ata_port *ap);
|
||||
extern void ata_std_error_handler(struct ata_port *ap)
|
||||
__must_hold(&ap->host->eh_mutex);
|
||||
extern void ata_std_sched_eh(struct ata_port *ap);
|
||||
extern void ata_std_end_eh(struct ata_port *ap);
|
||||
extern int ata_link_nr_enabled(struct ata_link *link);
|
||||
@@ -1999,7 +2001,8 @@ extern void ata_timing_merge(const struct ata_timing *,
|
||||
extern const struct ata_port_operations sata_pmp_port_ops;
|
||||
|
||||
extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc);
|
||||
extern void sata_pmp_error_handler(struct ata_port *ap);
|
||||
extern void sata_pmp_error_handler(struct ata_port *ap)
|
||||
__must_hold(&ap->host->eh_mutex);
|
||||
|
||||
#else /* CONFIG_SATA_PMP */
|
||||
|
||||
@@ -2063,7 +2066,8 @@ extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes);
|
||||
extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc);
|
||||
extern void ata_sff_error_handler(struct ata_port *ap);
|
||||
extern void ata_sff_error_handler(struct ata_port *ap)
|
||||
__must_hold(&ap->host->eh_mutex);
|
||||
extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
|
||||
#ifdef CONFIG_PCI
|
||||
extern int ata_pci_sff_init_host(struct ata_host *host);
|
||||
@@ -2093,7 +2097,8 @@ extern enum ata_completion_errors ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *
|
||||
extern unsigned int ata_bmdma_port_intr(struct ata_port *ap,
|
||||
struct ata_queued_cmd *qc);
|
||||
extern irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance);
|
||||
extern void ata_bmdma_error_handler(struct ata_port *ap);
|
||||
extern void ata_bmdma_error_handler(struct ata_port *ap)
|
||||
__must_hold(&ap->host->eh_mutex);
|
||||
extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
|
||||
extern void ata_bmdma_irq_clear(struct ata_port *ap);
|
||||
extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
|
||||
|
||||
Reference in New Issue
Block a user