On Sun, Mar 27, 2022 at 03:36:20PM +0200, Sebastien Marie wrote:
> Hi,
>
> v_numoutput is a struct member of vnode which is used to keep track the
> number
> of writes in progress.
>
> in several function comments, it is marked as "Manipulates v_numoutput. Must
> be
> called at splbio()".
>
> So I added a "[B]" mark in the comment to properly document the need of
> IPL_BIO
> protection.
>
> Next, I audited the tree for usage. I found 2 occurrences of v_numoutput
> (modification) without the required protection, inside dev/softraid.c. I
> added
> them.
>
> Comments or OK ?
anyone ?
the purpose of splbio() is to protect v_numoutput manipulation from interrupts.
for example, bread_cluster_callback() is called from interrupt context (per
code
documentation), and could modify v_numoutput (code path: bread_cluster_callback
-> biodone -> vwakeup).
to ensure that it effectively required (code not already called at IPL_BIO
level), I added some splassert() (the machine is using softraid with encrypting
discipline):
- for sr_rw:
splassert_check(6,ffffffff81fde589,30859b2dea1d26e8,400,8000,8000) at
splassert_check+0x4d
sr_rw(ffff80000041f000,400,ffff800000472000,8000,10,0) at sr_rw+0x1fe
sr_meta_save(ffff800000422000,1,628df3ebb476eac1,ffff800000422000,ffffffff82712a68,0)
at sr_meta_save+0x23d
sr_ioctl_createraid(ffff80000041f000,ffffffff82712a68,0,ffffffff822fe290,cae617dbeff84e1f,ffffffff82712d50)
at sr_ioctl_createraid+0xe03
sr_boot_assembly(ffff80000041f000,ffff80000041f000,e2eb5961e3789080,ffff80000041f328,ffff80000041f000,ffffffff8229fd40)
at sr_boot_assembly+0x936
sr_attach(0,ffff80000041f000,0,0,ab529b23aa62cd2b,0) at sr_attach+0x157
config_attach(0,ffffffff822bff60,0,0,33d5fbe4fc2cb990,c000000) at
config_attach+0x1f4
main(0,0,c000000,1001000,1000000,ffff8000fffffa40) at main+0x4fb
splassert: sr_rw: want 6 have 0
Starting stack trace...
splassert_check(6,ffffffff81fde589) at splassert_check+0x4d
sr_rw(ffff80000041f000,413,ffff800001a52000,8000,10,0) at sr_rw+0x1fe
sr_meta_save(ffff800001a0b000,1) at sr_meta_save+0x23d
sr_ioctl_createraid(ffff80000041f000,ffff80000199b800,1,0) at
sr_ioctl_createraid+0xe03
sr_bio_handler(ffff80000041f000,0,c2e84226,ffff80000199b800) at
sr_bio_handler+0x223
VOP_IOCTL(ffff8000a7ae9730,c2e84226,ffff80000199b800,3,fffffd879e7e4f00,ffff8000a76acd28)
at VOP_IOCTL+0x5c
vn_ioctl(fffffd8746f39080,c2e84226,ffff80000199b800,ffff8000a76acd28) at
vn_ioctl+0x75
sys_ioctl(ffff8000a76acd28,ffff8000a7d277e0,ffff8000a7d27830) at sys_ioctl+0x2c4
syscall(ffff8000a7d278a0) at syscall+0x374
Xsyscall() at Xsyscall+0x128
end of kernel
- for sr_ccb_rw, I had some problem to get proper/readable stack trace as the
console is just spammed too much and stack trace are interleaved.
splassert: sr_ccb_rw: want 6 have 0
Starting stack trace...
splassert_check(6,ffffffff81f0b74d) at splassert_check+0x4d
sr_ccb_rw(ffff800000422000,0,836b80,3800,ffff800021bff000,1001,f0cbd67d55f39eb0)
at sr_ccb_rw+0x194
sr_crypto_dev_rw(ffff800000423300,ffff800000423300) at sr_crypto_dev_rw+0x4a
sr_crypto_rw(ffff800000423300) at sr_crypto_rw+0xb6
sr_scsi_cmd(fffffd86af9f11c0) at sr_scsi_cmd+0x30c
scsi_xs_exec(fffffd86af9f11c0) at scsi_xs_exec+0x3f
sdstart(fffffd86af9f11c0) at sdstart+0x2d1
scsi_iopool_run(ffff800000422aa8) at scsi_iopool_run+0x159
scsi_xsh_runqueueffffd86af9f11c0) at scsi_xs_exec+0x3f
sdstart(fffffd86af9f11c0) 00000419d80) at scsi_xsh_add+0x91
sdstrategy(fffffd86b037fec8) at sdstrategy+0x112
spec_strategy(ffff8000a7689c88) at spec_strategy+0x56
VOP_STRATEGY(ffff8000fffda770,fffffd86b037fec8) at VOP_STRATEGY+0x4c
ufs_strategy(ffff8000a7689d18) at ufs_strategy+0xe5
VOP_STRATEGY(ffff8000a78bab98,fffffd86b037fec8) at VOP_STRATEGY+0x4c
bwrite(fffffd86b037fec8) at bwrite+0x138
ufs_dirremove(ffff8000a78bab98,fffffd874cda31e0,800c,0) at ufs_dirremove+0x19f
ufs_remove(ffff8000a7689e50) at ufs_remove+0xbe
VOP_REMOVE(ffff80s_truncate+0x7d0
ufs_inactive(ffff8000a7689d98) at ufs_inactive+
dounlinkat(ffff8000a766e540,ffffff9c,146b649b778,0) at dounlinkat+0xbd
syscall(ffff8000a768a070) at syscall+0x374
Xsyscall() at Xsyscall+0x128
end of kernel
end trace frame: 0x7f7ffffbffa0, count: 235
End of stack trace.
> --
> Sebastien Marie
>
> Index: dev/softraid.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/softraid.c,v
> retrieving revision 1.422
> diff -u -p -r1.422 softraid.c
> --- dev/softraid.c 20 Mar 2022 13:14:02 -0000 1.422
> +++ dev/softraid.c 27 Mar 2022 13:28:55 -0000
> @@ -437,8 +437,12 @@ sr_rw(struct sr_softc *sc, dev_t dev, ch
> b.b_resid = bufsize;
> b.b_vp = vp;
>
> - if ((b.b_flags & B_READ) == 0)
> + if ((b.b_flags & B_READ) == 0) {
> + int s;
> + s = splbio();
> vp->v_numoutput++;
> + splx(s);
> + }
>
> LIST_INIT(&b.b_dep);
> VOP_STRATEGY(vp, &b);
> @@ -2006,8 +2010,12 @@ sr_ccb_rw(struct sr_discipline *sd, int
> ccb->ccb_buf.b_vp = sc->src_vn;
> ccb->ccb_buf.b_bq = NULL;
>
> - if (!ISSET(ccb->ccb_buf.b_flags, B_READ))
> + if (!ISSET(ccb->ccb_buf.b_flags, B_READ)) {
> + int s;
> + s = splbio();
> ccb->ccb_buf.b_vp->v_numoutput++;
> + splx(s);
> + }
>
> LIST_INIT(&ccb->ccb_buf.b_dep);
>
> Index: sys/vnode.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/vnode.h,v
> retrieving revision 1.163
> diff -u -p -r1.163 vnode.h
> --- sys/vnode.h 12 Dec 2021 09:14:59 -0000 1.163
> +++ sys/vnode.h 27 Mar 2022 13:28:56 -0000
> @@ -89,6 +89,7 @@ RBT_HEAD(namecache_rb_cache, namecache);
> * Locks used to protect struct members in struct vnode:
> * a atomic
> * V vnode_mtx
> + * B IPL_BIO
> */
> struct uvm_vnode;
> struct vnode {
> @@ -113,7 +114,7 @@ struct vnode {
> struct buf_rb_bufs v_bufs_tree; /* lookup of all bufs */
> struct buflists v_cleanblkhd; /* clean blocklist head */
> struct buflists v_dirtyblkhd; /* dirty blocklist head */
> - u_int v_numoutput; /* num of writes in progress */
> + u_int v_numoutput; /* [B] num of writes in progress */
> LIST_ENTRY(vnode) v_synclist; /* vnode with dirty buffers */
> union {
> struct mount *vu_mountedhere;/* ptr to mounted vfs (VDIR) */
--
Sebastien Marie