Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

locking/rwsem: Add context analysis

Add compiler context analysis annotations.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260306101417.GT1282955@noisy.programming.kicks-ass.net

+28 -5
+2 -2
include/linux/rwsem.h
··· 57 57 struct optimistic_spin_queue osq; /* spinner MCS lock */ 58 58 #endif 59 59 raw_spinlock_t wait_lock; 60 - struct rwsem_waiter *first_waiter; 60 + struct rwsem_waiter *first_waiter __guarded_by(&wait_lock); 61 61 #ifdef CONFIG_DEBUG_RWSEMS 62 62 void *magic; 63 63 #endif ··· 131 131 */ 132 132 static inline bool rwsem_is_contended(struct rw_semaphore *sem) 133 133 { 134 - return sem->first_waiter != NULL; 134 + return data_race(sem->first_waiter != NULL); 135 135 } 136 136 137 137 #if defined(CONFIG_DEBUG_RWSEMS) || defined(CONFIG_DETECT_HUNG_TASK_BLOCKER)
+1
kernel/locking/Makefile
··· 6 6 CONTEXT_ANALYSIS_mutex.o := y 7 7 CONTEXT_ANALYSIS_rtmutex_api.o := y 8 8 CONTEXT_ANALYSIS_ww_rt_mutex.o := y 9 + CONTEXT_ANALYSIS_rwsem.o := y 9 10 10 11 obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o 11 12
+1
kernel/locking/rwbase_rt.c
··· 186 186 187 187 static inline void __rwbase_write_unlock(struct rwbase_rt *rwb, int bias, 188 188 unsigned long flags) 189 + __releases(&rwb->rtmutex.wait_lock) 189 190 { 190 191 struct rt_mutex_base *rtm = &rwb->rtmutex; 191 192
+24 -3
kernel/locking/rwsem.c
··· 72 72 #c, atomic_long_read(&(sem)->count), \ 73 73 (unsigned long) sem->magic, \ 74 74 atomic_long_read(&(sem)->owner), (long)current, \ 75 - (sem)->first_waiter ? "" : "not ")) \ 75 + rwsem_is_contended(sem) ? "" : "not ")) \ 76 76 debug_locks_off(); \ 77 77 } while (0) 78 78 #else ··· 320 320 sem->magic = sem; 321 321 #endif 322 322 atomic_long_set(&sem->count, RWSEM_UNLOCKED_VALUE); 323 - raw_spin_lock_init(&sem->wait_lock); 324 - sem->first_waiter = NULL; 325 323 atomic_long_set(&sem->owner, 0L); 324 + scoped_guard (raw_spinlock_init, &sem->wait_lock) { 325 + sem->first_waiter = NULL; 326 + } 326 327 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 327 328 osq_lock_init(&sem->osq); 328 329 #endif ··· 366 365 367 366 static inline 368 367 bool __rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter) 368 + __must_hold(&sem->wait_lock) 369 369 { 370 370 if (list_empty(&waiter->list)) { 371 371 sem->first_waiter = NULL; ··· 403 401 static inline 404 402 struct rwsem_waiter *next_waiter(const struct rw_semaphore *sem, 405 403 const struct rwsem_waiter *waiter) 404 + __must_hold(&sem->wait_lock) 406 405 { 407 406 struct rwsem_waiter *next = list_first_entry(&waiter->list, 408 407 struct rwsem_waiter, list); ··· 624 621 */ 625 622 static inline bool rwsem_try_write_lock(struct rw_semaphore *sem, 626 623 struct rwsem_waiter *waiter) 624 + __must_hold(&sem->wait_lock) 627 625 { 628 626 struct rwsem_waiter *first = sem->first_waiter; 629 627 long count, new; ··· 1562 1558 * lock for reading 1563 1559 */ 1564 1560 void __sched down_read(struct rw_semaphore *sem) 1561 + __no_context_analysis 1565 1562 { 1566 1563 might_sleep(); 1567 1564 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); ··· 1572 1567 EXPORT_SYMBOL(down_read); 1573 1568 1574 1569 int __sched down_read_interruptible(struct rw_semaphore *sem) 1570 + __no_context_analysis 1575 1571 { 1576 1572 might_sleep(); 1577 1573 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); ··· 1587 1581 EXPORT_SYMBOL(down_read_interruptible); 1588 1582 1589 1583 int __sched down_read_killable(struct rw_semaphore *sem) 1584 + __no_context_analysis 1590 1585 { 1591 1586 might_sleep(); 1592 1587 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); ··· 1605 1598 * trylock for reading -- returns 1 if successful, 0 if contention 1606 1599 */ 1607 1600 int down_read_trylock(struct rw_semaphore *sem) 1601 + __no_context_analysis 1608 1602 { 1609 1603 int ret = __down_read_trylock(sem); 1610 1604 ··· 1619 1611 * lock for writing 1620 1612 */ 1621 1613 void __sched down_write(struct rw_semaphore *sem) 1614 + __no_context_analysis 1622 1615 { 1623 1616 might_sleep(); 1624 1617 rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); ··· 1631 1622 * lock for writing 1632 1623 */ 1633 1624 int __sched down_write_killable(struct rw_semaphore *sem) 1625 + __no_context_analysis 1634 1626 { 1635 1627 might_sleep(); 1636 1628 rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); ··· 1650 1640 * trylock for writing -- returns 1 if successful, 0 if contention 1651 1641 */ 1652 1642 int down_write_trylock(struct rw_semaphore *sem) 1643 + __no_context_analysis 1653 1644 { 1654 1645 int ret = __down_write_trylock(sem); 1655 1646 ··· 1665 1654 * release a read lock 1666 1655 */ 1667 1656 void up_read(struct rw_semaphore *sem) 1657 + __no_context_analysis 1668 1658 { 1669 1659 rwsem_release(&sem->dep_map, _RET_IP_); 1670 1660 __up_read(sem); ··· 1676 1664 * release a write lock 1677 1665 */ 1678 1666 void up_write(struct rw_semaphore *sem) 1667 + __no_context_analysis 1679 1668 { 1680 1669 rwsem_release(&sem->dep_map, _RET_IP_); 1681 1670 __up_write(sem); ··· 1687 1674 * downgrade write lock to read lock 1688 1675 */ 1689 1676 void downgrade_write(struct rw_semaphore *sem) 1677 + __no_context_analysis 1690 1678 { 1691 1679 lock_downgrade(&sem->dep_map, _RET_IP_); 1692 1680 __downgrade_write(sem); ··· 1697 1683 #ifdef CONFIG_DEBUG_LOCK_ALLOC 1698 1684 1699 1685 void down_read_nested(struct rw_semaphore *sem, int subclass) 1686 + __no_context_analysis 1700 1687 { 1701 1688 might_sleep(); 1702 1689 rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_); ··· 1706 1691 EXPORT_SYMBOL(down_read_nested); 1707 1692 1708 1693 int down_read_killable_nested(struct rw_semaphore *sem, int subclass) 1694 + __no_context_analysis 1709 1695 { 1710 1696 might_sleep(); 1711 1697 rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_); ··· 1721 1705 EXPORT_SYMBOL(down_read_killable_nested); 1722 1706 1723 1707 void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) 1708 + __no_context_analysis 1724 1709 { 1725 1710 might_sleep(); 1726 1711 rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); ··· 1730 1713 EXPORT_SYMBOL(_down_write_nest_lock); 1731 1714 1732 1715 void down_read_non_owner(struct rw_semaphore *sem) 1716 + __no_context_analysis 1733 1717 { 1734 1718 might_sleep(); 1735 1719 __down_read(sem); ··· 1745 1727 EXPORT_SYMBOL(down_read_non_owner); 1746 1728 1747 1729 void down_write_nested(struct rw_semaphore *sem, int subclass) 1730 + __no_context_analysis 1748 1731 { 1749 1732 might_sleep(); 1750 1733 rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_); ··· 1754 1735 EXPORT_SYMBOL(down_write_nested); 1755 1736 1756 1737 int __sched down_write_killable_nested(struct rw_semaphore *sem, int subclass) 1738 + __no_context_analysis 1757 1739 { 1758 1740 might_sleep(); 1759 1741 rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_); ··· 1770 1750 EXPORT_SYMBOL(down_write_killable_nested); 1771 1751 1772 1752 void up_read_non_owner(struct rw_semaphore *sem) 1753 + __no_context_analysis 1773 1754 { 1774 1755 DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); 1775 1756 __up_read(sem);