Skip to content

Commit 407773f

Browse files
committed
Merge: scsi: fnic: Fix crash in fnic_wq_cmpl_handler when FDMI times out
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7062 # Merge Request Required Information MR for upstream patches: 85d6fbc scsi: fnic: Fix missing DMA mapping error in fnic_send_frame() 18b5cb6 scsi: fnic: Set appropriate logging level for log message 9b9b859 scsi: fnic: Add and improve logs in FDMI and FDMI ABTS paths 74f46a0 scsi: fnic: Turn off FDMI ACTIVE flags on link down a35b29b scsi: fnic: Fix crash in fnic_wq_cmpl_handler when FDMI times out Signed-off-by: Karan Kumar <karkumar@redhat.com> ## Summary of Changes Fix for the double frame free bug Fix for FDMI being inactive after link down/up Other fixes are good to have ## Approved Development Ticket(s) All submissions to CentOS Stream must reference a ticket in [Red Hat Jira](https://issues.redhat.com/). JIRA: https://issues.redhat.com/browse/RHEL-90133 Approved-by: John Meneghini <jmeneghi@redhat.com> Approved-by: Maurizio Lombardi <mlombard@redhat.com> Approved-by: Chris Leech <cleech@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents c19c222 + 3f8964a commit 407773f

File tree

5 files changed

+154
-40
lines changed

5 files changed

+154
-40
lines changed

drivers/scsi/fnic/fdls_disc.c

Lines changed: 149 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -763,50 +763,86 @@ static void fdls_send_fabric_abts(struct fnic_iport_s *iport)
763763
iport->fabric.timer_pending = 1;
764764
}
765765

766-
static void fdls_send_fdmi_abts(struct fnic_iport_s *iport)
766+
static uint8_t *fdls_alloc_init_fdmi_abts_frame(struct fnic_iport_s *iport,
767+
uint16_t oxid)
767768
{
768-
uint8_t *frame;
769+
struct fc_frame_header *pfdmi_abts;
769770
uint8_t d_id[3];
771+
uint8_t *frame;
770772
struct fnic *fnic = iport->fnic;
771-
struct fc_frame_header *pfabric_abts;
772-
unsigned long fdmi_tov;
773-
uint16_t oxid;
774-
uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET +
775-
sizeof(struct fc_frame_header);
776773

777774
frame = fdls_alloc_frame(iport);
778775
if (frame == NULL) {
779776
FNIC_FCS_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
780777
"Failed to allocate frame to send FDMI ABTS");
781-
return;
778+
return NULL;
782779
}
783780

784-
pfabric_abts = (struct fc_frame_header *) (frame + FNIC_ETH_FCOE_HDRS_OFFSET);
781+
pfdmi_abts = (struct fc_frame_header *) (frame + FNIC_ETH_FCOE_HDRS_OFFSET);
785782
fdls_init_fabric_abts_frame(frame, iport);
786783

787784
hton24(d_id, FC_FID_MGMT_SERV);
788-
FNIC_STD_SET_D_ID(*pfabric_abts, d_id);
785+
FNIC_STD_SET_D_ID(*pfdmi_abts, d_id);
786+
FNIC_STD_SET_OX_ID(*pfdmi_abts, oxid);
787+
788+
return frame;
789+
}
790+
791+
static void fdls_send_fdmi_abts(struct fnic_iport_s *iport)
792+
{
793+
uint8_t *frame;
794+
struct fnic *fnic = iport->fnic;
795+
unsigned long fdmi_tov;
796+
uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET +
797+
sizeof(struct fc_frame_header);
789798

790799
if (iport->fabric.fdmi_pending & FDLS_FDMI_PLOGI_PENDING) {
791-
oxid = iport->active_oxid_fdmi_plogi;
792-
FNIC_STD_SET_OX_ID(*pfabric_abts, oxid);
800+
frame = fdls_alloc_init_fdmi_abts_frame(iport,
801+
iport->active_oxid_fdmi_plogi);
802+
if (frame == NULL)
803+
return;
804+
805+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
806+
"0x%x: FDLS send FDMI PLOGI abts. iport->fabric.state: %d oxid: 0x%x",
807+
iport->fcid, iport->fabric.state, iport->active_oxid_fdmi_plogi);
793808
fnic_send_fcoe_frame(iport, frame, frame_size);
794809
} else {
795810
if (iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING) {
796-
oxid = iport->active_oxid_fdmi_rhba;
797-
FNIC_STD_SET_OX_ID(*pfabric_abts, oxid);
811+
frame = fdls_alloc_init_fdmi_abts_frame(iport,
812+
iport->active_oxid_fdmi_rhba);
813+
if (frame == NULL)
814+
return;
815+
816+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
817+
"0x%x: FDLS send FDMI RHBA abts. iport->fabric.state: %d oxid: 0x%x",
818+
iport->fcid, iport->fabric.state, iport->active_oxid_fdmi_rhba);
798819
fnic_send_fcoe_frame(iport, frame, frame_size);
799820
}
800821
if (iport->fabric.fdmi_pending & FDLS_FDMI_RPA_PENDING) {
801-
oxid = iport->active_oxid_fdmi_rpa;
802-
FNIC_STD_SET_OX_ID(*pfabric_abts, oxid);
822+
frame = fdls_alloc_init_fdmi_abts_frame(iport,
823+
iport->active_oxid_fdmi_rpa);
824+
if (frame == NULL) {
825+
if (iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING)
826+
goto arm_timer;
827+
else
828+
return;
829+
}
830+
831+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
832+
"0x%x: FDLS send FDMI RPA abts. iport->fabric.state: %d oxid: 0x%x",
833+
iport->fcid, iport->fabric.state, iport->active_oxid_fdmi_rpa);
803834
fnic_send_fcoe_frame(iport, frame, frame_size);
804835
}
805836
}
806837

838+
arm_timer:
807839
fdmi_tov = jiffies + msecs_to_jiffies(2 * iport->e_d_tov);
808840
mod_timer(&iport->fabric.fdmi_timer, round_jiffies(fdmi_tov));
809841
iport->fabric.fdmi_pending |= FDLS_FDMI_ABORT_PENDING;
842+
843+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
844+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
845+
iport->fcid, iport->fabric.fdmi_pending);
810846
}
811847

812848
static void fdls_send_fabric_flogi(struct fnic_iport_s *iport)
@@ -2244,6 +2280,21 @@ void fdls_fabric_timer_callback(struct timer_list *t)
22442280
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
22452281
}
22462282

2283+
void fdls_fdmi_retry_plogi(struct fnic_iport_s *iport)
2284+
{
2285+
struct fnic *fnic = iport->fnic;
2286+
2287+
iport->fabric.fdmi_pending = 0;
2288+
/* If max retries not exhausted, start over from fdmi plogi */
2289+
if (iport->fabric.fdmi_retry < FDLS_FDMI_MAX_RETRY) {
2290+
iport->fabric.fdmi_retry++;
2291+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2292+
"Retry FDMI PLOGI. FDMI retry: %d",
2293+
iport->fabric.fdmi_retry);
2294+
fdls_send_fdmi_plogi(iport);
2295+
}
2296+
}
2297+
22472298
void fdls_fdmi_timer_callback(struct timer_list *t)
22482299
{
22492300
struct fnic_fdls_fabric_s *fabric = from_timer(fabric, t, fdmi_timer);
@@ -2255,15 +2306,15 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22552306
spin_lock_irqsave(&fnic->fnic_lock, flags);
22562307

22572308
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2258-
"fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending);
2309+
"iport->fabric.fdmi_pending: 0x%x\n", iport->fabric.fdmi_pending);
22592310

22602311
if (!iport->fabric.fdmi_pending) {
22612312
/* timer expired after fdmi responses received. */
22622313
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
22632314
return;
22642315
}
22652316
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2266-
"fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending);
2317+
"iport->fabric.fdmi_pending: 0x%x\n", iport->fabric.fdmi_pending);
22672318

22682319
/* if not abort pending, send an abort */
22692320
if (!(iport->fabric.fdmi_pending & FDLS_FDMI_ABORT_PENDING)) {
@@ -2272,33 +2323,37 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22722323
return;
22732324
}
22742325
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2275-
"fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending);
2326+
"iport->fabric.fdmi_pending: 0x%x\n", iport->fabric.fdmi_pending);
22762327

22772328
/* ABTS pending for an active fdmi request that is pending.
22782329
* That means FDMI ABTS timed out
22792330
* Schedule to free the OXID after 2*r_a_tov and proceed
22802331
*/
22812332
if (iport->fabric.fdmi_pending & FDLS_FDMI_PLOGI_PENDING) {
2333+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2334+
"FDMI PLOGI ABTS timed out. Schedule oxid free: 0x%x\n",
2335+
iport->active_oxid_fdmi_plogi);
22822336
fdls_schedule_oxid_free(iport, &iport->active_oxid_fdmi_plogi);
22832337
} else {
2284-
if (iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING)
2338+
if (iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING) {
2339+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2340+
"FDMI RHBA ABTS timed out. Schedule oxid free: 0x%x\n",
2341+
iport->active_oxid_fdmi_rhba);
22852342
fdls_schedule_oxid_free(iport, &iport->active_oxid_fdmi_rhba);
2286-
if (iport->fabric.fdmi_pending & FDLS_FDMI_RPA_PENDING)
2343+
}
2344+
if (iport->fabric.fdmi_pending & FDLS_FDMI_RPA_PENDING) {
2345+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2346+
"FDMI RPA ABTS timed out. Schedule oxid free: 0x%x\n",
2347+
iport->active_oxid_fdmi_rpa);
22872348
fdls_schedule_oxid_free(iport, &iport->active_oxid_fdmi_rpa);
2349+
}
22882350
}
22892351
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2290-
"fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending);
2352+
"iport->fabric.fdmi_pending: 0x%x\n", iport->fabric.fdmi_pending);
22912353

2292-
iport->fabric.fdmi_pending = 0;
2293-
/* If max retries not exhaused, start over from fdmi plogi */
2294-
if (iport->fabric.fdmi_retry < FDLS_FDMI_MAX_RETRY) {
2295-
iport->fabric.fdmi_retry++;
2296-
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2297-
"retry fdmi timer %d", iport->fabric.fdmi_retry);
2298-
fdls_send_fdmi_plogi(iport);
2299-
}
2354+
fdls_fdmi_retry_plogi(iport);
23002355
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
2301-
"fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending);
2356+
"iport->fabric.fdmi_pending: 0x%x\n", iport->fabric.fdmi_pending);
23022357
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
23032358
}
23042359

@@ -3713,13 +3768,60 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37133768

37143769
switch (FNIC_FRAME_TYPE(oxid)) {
37153770
case FNIC_FRAME_TYPE_FDMI_PLOGI:
3771+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3772+
"Received FDMI PLOGI ABTS rsp with oxid: 0x%x", oxid);
3773+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3774+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
3775+
iport->fcid, iport->fabric.fdmi_pending);
37163776
fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_plogi);
3777+
3778+
iport->fabric.fdmi_pending &= ~FDLS_FDMI_PLOGI_PENDING;
3779+
iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING;
3780+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3781+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
3782+
iport->fcid, iport->fabric.fdmi_pending);
37173783
break;
37183784
case FNIC_FRAME_TYPE_FDMI_RHBA:
3785+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3786+
"Received FDMI RHBA ABTS rsp with oxid: 0x%x", oxid);
3787+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3788+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
3789+
iport->fcid, iport->fabric.fdmi_pending);
3790+
3791+
iport->fabric.fdmi_pending &= ~FDLS_FDMI_REG_HBA_PENDING;
3792+
3793+
/* If RPA is still pending, don't turn off ABORT PENDING.
3794+
* We count on the timer to detect the ABTS timeout and take
3795+
* corrective action.
3796+
*/
3797+
if (!(iport->fabric.fdmi_pending & FDLS_FDMI_RPA_PENDING))
3798+
iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING;
3799+
37193800
fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_rhba);
3801+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3802+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
3803+
iport->fcid, iport->fabric.fdmi_pending);
37203804
break;
37213805
case FNIC_FRAME_TYPE_FDMI_RPA:
3806+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3807+
"Received FDMI RPA ABTS rsp with oxid: 0x%x", oxid);
3808+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3809+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
3810+
iport->fcid, iport->fabric.fdmi_pending);
3811+
3812+
iport->fabric.fdmi_pending &= ~FDLS_FDMI_RPA_PENDING;
3813+
3814+
/* If RHBA is still pending, don't turn off ABORT PENDING.
3815+
* We count on the timer to detect the ABTS timeout and take
3816+
* corrective action.
3817+
*/
3818+
if (!(iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING))
3819+
iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING;
3820+
37223821
fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_rpa);
3822+
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
3823+
"0x%x: iport->fabric.fdmi_pending: 0x%x",
3824+
iport->fcid, iport->fabric.fdmi_pending);
37233825
break;
37243826
default:
37253827
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
@@ -3728,10 +3830,16 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37283830
break;
37293831
}
37303832

3731-
del_timer_sync(&iport->fabric.fdmi_timer);
3732-
iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING;
3733-
3734-
fdls_send_fdmi_plogi(iport);
3833+
/*
3834+
* Only if ABORT PENDING is off, delete the timer, and if no other
3835+
* operations are pending, retry FDMI.
3836+
* Otherwise, let the timer pop and take the appropriate action.
3837+
*/
3838+
if (!(iport->fabric.fdmi_pending & FDLS_FDMI_ABORT_PENDING)) {
3839+
timer_delete_sync(&iport->fabric.fdmi_timer);
3840+
if (!iport->fabric.fdmi_pending)
3841+
fdls_fdmi_retry_plogi(iport);
3842+
}
37353843
}
37363844

37373845
static void
@@ -4970,9 +5078,12 @@ void fnic_fdls_link_down(struct fnic_iport_s *iport)
49705078
fdls_delete_tport(iport, tport);
49715079
}
49725080

4973-
if ((fnic_fdmi_support == 1) && (iport->fabric.fdmi_pending > 0)) {
4974-
del_timer_sync(&iport->fabric.fdmi_timer);
4975-
iport->fabric.fdmi_pending = 0;
5081+
if (fnic_fdmi_support == 1) {
5082+
if (iport->fabric.fdmi_pending > 0) {
5083+
timer_delete_sync(&iport->fabric.fdmi_timer);
5084+
iport->fabric.fdmi_pending = 0;
5085+
}
5086+
iport->flags &= ~FNIC_FDMI_ACTIVE;
49765087
}
49775088

49785089
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,

drivers/scsi/fnic/fnic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
#define DRV_NAME "fnic"
4444
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
45-
#define DRV_VERSION "1.8.0.0"
45+
#define DRV_VERSION "1.8.0.2"
4646
#define PFX DRV_NAME ": "
4747
#define DFX DRV_NAME "%d: "
4848

drivers/scsi/fnic/fnic_fcs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ static int fnic_send_frame(struct fnic *fnic, void *frame, int frame_len)
648648
unsigned long flags;
649649

650650
pa = dma_map_single(&fnic->pdev->dev, frame, frame_len, DMA_TO_DEVICE);
651+
if (dma_mapping_error(&fnic->pdev->dev, pa))
652+
return -ENOMEM;
651653

652654
if ((fnic_fc_trace_set_data(fnic->fnic_num,
653655
FNIC_FC_SEND | 0x80, (char *) frame,

drivers/scsi/fnic/fnic_fdls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ void fdls_send_tport_abts(struct fnic_iport_s *iport,
394394
bool fdls_delete_tport(struct fnic_iport_s *iport,
395395
struct fnic_tport_s *tport);
396396
void fdls_fdmi_timer_callback(struct timer_list *t);
397+
void fdls_fdmi_retry_plogi(struct fnic_iport_s *iport);
397398

398399
/* fnic_fcs.c */
399400
void fnic_fdls_init(struct fnic *fnic, int usefip);

drivers/scsi/fnic/fnic_scsi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, unsigned int cq_ind
10581058
if (icmnd_cmpl->scsi_status == SAM_STAT_TASK_SET_FULL)
10591059
atomic64_inc(&fnic_stats->misc_stats.queue_fulls);
10601060

1061-
FNIC_SCSI_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
1061+
FNIC_SCSI_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
10621062
"xfer_len: %llu", xfer_len);
10631063
break;
10641064

0 commit comments

Comments
 (0)