devfs(4): defer freeing until we drop devmtx ("cdev")
Before r332974 the old code would sometimes cause a rare lock order reversal against pagequeue, which looked roughly like this: witness_checkorder() __mtx_lock-flags() vm_page_alloc() uma_small_alloc() keg_alloc_slab() keg_fetch-slab() zone_fetch-slab() zone_import() zone_alloc_bucket() uma_zalloc_arg() bucket_alloc() uma_zfree_arg() free() devfs_metoo() devfs_populate_loop() devfs_populate() devfs_rioctl() VOP_IOCTL_APV() VOP_IOCTL() vn_ioctl() fo_ioctl() kern_ioctl() sys_ioctl() Since r332974 the original problem no longer exists, but it still makes sense to move things out of the - often congested - lock. Reviewed By: kib, markj Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D27334
This commit is contained in:
parent
e9556246be
commit
4ddb3cc597
@ -482,7 +482,7 @@ devfs_purge(struct devfs_mount *dm, struct devfs_dirent *dd)
|
||||
static void
|
||||
devfs_metoo(struct cdev_priv *cdp, struct devfs_mount *dm)
|
||||
{
|
||||
struct devfs_dirent **dep;
|
||||
struct devfs_dirent **dep, **olddep;
|
||||
int siz;
|
||||
|
||||
siz = (dm->dm_idx + 1) * sizeof *dep;
|
||||
@ -495,8 +495,7 @@ devfs_metoo(struct cdev_priv *cdp, struct devfs_mount *dm)
|
||||
return;
|
||||
}
|
||||
memcpy(dep, cdp->cdp_dirents, (cdp->cdp_maxdirent + 1) * sizeof *dep);
|
||||
if (cdp->cdp_maxdirent > 0)
|
||||
free(cdp->cdp_dirents, M_DEVFS2);
|
||||
olddep = cdp->cdp_maxdirent > 0 ? cdp->cdp_dirents : NULL;
|
||||
cdp->cdp_dirents = dep;
|
||||
/*
|
||||
* XXX: if malloc told us how much we actually got this could
|
||||
@ -504,6 +503,7 @@ devfs_metoo(struct cdev_priv *cdp, struct devfs_mount *dm)
|
||||
*/
|
||||
cdp->cdp_maxdirent = dm->dm_idx;
|
||||
dev_unlock();
|
||||
free(olddep, M_DEVFS2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user