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.

Merge tag 'locking-urgent-2024-12-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull locking fix from Ingo Molnar:
"Fix missed rtmutex wakeups causing sporadic boot hangs and other
misbehavior"

* tag 'locking-urgent-2024-12-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/rtmutex: Make sure we wake anything on the wake_q when we release the lock->wait_lock

+17 -3
+16 -2
kernel/locking/rtmutex.c
··· 1292 1292 */ 1293 1293 get_task_struct(owner); 1294 1294 1295 + preempt_disable(); 1295 1296 raw_spin_unlock_irq(&lock->wait_lock); 1297 + /* wake up any tasks on the wake_q before calling rt_mutex_adjust_prio_chain */ 1298 + wake_up_q(wake_q); 1299 + wake_q_init(wake_q); 1300 + preempt_enable(); 1301 + 1296 1302 1297 1303 res = rt_mutex_adjust_prio_chain(owner, chwalk, lock, 1298 1304 next_lock, waiter, task); ··· 1602 1596 * or TASK_UNINTERRUPTIBLE) 1603 1597 * @timeout: the pre-initialized and started timer, or NULL for none 1604 1598 * @waiter: the pre-initialized rt_mutex_waiter 1599 + * @wake_q: wake_q of tasks to wake when we drop the lock->wait_lock 1605 1600 * 1606 1601 * Must be called with lock->wait_lock held and interrupts disabled 1607 1602 */ ··· 1610 1603 struct ww_acquire_ctx *ww_ctx, 1611 1604 unsigned int state, 1612 1605 struct hrtimer_sleeper *timeout, 1613 - struct rt_mutex_waiter *waiter) 1606 + struct rt_mutex_waiter *waiter, 1607 + struct wake_q_head *wake_q) 1614 1608 __releases(&lock->wait_lock) __acquires(&lock->wait_lock) 1615 1609 { 1616 1610 struct rt_mutex *rtm = container_of(lock, struct rt_mutex, rtmutex); ··· 1642 1634 owner = rt_mutex_owner(lock); 1643 1635 else 1644 1636 owner = NULL; 1637 + preempt_disable(); 1645 1638 raw_spin_unlock_irq(&lock->wait_lock); 1639 + if (wake_q) { 1640 + wake_up_q(wake_q); 1641 + wake_q_init(wake_q); 1642 + } 1643 + preempt_enable(); 1646 1644 1647 1645 if (!owner || !rtmutex_spin_on_owner(lock, waiter, owner)) 1648 1646 rt_mutex_schedule(); ··· 1722 1708 1723 1709 ret = task_blocks_on_rt_mutex(lock, waiter, current, ww_ctx, chwalk, wake_q); 1724 1710 if (likely(!ret)) 1725 - ret = rt_mutex_slowlock_block(lock, ww_ctx, state, NULL, waiter); 1711 + ret = rt_mutex_slowlock_block(lock, ww_ctx, state, NULL, waiter, wake_q); 1726 1712 1727 1713 if (likely(!ret)) { 1728 1714 /* acquired the lock */
+1 -1
kernel/locking/rtmutex_api.c
··· 383 383 raw_spin_lock_irq(&lock->wait_lock); 384 384 /* sleep on the mutex */ 385 385 set_current_state(TASK_INTERRUPTIBLE); 386 - ret = rt_mutex_slowlock_block(lock, NULL, TASK_INTERRUPTIBLE, to, waiter); 386 + ret = rt_mutex_slowlock_block(lock, NULL, TASK_INTERRUPTIBLE, to, waiter, NULL); 387 387 /* 388 388 * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might 389 389 * have to fix that up.