LU-11089 obdclass: remove locking from lu_context_exit()
Recent patches suggest that the locking in lu_context_exit() hurts
performance as the changes that make are to improve performance.
Let's go all the way and remove the locking completely.
The race of interest is between lu_context_exit() finalizing a
value with ->lct_exit, and lu_context_key_quiesce() freeing
the value with key_fini().
If lu_context_key_quiesce() has started, there is no need to
finalize the value - it can just be freed. So lu_context_exit()
is changed to skip the call to ->lcu_exit if LCT_QUIESCENT it set.
If lc_context_exit() has started, lu_context_key_quiesce() must wait
for it to complete - it cannot just skip the freeing. To allow
this we introduce a new lc_state, LCS_LEAVING. This indicates that
->lcu_exit might be called. Before calling key_fini() on a context,
lu_context_key_quiesce() waits (spinning) for lc_state to move on from
LCS_LEAVING.
Linux-commit:
ac3f8fd6e61b245fa9c14e3164203c1211c5ef6b
fix possible hang waiting for LCS_LEAVING
As lu_context_key_quiesce() spins waiting for LCS_LEAVING to
change, it is important the we set and then clear in within a
non-preemptible region. If the thread that spins pre-empty the
thread that sets-and-clears the state while the state is LCS_LEAVING,
then it can spin indefinitely, particularly on a single-CPU machine.
Also update the comment to explain this dependency.
Linux-commit:
4859716f66db6989ef4bf52434b5b1d813c6adc1
Change-Id: I92ef27304eab43518fcb216b9c9cb4875cc9b98c
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/32713
Tested-by: Jenkins
Reviewed-by: Gu Zheng <gzheng@ddn.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>