Skip to content

Commit 7725c45

Browse files
bvanasschefloatious
authored andcommitted
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>
1 parent 4b3c2ca commit 7725c45

21 files changed

Lines changed: 48 additions & 10 deletions

drivers/ata/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3+
CONTEXT_ANALYSIS := y
4+
35
obj-$(CONFIG_ATA) += libata.o
46

57
# non-SFF interface

drivers/ata/ahci.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,8 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
448448
int ahci_reset_em(struct ata_host *host);
449449
void ahci_print_info(struct ata_host *host, const char *scc_s);
450450
int ahci_host_activate(struct ata_host *host, const struct scsi_host_template *sht);
451-
void ahci_error_handler(struct ata_port *ap);
451+
void ahci_error_handler(struct ata_port *ap)
452+
__must_hold(&ap->host->eh_mutex);
452453
u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked);
453454

454455
static inline void __iomem *__ahci_port_base(struct ahci_host_priv *hpriv,

drivers/ata/ahci_imx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
598598
}
599599

600600
static void ahci_imx_error_handler(struct ata_port *ap)
601+
__must_hold(&ap->host->eh_mutex)
601602
{
602603
u32 reg_val;
603604
struct ata_device *dev;

drivers/ata/libahci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,6 +2208,7 @@ static void ahci_thaw(struct ata_port *ap)
22082208
}
22092209

22102210
void ahci_error_handler(struct ata_port *ap)
2211+
__must_hold(&ap->host->eh_mutex)
22112212
{
22122213
struct ahci_host_priv *hpriv = ap->host->private_data;
22132214

drivers/ata/libata-core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6835,6 +6835,7 @@ EXPORT_SYMBOL_GPL(ata_ratelimit);
68356835
* Might sleep.
68366836
*/
68376837
void ata_msleep(struct ata_port *ap, unsigned int msecs)
6838+
__context_unsafe(conditional locking)
68386839
{
68396840
bool owns_eh = ap && ap->host->eh_owner == current;
68406841

@@ -6909,6 +6910,7 @@ static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
69096910
}
69106911

69116912
static void ata_dummy_error_handler(struct ata_port *ap)
6913+
__must_hold(&ap->host->eh_mutex)
69126914
{
69136915
/* truly dummy */
69146916
}

drivers/ata/libata-eh.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
469469
* EH context.
470470
*/
471471
void ata_eh_acquire(struct ata_port *ap)
472+
__acquires(&ap->host->eh_mutex)
472473
{
473474
mutex_lock(&ap->host->eh_mutex);
474475
WARN_ON_ONCE(ap->host->eh_owner);
@@ -486,6 +487,7 @@ void ata_eh_acquire(struct ata_port *ap)
486487
* EH context.
487488
*/
488489
void ata_eh_release(struct ata_port *ap)
490+
__releases(&ap->host->eh_mutex)
489491
{
490492
WARN_ON_ONCE(ap->host->eh_owner != current);
491493
ap->host->eh_owner = NULL;
@@ -2833,6 +2835,7 @@ static bool ata_eh_followup_srst_needed(struct ata_link *link, int rc)
28332835

28342836
int ata_eh_reset(struct ata_port *ap, struct ata_link *link, int classify,
28352837
struct ata_reset_operations *reset_ops)
2838+
__must_hold(&ap->host->eh_mutex)
28362839
{
28372840
struct ata_link *slave = ap->slave_link;
28382841
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)
38153818
*/
38163819
int ata_eh_recover(struct ata_port *ap, struct ata_reset_operations *reset_ops,
38173820
struct ata_link **r_failed_link)
3821+
__must_hold(&ap->host->eh_mutex)
38183822
{
38193823
struct ata_link *link;
38203824
struct ata_device *dev;
@@ -4112,6 +4116,7 @@ void ata_eh_finish(struct ata_port *ap)
41124116
* Kernel thread context (may sleep).
41134117
*/
41144118
void ata_std_error_handler(struct ata_port *ap)
4119+
__must_hold(&ap->host->eh_mutex)
41154120
{
41164121
struct ata_reset_operations *reset_ops = &ap->ops->reset;
41174122
struct ata_link *link = &ap->link;

drivers/ata/libata-pmp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ static int sata_pmp_revalidate_quick(struct ata_device *dev)
756756
*/
757757
static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
758758
struct ata_reset_operations *reset_ops)
759+
__must_hold(&ap->host->eh_mutex)
759760
{
760761
struct ata_link *link = &ap->link;
761762
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)
921922
* 0 on success, -errno on failure.
922923
*/
923924
static int sata_pmp_eh_recover(struct ata_port *ap)
925+
__must_hold(&ap->host->eh_mutex)
924926
{
925927
struct ata_port_operations *ops = ap->ops;
926928
int pmp_tries, link_tries[SATA_PMP_MAX_PORTS];
@@ -1098,6 +1100,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
10981100
* Kernel thread context (may sleep).
10991101
*/
11001102
void sata_pmp_error_handler(struct ata_port *ap)
1103+
__must_hold(&ap->host->eh_mutex)
11011104
{
11021105
ata_eh_autopsy(ap);
11031106
ata_eh_report(ap);

drivers/ata/libata-sff.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,7 @@ EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
20532053
* Kernel thread context (may sleep)
20542054
*/
20552055
void ata_sff_error_handler(struct ata_port *ap)
2056+
__must_hold(&ap->host->eh_mutex)
20562057
{
20572058
struct ata_queued_cmd *qc;
20582059
unsigned long flags;
@@ -2769,6 +2770,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_interrupt);
27692770
* Kernel thread context (may sleep)
27702771
*/
27712772
void ata_bmdma_error_handler(struct ata_port *ap)
2773+
__must_hold(&ap->host->eh_mutex)
27722774
{
27732775
struct ata_queued_cmd *qc;
27742776
unsigned long flags;

drivers/ata/libata.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,10 @@ void ata_scsi_requeue_deferred_qc(struct ata_port *ap);
173173
/* libata-eh.c */
174174
extern unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
175175
extern void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd);
176-
extern void ata_eh_acquire(struct ata_port *ap);
177-
extern void ata_eh_release(struct ata_port *ap);
176+
extern void ata_eh_acquire(struct ata_port *ap)
177+
__acquires(&ap->host->eh_mutex);
178+
extern void ata_eh_release(struct ata_port *ap)
179+
__releases(&ap->host->eh_mutex);
178180
extern void ata_scsi_error(struct Scsi_Host *host);
179181
extern void ata_eh_fastdrain_timerfn(struct timer_list *t);
180182
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
@@ -188,10 +190,12 @@ extern void ata_eh_autopsy(struct ata_port *ap);
188190
const char *ata_get_cmd_name(u8 command);
189191
extern void ata_eh_report(struct ata_port *ap);
190192
extern int ata_eh_reset(struct ata_port *ap, struct ata_link *link,
191-
int classify, struct ata_reset_operations *reset_ops);
193+
int classify, struct ata_reset_operations *reset_ops)
194+
__must_hold(&ap->host->eh_mutex);
192195
extern int ata_eh_recover(struct ata_port *ap,
193196
struct ata_reset_operations *reset_ops,
194-
struct ata_link **r_failed_disk);
197+
struct ata_link **r_failed_disk)
198+
__must_hold(&ap->host->eh_mutex);
195199
extern void ata_eh_finish(struct ata_port *ap);
196200
extern int ata_ering_map(struct ata_ering *ering,
197201
int (*map_fn)(struct ata_ering_entry *, void *),

drivers/ata/pata_arasan_cf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ static void arasan_cf_freeze(struct ata_port *ap)
658658
}
659659

660660
static void arasan_cf_error_handler(struct ata_port *ap)
661+
__must_hold(&ap->host->eh_mutex)
661662
{
662663
struct arasan_cf_dev *acdev = ap->host->private_data;
663664

0 commit comments

Comments
 (0)