Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bus: mhi: host: pci_generic: Read SUBSYSTEM_VENDOR_ID for VF's to check status

In SR-IOV enabled devices, reading the VF DEVICE/VENDOR ID register
returns `FFFFh`, as specified in section 3.4.1.1 of the PCIe SR-IOV spec.
To accurately determine device activity, read the PCIe VENDOR_ID of
the Physical Function (PF) instead.
Health check monitoring for Virtual Functions (VFs) has been disabled,
since VFs are not physical functions and lack direct hardware control.
This change prevents unnecessary CPU cycles from being consumed by VF
health checks, which are both unintended and non-functional.

Signed-off-by: Vivek Pernamitta <quic_vpernami@quicinc.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Reviewed-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Link: https://patch.msgid.link/20250912-uevent_vdev_next-20250911-v4-2-fa2f6ccd301b@quicinc.com

authored by

Vivek Pernamitta and committed by
Manivannan Sadhasivam
b4d01c5b a9e3d5a6

+24 -10
+24 -10
drivers/bus/mhi/host/pci_generic.c
··· 1082 1082 struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev); 1083 1083 u16 vendor = 0; 1084 1084 1085 - if (pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor)) 1085 + if (pci_read_config_word(pci_physfn(pdev), PCI_VENDOR_ID, &vendor)) 1086 1086 return false; 1087 1087 1088 1088 if (vendor == (u16) ~0 || vendor == 0) ··· 1193 1193 1194 1194 dev_warn(&pdev->dev, "device recovery started\n"); 1195 1195 1196 - timer_delete(&mhi_pdev->health_check_timer); 1196 + if (pdev->is_physfn) 1197 + timer_delete(&mhi_pdev->health_check_timer); 1198 + 1197 1199 pm_runtime_forbid(&pdev->dev); 1198 1200 1199 1201 /* Clean up MHI state */ ··· 1222 1220 dev_dbg(&pdev->dev, "Recovery completed\n"); 1223 1221 1224 1222 set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status); 1225 - mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1223 + 1224 + if (pdev->is_physfn) 1225 + mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1226 + 1226 1227 return; 1227 1228 1228 1229 err_unprepare: ··· 1312 1307 else 1313 1308 mhi_cntrl_config = info->config; 1314 1309 1315 - timer_setup(&mhi_pdev->health_check_timer, health_check, 0); 1310 + /* Initialize health check monitor only for Physical functions */ 1311 + if (pdev->is_physfn) 1312 + timer_setup(&mhi_pdev->health_check_timer, health_check, 0); 1316 1313 1317 1314 mhi_cntrl = &mhi_pdev->mhi_cntrl; 1318 1315 ··· 1378 1371 set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status); 1379 1372 1380 1373 /* start health check */ 1381 - mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1374 + if (pdev->is_physfn) 1375 + mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1382 1376 1383 1377 /* Allow runtime suspend only if both PME from D3Hot and M3 are supported */ 1384 1378 if (pci_pme_capable(pdev, PCI_D3hot) && !(info->no_m3)) { ··· 1404 1396 struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev); 1405 1397 struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl; 1406 1398 1407 - timer_delete_sync(&mhi_pdev->health_check_timer); 1399 + if (pdev->is_physfn) 1400 + timer_delete_sync(&mhi_pdev->health_check_timer); 1408 1401 cancel_work_sync(&mhi_pdev->recovery_work); 1409 1402 1410 1403 if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { ··· 1433 1424 1434 1425 dev_info(&pdev->dev, "reset\n"); 1435 1426 1436 - timer_delete(&mhi_pdev->health_check_timer); 1427 + if (pdev->is_physfn) 1428 + timer_delete(&mhi_pdev->health_check_timer); 1437 1429 1438 1430 /* Clean up MHI state */ 1439 1431 if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { ··· 1479 1469 } 1480 1470 1481 1471 set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status); 1482 - mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1472 + if (pdev->is_physfn) 1473 + mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1483 1474 } 1484 1475 1485 1476 static pci_ers_result_t mhi_pci_error_detected(struct pci_dev *pdev, ··· 1545 1534 if (test_and_set_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status)) 1546 1535 return 0; 1547 1536 1548 - timer_delete(&mhi_pdev->health_check_timer); 1537 + if (pdev->is_physfn) 1538 + timer_delete(&mhi_pdev->health_check_timer); 1539 + 1549 1540 cancel_work_sync(&mhi_pdev->recovery_work); 1550 1541 1551 1542 if (!test_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status) || ··· 1598 1585 } 1599 1586 1600 1587 /* Resume health check */ 1601 - mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1588 + if (pdev->is_physfn) 1589 + mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1602 1590 1603 1591 /* It can be a remote wakeup (no mhi runtime_get), update access time */ 1604 1592 pm_runtime_mark_last_busy(dev);