bus/pci: support sigbus handler
This patch implements the ops for the PCI bus sigbus handler. It finds the PCI device that is being hot-unplugged and calls the relevant ops of the hot-unplug handler to handle the hot-unplug failure of the device. Signed-off-by: Jeff Guo <jia.guo@intel.com> Acked-by: Shaopeng He <shaopeng.he@intel.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
This commit is contained in:
parent
538d974bcd
commit
5c96a29934
@ -403,6 +403,36 @@ pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find the device which encounter the failure, by iterate over all device on
|
||||||
|
* PCI bus to check if the memory failure address is located in the range
|
||||||
|
* of the BARs of the device.
|
||||||
|
*/
|
||||||
|
static struct rte_pci_device *
|
||||||
|
pci_find_device_by_addr(const void *failure_addr)
|
||||||
|
{
|
||||||
|
struct rte_pci_device *pdev = NULL;
|
||||||
|
uint64_t check_point, start, end, len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
check_point = (uint64_t)(uintptr_t)failure_addr;
|
||||||
|
|
||||||
|
FOREACH_DEVICE_ON_PCIBUS(pdev) {
|
||||||
|
for (i = 0; i != RTE_DIM(pdev->mem_resource); i++) {
|
||||||
|
start = (uint64_t)(uintptr_t)pdev->mem_resource[i].addr;
|
||||||
|
len = pdev->mem_resource[i].len;
|
||||||
|
end = start + len;
|
||||||
|
if (check_point >= start && check_point < end) {
|
||||||
|
RTE_LOG(DEBUG, EAL, "Failure address %16.16"
|
||||||
|
PRIx64" belongs to device %s!\n",
|
||||||
|
check_point, pdev->device.name);
|
||||||
|
return pdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pci_hot_unplug_handler(struct rte_device *dev)
|
pci_hot_unplug_handler(struct rte_device *dev)
|
||||||
{
|
{
|
||||||
@ -430,6 +460,29 @@ pci_hot_unplug_handler(struct rte_device *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pci_sigbus_handler(const void *failure_addr)
|
||||||
|
{
|
||||||
|
struct rte_pci_device *pdev = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
pdev = pci_find_device_by_addr(failure_addr);
|
||||||
|
if (!pdev) {
|
||||||
|
/* It is a generic sigbus error, no bus would handle it. */
|
||||||
|
ret = 1;
|
||||||
|
} else {
|
||||||
|
/* The sigbus error is caused of hot-unplug. */
|
||||||
|
ret = pci_hot_unplug_handler(&pdev->device);
|
||||||
|
if (ret) {
|
||||||
|
RTE_LOG(ERR, EAL,
|
||||||
|
"Failed to handle hot-unplug for device %s",
|
||||||
|
pdev->name);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pci_plug(struct rte_device *dev)
|
pci_plug(struct rte_device *dev)
|
||||||
{
|
{
|
||||||
@ -462,6 +515,7 @@ struct rte_pci_bus rte_pci_bus = {
|
|||||||
.get_iommu_class = rte_pci_get_iommu_class,
|
.get_iommu_class = rte_pci_get_iommu_class,
|
||||||
.dev_iterate = rte_pci_dev_iterate,
|
.dev_iterate = rte_pci_dev_iterate,
|
||||||
.hot_unplug_handler = pci_hot_unplug_handler,
|
.hot_unplug_handler = pci_hot_unplug_handler,
|
||||||
|
.sigbus_handler = pci_sigbus_handler,
|
||||||
},
|
},
|
||||||
.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
|
.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
|
||||||
.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
|
.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user