Fix for deadlock situation in the LinuxKPI's RCU synchronize API.

Deadlock condition:
The return value of TDQ_LOCKPTR(td) is the same for two threads.

1) The first thread signals a wakeup while keeping the rcu_read_lock().
This invokes sched_add() which in turn will try to lock TDQ_LOCK().

2) The second thread is calling synchronize_rcu() calling mi_switch() over
and over again trying to yield(). This prevents the first thread from running
and releasing the RCU reader lock.

Solution:
Release the thread lock while yielding to allow other threads to acquire the
lock pointed to by TDQ_LOCKPTR(td).

Found by:	KrishnamRaju ErapaRaju <Krishna2@chelsio.com>
MFC after:	1 week
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2017-08-21 11:51:40 +00:00
parent 0554abf0e0
commit 714ed5b27b

View File

@ -258,6 +258,15 @@ linux_synchronize_rcu_cb(ck_epoch_t *epoch __unused, ck_epoch_record_t *epoch_re
sched_prio(td, prio);
/* task switch */
mi_switch(SW_VOL | SWT_RELINQUISH, NULL);
/*
* Release the thread lock while yielding to
* allow other threads to acquire the lock
* pointed to by TDQ_LOCKPTR(td). Else a
* deadlock like situation might happen.
*/
thread_unlock(td);
thread_lock(td);
}
} else {
/*