NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/60504: lfs_cleanerd can kernel crash on load in lfs_fcntl; lfs_sp == NULL
The following reply was made to PR kern/60504; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Shinichi Doyashiki <clare%csel.org@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost, perseant%NetBSD.org@localhost
Subject: Re: kern/60504: lfs_cleanerd can kernel crash on load in lfs_fcntl;
lfs_sp == NULL
Date: Thu, 27 Aug 2026 02:22:18 +0000
This is a multi-part message in MIME format.
--=_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS
> Date: Sat, 08 Aug 2026 19:47:30 +0900
> From: Shinichi Doyashiki <clare%csel.org@localhost>
>
> I experienced kernel crash while running cvs update on the LFS with
> the WIP patch.
>
> [ 2136.0027704] panic: cpu0: softints stuck for 16 seconds
> [ 2136.0027704] cpu0: Begin traceback...
> [ 2136.0027704] vpanic() at netbsd:vpanic+0x171
> [ 2136.0027704] panic() at netbsd:panic+0x3c
> [ 2136.0027704] heartbeat() at netbsd:heartbeat+0x310
> [ 2136.0027704] hardclock() at netbsd:hardclock+0x89
> [ 2136.0027704] Xresume_lapic_ltimer() at netbsd:Xresume_lapic_ltimer+0x1e
> [ 2136.0027704] --- interrupt ---
> [ 2136.0027704] _kernel_lock() at netbsd:_kernel_lock+0x13e
> [ 2136.0027704] lfs_cluster_work() at netbsd:lfs_cluster_work+0x22
> [ 2136.0027704] workqueue_worker() at netbsd:workqueue_worker+0xf3
> [ 2136.0027704] cpu0: End traceback...
I bet this is just a matter of doing too much work in lfs with the
kernel lock held. I think this is going to require ripping the
band-aid that is the kernel lock off lfs, which we need to do anyway
sooner or later. Most of it is serialized by lfs_lock anyway. Try
the attached patch?
--=_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS
Content-Type: text/plain; charset="ISO-8859-1"; name="lfskernellock"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="lfskernellock.patch"
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1787517532 0
# Sun Aug 23 20:38:52 2026 +0000
# Branch trunk
# Node ID ab8e67a9238a093c16504fef6720a224a9f31a9e
# Parent 4fbd288ac1da9e7d9592ddecf04f7513e244152f
# EXP-Topic riastradh-20260823-lfshacks
WIP: lfs: Run this without the kernel lock.
diff -r 4fbd288ac1da -r ab8e67a9238a sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c Mon Aug 10 13:36:10 2026 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c Sun Aug 23 20:38:52 2026 +0000
@@ -130,7 +130,6 @@ sys_lfs_markv(struct lwp *l, const struc
if ((u_int) blkcnt > LFS_MARKV_MAXBLKCNT)
return (EINVAL);
=20
- KERNEL_LOCK(1, NULL);
blkiov =3D lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
if ((error =3D copyin(SCARG(uap, blkiov), blkiov,
blkcnt * sizeof(BLOCK_INFO))) !=3D 0)
@@ -141,7 +140,6 @@ sys_lfs_markv(struct lwp *l, const struc
blkcnt * sizeof(BLOCK_INFO));
out:
lfs_free(fs, blkiov, LFS_NB_BLKIOV);
- KERNEL_UNLOCK_ONE(NULL);
return error;
}
#else
@@ -171,7 +169,6 @@ sys_lfs_markv(struct lwp *l, const struc
if ((u_int) blkcnt > LFS_MARKV_MAXBLKCNT)
return (EINVAL);
=20
- KERNEL_LOCK(1, NULL);
blkiov =3D lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
blkiov15 =3D lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO_15), LFS_NB_BLKIOV=
);
if ((error =3D copyin(SCARG(uap, blkiov), blkiov15,
@@ -204,7 +201,6 @@ sys_lfs_markv(struct lwp *l, const struc
out:
lfs_free(fs, blkiov, LFS_NB_BLKIOV);
lfs_free(fs, blkiov15, LFS_NB_BLKIOV);
- KERNEL_UNLOCK_ONE(NULL);
return error;
}
#endif
@@ -575,7 +571,6 @@ sys_lfs_bmapv(struct lwp *l, const struc
if ((u_int) blkcnt > SIZE_T_MAX / sizeof(BLOCK_INFO))
return (EINVAL);
#endif
- KERNEL_LOCK(1, NULL);
blkiov =3D lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
if ((error =3D copyin(SCARG(uap, blkiov), blkiov,
blkcnt * sizeof(BLOCK_INFO))) !=3D 0)
@@ -586,7 +581,6 @@ sys_lfs_bmapv(struct lwp *l, const struc
blkcnt * sizeof(BLOCK_INFO));
out:
lfs_free(fs, blkiov, LFS_NB_BLKIOV);
- KERNEL_UNLOCK_ONE(NULL);
return error;
}
#else
@@ -615,7 +609,6 @@ sys_lfs_bmapv(struct lwp *l, const struc
blkcnt =3D SCARG(uap, blkcnt);
if ((size_t) blkcnt > SIZE_T_MAX / sizeof(BLOCK_INFO))
return (EINVAL);
- KERNEL_LOCK(1, NULL);
blkiov =3D lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
blkiov15 =3D lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO_15), LFS_NB_BLKIOV=
);
if ((error =3D copyin(SCARG(uap, blkiov), blkiov15,
@@ -648,7 +641,6 @@ sys_lfs_bmapv(struct lwp *l, const struc
out:
lfs_free(fs, blkiov, LFS_NB_BLKIOV);
lfs_free(fs, blkiov15, LFS_NB_BLKIOV);
- KERNEL_UNLOCK_ONE(NULL);
return error;
}
#endif
@@ -683,9 +675,17 @@ lfs_bmapv(struct lwp *l, fsid_t *fsidp,=20
ump =3D VFSTOULFS(mntp);
fs =3D ump->um_lfs;
=20
- if (fs->lfs_cleaner_thread =3D=3D NULL)
+ mutex_enter(&lfs_lock);
+ if (fs->lfs_cleaner_thread =3D=3D NULL) {
fs->lfs_cleaner_thread =3D curlwp;
+ } else if (fs->lfs_cleaner_thread !=3D curlwp) {
+ error =3D EBUSY;
+ mutex_exit(&lfs_lock);
+ goto out;
+ }
+ panic("cleaning");
KASSERT(fs->lfs_cleaner_thread =3D=3D curlwp);
+ mutex_exit(&lfs_lock);
=20
cnt =3D blkcnt;
=20
@@ -791,6 +791,12 @@ lfs_bmapv(struct lwp *l, fsid_t *fsidp,=20
=20
KASSERTMSG((numrefed =3D=3D 0), "lfs_bmapv: numrefed=3D%d", numrefed);
=20
+ mutex_enter(&lfs_lock);
+ KASSERTMSG(fs->lfs_cleaner_thread =3D=3D curlwp, "cleaner thread is %p",
+ fs->lfs_cleaner_thread);
+ fs->lfs_cleaner_thread =3D NULL;
+ mutex_exit(&lfs_lock);
+out:
vfs_unbusy(mntp);
=20
return 0;
@@ -833,11 +839,9 @@ sys_lfs_segclean(struct lwp *l, const st
if ((error =3D vfs_busy(mntp)) !=3D 0)
return (error);
=20
- KERNEL_LOCK(1, NULL);
lfs_prelock(fs, 0);
error =3D lfs_do_segclean(fs, segnum, l->l_cred, l);
lfs_preunlock(fs);
- KERNEL_UNLOCK_ONE(NULL);
vfs_unbusy(mntp);
return error;
}
diff -r 4fbd288ac1da -r ab8e67a9238a sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c Mon Aug 10 13:36:10 2026 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c Sun Aug 23 20:38:52 2026 +0000
@@ -1184,6 +1184,7 @@ lfs_mountfs(struct vnode *devvp, struct=20
mp->mnt_stat.f_namemax =3D LFS_MAXNAMLEN;
mp->mnt_stat.f_iosize =3D lfs_sb_getbsize(fs);
mp->mnt_flag |=3D MNT_LOCAL;
+ mp->mnt_iflag |=3D IMNT_MPSAFE;
mp->mnt_iflag |=3D IMNT_SHRLOOKUP;
mp->mnt_fs_bshift =3D lfs_sb_getbshift(fs);
mp->mnt_iflag |=3D IMNT_CAN_RWTORO;
diff -r 4fbd288ac1da -r ab8e67a9238a sys/ufs/lfs/lfs_vnops.c
--- a/sys/ufs/lfs/lfs_vnops.c Mon Aug 10 13:36:10 2026 +0000
+++ b/sys/ufs/lfs/lfs_vnops.c Sun Aug 23 20:38:52 2026 +0000
@@ -547,10 +547,8 @@ lfs_set_dirop(struct vnode *dvp, struct=20
if ((error =3D mtsleep(&lfs_dirvcount,
PCATCH | PUSER | PNORELOCK, "lfs_maxdirop", 0,
&lfs_lock)) !=3D 0) {
- mutex_exit(&lfs_lock);
goto unreserve;
}
- mutex_exit(&lfs_lock);
goto restart;
}
=20
--=_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS--
Home |
Main Index |
Thread Index |
Old Index