Whamcloud - gitweb
LU-10428 lnet: call event handlers without res_lock 68/37068/23
authorMr NeilBrown <neilb@suse.de>
Fri, 20 Dec 2019 00:51:43 +0000 (11:51 +1100)
committerOleg Drokin <green@whamcloud.com>
Tue, 1 Sep 2020 03:42:58 +0000 (03:42 +0000)
commitd05427a7856e8f89cf6ec47f2731e12c6fa22901
tree9bfc30c33a8986085becbaee640fbf9d0b87ddad
parent1dda0ef6a70b2c1f6b01054d851ace22e99bb048
LU-10428 lnet: call event handlers without res_lock

Currently event handlers are called with the lnet_res_lock()
(a spinlock) held.  This is a problem if the handler wants
to take a mutex, allocate memory, or sleep for some other
reason.

The lock is needed because handlers for a given md need to
be serialized.  At the very least, the final event which
reports that the md is "unlinked" needs to be called last,
after any other events have been handled.

Instead of using a spinlock to ensure this ordering, we can
use a flag bit in the md.

- Before considering whether to send an event we wait for the flag bit
  to be cleared.  This ensures serialization.
- Also wait for the flag to be cleared before final freeing of the md.
- If this is not an unlink event and we need to call the handler, we
  set the flag bit before dropping lnet_res_lock().  This
  ensures the not further events will happen, and that the md
  won't be freed - so we can still clear the flag.
- use wait_var_event to wait for the flag it to be cleared,
  and wake_up_var() to signal a wakeup.  After wait_var_event()
  returns, we need to take the spinlock and check again.

Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: I4dada92c4c06547bdc567838d129a8851d7de3bd
Reviewed-on: https://review.whamcloud.com/37068
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Chris Horn <chris.horn@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/include/lnet/lib-lnet.h
lnet/include/lnet/lib-types.h
lnet/lnet/lib-md.c
lnet/lnet/lib-msg.c