From d2f1b78596019c01f3fe2c0fe8acc4ba6b1d2b78 Mon Sep 17 00:00:00 2001 From: Zheng Zengkai Date: Wed, 21 Jun 2023 11:50:31 +0800 Subject: [PATCH 1/3] Revert "locking/rwsem: Prevent potential lock starvation" hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7F5L7 CVE: NA -------------------------------- 2f06f702925b ("locking/rwsem: Prevent potential lock starvation"): This patch may have some impact on reader performance as it reduces reader optimistic spinning especially if the lock critical sections are short the number of contending readers are small. This patch will lead to 30%+ performance degradation to fio write_iops_blocksize 4KB testcase, and we stress the system with mysql tpcc for 12 hours, no hungtask occur, So revert this patchset temporarily. This reverts commit f66f7f34a98fe52a924f11f84ceb8f77037978d5. Signed-off-by: Zheng Zengkai --- kernel/locking/rwsem.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 976b20b2dea7..2c4994e58f73 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -998,27 +998,16 @@ rwsem_spin_on_owner(struct rw_semaphore *sem, unsigned long nonspinnable) static struct rw_semaphore __sched * rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, int state) { - long owner, adjustment = -RWSEM_READER_BIAS; - long rcnt = (count >> RWSEM_READER_SHIFT); + long adjustment = -RWSEM_READER_BIAS; struct rwsem_waiter waiter; DEFINE_WAKE_Q(wake_q); bool wake = false; - /* - * To prevent a constant stream of readers from starving a sleeping - * waiter, don't attempt optimistic spinning if the lock is currently - * owned by readers. - */ - owner = atomic_long_read(&sem->owner); - if ((owner & RWSEM_READER_OWNED) && (rcnt > 1) && - !(count & RWSEM_WRITER_LOCKED)) - goto queue; - /* * Save the current read-owner of rwsem, if available, and the * reader nonspinnable bit. */ - waiter.last_rowner = owner; + waiter.last_rowner = atomic_long_read(&sem->owner); if (!(waiter.last_rowner & RWSEM_READER_OWNED)) waiter.last_rowner &= RWSEM_RD_NONSPINNABLE; -- Gitee From 17c1456e0fd5d8583085e2e0c66fa9edf9537a08 Mon Sep 17 00:00:00 2001 From: Zheng Zengkai Date: Wed, 21 Jun 2023 11:50:32 +0800 Subject: [PATCH 2/3] Revert "locking/rwsem: Pass the current atomic count to rwsem_down_read_slowpath()" hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7F5L7 CVE: NA -------------------------------- Revert this patch due to fio performance degradation. This reverts commit fa59b0b02511a925d160070c35ba843f0970b511. Signed-off-by: Zheng Zengkai --- kernel/locking/rwsem.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 2c4994e58f73..7bf45b0a1b1d 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -270,14 +270,14 @@ static inline void rwsem_set_nonspinnable(struct rw_semaphore *sem) owner | RWSEM_NONSPINNABLE)); } -static inline bool rwsem_read_trylock(struct rw_semaphore *sem, long *cntp) +static inline bool rwsem_read_trylock(struct rw_semaphore *sem) { - *cntp = atomic_long_add_return_acquire(RWSEM_READER_BIAS, &sem->count); + long cnt = atomic_long_add_return_acquire(RWSEM_READER_BIAS, &sem->count); - if (WARN_ON_ONCE(*cntp < 0)) + if (WARN_ON_ONCE(cnt < 0)) rwsem_set_nonspinnable(sem); - if (!(*cntp & RWSEM_READ_FAILED_MASK)) { + if (!(cnt & RWSEM_READ_FAILED_MASK)) { rwsem_set_reader_owned(sem); return true; } @@ -996,9 +996,9 @@ rwsem_spin_on_owner(struct rw_semaphore *sem, unsigned long nonspinnable) * Wait for the read lock to be granted */ static struct rw_semaphore __sched * -rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, int state) +rwsem_down_read_slowpath(struct rw_semaphore *sem, int state) { - long adjustment = -RWSEM_READER_BIAS; + long count, adjustment = -RWSEM_READER_BIAS; struct rwsem_waiter waiter; DEFINE_WAKE_Q(wake_q); bool wake = false; @@ -1344,20 +1344,16 @@ static struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem) */ static inline void __down_read(struct rw_semaphore *sem) { - long count; - - if (!rwsem_read_trylock(sem, &count)) { - rwsem_down_read_slowpath(sem, count, TASK_UNINTERRUPTIBLE); + if (!rwsem_read_trylock(sem)) { + rwsem_down_read_slowpath(sem, TASK_UNINTERRUPTIBLE); DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); } } static inline int __down_read_interruptible(struct rw_semaphore *sem) { - long count; - - if (!rwsem_read_trylock(sem, &count)) { - if (IS_ERR(rwsem_down_read_slowpath(sem, count, TASK_INTERRUPTIBLE))) + if (!rwsem_read_trylock(sem)) { + if (IS_ERR(rwsem_down_read_slowpath(sem, TASK_INTERRUPTIBLE))) return -EINTR; DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); } @@ -1366,10 +1362,8 @@ static inline int __down_read_interruptible(struct rw_semaphore *sem) static inline int __down_read_killable(struct rw_semaphore *sem) { - long count; - - if (!rwsem_read_trylock(sem, &count)) { - if (IS_ERR(rwsem_down_read_slowpath(sem, count, TASK_KILLABLE))) + if (!rwsem_read_trylock(sem)) { + if (IS_ERR(rwsem_down_read_slowpath(sem, TASK_KILLABLE))) return -EINTR; DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); } -- Gitee From 6d20e85fb25fc5aa35e432d312b35bc06e2e400e Mon Sep 17 00:00:00 2001 From: Zheng Zengkai Date: Wed, 21 Jun 2023 11:50:33 +0800 Subject: [PATCH 3/3] Revert "locking/rwsem: Better collate rwsem_read_trylock()" hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7F5L7 CVE: NA -------------------------------- Revert this patch due to fio performance degradation. This reverts commit 70e33beccb0a795f19594c41dd5be4146f097bca. Signed-off-by: Zheng Zengkai --- kernel/locking/rwsem.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 7bf45b0a1b1d..cc5cc889b5b7 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -273,16 +273,9 @@ static inline void rwsem_set_nonspinnable(struct rw_semaphore *sem) static inline bool rwsem_read_trylock(struct rw_semaphore *sem) { long cnt = atomic_long_add_return_acquire(RWSEM_READER_BIAS, &sem->count); - if (WARN_ON_ONCE(cnt < 0)) rwsem_set_nonspinnable(sem); - - if (!(cnt & RWSEM_READ_FAILED_MASK)) { - rwsem_set_reader_owned(sem); - return true; - } - - return false; + return !(cnt & RWSEM_READ_FAILED_MASK); } /* @@ -1347,6 +1340,8 @@ static inline void __down_read(struct rw_semaphore *sem) if (!rwsem_read_trylock(sem)) { rwsem_down_read_slowpath(sem, TASK_UNINTERRUPTIBLE); DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); + } else { + rwsem_set_reader_owned(sem); } } @@ -1356,6 +1351,8 @@ static inline int __down_read_interruptible(struct rw_semaphore *sem) if (IS_ERR(rwsem_down_read_slowpath(sem, TASK_INTERRUPTIBLE))) return -EINTR; DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); + } else { + rwsem_set_reader_owned(sem); } return 0; } @@ -1366,6 +1363,8 @@ static inline int __down_read_killable(struct rw_semaphore *sem) if (IS_ERR(rwsem_down_read_slowpath(sem, TASK_KILLABLE))) return -EINTR; DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); + } else { + rwsem_set_reader_owned(sem); } return 0; } -- Gitee