ww_mutex.h revision 328653
1328653Shselasky/*- 2328653Shselasky * Copyright (c) 2017 Mellanox Technologies, Ltd. 3328653Shselasky * All rights reserved. 4328653Shselasky * 5328653Shselasky * Redistribution and use in source and binary forms, with or without 6328653Shselasky * modification, are permitted provided that the following conditions 7328653Shselasky * are met: 8328653Shselasky * 1. Redistributions of source code must retain the above copyright 9328653Shselasky * notice unmodified, this list of conditions, and the following 10328653Shselasky * disclaimer. 11328653Shselasky * 2. Redistributions in binary form must reproduce the above copyright 12328653Shselasky * notice, this list of conditions and the following disclaimer in the 13328653Shselasky * documentation and/or other materials provided with the distribution. 14328653Shselasky * 15328653Shselasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16328653Shselasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17328653Shselasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18328653Shselasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19328653Shselasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20328653Shselasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21328653Shselasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22328653Shselasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23328653Shselasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24328653Shselasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25328653Shselasky * 26328653Shselasky * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/ww_mutex.h 328653 2018-02-01 13:01:44Z hselasky $ 27328653Shselasky */ 28328653Shselasky#ifndef _LINUX_WW_MUTEX_H_ 29328653Shselasky#define _LINUX_WW_MUTEX_H_ 30328653Shselasky 31328653Shselasky#include <sys/param.h> 32328653Shselasky#include <sys/proc.h> 33328653Shselasky#include <sys/condvar.h> 34328653Shselasky#include <sys/kernel.h> 35328653Shselasky 36328653Shselasky#include <linux/mutex.h> 37328653Shselasky 38328653Shselaskystruct ww_class { 39328653Shselasky const char *mutex_name; 40328653Shselasky}; 41328653Shselasky 42328653Shselaskystruct ww_acquire_ctx { 43328653Shselasky}; 44328653Shselasky 45328653Shselaskystruct ww_mutex { 46328653Shselasky struct mutex base; 47328653Shselasky struct cv condvar; 48328653Shselasky}; 49328653Shselasky 50328653Shselasky#define DEFINE_WW_CLASS(name) \ 51328653Shselasky struct ww_class name = { \ 52328653Shselasky .mutex_name = mutex_name(#name "_mutex") \ 53328653Shselasky } 54328653Shselasky 55328653Shselasky#define DEFINE_WW_MUTEX(name, ww_class) \ 56328653Shselasky struct ww_mutex name; \ 57328653Shselasky static void name##_init(void *arg) \ 58328653Shselasky { \ 59328653Shselasky ww_mutex_init(&name, &ww_class); \ 60328653Shselasky } \ 61328653Shselasky SYSINIT(name, SI_SUB_LOCK, SI_ORDER_SECOND, name##_init, NULL) 62328653Shselasky 63328653Shselasky#define ww_mutex_is_locked(_m) \ 64328653Shselasky sx_xlocked(&(_m)->base.sx) 65328653Shselasky 66328653Shselasky#define ww_mutex_lock_slow(_m, _x) \ 67328653Shselasky ww_mutex_lock(_m, _x) 68328653Shselasky 69328653Shselasky#define ww_mutex_lock_slow_interruptible(_m, _x) \ 70328653Shselasky ww_mutex_lock_interruptible(_m, _x) 71328653Shselasky 72328653Shselaskystatic inline int __must_check 73328653Shselaskyww_mutex_trylock(struct ww_mutex *lock) 74328653Shselasky{ 75328653Shselasky return (mutex_trylock(&lock->base)); 76328653Shselasky} 77328653Shselasky 78328653Shselaskyextern int linux_ww_mutex_lock_sub(struct ww_mutex *, int catch_signal); 79328653Shselasky 80328653Shselaskystatic inline int 81328653Shselaskyww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) 82328653Shselasky{ 83328653Shselasky if (MUTEX_SKIP()) 84328653Shselasky return (0); 85328653Shselasky else if ((struct thread *)SX_OWNER(lock->base.sx.sx_lock) == curthread) 86328653Shselasky return (-EALREADY); 87328653Shselasky else 88328653Shselasky return (linux_ww_mutex_lock_sub(lock, 0)); 89328653Shselasky} 90328653Shselasky 91328653Shselaskystatic inline int 92328653Shselaskyww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) 93328653Shselasky{ 94328653Shselasky if (MUTEX_SKIP()) 95328653Shselasky return (0); 96328653Shselasky else if ((struct thread *)SX_OWNER(lock->base.sx.sx_lock) == curthread) 97328653Shselasky return (-EALREADY); 98328653Shselasky else 99328653Shselasky return (linux_ww_mutex_lock_sub(lock, 1)); 100328653Shselasky} 101328653Shselasky 102328653Shselaskyextern void linux_ww_mutex_unlock_sub(struct ww_mutex *); 103328653Shselasky 104328653Shselaskystatic inline void 105328653Shselaskyww_mutex_unlock(struct ww_mutex *lock) 106328653Shselasky{ 107328653Shselasky if (MUTEX_SKIP()) 108328653Shselasky return; 109328653Shselasky else 110328653Shselasky linux_ww_mutex_unlock_sub(lock); 111328653Shselasky} 112328653Shselasky 113328653Shselaskystatic inline void 114328653Shselaskyww_mutex_destroy(struct ww_mutex *lock) 115328653Shselasky{ 116328653Shselasky cv_destroy(&lock->condvar); 117328653Shselasky mutex_destroy(&lock->base); 118328653Shselasky} 119328653Shselasky 120328653Shselaskystatic inline void 121328653Shselaskyww_acquire_init(struct ww_acquire_ctx *ctx, struct ww_class *ww_class) 122328653Shselasky{ 123328653Shselasky} 124328653Shselasky 125328653Shselaskystatic inline void 126328653Shselaskyww_mutex_init(struct ww_mutex *lock, struct ww_class *ww_class) 127328653Shselasky{ 128328653Shselasky linux_mutex_init(&lock->base, ww_class->mutex_name, SX_NOWITNESS); 129328653Shselasky cv_init(&lock->condvar, "lkpi-ww"); 130328653Shselasky} 131328653Shselasky 132328653Shselaskystatic inline void 133328653Shselaskyww_acquire_fini(struct ww_acquire_ctx *ctx) 134328653Shselasky{ 135328653Shselasky} 136328653Shselasky 137328653Shselaskystatic inline void 138328653Shselaskyww_acquire_done(struct ww_acquire_ctx *ctx) 139328653Shselasky{ 140328653Shselasky} 141328653Shselasky 142328653Shselasky#endif /* _LINUX_WW_MUTEX_H_ */ 143