On Tue, May 19, 2020 at 11:46 AM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > On Tue, May 19, 2020 at 12:03:06AM -0700, Dan Williams wrote: > > +void revoke_devmem(struct resource *res) > > +{ > > + struct inode *inode = READ_ONCE(devmem_inode); > > + > > + /* > > + * Check that the initialization has completed. Losing the race > > + * is ok because it means drivers are claiming resources before > > + * the fs_initcall level of init and prevent /dev/mem from > > + * establishing mappings. > > + */ > > + smp_rmb(); > > + if (!inode) > > + return; > > Which wmb() is this pairing with? > > > +static int devmem_init_inode(void) > > +{ > > + static struct vfsmount *devmem_vfs_mount; > > + static int devmem_fs_cnt; > > + struct inode *inode; > > + int rc; > > + > > + rc = simple_pin_fs(&devmem_fs_type, &devmem_vfs_mount, &devmem_fs_cnt); > > + if (rc < 0) { > > + pr_err("Cannot mount /dev/mem pseudo filesystem: %d\n", rc); > > + return rc; > > + } > > + > > + inode = alloc_anon_inode(devmem_vfs_mount->mnt_sb); > > + if (IS_ERR(inode)) { > > + rc = PTR_ERR(inode); > > + pr_err("Cannot allocate inode for /dev/mem: %d\n", rc); > > + simple_release_fs(&devmem_vfs_mount, &devmem_fs_cnt); > > + return rc; > > + } > > + > > + /* publish /dev/mem initialized */ > > + WRITE_ONCE(devmem_inode, inode); > > + smp_wmb(); > > + > > + return 0; > > ... is that this one? I don't see what it's guarding against. Surely if > it's needed to ensure that the writes to 'inode' have happened before > the write of the inode pointer, the smp_wmb() needs to be before the > WRITE_ONCE, not after it? Whoops, yes. Thanks for the catch.