Commit ebf4c55c authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar
Browse files

locking/mutex: Make mutex::wait_lock raw



The wait_lock of mutex is really a low level lock. Convert it to a
raw_spinlock like the wait_lock of rtmutex.

[ mingo: backmerged the test_lockup.c build fix by bigeasy. ]

Co-developed-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20210815211304.166863404@linutronix.de
parent 4f1893ec
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -50,7 +50,7 @@
 */
 */
struct mutex {
struct mutex {
	atomic_long_t		owner;
	atomic_long_t		owner;
	spinlock_t		wait_lock;
	raw_spinlock_t		wait_lock;
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
	struct optimistic_spin_queue osq; /* Spinner MCS lock */
	struct optimistic_spin_queue osq; /* Spinner MCS lock */
#endif
#endif
@@ -105,7 +105,7 @@ do { \


#define __MUTEX_INITIALIZER(lockname) \
#define __MUTEX_INITIALIZER(lockname) \
		{ .owner = ATOMIC_LONG_INIT(0) \
		{ .owner = ATOMIC_LONG_INIT(0) \
		, .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \
		, .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(lockname.wait_lock) \
		, .wait_list = LIST_HEAD_INIT(lockname.wait_list) \
		, .wait_list = LIST_HEAD_INIT(lockname.wait_list) \
		__DEBUG_MUTEX_INITIALIZER(lockname) \
		__DEBUG_MUTEX_INITIALIZER(lockname) \
		__DEP_MAP_MUTEX_INITIALIZER(lockname) }
		__DEP_MAP_MUTEX_INITIALIZER(lockname) }
+11 −11
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ void
__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
{
{
	atomic_long_set(&lock->owner, 0);
	atomic_long_set(&lock->owner, 0);
	spin_lock_init(&lock->wait_lock);
	raw_spin_lock_init(&lock->wait_lock);
	INIT_LIST_HEAD(&lock->wait_list);
	INIT_LIST_HEAD(&lock->wait_list);
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
	osq_lock_init(&lock->osq);
	osq_lock_init(&lock->osq);
@@ -486,9 +486,9 @@ ww_mutex_set_context_fastpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
	 * Uh oh, we raced in fastpath, check if any of the waiters need to
	 * Uh oh, we raced in fastpath, check if any of the waiters need to
	 * die or wound us.
	 * die or wound us.
	 */
	 */
	spin_lock(&lock->base.wait_lock);
	raw_spin_lock(&lock->base.wait_lock);
	__ww_mutex_check_waiters(&lock->base, ctx);
	__ww_mutex_check_waiters(&lock->base, ctx);
	spin_unlock(&lock->base.wait_lock);
	raw_spin_unlock(&lock->base.wait_lock);
}
}


#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
@@ -966,7 +966,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
		return 0;
		return 0;
	}
	}


	spin_lock(&lock->wait_lock);
	raw_spin_lock(&lock->wait_lock);
	/*
	/*
	 * After waiting to acquire the wait_lock, try again.
	 * After waiting to acquire the wait_lock, try again.
	 */
	 */
@@ -1032,7 +1032,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
				goto err;
				goto err;
		}
		}


		spin_unlock(&lock->wait_lock);
		raw_spin_unlock(&lock->wait_lock);
		schedule_preempt_disabled();
		schedule_preempt_disabled();


		first = __mutex_waiter_is_first(lock, &waiter);
		first = __mutex_waiter_is_first(lock, &waiter);
@@ -1047,9 +1047,9 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
		    (first && mutex_optimistic_spin(lock, ww_ctx, &waiter)))
		    (first && mutex_optimistic_spin(lock, ww_ctx, &waiter)))
			break;
			break;


		spin_lock(&lock->wait_lock);
		raw_spin_lock(&lock->wait_lock);
	}
	}
	spin_lock(&lock->wait_lock);
	raw_spin_lock(&lock->wait_lock);
acquired:
acquired:
	__set_current_state(TASK_RUNNING);
	__set_current_state(TASK_RUNNING);


@@ -1074,7 +1074,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
	if (ww_ctx)
	if (ww_ctx)
		ww_mutex_lock_acquired(ww, ww_ctx);
		ww_mutex_lock_acquired(ww, ww_ctx);


	spin_unlock(&lock->wait_lock);
	raw_spin_unlock(&lock->wait_lock);
	preempt_enable();
	preempt_enable();
	return 0;
	return 0;


@@ -1082,7 +1082,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
	__set_current_state(TASK_RUNNING);
	__set_current_state(TASK_RUNNING);
	__mutex_remove_waiter(lock, &waiter);
	__mutex_remove_waiter(lock, &waiter);
err_early_kill:
err_early_kill:
	spin_unlock(&lock->wait_lock);
	raw_spin_unlock(&lock->wait_lock);
	debug_mutex_free_waiter(&waiter);
	debug_mutex_free_waiter(&waiter);
	mutex_release(&lock->dep_map, ip);
	mutex_release(&lock->dep_map, ip);
	preempt_enable();
	preempt_enable();
@@ -1243,7 +1243,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
		}
		}
	}
	}


	spin_lock(&lock->wait_lock);
	raw_spin_lock(&lock->wait_lock);
	debug_mutex_unlock(lock);
	debug_mutex_unlock(lock);
	if (!list_empty(&lock->wait_list)) {
	if (!list_empty(&lock->wait_list)) {
		/* get the first entry from the wait-list: */
		/* get the first entry from the wait-list: */
@@ -1260,7 +1260,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
	if (owner & MUTEX_FLAG_HANDOFF)
	if (owner & MUTEX_FLAG_HANDOFF)
		__mutex_handoff(lock, next);
		__mutex_handoff(lock, next);


	spin_unlock(&lock->wait_lock);
	raw_spin_unlock(&lock->wait_lock);


	wake_up_q(&wake_q);
	wake_up_q(&wake_q);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -502,7 +502,7 @@ static int __init test_lockup_init(void)
		       offsetof(rwlock_t, magic),
		       offsetof(rwlock_t, magic),
		       RWLOCK_MAGIC) ||
		       RWLOCK_MAGIC) ||
	    test_magic(lock_mutex_ptr,
	    test_magic(lock_mutex_ptr,
		       offsetof(struct mutex, wait_lock.rlock.magic),
		       offsetof(struct mutex, wait_lock.magic),
		       SPINLOCK_MAGIC) ||
		       SPINLOCK_MAGIC) ||
	    test_magic(lock_rwsem_ptr,
	    test_magic(lock_rwsem_ptr,
		       offsetof(struct rw_semaphore, wait_lock.magic),
		       offsetof(struct rw_semaphore, wait_lock.magic),