diff options
Diffstat (limited to 'module/spl')
-rw-r--r-- | module/spl/spl-rwlock.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/module/spl/spl-rwlock.c b/module/spl/spl-rwlock.c index 77f46f2d6..9e96c4f27 100644 --- a/module/spl/spl-rwlock.c +++ b/module/spl/spl-rwlock.c @@ -32,7 +32,37 @@ #define DEBUG_SUBSYSTEM S_RWLOCK -#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK) +#if defined(CONFIG_PREEMPT_RT_FULL) + +#include <linux/rtmutex.h> + +static int +__rwsem_tryupgrade(struct rw_semaphore *rwsem) +{ + ASSERT(rt_mutex_owner(&rwsem->lock) == current); + + /* + * Under the realtime patch series, rwsem is implemented as a + * single mutex held by readers and writers alike. However, + * this implementation would prevent a thread from taking a + * read lock twice, as the mutex would already be locked on + * the second attempt. Therefore the implementation allows a + * single thread to take a rwsem as read lock multiple times + * tracking that nesting as read_depth counter. + */ + if (rwsem->read_depth <= 1) { + /* + * In case, the current thread has not taken the lock + * more than once as read lock, we can allow an + * upgrade to a write lock. rwsem_rt.h implements + * write locks as read_depth == 0. + */ + rwsem->read_depth = 0; + return (1); + } + return (0); +} +#elif defined(CONFIG_RWSEM_GENERIC_SPINLOCK) static int __rwsem_tryupgrade(struct rw_semaphore *rwsem) { |