Skip to content

Commit e4e0e39

Browse files
Dean Luickdledford
authored andcommitted
IB/hfi1: Fix double QSFP resource acquire on cache refresh
The function refresh_qsfp_cache() acquires the i2c chain resource, but one caller already holds the resource. Change the acquire so all calls to refresh_qsfp_cache() are covered by the acquire and remove the acquire within refresh_qsfp_cache(). Reviewed-by: Easwar Hariharan <[email protected]> Signed-off-by: Dean Luick <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 90315ad commit e4e0e39

File tree

2 files changed

+23
-29
lines changed

2 files changed

+23
-29
lines changed

drivers/staging/rdma/hfi1/platform.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -603,33 +603,27 @@ static void apply_tunings(
603603
"Applying TX settings");
604604
}
605605

606+
/* Must be holding the QSFP i2c resource */
606607
static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
607608
u32 *ptr_rx_preset, u32 *ptr_total_atten)
608609
{
609610
int ret;
610611
u16 lss = ppd->link_speed_supported, lse = ppd->link_speed_enabled;
611612
u8 *cache = ppd->qsfp_info.cache;
612613

613-
ret = acquire_chip_resource(ppd->dd, qsfp_resource(ppd->dd), QSFP_WAIT);
614-
if (ret) {
615-
dd_dev_err(ppd->dd, "%s: hfi%d: cannot lock i2c chain\n",
616-
__func__, (int)ppd->dd->hfi1_id);
617-
return ret;
618-
}
619-
620614
ppd->qsfp_info.limiting_active = 1;
621615

622616
ret = set_qsfp_tx(ppd, 0);
623617
if (ret)
624-
goto bail_unlock;
618+
return ret;
625619

626620
ret = qual_power(ppd);
627621
if (ret)
628-
goto bail_unlock;
622+
return ret;
629623

630624
ret = qual_bitrate(ppd);
631625
if (ret)
632-
goto bail_unlock;
626+
return ret;
633627

634628
if (ppd->qsfp_info.reset_needed) {
635629
reset_qsfp(ppd);
@@ -641,7 +635,7 @@ static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
641635

642636
ret = set_qsfp_high_power(ppd);
643637
if (ret)
644-
goto bail_unlock;
638+
return ret;
645639

646640
if (cache[QSFP_EQ_INFO_OFFS] & 0x4) {
647641
ret = get_platform_config_field(
@@ -651,7 +645,7 @@ static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
651645
ptr_tx_preset, 4);
652646
if (ret) {
653647
*ptr_tx_preset = OPA_INVALID_INDEX;
654-
goto bail_unlock;
648+
return ret;
655649
}
656650
} else {
657651
ret = get_platform_config_field(
@@ -661,7 +655,7 @@ static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
661655
ptr_tx_preset, 4);
662656
if (ret) {
663657
*ptr_tx_preset = OPA_INVALID_INDEX;
664-
goto bail_unlock;
658+
return ret;
665659
}
666660
}
667661

@@ -670,7 +664,7 @@ static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
670664
PORT_TABLE_RX_PRESET_IDX, ptr_rx_preset, 4);
671665
if (ret) {
672666
*ptr_rx_preset = OPA_INVALID_INDEX;
673-
goto bail_unlock;
667+
return ret;
674668
}
675669

676670
if ((lss & OPA_LINK_SPEED_25G) && (lse & OPA_LINK_SPEED_25G))
@@ -690,8 +684,6 @@ static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
690684

691685
ret = set_qsfp_tx(ppd, 1);
692686

693-
bail_unlock:
694-
release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
695687
return ret;
696688
}
697689

@@ -846,6 +838,14 @@ void tune_serdes(struct hfi1_pportdata *ppd)
846838
break;
847839
case PORT_TYPE_QSFP:
848840
if (qsfp_mod_present(ppd)) {
841+
ret = acquire_chip_resource(ppd->dd,
842+
qsfp_resource(ppd->dd),
843+
QSFP_WAIT);
844+
if (ret) {
845+
dd_dev_err(ppd->dd, "%s: hfi%d: cannot lock i2c chain\n",
846+
__func__, (int)ppd->dd->hfi1_id);
847+
goto bail;
848+
}
849849
refresh_qsfp_cache(ppd, &ppd->qsfp_info);
850850

851851
if (ppd->qsfp_info.cache_valid) {
@@ -860,17 +860,17 @@ void tune_serdes(struct hfi1_pportdata *ppd)
860860
* update the cache to reflect the changes
861861
*/
862862
refresh_qsfp_cache(ppd, &ppd->qsfp_info);
863-
if (ret)
864-
goto bail;
865-
866863
limiting_active =
867864
ppd->qsfp_info.limiting_active;
868865
} else {
869866
dd_dev_err(dd,
870867
"%s: Reading QSFP memory failed\n",
871868
__func__);
872-
goto bail;
869+
ret = -EINVAL; /* a fail indication */
873870
}
871+
release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
872+
if (ret)
873+
goto bail;
874874
} else {
875875
ppd->offline_disabled_reason =
876876
HFI1_ODR_MASK(

drivers/staging/rdma/hfi1/qsfp.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ int one_qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
355355
* The calls to qsfp_{read,write} in this function correctly handle the
356356
* address map difference between this mapping and the mapping implemented
357357
* by those functions
358+
*
359+
* The caller must be holding the QSFP i2c chain resource.
358360
*/
359361
int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
360362
{
@@ -371,13 +373,9 @@ int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
371373

372374
if (!qsfp_mod_present(ppd)) {
373375
ret = -ENODEV;
374-
goto bail_no_release;
376+
goto bail;
375377
}
376378

377-
ret = acquire_chip_resource(ppd->dd, qsfp_resource(ppd->dd), QSFP_WAIT);
378-
if (ret)
379-
goto bail_no_release;
380-
381379
ret = qsfp_read(ppd, target, 0, cache, QSFP_PAGESIZE);
382380
if (ret != QSFP_PAGESIZE) {
383381
dd_dev_info(ppd->dd,
@@ -440,8 +438,6 @@ int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
440438
}
441439
}
442440

443-
release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
444-
445441
spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
446442
ppd->qsfp_info.cache_valid = 1;
447443
ppd->qsfp_info.cache_refresh_required = 0;
@@ -450,8 +446,6 @@ int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
450446
return 0;
451447

452448
bail:
453-
release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
454-
bail_no_release:
455449
memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
456450
return ret;
457451
}

0 commit comments

Comments
 (0)