include/linux/ww_mutex.h

Source file repositories/reference/linux-study-clean/include/linux/ww_mutex.h

File Facts

System
Linux kernel
Corpus path
include/linux/ww_mutex.h
Extension
.h
Size
14137 bytes
Lines
394
Domain
Core OS
Bucket
Core Kernel Interface
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ww_class {
	atomic_long_t stamp;
	struct lock_class_key acquire_key;
	struct lock_class_key mutex_key;
	const char *acquire_name;
	const char *mutex_name;
	unsigned int is_wait_die;
};

context_lock_struct(ww_mutex) {
	struct WW_MUTEX_BASE base;
	struct ww_acquire_ctx *ctx;
#ifdef DEBUG_WW_MUTEXES
	struct ww_class *ww_class;
#endif
};

context_lock_struct(ww_acquire_ctx) {
	struct task_struct *task;
	unsigned long stamp;
	unsigned int acquired;
	unsigned short wounded;
	unsigned short is_wait_die;
#ifdef DEBUG_WW_MUTEXES
	unsigned int done_acquire;
	struct ww_class *ww_class;
	void *contending_lock;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map dep_map;
	/**
	 * @first_lock_dep_map: fake lockdep_map for first locked ww_mutex.
	 *
	 * lockdep requires the lockdep_map for the first locked ww_mutex
	 * in a ww transaction to remain in memory until all ww_mutexes of
	 * the transaction have been unlocked. Ensure this by keeping a
	 * fake locked ww_mutex lockdep map between ww_acquire_init() and
	 * ww_acquire_fini().
	 */
	struct lockdep_map first_lock_dep_map;
#endif
#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
	unsigned int deadlock_inject_interval;
	unsigned int deadlock_inject_countdown;
#endif
};

#define __WW_CLASS_INITIALIZER(ww_class, _is_wait_die)	    \
		{ .stamp = ATOMIC_LONG_INIT(0) \
		, .acquire_name = #ww_class "_acquire" \
		, .mutex_name = #ww_class "_mutex" \
		, .is_wait_die = _is_wait_die }

#define DEFINE_WD_CLASS(classname) \
	struct ww_class classname = __WW_CLASS_INITIALIZER(classname, 1)

#define DEFINE_WW_CLASS(classname) \
	struct ww_class classname = __WW_CLASS_INITIALIZER(classname, 0)

/**
 * ww_mutex_init - initialize the w/w mutex
 * @lock: the mutex to be initialized
 * @ww_class: the w/w class the mutex should belong to
 *
 * Initialize the w/w mutex to unlocked state and associate it with the given
 * class. Static define macro for w/w mutex is not provided and this function
 * is the only way to properly initialize the w/w mutex.
 *
 * It is not allowed to initialize an already locked mutex.
 */
static inline void ww_mutex_init(struct ww_mutex *lock,
				 struct ww_class *ww_class)
{
	ww_mutex_base_init(&lock->base, ww_class->mutex_name, &ww_class->mutex_key);
	lock->ctx = NULL;
#ifdef DEBUG_WW_MUTEXES
	lock->ww_class = ww_class;
#endif
}

/**
 * ww_acquire_init - initialize a w/w acquire context
 * @ctx: w/w acquire context to initialize
 * @ww_class: w/w class of the context
 *
 * Initializes an context to acquire multiple mutexes of the given w/w class.
 *
 * Context-based w/w mutex acquiring can be done in any order whatsoever within
 * a given lock class. Deadlocks will be detected and handled with the
 * wait/die logic.

Annotation

Implementation Notes