Re: [5.19 cycle] Planning and goals

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 11, 2022 at 05:31:21PM +1000, Dave Chinner wrote:
> On Mon, Apr 11, 2022 at 01:59:35PM +1000, Dave Chinner wrote:
> > On Mon, Apr 11, 2022 at 11:50:23AM +1000, Dave Chinner wrote:
> > > On Thu, Apr 07, 2022 at 03:40:08PM -0700, Alli wrote:
> > > > On Thu, 2022-04-07 at 15:49 +1000, Dave Chinner wrote:
> > > > > On Wed, Apr 06, 2022 at 08:11:06PM -0700, Darrick J. Wong wrote:
> > > > > > On Tue, Apr 05, 2022 at 12:03:12PM +1000, Dave Chinner wrote:
> > > > > > > - Logged attributes V28 (Allison)
> > > > > > > 	- I haven't looked at this since V24, so I'm not sure what
> > > > > > > 	  the current status is. I will do that discovery later in
> > > > > > > 	  the week.
> > > > > > > 	- Merge criteria and status:
> > > > > > > 		- review complete: Not sure
> > > > So far each patch in v29 has at least 2 rvbs I think
> > > 
> > > OK.
> > > 
> > > > > > > 		- no regressions when not enabled: v24 was OK
> > > > > > > 		- no major regressions when enabled: v24 had issues
> > > > > > > 	- Open questions:
> > > > > > > 		- not sure what review will uncover
> > > > > > > 		- don't know what problems testing will show
> > > > > > > 		- what other log fixes does it depend on?
> > > > If it goes on top of whiteouts, it will need some modifications to
> > > > follow the new log item changes that the whiteout set makes.
> > > > 
> > > > Alternately, if the white out set goes in after the larp set, then it
> > > > will need to apply the new log item changes to xfs_attr_item.c as well
> > > 
> > > I figured as much, thanks for confirming!
> > 
> > Ok, so I've just gone through the process of merging the two
> > branches to see where we stand. The modifications to the log code
> > that are needed for the larp code - changes to log iovec processing
> > and padding - are out of date in the LARP v29 patchset.
> > 
> > That is, the versions that are in the intent whiteout patchset are
> > much more sophisticated and cleanly separated. The version of the
> > "avoid extra transactions when no intents" patch in the LARP v29
> > series is really only looking at whether the transaction is dirty,
> > not whether there are intents in the transactions, which is what we
> > really need to know when deciding whether to commit the transaction
> > or not.
> > 
> > There are also a bunch of log iovec changes buried in patch 4 of the
> > LARP patchset which is labelled as "infrastructure". Those changes
> > are cleanly split out as patch 1 in the intent whiteout patchset and
> > provide the xlog_calc_vec_len() function that the LARP code needs.
> > 
> > As such, the RVBs on the patches in the LARPv29 series don't carry
> > over to the patches in the intent whiteout series - they are just
> > too different for that to occur.
> > 
> > The additional changes needed to support intent whiteouts are
> > relatively straight forward for the attri/attrd items, so at this
> > point I'd much prefer that the two patchsets are ordered "intent
> > whiteouts" then "LARP".
> > 
> > I've pushed the compose I just processed to get most of the pending
> > patchsets as they stand into topic branches and onto test machines
> > out to kernel.org. Have a look at:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git xfs-5.19-compose
> > 
> > to see how I merged everything and maybe give it a run through your
> > test cycle to see if there's anything I broke when LARP is enabled....
> 
> generic/642 producded this splat:
> 
>  XFS: Assertion failed: !list_empty(&cil->xc_cil), file: fs/xfs/xfs_log_cil.c, line: 1274
>  ------------[ cut here ]------------
>  kernel BUG at fs/xfs/xfs_message.c:102!
>  invalid opcode: 0000 [#1] PREEMPT SMP
>  CPU: 1 PID: 2187772 Comm: fsstress Not tainted 5.18.0-rc2-dgc+ #1108
>  Call Trace:
>   <TASK>
>   xlog_cil_commit+0xa5a/0xad0
>   __xfs_trans_commit+0xb8/0x330
>   xfs_trans_commit+0x10/0x20
>   xfs_attr_set+0x3e2/0x4c0
>   xfs_xattr_set+0x8d/0xe0
>   __vfs_setxattr+0x6b/0x90
>   __vfs_setxattr_noperm+0x76/0x220
>   __vfs_setxattr_locked+0xdf/0x100
>   vfs_setxattr+0x94/0x170
>   setxattr+0x110/0x200
>   ? __might_fault+0x22/0x30
>   ? strncpy_from_user+0x23/0x170
>   ? getname_flags.part.0+0x4c/0x1b0
>   ? kmem_cache_free+0x1fc/0x380
>   ? __might_sleep+0x43/0x70
>   path_setxattr+0xbf/0xe0
>   __x64_sys_setxattr+0x2b/0x30
>   do_syscall_64+0x35/0x80
>   entry_SYSCALL_64_after_hwframe+0x44/0xae
> 
> Which implies a dirty transaction with nothing in it at the end of
> a run through xfs_attr_set_iter() without LARP enabled. It raced
> with a CIL push, so when the empty dirty transaction tries to push
> the CIL, it assert fails because the CIL is empty....
> 
> I don't know how this happens yet, but there are no intents involved
> here so it doesn't appear to have anything to do with intent logging
> or intent whiteouts at this point.

100% reproducable, and yup, there it is:

STATIC int
xfs_xattri_finish_update(
        struct xfs_attr_item            *attr,
        struct xfs_attrd_log_item       *attrdp,
        uint32_t                        op_flags)
{
.....
        switch (op) {
        case XFS_ATTR_OP_FLAGS_SET:
                error = xfs_attr_set_iter(attr);
                break;
.....
        /*
         * Mark the transaction dirty, even on error. This ensures the
         * transaction is aborted, which:
         *
         * 1.) releases the ATTRI and frees the ATTRD
         * 2.) shuts down the filesystem
         */
        args->trans->t_flags |= XFS_TRANS_DIRTY;
....

Ok, so the problem path is a create that ends up being a pure leaf
add operation. The trace looks like (trimmed for readability):

# trace-cmd record -e xfs_attr\* -e xfs_defer\* -e printk
....

 xfs_attr_leaf_lookup:		ino 0x99a name x11 namelen 3 valuelen 28 hashval 0x1e18b1 filter  flags  op_flags ADDNAME|OKNOENT
 xfs_defer_finish:		tp 0xffff888802e27138 caller __xfs_trans_commit+0x144
 xfs_defer_create_intent:	optype 5 intent (nil) committed 0 nr 1
 xfs_defer_pending_finish:	optype 5 intent (nil) committed 0 nr 1
 xfs_attr_leaf_lookup:		ino 0x99a name x11 namelen 3 valuelen 28 hashval 0x1e18b1 filter  flags  op_flags ADDNAME|OKNOENT
 xfs_attr_leaf_add:		ino 0x99a name x11 namelen 3 valuelen 28 hashval 0x1e18b1 filter  flags  op_flags ADDNAME|OKNOENT
 xfs_attr_leaf_add_work:	ino 0x99a name x11 namelen 3 valuelen 28 hashval 0x1e18b1 filter  flags  op_flags ADDNAME|OKNOENT
 xfs_attr_leaf_addname_return:	state change 4 ino 0x99a
 xfs_defer_trans_roll:		tp 0xffff888802e27138 caller xfs_defer_finish_noroll+0x2a5
 xfs_defer_pending_finish:	optype 5 intent (nil) committed 0 nr 1
 xfs_defer_finish_done:		tp 0xffff888802e273f0 caller __xfs_trans_commit+0x144
 console:			[   94.219375] XFS: Assertion failed: !list_empty(&cil->xc_cil), file: fs/xfs/

So we have a create/set operation here. THe first lookup is to check
that xattr exists or not. Gets -ENOENT so it sets the transaction
to deferred and commits it. That gets us into xfs_defer_finish()
where we process the xattri. We don't create an intent (because larp
is false), then we finish it. This calls into:

xfs_xattri_finish_update()
  xfs_attr_set_iter()
    case XFS_DAS_UNINIT:
      xfs_attr_leaf_addname()
        xfs_attr_leaf_try_add()
	  xfs_attr3_leaf_add()
	    xfs_attr3_leaf_add_work()
        attr->xattri_dela_state = XFS_DAS_FOUND_LBLK;
	trace_xfs_attr_leaf_addname_return()
	  state change 4, XFS_DAS_FOUND_LBLK == 4
	return -EAGAIN;

args->trans->t_flags |= XFS_TRANS_DIRTY;

Now we return -EAGAIN to xfs_defer_finish_one(), which requeues
the defered item onto the deferred work, which then returns to
xfs_defer_finish_noroll() and we go around the loop again.
We roll the dirty transaction that contained the dirty leaf buffer,
committing it, then run the loop again.

This time however, we run:

xfs_xattri_finish_update
  xfs_attr_set_iter
    case XFS_DAS_FOUND_LBLK:
      <tries to set up and copy remote xattr val>  <XXX - why?>
      <no remote xattr, nothing dirtied>
      <not a RENAME op>
        <no remote blocks, nothing dirtied>
      return 0;

args->trans->t_flags |= XFS_TRANS_DIRTY;

So, at this point, we now have a dirty transaction with no modified
objects in it. All we need to do how is have some other thread flush
the CIL and then for this task to win the race to be the first
transaction to commit once the push switches to a new, empty
context and unlocks the context lock....

And then xlog_cil_commit() trips over an empty CIL because we had a
dirty transaction with no dirty items attached to it.

So, the code snippet I pointed to above that unconditionally makes
the xattr transaction dirty is invalid. We should only be setting
the transaction dirty when we attach dirty an item attached to the
transaction. If we need to abort because of an unrecoverable error,
we need to shut down the log here. That will cause the transaction
to be aborted when it returns to the core defer/commit code.

In debugging this, there are several things I've noticed that need
correcting/fixing. Rather than go around the review circle to try to
get them all understood and fixed, I think I'm just going to writing
patches and send them out for review as I get them done and tested.
The faster we knock out the problems, the sooner we get this stuff
merged.

I'll start on this tomorrow morning....

Cheers,

Dave.
-- 
Dave Chinner
david@xxxxxxxxxxxxx



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux