Date: Tue, 29 Dec 2020 14:06:25 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 4ddb3cc5973b - main - devfs(4): defer freeing until we drop devmtx ("cdev") Message-ID: <202012291406.0BTE6Px0069603@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by trasz: URL: https://cgit.FreeBSD.org/src/commit/?id=4ddb3cc5973b94b0502e1683accac87998235857 commit 4ddb3cc5973b94b0502e1683accac87998235857 Author: Edward Tomasz Napierala <trasz@FreeBSD.org> AuthorDate: 2020-12-29 13:45:53 +0000 Commit: Edward Tomasz Napierala <trasz@FreeBSD.org> CommitDate: 2020-12-29 13:47:36 +0000 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 --- sys/fs/devfs/devfs_devs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index cb2db0c1b8b5..19619d94ba1c 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -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); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012291406.0BTE6Px0069603>