Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

looping in zfs_unlinked_drain? #2240

Closed
prometheanfire opened this issue Apr 5, 2014 · 7 comments
Closed

looping in zfs_unlinked_drain? #2240

prometheanfire opened this issue Apr 5, 2014 · 7 comments
Milestone

Comments

@prometheanfire
Copy link
Contributor

here are all backtraces (and a couple of sysrq-w) thown in.

The system is still up, so if you want any live debugging, tell me now :D

forgot the link... https://gist.github.com/prometheanfire/9988183
and the patches I'm using... https://gist.github.com/9999082

@prometheanfire
Copy link
Contributor Author

could it be related to this or no? openzfs/spl#340

@behlendorf behlendorf added this to the 0.6.4 milestone Apr 7, 2014
@behlendorf behlendorf added the Bug label Apr 7, 2014
@behlendorf
Copy link
Contributor

@prometheanfire I don't think this is related to the spl issue. I assume the only problem this is causing in the rcu stall? It would be useful to get the perf top output for the system if you're seeing it take a large amount of cpu time.

Beyond that if you're rebooting the server it would be very useful just to run with the latest master code. It contains @ryao's zfs_zget() change but not the additional writepage work. If you're able to cause problems we'll want to consider reverting those changes.

@behlendorf behlendorf modified the milestones: 0.6.3, 0.6.4 Apr 7, 2014
@ryao
Copy link
Contributor

ryao commented Apr 9, 2014

@behlendorf I asked @prometheanfire to run perf record -F 997 -p $PID -g -- sleep 10 on the hung thread to determine if it had deadlocked or it was looping infinitely. The resulting flame graph strongly suggests that the thread is looping infinitely:

http://dev.gentoo.org/~ryao/zfs-issue-2240.svg

The pre-processed data from perf script | ./stackcollapse-perf.pl is available at a pastebin:

http://bpaste.net/show/199721/

Interestingly, the infinite loop appears to be in zfs_unlinked_drain(), rather than zfs_zget() as I had thought.

@prometheanfire prometheanfire changed the title looping in zfs_zget? looping in zfs_unlinked_drain? Apr 9, 2014
@behlendorf behlendorf modified the milestones: 0.6.4, 0.6.3 May 2, 2014
ryao added a commit to ryao/zfs that referenced this issue Jun 20, 2014
This reverts commit 7973e46. That had
been intended to workaround a deadlock issue involving zfs_zget(), which
was fixed by 6f9548c. The workaround
had the side effect of causing zfs_zinactive() to cause excessive cpu
utilization in zfs_iput_taskq by queuing an iteration of all objects in
a dataset on every unlink on a directory that had extended attributes.
That resulted in many issue reports about iput_taskq spinning. Since the
original rationale for the change is no longer valid, we can safely
revert it to resolve all of those issue reports.

Conflicts:
	module/zfs/zfs_dir.c

Closes:
	openzfs#457
	openzfs#2058
	openzfs#2128
	openzfs#2240
ryao added a commit to ryao/zfs that referenced this issue Jun 27, 2014
This reverts commit 7973e46. That had
been intended to workaround a deadlock issue involving zfs_zget(), which
was fixed by 6f9548c. The workaround
had the side effect of causing zfs_zinactive() to cause excessive cpu
utilization in zfs_iput_taskq by queuing an iteration of all objects in
a dataset on every unlink on a directory that had extended attributes.
That resulted in many issue reports about iput_taskq spinning. Since the
original rationale for the change is no longer valid, we can safely
revert it to resolve all of those issue reports.

Conflicts:
	module/zfs/zfs_dir.c

Closes:
	openzfs#457
	openzfs#2058
	openzfs#2128
	openzfs#2240
@avg-I
Copy link
Contributor

avg-I commented Jul 31, 2014

This is just a guess.
Does anybody know if it is safe to modify a ZAP object while iterating
over it with zap cursor (within the iteration loop) ?

Let me explain the question.
I see the following in ZoL version of zfs_unlinked_drain, which is not
present in other OpenZFS variants:

        /*
         * Iterate over the contents of the unlinked set.
         */
        for (zap_cursor_init(&zc, zsb->z_os, zsb->z_unlinkedobj);
            zap_cursor_retrieve(&zc, &zap) == 0;
            zap_cursor_advance(&zc)) {
...
                /*
                 * If this is an attribute directory, purge its contents.
                 */
                if (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_XATTR)) {
                        /*
                         * We don't need to check the return value of
                         * zfs_purgedir here, because zfs_rmnode will just
                         * return this xattr directory to the unlinked set
                         * until all of its xattrs are gone.
                         */
                        (void) zfs_purgedir(zp);
                }
...
        }
        zap_cursor_fini(&zc);

So, the code iterates over object IDs in z_unlinkedobj and it may call zfs_purgedir which ends up adding stuff to z_unlinkedobj.

@avg-I
Copy link
Contributor

avg-I commented Aug 5, 2014

I can reproduce this almost every time I crash a system or forcefully reboot it (e.g. power cycle).

@ryao
Copy link
Contributor

ryao commented Aug 5, 2014

@avg-I How many files do you have in the filesystem? Is the forced crash/reboot under any particular workload?

behlendorf added a commit to behlendorf/zfs that referenced this issue Aug 5, 2014
This reverts commit 7973e46 which brings the basic flow of the
code back inline with the other ZFS implementations.  This was
possible due to the work done in these in previous commits.

e89260a Directory xattr znodes hold a reference on their parent
26cb948 Avoid 128K kmem allocations in mzap_upgrade()
4acaaf7 Add zfs_iput_async() interface

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#2408
Issue openzfs#457
Issue openzfs#2058
Issue openzfs#2128
Issue openzfs#2240
@behlendorf
Copy link
Contributor

@avg-I Could you try the patches in #2573, they're designed to address this problem. They've passed all the automated testing and held up perfectly but I'd like to make sure they fix your test case.

Specifically these changes revert the code back so it largely matches the OpenZFS implementation. However, a few iput()'s were left asynchronous to avoid certain deadlocks which can occur under Linux but not the other platforms.

Does anybody know if it is safe to modify a ZAP object while iterating over it with zap cursor (within the iteration loop) ?

This is safe in the sense that it won't deadlock. But unless you lock the entire zap for the traversal you might entries due to concurrent adds/removes. So it's a good thing to avoid if possible.

behlendorf added a commit to behlendorf/zfs that referenced this issue Aug 8, 2014
This reverts commit 7973e46 which brings the basic flow of the
code back in line with the other ZFS implementations.  This
was possible due to the following related changes.

e89260a Directory xattr znodes hold a reference on their parent
6f9548c Fix deadlock in zfs_zget()
26cb948 Avoid 128K kmem allocations in mzap_upgrade()
4acaaf7 Add zfs_iput_async() interface

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#457
Issue openzfs#2058
Issue openzfs#2128
Issue openzfs#2240
behlendorf added a commit to behlendorf/zfs that referenced this issue Aug 8, 2014
This reverts commit 7973e46 which brings the basic flow of the
code back in line with the other ZFS implementations.  This
was possible due to the following related changes.

e89260a Directory xattr znodes hold a reference on their parent
6f9548c Fix deadlock in zfs_zget()
ca043ca Add zfs_iput_async() interface
dd2a794 Avoid 128K kmem allocations in mzap_upgrade()

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#457
Issue openzfs#2058
Issue openzfs#2128
Issue openzfs#2240
ryao pushed a commit to ryao/zfs that referenced this issue Aug 11, 2014
This reverts commit 7973e46 which brings the basic flow of the
code back in line with the other ZFS implementations.  This
was possible due to the following related changes.

e89260a Directory xattr znodes hold a reference on their parent
6f9548c Fix deadlock in zfs_zget()
ca043ca Add zfs_iput_async() interface
dd2a794 Avoid 128K kmem allocations in mzap_upgrade()

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#457
Issue openzfs#2058
Issue openzfs#2128
Issue openzfs#2240
ryao pushed a commit to ryao/zfs that referenced this issue Oct 8, 2014
This reverts commit 7973e46 which brings the basic flow of the
code back in line with the other ZFS implementations.  This
was possible due to the following related changes.

e89260a Directory xattr znodes hold a reference on their parent
6f9548c Fix deadlock in zfs_zget()
ca043ca Add zfs_iput_async() interface
dd2a794 Avoid 128K kmem allocations in mzap_upgrade()

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#457
Issue openzfs#2058
Issue openzfs#2128
Issue openzfs#2240
ryao pushed a commit to ryao/zfs that referenced this issue Nov 29, 2014
This reverts commit 7973e46 which brings the basic flow of the
code back in line with the other ZFS implementations.  This
was possible due to the following related changes.

e89260a Directory xattr znodes hold a reference on their parent
6f9548c Fix deadlock in zfs_zget()
0a50679 Add zfs_iput_async() interface
4dd1893 Avoid 128K kmem allocations in mzap_upgrade()

Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Richard Yao <[email protected]>
Closes openzfs#457
Closes openzfs#2058
Closes openzfs#2128
Closes openzfs#2240
behlendorf added a commit to behlendorf/zfs that referenced this issue Jun 9, 2015
This reverts commit 7973e46 which brings the basic flow of the
code back in line with the other ZFS implementations.  This
was possible due to the following related changes.

e89260a Directory xattr znodes hold a reference on their parent
6f9548c Fix deadlock in zfs_zget()
ca043ca Add zfs_iput_async() interface
dd2a794 Avoid 128K kmem allocations in mzap_upgrade()

Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Richard Yao <[email protected]>
Closes openzfs#457
Closes openzfs#2058
Closes openzfs#2128
Closes openzfs#2240
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants