Hyper-V: hn: Relinquish cpu in HN_LOCK to avoid deadlock

The try lock loop in HN_LOCK put the thread spinning on cpu if the lock
is not available. It is possible to cause deadlock if the thread holding
the lock is sleeping. Relinquish the cpu to work around this problem even
it doesn't completely solve the issue. The priority inversion could cause
the livelock no matter how less likely it could happen. A more complete
solution may be needed in the future.

Reported by:	Microsoft, Netapp
MFC after:	2 weeks
Sponsored by:	Microsoft
This commit is contained in:
Wei Hu 2020-10-15 11:44:28 +00:00
parent 75c2786c25
commit b3460f4452
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366721

View File

@ -71,8 +71,10 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/queue.h>
#include <sys/lock.h>
#include <sys/proc.h>
#include <sys/rmlock.h>
#include <sys/sbuf.h>
#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@ -165,8 +167,11 @@ __FBSDID("$FreeBSD$");
#define HN_LOCK_ASSERT(sc) sx_assert(&(sc)->hn_lock, SA_XLOCKED)
#define HN_LOCK(sc) \
do { \
while (sx_try_xlock(&(sc)->hn_lock) == 0) \
while (sx_try_xlock(&(sc)->hn_lock) == 0) { \
/* Relinquish cpu to avoid deadlock */ \
sched_relinquish(curthread); \
DELAY(1000); \
} \
} while (0)
#define HN_UNLOCK(sc) sx_xunlock(&(sc)->hn_lock)