diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-10-09 15:06:24 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-10-10 13:36:17 +1100 |
commit | 347e24521e87549f50ab049fc131567dd2d0ff92 (patch) | |
tree | e132f53dde47a76e79dac95b7b69ed1d05dede60 /core/pci.c | |
parent | c375cfca55d70b079720b80153a8631a60504bcb (diff) | |
download | skiboot-347e24521e87549f50ab049fc131567dd2d0ff92.zip skiboot-347e24521e87549f50ab049fc131567dd2d0ff92.tar.gz skiboot-347e24521e87549f50ab049fc131567dd2d0ff92.tar.bz2 |
pci-iov: free memory across fast-reboot
pci_set_cap needs a callback to free data and we need to call
that when we're doing __pci_reset()
We also need to free pcrf entries.
In the future, __pci_reset() and pci_remove_bus() need to come
together to be one canonical place on how to free a PCI device
rather than the two we have now. This patch *purely* focuses
on the problem of not leaking memory across fast-reboot.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/pci.c')
-rw-r--r-- | core/pci.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -162,7 +162,7 @@ static void pci_init_pcie_cap(struct phb *phb, struct pci_device *pd) return; } - pci_set_cap(pd, PCI_CFG_CAP_ID_EXP, ecap, NULL, false); + pci_set_cap(pd, PCI_CFG_CAP_ID_EXP, ecap, NULL, NULL, false); /* * XXX We observe a problem on some PLX switches where one @@ -198,7 +198,7 @@ static void pci_init_aer_cap(struct phb *phb, struct pci_device *pd) pos = pci_find_ecap(phb, pd->bdfn, PCIECAP_ID_AER, NULL); if (pos > 0) - pci_set_cap(pd, PCIECAP_ID_AER, pos, NULL, true); + pci_set_cap(pd, PCIECAP_ID_AER, pos, NULL, NULL, true); } static void pci_init_pm_cap(struct phb *phb, struct pci_device *pd) @@ -207,7 +207,7 @@ static void pci_init_pm_cap(struct phb *phb, struct pci_device *pd) pos = pci_find_cap(phb, pd->bdfn, PCI_CFG_CAP_ID_PM); if (pos > 0) - pci_set_cap(pd, PCI_CFG_CAP_ID_PM, pos, NULL, false); + pci_set_cap(pd, PCI_CFG_CAP_ID_PM, pos, NULL, NULL, false); } void pci_init_capabilities(struct phb *phb, struct pci_device *pd) @@ -1651,11 +1651,19 @@ void pci_add_device_nodes(struct phb *phb, static void __pci_reset(struct list_head *list) { struct pci_device *pd; + struct pci_cfg_reg_filter *pcrf; + int i; while ((pd = list_pop(list, struct pci_device, link)) != NULL) { __pci_reset(&pd->children); dt_free(pd->dn); free(pd->slot); + while((pcrf = list_pop(&pd->pcrf, struct pci_cfg_reg_filter, link)) != NULL) { + free(pcrf); + } + for(i=0; i < 64; i++) + if (pd->cap[i].free_func) + pd->cap[i].free_func(pd->cap[i].data); free(pd); } } |