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
> 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?
# 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);
- KERNEL_LOCK(1, NULL);
blkiov = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
if ((error = copyin(SCARG(uap, blkiov), blkiov,
blkcnt * sizeof(BLOCK_INFO))) != 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);
- KERNEL_LOCK(1, NULL);
blkiov = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
blkiov15 = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO_15), LFS_NB_BLKIOV);
if ((error = 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 = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
if ((error = copyin(SCARG(uap, blkiov), blkiov,
blkcnt * sizeof(BLOCK_INFO))) != 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 = SCARG(uap, blkcnt);
if ((size_t) blkcnt > SIZE_T_MAX / sizeof(BLOCK_INFO))
return (EINVAL);
- KERNEL_LOCK(1, NULL);
blkiov = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
blkiov15 = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO_15), LFS_NB_BLKIOV);
if ((error = 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,
ump = VFSTOULFS(mntp);
fs = ump->um_lfs;
- if (fs->lfs_cleaner_thread == NULL)
+ mutex_enter(&lfs_lock);
+ if (fs->lfs_cleaner_thread == NULL) {
fs->lfs_cleaner_thread = curlwp;
+ } else if (fs->lfs_cleaner_thread != curlwp) {
+ error = EBUSY;
+ mutex_exit(&lfs_lock);
+ goto out;
+ }
+ panic("cleaning");
KASSERT(fs->lfs_cleaner_thread == curlwp);
+ mutex_exit(&lfs_lock);
cnt = blkcnt;
@@ -791,6 +791,12 @@ lfs_bmapv(struct lwp *l, fsid_t *fsidp,
KASSERTMSG((numrefed == 0), "lfs_bmapv: numrefed=%d", numrefed);
+ mutex_enter(&lfs_lock);
+ KASSERTMSG(fs->lfs_cleaner_thread == curlwp, "cleaner thread is %p",
+ fs->lfs_cleaner_thread);
+ fs->lfs_cleaner_thread = NULL;
+ mutex_exit(&lfs_lock);
+out:
vfs_unbusy(mntp);
return 0;
@@ -833,11 +839,9 @@ sys_lfs_segclean(struct lwp *l, const st
if ((error = vfs_busy(mntp)) != 0)
return (error);
- KERNEL_LOCK(1, NULL);
lfs_prelock(fs, 0);
error = 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
mp->mnt_stat.f_namemax = LFS_MAXNAMLEN;
mp->mnt_stat.f_iosize = lfs_sb_getbsize(fs);
mp->mnt_flag |= MNT_LOCAL;
+ mp->mnt_iflag |= IMNT_MPSAFE;
mp->mnt_iflag |= IMNT_SHRLOOKUP;
mp->mnt_fs_bshift = lfs_sb_getbshift(fs);
mp->mnt_iflag |= 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
if ((error = mtsleep(&lfs_dirvcount,
PCATCH | PUSER | PNORELOCK, "lfs_maxdirop", 0,
&lfs_lock)) != 0) {
- mutex_exit(&lfs_lock);
goto unreserve;
}
- mutex_exit(&lfs_lock);
goto restart;
}
Home |
Main Index |
Thread Index |
Old Index