Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Implement a proper rw_tryupgrade #554

Closed
wants to merge 1 commit into from
Closed

Conversation

tuxoko
Copy link
Contributor

@tuxoko tuxoko commented May 25, 2016

Current rw_tryupgrade does rw_exit and then rw_tryenter(RW_RWITER), and then
does rw_enter(RW_READER) if it fails. This violate the assumption that
rw_tryupgrade should be atomic and could cause extra contention or even lock
inversion.

This patch we implement a proper rw_tryupgrade. For rwsem-spinlock, we take
the spinlock to check rwsem->count and rwsem->wait_list. For normal rwsem, we
use cmpxchg on rwsem->count to change the value from single reader to single
writer.

Signed-off-by: Chunwei Chen [email protected]

@behlendorf
Copy link
Contributor

behlendorf commented May 26, 2016

@tuxoko could you open a dummy zfs PR so we can get a test run of this patch. That should give us some build coverage for a few architectures and kernels, plus some functional testing.

That said, this is a quite a bit smaller than I was expecting it to be which is a nice surprise. Maybe this won't be as fragile as I expected.

@dweeezil
Copy link
Contributor

As I alluded to in openzfs/zfs#4692 my only real concern was non-x86 architectures (ARM mainly) and where they are and may be going with their implementations.

@tuxoko
Copy link
Contributor Author

tuxoko commented May 26, 2016

While it may seems that many archs have their own implementations. Actually, they are just optimization for the fast path. They all share the same structure and same slow path. So they should all be logically the same.

Current rw_tryupgrade does rw_exit and then rw_tryenter(RW_RWITER), and then
does rw_enter(RW_READER) if it fails. This violate the assumption that
rw_tryupgrade should be atomic and could cause extra contention or even lock
inversion.

This patch we implement a proper rw_tryupgrade. For rwsem-spinlock, we take
the spinlock to check rwsem->count and rwsem->wait_list. For normal rwsem, we
use cmpxchg on rwsem->count to change the value from single reader to single
writer.

Signed-off-by: Chunwei Chen <[email protected]>
@tuxoko
Copy link
Contributor Author

tuxoko commented May 26, 2016

update: fix splat use RWSEM_COUNT

@behlendorf
Copy link
Contributor

This LGTM. I'm OK with supporting this approach at least until it's no longer maintainable for some reason.

nedbass pushed a commit to nedbass/spl that referenced this pull request Aug 26, 2016
Current rw_tryupgrade does rw_exit and then rw_tryenter(RW_RWITER), and then
does rw_enter(RW_READER) if it fails. This violate the assumption that
rw_tryupgrade should be atomic and could cause extra contention or even lock
inversion.

This patch we implement a proper rw_tryupgrade. For rwsem-spinlock, we take
the spinlock to check rwsem->count and rwsem->wait_list. For normal rwsem, we
use cmpxchg on rwsem->count to change the value from single reader to single
writer.

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Closes openzfs/zfs#4692
Closes openzfs#554
tuxoko pushed a commit to tuxoko/spl that referenced this pull request Sep 8, 2016
Current rw_tryupgrade does rw_exit and then rw_tryenter(RW_RWITER), and then
does rw_enter(RW_READER) if it fails. This violate the assumption that
rw_tryupgrade should be atomic and could cause extra contention or even lock
inversion.

This patch we implement a proper rw_tryupgrade. For rwsem-spinlock, we take
the spinlock to check rwsem->count and rwsem->wait_list. For normal rwsem, we
use cmpxchg on rwsem->count to change the value from single reader to single
writer.

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Closes openzfs/zfs#4692
Closes openzfs#554
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants