git: 88a502a77b8f - MFC r368749: pci_iov: When pci_iov_detach(9) is called, destroy VF children instead of bailing out with EBUSY if there are any.
Konstantin Belousov
kib at FreeBSD.org
Fri Dec 25 13:47:38 UTC 2020
The branch stable/12 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=88a502a77b8fb48475e02205153c15580c98fc9e
commit 88a502a77b8fb48475e02205153c15580c98fc9e
Author: Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2020-12-18 03:46:50 +0000
Commit: Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2020-12-25 13:22:37 +0000
MFC r368749:
pci_iov: When pci_iov_detach(9) is called, destroy VF children
instead of bailing out with EBUSY if there are any.
(cherry picked from commit 94f5c1cc7186ae555b962d2450cc17e06fd4fda0)
---
sys/dev/pci/pci_iov.c | 53 ++++++++++++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index db8a035f21aa..1173ed15addc 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -94,6 +94,7 @@ static void pci_iov_build_pf_schema(nvlist_t *schema,
nvlist_t **driver_schema);
static void pci_iov_build_vf_schema(nvlist_t *schema,
nvlist_t **driver_schema);
+static int pci_iov_delete_iov_children(struct pci_devinfo *dinfo);
static nvlist_t *pci_iov_get_pf_subsystem_schema(void);
static nvlist_t *pci_iov_get_vf_subsystem_schema(void);
@@ -190,6 +191,7 @@ pci_iov_detach_method(device_t bus, device_t dev)
{
struct pci_devinfo *dinfo;
struct pcicfg_iov *iov;
+ int error;
mtx_lock(&Giant);
dinfo = device_get_ivars(dev);
@@ -200,11 +202,17 @@ pci_iov_detach_method(device_t bus, device_t dev)
return (0);
}
- if (iov->iov_num_vfs != 0 || iov->iov_flags & IOV_BUSY) {
+ if ((iov->iov_flags & IOV_BUSY) != 0) {
mtx_unlock(&Giant);
return (EBUSY);
}
+ error = pci_iov_delete_iov_children(dinfo);
+ if (error != 0) {
+ mtx_unlock(&Giant);
+ return (error);
+ }
+
dinfo->cfg.iov = NULL;
if (iov->iov_cdev) {
@@ -822,31 +830,20 @@ pci_iov_is_child_vf(struct pcicfg_iov *pf, device_t child)
}
static int
-pci_iov_delete(struct cdev *cdev)
+pci_iov_delete_iov_children(struct pci_devinfo *dinfo)
{
device_t bus, dev, vf, *devlist;
- struct pci_devinfo *dinfo;
struct pcicfg_iov *iov;
int i, error, devcount;
uint32_t iov_ctl;
- mtx_lock(&Giant);
- dinfo = cdev->si_drv1;
+ mtx_assert(&Giant, MA_OWNED);
+
iov = dinfo->cfg.iov;
dev = dinfo->cfg.dev;
bus = device_get_parent(dev);
devlist = NULL;
- if (iov->iov_flags & IOV_BUSY) {
- mtx_unlock(&Giant);
- return (EBUSY);
- }
-
- if (iov->iov_num_vfs == 0) {
- mtx_unlock(&Giant);
- return (ECHILD);
- }
-
iov->iov_flags |= IOV_BUSY;
error = device_get_children(bus, &devlist, &devcount);
@@ -904,6 +901,32 @@ pci_iov_delete(struct cdev *cdev)
out:
free(devlist, M_TEMP);
iov->iov_flags &= ~IOV_BUSY;
+ return (error);
+}
+
+static int
+pci_iov_delete(struct cdev *cdev)
+{
+ struct pci_devinfo *dinfo;
+ struct pcicfg_iov *iov;
+ int error;
+
+ mtx_lock(&Giant);
+ dinfo = cdev->si_drv1;
+ iov = dinfo->cfg.iov;
+
+ if ((iov->iov_flags & IOV_BUSY) != 0) {
+ error = EBUSY;
+ goto out;
+ }
+ if (iov->iov_num_vfs == 0) {
+ error = ECHILD;
+ goto out;
+ }
+
+ error = pci_iov_delete_iov_children(dinfo);
+
+out:
mtx_unlock(&Giant);
return (error);
}
More information about the dev-commits-src-branches
mailing list