From 70d2304ae575c0432251f36231d32e6ff0eb4f7f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 25 Sep 2026 11:26:04 -0700 Subject: [PATCH] scsi: fnic: Enable lock context analysis Document locking requirements with __must_hold(). Suppress complaints about conditional locking in fnic_device_reset() with __acquire() and __release(). Cc: Karan Tilak Kumar Signed-off-by: Bart Van Assche Link: https://patch.msgid.link/e8ac2000b7ed23cec78f5be360a21d741f50a73e.1790360262.git.bvanassche@acm.org Signed-off-by: Martin K. Petersen (Oracle) --- drivers/scsi/fnic/Makefile | 3 +++ drivers/scsi/fnic/fdls_disc.c | 46 +++++++++++++++++++++++++++++++++-- drivers/scsi/fnic/fip.c | 2 ++ drivers/scsi/fnic/fnic_fcs.c | 2 ++ drivers/scsi/fnic/fnic_scsi.c | 4 +++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile index 48c5e0cb8ca6..22a463380dee 100644 --- a/drivers/scsi/fnic/Makefile +++ b/drivers/scsi/fnic/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_FCOE_FNIC) += fnic.o fnic-y := \ diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c index 7a33ec703391..b04bb9a5dfa8 100644 --- a/drivers/scsi/fnic/fdls_disc.c +++ b/drivers/scsi/fnic/fdls_disc.c @@ -418,6 +418,7 @@ static void fdls_reset_oxid_pool(struct fnic_iport_s *iport) } void fnic_del_fabric_timer_sync(struct fnic *fnic) + __must_hold(&fnic->fnic_lock) { fnic->iport.fabric.del_timer_inprogress = 1; spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags); @@ -426,8 +427,8 @@ void fnic_del_fabric_timer_sync(struct fnic *fnic) fnic->iport.fabric.del_timer_inprogress = 0; } -void fnic_del_tport_timer_sync(struct fnic *fnic, - struct fnic_tport_s *tport) +void fnic_del_tport_timer_sync(struct fnic *fnic, struct fnic_tport_s *tport) + __must_hold(&fnic->fnic_lock) { tport->del_timer_inprogress = 1; spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags); @@ -438,6 +439,7 @@ void fnic_del_tport_timer_sync(struct fnic *fnic, static void fdls_start_fabric_timer(struct fnic_iport_s *iport, int timeout) + __must_hold(&iport->fnic->fnic_lock) { u64 fabric_tov; struct fnic *fnic = iport->fnic; @@ -463,6 +465,7 @@ fdls_start_fabric_timer(struct fnic_iport_s *iport, int timeout) static void fdls_start_tport_timer(struct fnic_iport_s *iport, struct fnic_tport_s *tport, int timeout) + __must_hold(&iport->fnic->fnic_lock) { u64 fabric_tov; struct fnic *fnic = iport->fnic; @@ -718,6 +721,7 @@ int fdls_send_ls_req_abts(struct fnic_iport_s *iport, void fdls_send_tport_abts(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; uint8_t s_id[3]; @@ -761,7 +765,9 @@ fdls_send_tport_abts(struct fnic_iport_s *iport, /* Even if fnic_send_fcoe_frame() fails we want to retry after timeout */ fdls_start_tport_timer(iport, tport, 2 * iport->e_d_tov); } + static void fdls_send_fabric_abts(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; uint8_t s_id[3]; @@ -933,6 +939,7 @@ static void fdls_send_fdmi_abts(struct fnic_iport_s *iport) } static void fdls_send_fabric_flogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_flogi *pflogi; @@ -993,6 +1000,7 @@ static void fdls_send_fabric_flogi(struct fnic_iport_s *iport) } static void fdls_send_fabric_plogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_flogi *pplogi; @@ -1085,6 +1093,7 @@ static void fdls_send_fdmi_plogi(struct fnic_iport_s *iport) } static void fdls_send_rpn_id(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_rpn_id *prpn_id; @@ -1144,6 +1153,7 @@ static void fdls_send_rpn_id(struct fnic_iport_s *iport) } static void fdls_send_scr(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_scr *pscr; @@ -1199,6 +1209,7 @@ static void fdls_send_scr(struct fnic_iport_s *iport) } static void fdls_send_gpn_ft(struct fnic_iport_s *iport, int fdls_state) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_gpn_ft *pgpn_ft; @@ -1258,6 +1269,7 @@ static void fdls_send_gpn_ft(struct fnic_iport_s *iport, int fdls_state) static void fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_els_adisc *padisc; @@ -1323,6 +1335,7 @@ fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport) } bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_event_s *tport_del_evt; struct fnic *fnic = iport->fnic; @@ -1388,6 +1401,7 @@ bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport) static void fdls_send_tgt_plogi(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_flogi *pplogi; @@ -1456,6 +1470,7 @@ fnic_fc_plogi_rsp_rdf(struct fnic_iport_s *iport, } static void fdls_send_register_fc4_types(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_rft_id *prft_id; @@ -1523,6 +1538,7 @@ static void fdls_send_register_fc4_types(struct fnic_iport_s *iport) } static void fdls_send_register_fc4_features(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_rff_id *prff_id; @@ -1582,6 +1598,7 @@ static void fdls_send_register_fc4_features(struct fnic_iport_s *iport) static void fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_els_prli *pprli; @@ -1663,6 +1680,7 @@ fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport) * Currently this assumes to be called with fnic lock held. */ void fdls_send_fabric_logo(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_logo *plogo; @@ -1762,6 +1780,7 @@ void fdls_tgt_logout(struct fnic_iport_s *iport, struct fnic_tport_s *tport) } static void fdls_tgt_discovery_start(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_s *tport, *next; u32 old_link_down_cnt = iport->fnic->link_down_cnt; @@ -1813,6 +1832,7 @@ static void fdls_tgt_discovery_start(struct fnic_iport_s *iport) */ static void fdls_target_restart_nexus(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_s *new_tport = NULL; uint32_t fcid; @@ -2618,6 +2638,7 @@ static void fdls_tport_timer_callback(struct timer_list *t) } static void fnic_fdls_start_flogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { iport->fabric.retry_counter = 0; fdls_send_fabric_flogi(iport); @@ -2626,6 +2647,7 @@ static void fnic_fdls_start_flogi(struct fnic_iport_s *iport) } static void fnic_fdls_start_plogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { iport->fabric.retry_counter = 0; fdls_send_fabric_plogi(iport); @@ -2644,6 +2666,7 @@ static void fnic_fdls_start_plogi(struct fnic_iport_s *iport) static void fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t tgt_fcid; struct fnic_tport_s *tport; @@ -2734,6 +2757,7 @@ fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport, static void fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t tgt_fcid; struct fnic_tport_s *tport; @@ -2855,9 +2879,11 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport, fdls_set_tport_state(tport, FDLS_TGT_STATE_PRLI); fdls_send_tgt_prli(iport, tport); } + static void fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t tgt_fcid; struct fnic_tport_s *tport; @@ -3026,6 +3052,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport, static void fdls_process_rff_id_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic *fnic = iport->fnic; struct fnic_fdls_fabric_s *fdls = &iport->fabric; @@ -3099,6 +3126,7 @@ fdls_process_rff_id_rsp(struct fnic_iport_s *iport, static void fdls_process_rft_id_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_rft_id *rft_rsp = (struct fc_std_rft_id *) fchdr; @@ -3174,6 +3202,7 @@ fdls_process_rft_id_rsp(struct fnic_iport_s *iport, static void fdls_process_rpn_id_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_rpn_id *rpn_rsp = (struct fc_std_rpn_id *) fchdr; @@ -3244,6 +3273,7 @@ fdls_process_rpn_id_rsp(struct fnic_iport_s *iport, static void fdls_process_scr_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_scr *scr_rsp = (struct fc_std_scr *) fchdr; @@ -3316,6 +3346,7 @@ fdls_process_scr_rsp(struct fnic_iport_s *iport, static void fdls_process_gpn_ft_tgt_list(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, int len) + __must_hold(&iport->fnic->fnic_lock) { struct fc_gpn_ft_rsp_iu *gpn_ft_tgt; struct fnic_tport_s *tport, *next; @@ -3414,6 +3445,7 @@ fdls_process_gpn_ft_tgt_list(struct fnic_iport_s *iport, static void fdls_process_gpn_ft_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, int len) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_gpn_ft *gpn_ft_rsp = (struct fc_std_gpn_ft *) fchdr; @@ -3550,6 +3582,7 @@ fdls_process_gpn_ft_rsp(struct fnic_iport_s *iport, static void fdls_process_fabric_logo_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_flogi *flogo_rsp = (struct fc_std_flogi *) fchdr; struct fnic_fdls_fabric_s *fdls = &iport->fabric; @@ -3603,6 +3636,7 @@ fdls_process_fabric_logo_rsp(struct fnic_iport_s *iport, static void fdls_process_flogi_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, void *rx_frame) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fabric = &iport->fabric; struct fc_std_flogi *flogi_rsp = (struct fc_std_flogi *) fchdr; @@ -3742,6 +3776,7 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport, static void fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_flogi *plogi_rsp = (struct fc_std_flogi *) fchdr; struct fc_std_els_rjt_rsp *els_rjt = (struct fc_std_els_rjt_rsp *) fchdr; @@ -4003,6 +4038,7 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport, static void fdls_process_fabric_abts_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t s_id; struct fc_std_abts_ba_acc *ba_acc = (struct fc_std_abts_ba_acc *)fchdr; @@ -4360,6 +4396,7 @@ fdls_process_els_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, static void fdls_process_tgt_abts_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t s_id; struct fnic_tport_s *tport; @@ -4549,6 +4586,7 @@ fdls_process_plogi_req(struct fnic_iport_s *iport, static void fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_logo *logo = (struct fc_std_logo *)fchdr; uint32_t nport_id; @@ -4626,6 +4664,7 @@ fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) static void fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_rscn *rscn; struct fc_els_rscn_page *rscn_port = NULL; @@ -4759,6 +4798,7 @@ fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) } void fnic_fdls_disc_start(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic *fnic = iport->fnic; @@ -5103,6 +5143,7 @@ fnic_fdls_validate_and_get_frame_type(struct fnic_iport_s *iport, void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame, int len, int fchdr_offset) + __must_hold(&iport->fnic->fnic_lock) { struct fc_frame_header *fchdr; uint32_t s_id = 0; @@ -5224,6 +5265,7 @@ void fnic_fdls_disc_init(struct fnic_iport_s *iport) } void fnic_fdls_link_down(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_s *tport, *next; struct fnic *fnic = iport->fnic; diff --git a/drivers/scsi/fnic/fip.c b/drivers/scsi/fnic/fip.c index 231dec180675..8f44abfc01a5 100644 --- a/drivers/scsi/fnic/fip.c +++ b/drivers/scsi/fnic/fip.c @@ -602,6 +602,7 @@ void fnic_common_fip_cleanup(struct fnic *fnic) * and clean up and restart the vlan discovery. */ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph) + __must_hold(&fnic->fnic_lock) { struct fnic_iport_s *iport = &fnic->iport; struct fip_cvl *cvl_msg = (struct fip_cvl *)fiph; @@ -678,6 +679,7 @@ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph) * @frame: Received ethernet frame */ int fdls_fip_recv_frame(struct fnic *fnic, void *frame) + __must_hold(&fnic->fnic_lock) { struct ethhdr *eth = (struct ethhdr *)frame; struct fip_header *fiph; diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 0668770dfb5d..b5a6a2b99c4e 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -944,6 +944,7 @@ void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) void fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport, unsigned long flags) + __must_hold(&fnic->fnic_lock) { struct fc_rport *rport; struct fc_rport_identifiers ids; @@ -982,6 +983,7 @@ fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport, void fnic_fdls_remove_tport(struct fnic *fnic, struct fnic_tport_s *tport, unsigned long flags) + __must_hold(&fnic->fnic_lock) { struct rport_dd_data_s *rdd_data; struct fc_rport *rport; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 9607684bc610..afd6bf03b02d 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2641,6 +2641,8 @@ int fnic_device_reset(struct scsi_cmnd *sc) * allocated by mid layer. */ mutex_lock(&fnic->sgreset_mutex); + /* Fake __release() to keep the lock context analyzer happy. */ + __release(&fnic->sgreset_mutex); mqtag = fnic->fnic_max_tag_id; new_sc = 1; } else { @@ -2826,6 +2828,8 @@ int fnic_device_reset(struct scsi_cmnd *sc) if (new_sc) { fnic->sgreset_sc = NULL; + /* Fake __acquire() to keep the lock context analyzer happy. */ + __acquire(&fnic->sgreset_mutex); mutex_unlock(&fnic->sgreset_mutex); }