mutex.h revision 331756
1167465Smp/*- 259243Sobrien * Copyright (c) 2010 Isilon Systems, Inc. 359243Sobrien * Copyright (c) 2010 iX Systems, Inc. 459243Sobrien * Copyright (c) 2010 Panasas, Inc. 559243Sobrien * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. 659243Sobrien * All rights reserved. 759243Sobrien * 859243Sobrien * Redistribution and use in source and binary forms, with or without 959243Sobrien * modification, are permitted provided that the following conditions 1059243Sobrien * are met: 1159243Sobrien * 1. Redistributions of source code must retain the above copyright 1259243Sobrien * notice unmodified, this list of conditions, and the following 1359243Sobrien * disclaimer. 1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1559243Sobrien * notice, this list of conditions and the following disclaimer in the 1659243Sobrien * documentation and/or other materials provided with the distribution. 17100616Smp * 1859243Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1959243Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2059243Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2159243Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2259243Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2359243Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2459243Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2559243Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2659243Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2759243Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2859243Sobrien * 2959243Sobrien * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/mutex.h 331756 2018-03-30 02:04:46Z emaste $ 3059243Sobrien */ 3159243Sobrien#ifndef _LINUX_MUTEX_H_ 3259243Sobrien#define _LINUX_MUTEX_H_ 3359243Sobrien 3459243Sobrien#include <sys/param.h> 35167465Smp#include <sys/proc.h> 3659243Sobrien#include <sys/lock.h> 3759243Sobrien#include <sys/sx.h> 3859243Sobrien 3959243Sobrien#include <linux/spinlock.h> 4059243Sobrien 4159243Sobrientypedef struct mutex { 4259243Sobrien struct sx sx; 4359243Sobrien} mutex_t; 4459243Sobrien 4559243Sobrien/* 4659243Sobrien * By defining CONFIG_NO_MUTEX_SKIP LinuxKPI mutexes and asserts will 4759243Sobrien * not be skipped during panic(). 4859243Sobrien */ 49184072Sru#ifdef CONFIG_NO_MUTEX_SKIP 5059243Sobrien#define MUTEX_SKIP(void) 0 5159243Sobrien#else 5259243Sobrien#define MUTEX_SKIP(void) unlikely(SCHEDULER_STOPPED() || kdb_active) 5359243Sobrien#endif 5459243Sobrien 5559243Sobrien#define mutex_lock(_m) do { \ 5659243Sobrien if (MUTEX_SKIP()) \ 5759243Sobrien break; \ 5859243Sobrien sx_xlock(&(_m)->sx); \ 5959243Sobrien} while (0) 6059243Sobrien 6159243Sobrien#define mutex_lock_nested(_m, _s) mutex_lock(_m) 6259243Sobrien#define mutex_lock_nest_lock(_m, _s) mutex_lock(_m) 6359243Sobrien 6459243Sobrien#define mutex_lock_interruptible(_m) ({ \ 6559243Sobrien MUTEX_SKIP() ? 0 : \ 6659243Sobrien linux_mutex_lock_interruptible(_m); \ 6759243Sobrien}) 6859243Sobrien 6959243Sobrien#define mutex_unlock(_m) do { \ 7059243Sobrien if (MUTEX_SKIP()) \ 7159243Sobrien break; \ 7259243Sobrien sx_xunlock(&(_m)->sx); \ 7359243Sobrien} while (0) 7459243Sobrien 7559243Sobrien#define mutex_trylock(_m) ({ \ 7659243Sobrien MUTEX_SKIP() ? 1 : \ 7759243Sobrien !!sx_try_xlock(&(_m)->sx); \ 7859243Sobrien}) 7959243Sobrien 8059243Sobrienenum mutex_trylock_recursive_enum { 8159243Sobrien MUTEX_TRYLOCK_FAILED = 0, 8259243Sobrien MUTEX_TRYLOCK_SUCCESS = 1, 8359243Sobrien MUTEX_TRYLOCK_RECURSIVE = 2, 8459243Sobrien}; 8559243Sobrien 8659243Sobrienstatic inline __must_check enum mutex_trylock_recursive_enum 87145479Smpmutex_trylock_recursive(struct mutex *lock) 88145479Smp{ 8959243Sobrien if (unlikely(sx_xholder(&lock->sx) == curthread)) 9059243Sobrien return (MUTEX_TRYLOCK_RECURSIVE); 9159243Sobrien 9259243Sobrien return (mutex_trylock(lock)); 9359243Sobrien} 9459243Sobrien 9559243Sobrien#define mutex_init(_m) \ 9659243Sobrien linux_mutex_init(_m, mutex_name(#_m), SX_NOWITNESS) 9759243Sobrien 9859243Sobrien#define mutex_init_witness(_m) \ 9959243Sobrien linux_mutex_init(_m, mutex_name(#_m), SX_DUPOK) 10059243Sobrien 10159243Sobrien#define mutex_destroy(_m) \ 10259243Sobrien linux_mutex_destroy(_m) 10359243Sobrien 10459243Sobrienstatic inline bool 10559243Sobrienmutex_is_locked(mutex_t *m) 10659243Sobrien{ 10759243Sobrien return ((struct thread *)SX_OWNER(m->sx.sx_lock) != NULL); 10859243Sobrien} 10959243Sobrien 11059243Sobrienstatic inline bool 11159243Sobrienmutex_is_owned(mutex_t *m) 11259243Sobrien{ 11359243Sobrien return (sx_xlocked(&m->sx)); 11459243Sobrien} 11559243Sobrien 11669408Sache#ifdef WITNESS_ALL 11769408Sache/* NOTE: the maximum WITNESS name is 64 chars */ 118100616Smp#define __mutex_name(name, file, line) \ 11969408Sache (((const char *){file ":" #line "-" name}) + \ 12059243Sobrien (sizeof(file) > 16 ? sizeof(file) - 16 : 0)) 12159243Sobrien#else 12259243Sobrien#define __mutex_name(name, file, line) name 12359243Sobrien#endif 124131962Smp#define _mutex_name(...) __mutex_name(__VA_ARGS__) 125131962Smp#define mutex_name(name) _mutex_name(name, __FILE__, __LINE__) 126131962Smp 12759243Sobrien#define DEFINE_MUTEX(lock) \ 128131962Smp mutex_t lock; \ 129145479Smp SX_SYSINIT_FLAGS(lock, &(lock).sx, mutex_name(#lock), SX_DUPOK) 130145479Smp 131145479Smpstatic inline void 132145479Smplinux_mutex_init(mutex_t *m, const char *name, int flags) 133145479Smp{ 134145479Smp memset(m, 0, sizeof(*m)); 13559243Sobrien sx_init_flags(&m->sx, name, flags); 13659243Sobrien} 13759243Sobrien 13859243Sobrienstatic inline void 13959243Sobrienlinux_mutex_destroy(mutex_t *m) 140131962Smp{ 14159415Sobrien if (mutex_is_owned(m)) 14290446Smp mutex_unlock(m); 14359243Sobrien sx_destroy(&m->sx); 144131962Smp} 14559415Sobrien 14659415Sobrienextern int linux_mutex_lock_interruptible(mutex_t *m); 14759243Sobrien 14859415Sobrien#endif /* _LINUX_MUTEX_H_ */ 14959415Sobrien