mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-08-27 06:50:37 +00:00

- Add documentation template for CXL conventions to document CXL platform quirks - Replace mutex_lock_io() with mutex_lock() for mailbox - Add location limit for fake CFMWS range for cxl_test, ARM platform enabling - CXL documentation typo and clarity fixes - Use correct format specifier for function cxl_set_ecs_threshold() - Make cxl_bus_type constant - Introduce new helper cxl_resource_contains_addr() to check address availability - Fix wrong DPA checking for PPR operation - Remove core/acpi.c and CXL core dependency on ACPI - Introduce ACQUIRE() and ACQUIRE_ERR() for conditional locks - Add CXL updates utilizing ACQUIRE() macro to remove gotos and improve readability - Add return for the dummy version of cxl_decoder_detach() without CONFIG_CXL_REGION - CXL events updates for spec r3.2 - Fix return of __cxl_decoder_detach() error path - CXL debugfs documentation fix -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE5DAy15EJMCV1R6v9YGjFFmlTOEoFAmiM6yQACgkQYGjFFmlT OErolBAAnUcYHhpmPJV46KWIhahOx5yLzPTVTzDjpeYQVsbkWLNSTBAL2ygKZt3d 1zfWSI2f11xyA7nMWf0/2oP6oVRhrN9ty+NtoO118olqT909KQ3PGFnCGbYLLIUb SxPnZCxdWQ7xOq3KUgnF+2TSYoL+pa5Gv1m2bGCgf29KgPMrOk6wl/IoAwLEFfCU HVgIPDOo9IeYJkTZEZFSTPP4tr+JXygoFrd5k2+kj/GMqQJ5iDMYZxN4dPLhalic e4wOXQRMrD23defdegg6VDDWfftBGU3yQqixDNN7sFpWIM/hsnOMVPSz9sCbO0Bg 2130sTPpsJXMVMUJoniPO5Ad3clhM4M8PoZ/QAO1J8Uodwv5wnKKwAWYFVmu6JU1 mpn5xroWci1twXXxXCdlyM+sVA9TqvyFbndYvVWo5CTAyCkVHdx1oAvUbV0YzDXN 5oeJTz42Y9PfawzTDiE5cMlGMGWux/VCiY9n909hg66gmdkUU/7zjjGYPEGT3tNK GjCQ0SGIss6bNE9b0g55of/o0O+U00n+8TdvzCkqcc/lG0Yqt5jDGQb94cZKNVn0 OX01iyZj87w8vyroA1g2vi0aF4HB+88X7GKeiLuQCLe3iyYSkhNVz5EFyS5dQi7H r5gN5u7Fq9BfCVIWA6Hh1AU4BGVR1An3hxfib8dV7Ik0Bv1X9jA= =79ot -----END PGP SIGNATURE----- Merge tag 'cxl-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl Pull CXL updates from Dave Jiang: "The most significant changes in this pull request is the series that introduces ACQUIRE() and ACQUIRE_ERR() macros to replace conditional locking and ease the pain points of scoped_cond_guard(). The series also includes follow on changes that refactor the CXL sub-system to utilize the new macros. Detail summary: - Add documentation template for CXL conventions to document CXL platform quirks - Replace mutex_lock_io() with mutex_lock() for mailbox - Add location limit for fake CFMWS range for cxl_test, ARM platform enabling - CXL documentation typo and clarity fixes - Use correct format specifier for function cxl_set_ecs_threshold() - Make cxl_bus_type constant - Introduce new helper cxl_resource_contains_addr() to check address availability - Fix wrong DPA checking for PPR operation - Remove core/acpi.c and CXL core dependency on ACPI - Introduce ACQUIRE() and ACQUIRE_ERR() for conditional locks - Add CXL updates utilizing ACQUIRE() macro to remove gotos and improve readability - Add return for the dummy version of cxl_decoder_detach() without CONFIG_CXL_REGION - CXL events updates for spec r3.2 - Fix return of __cxl_decoder_detach() error path - CXL debugfs documentation fix" * tag 'cxl-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: (28 commits) Documentation/ABI/testing/debugfs-cxl: Add 'cxl' to clear_poison path cxl/region: Fix an ERR_PTR() vs NULL bug cxl/events: Trace Memory Sparing Event Record cxl/events: Add extra validity checks for CVME count in DRAM Event Record cxl/events: Add extra validity checks for corrected memory error count in General Media Event Record cxl/events: Update Common Event Record to CXL spec rev 3.2 cxl: Fix -Werror=return-type in cxl_decoder_detach() cleanup: Fix documentation build error for ACQUIRE updates cxl: Convert to ACQUIRE() for conditional rwsem locking cxl/region: Consolidate cxl_decoder_kill_region() and cxl_region_detach() cxl/region: Move ready-to-probe state check to a helper cxl/region: Split commit_store() into __commit() and queue_reset() helpers cxl/decoder: Drop pointless locking cxl/decoder: Move decoder register programming to a helper cxl/mbox: Convert poison list mutex to ACQUIRE() cleanup: Introduce ACQUIRE() and ACQUIRE_ERR() for conditional locks cxl: Remove core/acpi.c and cxl core dependency on ACPI cxl/core: Using cxl_resource_contains_addr() to check address availability cxl/edac: Fix wrong dpa checking for PPR operation cxl/core: Introduce a new helper cxl_resource_contains_addr() ...
235 lines
6.8 KiB
C
235 lines
6.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Mutexes: blocking mutual exclusion locks
|
|
*
|
|
* started by Ingo Molnar:
|
|
*
|
|
* Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
|
|
*
|
|
* This file contains the main data structure and API definitions.
|
|
*/
|
|
#ifndef __LINUX_MUTEX_H
|
|
#define __LINUX_MUTEX_H
|
|
|
|
#include <asm/current.h>
|
|
#include <linux/list.h>
|
|
#include <linux/spinlock_types.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/atomic.h>
|
|
#include <asm/processor.h>
|
|
#include <linux/osq_lock.h>
|
|
#include <linux/debug_locks.h>
|
|
#include <linux/cleanup.h>
|
|
#include <linux/mutex_types.h>
|
|
|
|
struct device;
|
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \
|
|
, .dep_map = { \
|
|
.name = #lockname, \
|
|
.wait_type_inner = LD_WAIT_SLEEP, \
|
|
}
|
|
#else
|
|
# define __DEP_MAP_MUTEX_INITIALIZER(lockname)
|
|
#endif
|
|
|
|
#ifdef CONFIG_DEBUG_MUTEXES
|
|
|
|
# define __DEBUG_MUTEX_INITIALIZER(lockname) \
|
|
, .magic = &lockname
|
|
|
|
extern void mutex_destroy(struct mutex *lock);
|
|
|
|
#else
|
|
|
|
# define __DEBUG_MUTEX_INITIALIZER(lockname)
|
|
|
|
static inline void mutex_destroy(struct mutex *lock) {}
|
|
|
|
#endif
|
|
|
|
/**
|
|
* mutex_init - initialize the mutex
|
|
* @mutex: the mutex to be initialized
|
|
*
|
|
* Initialize the mutex to unlocked state.
|
|
*
|
|
* It is not allowed to initialize an already locked mutex.
|
|
*/
|
|
#define mutex_init(mutex) \
|
|
do { \
|
|
static struct lock_class_key __key; \
|
|
\
|
|
__mutex_init((mutex), #mutex, &__key); \
|
|
} while (0)
|
|
|
|
/**
|
|
* mutex_init_with_key - initialize a mutex with a given lockdep key
|
|
* @mutex: the mutex to be initialized
|
|
* @key: the lockdep key to be associated with the mutex
|
|
*
|
|
* Initialize the mutex to the unlocked state.
|
|
*
|
|
* It is not allowed to initialize an already locked mutex.
|
|
*/
|
|
#define mutex_init_with_key(mutex, key) __mutex_init((mutex), #mutex, (key))
|
|
|
|
#ifndef CONFIG_PREEMPT_RT
|
|
#define __MUTEX_INITIALIZER(lockname) \
|
|
{ .owner = ATOMIC_LONG_INIT(0) \
|
|
, .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(lockname.wait_lock) \
|
|
, .wait_list = LIST_HEAD_INIT(lockname.wait_list) \
|
|
__DEBUG_MUTEX_INITIALIZER(lockname) \
|
|
__DEP_MAP_MUTEX_INITIALIZER(lockname) }
|
|
|
|
#define DEFINE_MUTEX(mutexname) \
|
|
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
|
|
|
|
extern void __mutex_init(struct mutex *lock, const char *name,
|
|
struct lock_class_key *key);
|
|
|
|
/**
|
|
* mutex_is_locked - is the mutex locked
|
|
* @lock: the mutex to be queried
|
|
*
|
|
* Returns true if the mutex is locked, false if unlocked.
|
|
*/
|
|
extern bool mutex_is_locked(struct mutex *lock);
|
|
|
|
#else /* !CONFIG_PREEMPT_RT */
|
|
/*
|
|
* Preempt-RT variant based on rtmutexes.
|
|
*/
|
|
|
|
#define __MUTEX_INITIALIZER(mutexname) \
|
|
{ \
|
|
.rtmutex = __RT_MUTEX_BASE_INITIALIZER(mutexname.rtmutex) \
|
|
__DEP_MAP_MUTEX_INITIALIZER(mutexname) \
|
|
}
|
|
|
|
#define DEFINE_MUTEX(mutexname) \
|
|
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
|
|
|
|
extern void __mutex_rt_init(struct mutex *lock, const char *name,
|
|
struct lock_class_key *key);
|
|
|
|
#define mutex_is_locked(l) rt_mutex_base_is_locked(&(l)->rtmutex)
|
|
|
|
#define __mutex_init(mutex, name, key) \
|
|
do { \
|
|
rt_mutex_base_init(&(mutex)->rtmutex); \
|
|
__mutex_rt_init((mutex), name, key); \
|
|
} while (0)
|
|
|
|
#endif /* CONFIG_PREEMPT_RT */
|
|
|
|
#ifdef CONFIG_DEBUG_MUTEXES
|
|
|
|
int __must_check __devm_mutex_init(struct device *dev, struct mutex *lock);
|
|
|
|
#else
|
|
|
|
static inline int __must_check __devm_mutex_init(struct device *dev, struct mutex *lock)
|
|
{
|
|
/*
|
|
* When CONFIG_DEBUG_MUTEXES is off mutex_destroy() is just a nop so
|
|
* no really need to register it in the devm subsystem.
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
#define __mutex_init_ret(mutex) \
|
|
({ \
|
|
typeof(mutex) mutex_ = (mutex); \
|
|
\
|
|
mutex_init(mutex_); \
|
|
mutex_; \
|
|
})
|
|
|
|
#define devm_mutex_init(dev, mutex) \
|
|
__devm_mutex_init(dev, __mutex_init_ret(mutex))
|
|
|
|
/*
|
|
* See kernel/locking/mutex.c for detailed documentation of these APIs.
|
|
* Also see Documentation/locking/mutex-design.rst.
|
|
*/
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
|
|
extern void _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock);
|
|
extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock,
|
|
unsigned int subclass);
|
|
extern int __must_check _mutex_lock_killable(struct mutex *lock,
|
|
unsigned int subclass, struct lockdep_map *nest_lock);
|
|
extern void mutex_lock_io_nested(struct mutex *lock, unsigned int subclass);
|
|
|
|
#define mutex_lock(lock) mutex_lock_nested(lock, 0)
|
|
#define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0)
|
|
#define mutex_lock_killable(lock) _mutex_lock_killable(lock, 0, NULL)
|
|
#define mutex_lock_io(lock) mutex_lock_io_nested(lock, 0)
|
|
|
|
#define mutex_lock_nest_lock(lock, nest_lock) \
|
|
do { \
|
|
typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
|
|
_mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \
|
|
} while (0)
|
|
|
|
#define mutex_lock_killable_nest_lock(lock, nest_lock) \
|
|
( \
|
|
typecheck(struct lockdep_map *, &(nest_lock)->dep_map), \
|
|
_mutex_lock_killable(lock, 0, &(nest_lock)->dep_map) \
|
|
)
|
|
|
|
#define mutex_lock_killable_nested(lock, subclass) \
|
|
_mutex_lock_killable(lock, subclass, NULL)
|
|
|
|
#else
|
|
extern void mutex_lock(struct mutex *lock);
|
|
extern int __must_check mutex_lock_interruptible(struct mutex *lock);
|
|
extern int __must_check mutex_lock_killable(struct mutex *lock);
|
|
extern void mutex_lock_io(struct mutex *lock);
|
|
|
|
# define mutex_lock_nested(lock, subclass) mutex_lock(lock)
|
|
# define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock)
|
|
# define mutex_lock_killable_nested(lock, subclass) mutex_lock_killable(lock)
|
|
# define mutex_lock_killable_nest_lock(lock, nest_lock) mutex_lock_killable(lock)
|
|
# define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock)
|
|
# define mutex_lock_io_nested(lock, subclass) mutex_lock_io(lock)
|
|
#endif
|
|
|
|
/*
|
|
* NOTE: mutex_trylock() follows the spin_trylock() convention,
|
|
* not the down_trylock() convention!
|
|
*
|
|
* Returns 1 if the mutex has been acquired successfully, and 0 on contention.
|
|
*/
|
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
extern int _mutex_trylock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock);
|
|
|
|
#define mutex_trylock_nest_lock(lock, nest_lock) \
|
|
( \
|
|
typecheck(struct lockdep_map *, &(nest_lock)->dep_map), \
|
|
_mutex_trylock_nest_lock(lock, &(nest_lock)->dep_map) \
|
|
)
|
|
|
|
#define mutex_trylock(lock) _mutex_trylock_nest_lock(lock, NULL)
|
|
#else
|
|
extern int mutex_trylock(struct mutex *lock);
|
|
#define mutex_trylock_nest_lock(lock, nest_lock) mutex_trylock(lock)
|
|
#endif
|
|
|
|
extern void mutex_unlock(struct mutex *lock);
|
|
|
|
extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
|
|
|
|
DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T))
|
|
DEFINE_GUARD_COND(mutex, _try, mutex_trylock(_T))
|
|
DEFINE_GUARD_COND(mutex, _intr, mutex_lock_interruptible(_T), _RET == 0)
|
|
|
|
extern unsigned long mutex_get_owner(struct mutex *lock);
|
|
|
|
#endif /* __LINUX_MUTEX_H */
|