From b3460f44524b145c6c8a760ebe65052560a810bf Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Thu, 15 Oct 2020 11:44:28 +0000 Subject: [PATCH] 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 --- sys/dev/hyperv/netvsc/if_hn.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c index 6c1e62c22d6f..5a57ea796d0e 100644 --- a/sys/dev/hyperv/netvsc/if_hn.c +++ b/sys/dev/hyperv/netvsc/if_hn.c @@ -71,8 +71,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include @@ -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)