1f8829a4aSRandall Stewart /*- 251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 351369649SPedro F. Giffuni * 4b1006367SRandall Stewart * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 5807aad63SMichael Tuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 6807aad63SMichael Tuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 7f8829a4aSRandall Stewart * 8f8829a4aSRandall Stewart * Redistribution and use in source and binary forms, with or without 9f8829a4aSRandall Stewart * modification, are permitted provided that the following conditions are met: 10f8829a4aSRandall Stewart * 11f8829a4aSRandall Stewart * a) Redistributions of source code must retain the above copyright notice, 12f8829a4aSRandall Stewart * this list of conditions and the following disclaimer. 13f8829a4aSRandall Stewart * 14f8829a4aSRandall Stewart * b) Redistributions in binary form must reproduce the above copyright 15f8829a4aSRandall Stewart * notice, this list of conditions and the following disclaimer in 16f8829a4aSRandall Stewart * the documentation and/or other materials provided with the distribution. 17f8829a4aSRandall Stewart * 18f8829a4aSRandall Stewart * c) Neither the name of Cisco Systems, Inc. nor the names of its 19f8829a4aSRandall Stewart * contributors may be used to endorse or promote products derived 20f8829a4aSRandall Stewart * from this software without specific prior written permission. 21f8829a4aSRandall Stewart * 22f8829a4aSRandall Stewart * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23f8829a4aSRandall Stewart * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24f8829a4aSRandall Stewart * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25f8829a4aSRandall Stewart * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26f8829a4aSRandall Stewart * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27f8829a4aSRandall Stewart * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28f8829a4aSRandall Stewart * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29f8829a4aSRandall Stewart * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30f8829a4aSRandall Stewart * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31f8829a4aSRandall Stewart * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32f8829a4aSRandall Stewart * THE POSSIBILITY OF SUCH DAMAGE. 33f8829a4aSRandall Stewart */ 34f8829a4aSRandall Stewart 35807aad63SMichael Tuexen #include <sys/cdefs.h> 36807aad63SMichael Tuexen __FBSDID("$FreeBSD$"); 37807aad63SMichael Tuexen 38807aad63SMichael Tuexen #ifndef _NETINET_SCTP_LOCK_BSD_H_ 39807aad63SMichael Tuexen #define _NETINET_SCTP_LOCK_BSD_H_ 40807aad63SMichael Tuexen 41f8829a4aSRandall Stewart /* 42f8829a4aSRandall Stewart * General locking concepts: The goal of our locking is to of course provide 43f8829a4aSRandall Stewart * consistency and yet minimize overhead. We will attempt to use 44f8829a4aSRandall Stewart * non-recursive locks which are supposed to be quite inexpensive. Now in 45f8829a4aSRandall Stewart * order to do this the goal is that most functions are not aware of locking. 46f8829a4aSRandall Stewart * Once we have a TCB we lock it and unlock when we are through. This means 47f8829a4aSRandall Stewart * that the TCB lock is kind-of a "global" lock when working on an 48f8829a4aSRandall Stewart * association. Caution must be used when asserting a TCB_LOCK since if we 49f8829a4aSRandall Stewart * recurse we deadlock. 50f8829a4aSRandall Stewart * 51f8829a4aSRandall Stewart * Most other locks (INP and INFO) attempt to localize the locking i.e. we try 52f8829a4aSRandall Stewart * to contain the lock and unlock within the function that needs to lock it. 53f8829a4aSRandall Stewart * This sometimes mean we do extra locks and unlocks and lose a bit of 54cd0a4ff6SPedro F. Giffuni * efficiency, but if the performance statements about non-recursive locks are 55f8829a4aSRandall Stewart * true this should not be a problem. One issue that arises with this only 56f8829a4aSRandall Stewart * lock when needed is that if an implicit association setup is done we have 57f8829a4aSRandall Stewart * a problem. If at the time I lookup an association I have NULL in the tcb 58f8829a4aSRandall Stewart * return, by the time I call to create the association some other processor 59f8829a4aSRandall Stewart * could have created it. This is what the CREATE lock on the endpoint. 60f8829a4aSRandall Stewart * Places where we will be implicitly creating the association OR just 61f8829a4aSRandall Stewart * creating an association (the connect call) will assert the CREATE_INP 62f8829a4aSRandall Stewart * lock. This will assure us that during all the lookup of INP and INFO if 63f8829a4aSRandall Stewart * another creator is also locking/looking up we can gate the two to 64f8829a4aSRandall Stewart * synchronize. So the CREATE_INP lock is also another one we must use 65f8829a4aSRandall Stewart * extreme caution in locking to make sure we don't hit a re-entrancy issue. 66f8829a4aSRandall Stewart * 67f8829a4aSRandall Stewart */ 68f8829a4aSRandall Stewart 69f8829a4aSRandall Stewart /* 70f8829a4aSRandall Stewart * When working with the global SCTP lists we lock and unlock the INP_INFO 71f8829a4aSRandall Stewart * lock. So when we go to lookup an association we will want to do a 72f8829a4aSRandall Stewart * SCTP_INP_INFO_RLOCK() and then when we want to add a new association to 73b3f1ea41SRandall Stewart * the SCTP_BASE_INFO() list's we will do a SCTP_INP_INFO_WLOCK(). 74f8829a4aSRandall Stewart */ 75a5d547adSRandall Stewart 76f8829a4aSRandall Stewart #define SCTP_IPI_COUNT_INIT() 77f8829a4aSRandall Stewart 78f8829a4aSRandall Stewart #define SCTP_STATLOG_INIT_LOCK() 79d084818dSMichael Tuexen #define SCTP_STATLOG_DESTROY() 80f8829a4aSRandall Stewart #define SCTP_STATLOG_LOCK() 81f8829a4aSRandall Stewart #define SCTP_STATLOG_UNLOCK() 82d084818dSMichael Tuexen 83d084818dSMichael Tuexen #define SCTP_INP_INFO_LOCK_INIT() do { \ 84d084818dSMichael Tuexen rw_init(&SCTP_BASE_INFO(ipi_ep_mtx), "sctp-info"); \ 85d084818dSMichael Tuexen } while (0) 86f8829a4aSRandall Stewart 87c99efcf6SRandall Stewart #define SCTP_INP_INFO_LOCK_DESTROY() do { \ 88b3f1ea41SRandall Stewart if (rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx))) { \ 89b3f1ea41SRandall Stewart rw_wunlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 90c99efcf6SRandall Stewart } \ 91b3f1ea41SRandall Stewart rw_destroy(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 92c99efcf6SRandall Stewart } while (0) 93a5d547adSRandall Stewart 94f8829a4aSRandall Stewart #define SCTP_INP_INFO_RLOCK() do { \ 95b3f1ea41SRandall Stewart rw_rlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 96f8829a4aSRandall Stewart } while (0) 97f8829a4aSRandall Stewart 98d084818dSMichael Tuexen #define SCTP_INP_INFO_WLOCK() do { \ 99d084818dSMichael Tuexen rw_wlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 100d084818dSMichael Tuexen } while (0) 101d084818dSMichael Tuexen 102d084818dSMichael Tuexen #define SCTP_INP_INFO_RUNLOCK() do { \ 103d084818dSMichael Tuexen rw_runlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 104d084818dSMichael Tuexen } while (0) 105d084818dSMichael Tuexen 106d084818dSMichael Tuexen #define SCTP_INP_INFO_WUNLOCK() do { \ 107d084818dSMichael Tuexen rw_wunlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 108d084818dSMichael Tuexen } while (0) 109d084818dSMichael Tuexen 110be8ee77eSMark Johnston #define SCTP_INP_INFO_LOCK_ASSERT() do { \ 111be8ee77eSMark Johnston rw_assert(&SCTP_BASE_INFO(ipi_ep_mtx), RA_LOCKED); \ 112be8ee77eSMark Johnston } while (0) 113be8ee77eSMark Johnston 114be8ee77eSMark Johnston #define SCTP_INP_INFO_RLOCK_ASSERT() do { \ 115be8ee77eSMark Johnston rw_assert(&SCTP_BASE_INFO(ipi_ep_mtx), RA_RLOCKED); \ 116be8ee77eSMark Johnston } while (0) 117be8ee77eSMark Johnston 118be8ee77eSMark Johnston #define SCTP_INP_INFO_WLOCK_ASSERT() do { \ 119be8ee77eSMark Johnston rw_assert(&SCTP_BASE_INFO(ipi_ep_mtx), RA_WLOCKED); \ 120be8ee77eSMark Johnston } while (0) 121be8ee77eSMark Johnston 122bfc46083SRandall Stewart #define SCTP_MCORE_QLOCK_INIT(cpstr) do { \ 123d084818dSMichael Tuexen mtx_init(&(cpstr)->que_mtx, "sctp-mcore_queue","queue_lock", \ 124bfc46083SRandall Stewart MTX_DEF | MTX_DUPOK); \ 125bfc46083SRandall Stewart } while (0) 126bfc46083SRandall Stewart 127d084818dSMichael Tuexen #define SCTP_MCORE_QDESTROY(cpstr) do { \ 128d084818dSMichael Tuexen if (mtx_owned(&(cpstr)->core_mtx)) { \ 129d084818dSMichael Tuexen mtx_unlock(&(cpstr)->que_mtx); \ 130d084818dSMichael Tuexen } \ 131d084818dSMichael Tuexen mtx_destroy(&(cpstr)->que_mtx); \ 132d084818dSMichael Tuexen } while (0) 133d084818dSMichael Tuexen 134bfc46083SRandall Stewart #define SCTP_MCORE_QLOCK(cpstr) do { \ 135bfc46083SRandall Stewart mtx_lock(&(cpstr)->que_mtx); \ 136bfc46083SRandall Stewart } while (0) 137bfc46083SRandall Stewart 138bfc46083SRandall Stewart #define SCTP_MCORE_QUNLOCK(cpstr) do { \ 139bfc46083SRandall Stewart mtx_unlock(&(cpstr)->que_mtx); \ 140bfc46083SRandall Stewart } while (0) 141bfc46083SRandall Stewart 142bfc46083SRandall Stewart #define SCTP_MCORE_LOCK_INIT(cpstr) do { \ 143d084818dSMichael Tuexen mtx_init(&(cpstr)->core_mtx, "sctp-cpulck","cpu_proc_lock", \ 144bfc46083SRandall Stewart MTX_DEF | MTX_DUPOK); \ 145bfc46083SRandall Stewart } while (0) 146bfc46083SRandall Stewart 147d084818dSMichael Tuexen #define SCTP_MCORE_DESTROY(cpstr) do { \ 148d084818dSMichael Tuexen if (mtx_owned(&(cpstr)->core_mtx)) { \ 149d084818dSMichael Tuexen mtx_unlock(&(cpstr)->core_mtx); \ 150d084818dSMichael Tuexen } \ 151d084818dSMichael Tuexen mtx_destroy(&(cpstr)->core_mtx); \ 152d084818dSMichael Tuexen } while (0) 153d084818dSMichael Tuexen 154bfc46083SRandall Stewart #define SCTP_MCORE_LOCK(cpstr) do { \ 155bfc46083SRandall Stewart mtx_lock(&(cpstr)->core_mtx); \ 156bfc46083SRandall Stewart } while (0) 157bfc46083SRandall Stewart 158bfc46083SRandall Stewart #define SCTP_MCORE_UNLOCK(cpstr) do { \ 159bfc46083SRandall Stewart mtx_unlock(&(cpstr)->core_mtx); \ 160bfc46083SRandall Stewart } while (0) 161bfc46083SRandall Stewart 162d084818dSMichael Tuexen #define SCTP_IPI_ADDR_INIT() do { \ 163d084818dSMichael Tuexen rw_init(&SCTP_BASE_INFO(ipi_addr_mtx), "sctp-addr"); \ 164bfc46083SRandall Stewart } while (0) 165f8829a4aSRandall Stewart 166c99efcf6SRandall Stewart #define SCTP_IPI_ADDR_DESTROY() do { \ 167b3f1ea41SRandall Stewart if (rw_wowned(&SCTP_BASE_INFO(ipi_addr_mtx))) { \ 168b3f1ea41SRandall Stewart rw_wunlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 169c99efcf6SRandall Stewart } \ 170b3f1ea41SRandall Stewart rw_destroy(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 171f8829a4aSRandall Stewart } while (0) 172d084818dSMichael Tuexen 173c99efcf6SRandall Stewart #define SCTP_IPI_ADDR_RLOCK() do { \ 174b3f1ea41SRandall Stewart rw_rlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 175c99efcf6SRandall Stewart } while (0) 176d084818dSMichael Tuexen 177c99efcf6SRandall Stewart #define SCTP_IPI_ADDR_WLOCK() do { \ 178b3f1ea41SRandall Stewart rw_wlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 179c99efcf6SRandall Stewart } while (0) 180c99efcf6SRandall Stewart 181d084818dSMichael Tuexen #define SCTP_IPI_ADDR_RUNLOCK() do { \ 182d084818dSMichael Tuexen rw_runlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 183d084818dSMichael Tuexen } while (0) 184d084818dSMichael Tuexen 185d084818dSMichael Tuexen #define SCTP_IPI_ADDR_WUNLOCK() do { \ 186d084818dSMichael Tuexen rw_wunlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 187d084818dSMichael Tuexen } while (0) 188c99efcf6SRandall Stewart 1897f0ad227SMichael Tuexen #define SCTP_IPI_ADDR_LOCK_ASSERT() do { \ 1907f0ad227SMichael Tuexen rw_assert(&SCTP_BASE_INFO(ipi_addr_mtx), RA_LOCKED); \ 1917f0ad227SMichael Tuexen } while (0) 1927f0ad227SMichael Tuexen 1937f0ad227SMichael Tuexen #define SCTP_IPI_ADDR_WLOCK_ASSERT() do { \ 1947f0ad227SMichael Tuexen rw_assert(&SCTP_BASE_INFO(ipi_addr_mtx), RA_WLOCKED); \ 1957f0ad227SMichael Tuexen } while (0) 19642551e99SRandall Stewart 197d084818dSMichael Tuexen #define SCTP_IPI_ITERATOR_WQ_INIT() do { \ 198d084818dSMichael Tuexen mtx_init(&sctp_it_ctl.ipi_iterator_wq_mtx, "sctp-it-wq", \ 199d084818dSMichael Tuexen "sctp_it_wq", MTX_DEF); \ 200d084818dSMichael Tuexen } while (0) 20142551e99SRandall Stewart 202d084818dSMichael Tuexen #define SCTP_IPI_ITERATOR_WQ_DESTROY() do { \ 203d084818dSMichael Tuexen mtx_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx); \ 204d084818dSMichael Tuexen } while (0) 20542551e99SRandall Stewart 20642551e99SRandall Stewart #define SCTP_IPI_ITERATOR_WQ_LOCK() do { \ 207f7517433SRandall Stewart mtx_lock(&sctp_it_ctl.ipi_iterator_wq_mtx); \ 20842551e99SRandall Stewart } while (0) 20942551e99SRandall Stewart 210d084818dSMichael Tuexen #define SCTP_IPI_ITERATOR_WQ_UNLOCK() do { \ 211d084818dSMichael Tuexen mtx_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx); \ 212d084818dSMichael Tuexen } while (0) 21342551e99SRandall Stewart 214d084818dSMichael Tuexen #define SCTP_IP_PKTLOG_INIT() do { \ 215d084818dSMichael Tuexen mtx_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), "sctp-pktlog", \ 216d084818dSMichael Tuexen "packetlog", MTX_DEF); \ 217d084818dSMichael Tuexen } while (0) 218207304d4SRandall Stewart 219d084818dSMichael Tuexen #define SCTP_IP_PKTLOG_DESTROY() do { \ 220d084818dSMichael Tuexen mtx_destroy(&SCTP_BASE_INFO(ipi_pktlog_mtx)); \ 221d084818dSMichael Tuexen } while (0) 222207304d4SRandall Stewart 223207304d4SRandall Stewart #define SCTP_IP_PKTLOG_LOCK() do { \ 224b3f1ea41SRandall Stewart mtx_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx)); \ 225207304d4SRandall Stewart } while (0) 226207304d4SRandall Stewart 227d084818dSMichael Tuexen #define SCTP_IP_PKTLOG_UNLOCK() do { \ 228d084818dSMichael Tuexen mtx_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx)); \ 229d084818dSMichael Tuexen } while (0) 23042551e99SRandall Stewart 231f8829a4aSRandall Stewart /* 232f8829a4aSRandall Stewart * The INP locks we will use for locking an SCTP endpoint, so for example if 233f8829a4aSRandall Stewart * we want to change something at the endpoint level for example random_store 234f8829a4aSRandall Stewart * or cookie secrets we lock the INP level. 235f8829a4aSRandall Stewart */ 236f8829a4aSRandall Stewart 237*6cb8b3b5SMichael Tuexen #define SCTP_INP_READ_LOCK_INIT(_inp) do { \ 238d084818dSMichael Tuexen mtx_init(&(_inp)->inp_rdata_mtx, "sctp-read", "inpr", \ 239d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 240d084818dSMichael Tuexen } while (0) 241f8829a4aSRandall Stewart 242*6cb8b3b5SMichael Tuexen #define SCTP_INP_READ_LOCK_DESTROY(_inp) do { \ 243d084818dSMichael Tuexen mtx_destroy(&(_inp)->inp_rdata_mtx); \ 244d084818dSMichael Tuexen } while (0) 245f8829a4aSRandall Stewart 246f8829a4aSRandall Stewart #define SCTP_INP_READ_LOCK(_inp) do { \ 247f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_rdata_mtx); \ 248f8829a4aSRandall Stewart } while (0) 249f8829a4aSRandall Stewart 250d084818dSMichael Tuexen #define SCTP_INP_READ_UNLOCK(_inp) do { \ 251d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_rdata_mtx); \ 252d084818dSMichael Tuexen } while (0) 253f8829a4aSRandall Stewart 254*6cb8b3b5SMichael Tuexen #define SCTP_INP_READ_LOCK_ASSERT(_inp) do { \ 255*6cb8b3b5SMichael Tuexen KASSERT(mtx_owned(&(_inp)->inp_rdata_mtx), \ 256*6cb8b3b5SMichael Tuexen ("Don't own INP read queue lock")); \ 257*6cb8b3b5SMichael Tuexen } while (0) 258*6cb8b3b5SMichael Tuexen 259d084818dSMichael Tuexen #define SCTP_INP_LOCK_INIT(_inp) do { \ 260d084818dSMichael Tuexen mtx_init(&(_inp)->inp_mtx, "sctp-inp", "inp", \ 261d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 262d084818dSMichael Tuexen } while (0) 263f8829a4aSRandall Stewart 264d084818dSMichael Tuexen #define SCTP_INP_LOCK_DESTROY(_inp) do { \ 265d084818dSMichael Tuexen mtx_destroy(&(_inp)->inp_mtx); \ 266d084818dSMichael Tuexen } while (0) 267f8829a4aSRandall Stewart 268d084818dSMichael Tuexen #define SCTP_INP_LOCK_CONTENDED(_inp) \ 269d084818dSMichael Tuexen ((_inp)->inp_mtx.mtx_lock & MTX_CONTESTED) 2708ce4a9a2SRandall Stewart 271d084818dSMichael Tuexen #define SCTP_INP_READ_CONTENDED(_inp) \ 272d084818dSMichael Tuexen ((_inp)->inp_rdata_mtx.mtx_lock & MTX_CONTESTED) 273f8829a4aSRandall Stewart 274f8829a4aSRandall Stewart #ifdef SCTP_LOCK_LOGGING 275f8829a4aSRandall Stewart #define SCTP_INP_RLOCK(_inp) do { \ 276d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 277d084818dSMichael Tuexen sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \ 278f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 279f8829a4aSRandall Stewart } while (0) 280f8829a4aSRandall Stewart 281f8829a4aSRandall Stewart #define SCTP_INP_WLOCK(_inp) do { \ 282d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 283d084818dSMichael Tuexen sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \ 284f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 285f8829a4aSRandall Stewart } while (0) 286f8829a4aSRandall Stewart #else 287f8829a4aSRandall Stewart #define SCTP_INP_RLOCK(_inp) do { \ 288f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 289f8829a4aSRandall Stewart } while (0) 290f8829a4aSRandall Stewart 291f8829a4aSRandall Stewart #define SCTP_INP_WLOCK(_inp) do { \ 292f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 293f8829a4aSRandall Stewart } while (0) 294f8829a4aSRandall Stewart #endif 295f8829a4aSRandall Stewart 296d084818dSMichael Tuexen #define SCTP_INP_RUNLOCK(_inp) do { \ 297d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_mtx); \ 298d084818dSMichael Tuexen } while (0) 299f8829a4aSRandall Stewart 300d084818dSMichael Tuexen #define SCTP_INP_WUNLOCK(_inp) do { \ 301d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_mtx); \ 302d084818dSMichael Tuexen } while (0) 303f8829a4aSRandall Stewart 304d084818dSMichael Tuexen #define SCTP_INP_RLOCK_ASSERT(_inp) do { \ 305d084818dSMichael Tuexen KASSERT(mtx_owned(&(_inp)->inp_mtx), \ 306d084818dSMichael Tuexen ("Don't own INP read lock")); \ 307d084818dSMichael Tuexen } while (0) 308d084818dSMichael Tuexen 309d084818dSMichael Tuexen #define SCTP_INP_WLOCK_ASSERT(_inp) do { \ 310d084818dSMichael Tuexen KASSERT(mtx_owned(&(_inp)->inp_mtx), \ 311d084818dSMichael Tuexen ("Don't own INP write lock")); \ 312d084818dSMichael Tuexen } while (0) 313d084818dSMichael Tuexen 314d084818dSMichael Tuexen #define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1) 315d084818dSMichael Tuexen #define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1) 316d084818dSMichael Tuexen 317d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) do { \ 318d084818dSMichael Tuexen mtx_init(&(_inp)->inp_create_mtx, "sctp-create", "inp_create", \ 319d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 320d084818dSMichael Tuexen } while (0) 321d084818dSMichael Tuexen 322d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) do { \ 323d084818dSMichael Tuexen mtx_destroy(&(_inp)->inp_create_mtx); \ 324d084818dSMichael Tuexen } while (0) 325d084818dSMichael Tuexen 326d084818dSMichael Tuexen #ifdef SCTP_LOCK_LOGGING 327d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK(_inp) do { \ 328d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 329d084818dSMichael Tuexen sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_CREATE); \ 330d084818dSMichael Tuexen mtx_lock(&(_inp)->inp_create_mtx); \ 331d084818dSMichael Tuexen } while (0) 332d084818dSMichael Tuexen #else 333d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK(_inp) do { \ 334d084818dSMichael Tuexen mtx_lock(&(_inp)->inp_create_mtx); \ 335d084818dSMichael Tuexen } while (0) 336d084818dSMichael Tuexen #endif 337d084818dSMichael Tuexen 338d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_UNLOCK(_inp) do { \ 339d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_create_mtx); \ 340d084818dSMichael Tuexen } while (0) 341d084818dSMichael Tuexen 342d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) \ 343d084818dSMichael Tuexen ((_inp)->inp_create_mtx.mtx_lock & MTX_CONTESTED) 344d084818dSMichael Tuexen 345f8829a4aSRandall Stewart /* 346f8829a4aSRandall Stewart * For the majority of things (once we have found the association) we will 347f8829a4aSRandall Stewart * lock the actual association mutex. This will protect all the assoiciation 348f8829a4aSRandall Stewart * level queues and streams and such. We will need to lock the socket layer 349f8829a4aSRandall Stewart * when we stuff data up into the receiving sb_mb. I.e. we will need to do an 350f8829a4aSRandall Stewart * extra SOCKBUF_LOCK(&so->so_rcv) even though the association is locked. 351f8829a4aSRandall Stewart */ 352f8829a4aSRandall Stewart 353d084818dSMichael Tuexen #define SCTP_TCB_LOCK_INIT(_tcb) do { \ 354d084818dSMichael Tuexen mtx_init(&(_tcb)->tcb_mtx, "sctp-tcb", "tcb", \ 355d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 356d084818dSMichael Tuexen } while (0) 357f8829a4aSRandall Stewart 358d084818dSMichael Tuexen #define SCTP_TCB_LOCK_DESTROY(_tcb) do { \ 359d084818dSMichael Tuexen mtx_destroy(&(_tcb)->tcb_mtx); \ 360d084818dSMichael Tuexen } while (0) 361f8829a4aSRandall Stewart 362f8829a4aSRandall Stewart #ifdef SCTP_LOCK_LOGGING 363f8829a4aSRandall Stewart #define SCTP_TCB_LOCK(_tcb) do { \ 364d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 365d084818dSMichael Tuexen sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \ 366f8829a4aSRandall Stewart mtx_lock(&(_tcb)->tcb_mtx); \ 367f8829a4aSRandall Stewart } while (0) 368f8829a4aSRandall Stewart #else 369f8829a4aSRandall Stewart #define SCTP_TCB_LOCK(_tcb) do { \ 370f8829a4aSRandall Stewart mtx_lock(&(_tcb)->tcb_mtx); \ 371f8829a4aSRandall Stewart } while (0) 372f8829a4aSRandall Stewart 373f8829a4aSRandall Stewart #endif 374f8829a4aSRandall Stewart 375d084818dSMichael Tuexen #define SCTP_TCB_TRYLOCK(_tcb) \ 376d084818dSMichael Tuexen mtx_trylock(&(_tcb)->tcb_mtx) 377f8829a4aSRandall Stewart 378d084818dSMichael Tuexen #define SCTP_TCB_UNLOCK(_tcb) do { \ 379d084818dSMichael Tuexen mtx_unlock(&(_tcb)->tcb_mtx); \ 380d084818dSMichael Tuexen } while (0) 381f8829a4aSRandall Stewart 382f8829a4aSRandall Stewart #define SCTP_TCB_UNLOCK_IFOWNED(_tcb) do { \ 383f8829a4aSRandall Stewart if (mtx_owned(&(_tcb)->tcb_mtx)) \ 384f8829a4aSRandall Stewart mtx_unlock(&(_tcb)->tcb_mtx); \ 385f8829a4aSRandall Stewart } while (0) 386f8829a4aSRandall Stewart 387f8829a4aSRandall Stewart #define SCTP_TCB_LOCK_ASSERT(_tcb) do { \ 388d084818dSMichael Tuexen KASSERT(mtx_owned(&(_tcb)->tcb_mtx), \ 389d084818dSMichael Tuexen ("Don't own TCB lock")); \ 390f8829a4aSRandall Stewart } while (0) 391f8829a4aSRandall Stewart 392d084818dSMichael Tuexen #define SCTP_ITERATOR_LOCK_INIT() do { \ 393d084818dSMichael Tuexen mtx_init(&sctp_it_ctl.it_mtx, "sctp-it", "iterator", MTX_DEF); \ 394d084818dSMichael Tuexen } while (0) 395d084818dSMichael Tuexen 396d084818dSMichael Tuexen #define SCTP_ITERATOR_LOCK_DESTROY() do { \ 397d084818dSMichael Tuexen mtx_destroy(&sctp_it_ctl.it_mtx); \ 398d084818dSMichael Tuexen } while (0) 399d084818dSMichael Tuexen 400f8829a4aSRandall Stewart #define SCTP_ITERATOR_LOCK() \ 401f8829a4aSRandall Stewart do { \ 402d084818dSMichael Tuexen KASSERT(!mtx_owned(&sctp_it_ctl.it_mtx), \ 403d084818dSMichael Tuexen ("Own the iterator lock")); \ 404f7517433SRandall Stewart mtx_lock(&sctp_it_ctl.it_mtx); \ 405f8829a4aSRandall Stewart } while (0) 406f8829a4aSRandall Stewart 407d084818dSMichael Tuexen #define SCTP_ITERATOR_UNLOCK() do { \ 408d084818dSMichael Tuexen mtx_unlock(&sctp_it_ctl.it_mtx); \ 409d084818dSMichael Tuexen } while (0) 410f7517433SRandall Stewart 411f7517433SRandall Stewart #define SCTP_WQ_ADDR_INIT() do { \ 412d084818dSMichael Tuexen mtx_init(&SCTP_BASE_INFO(wq_addr_mtx), \ 413d084818dSMichael Tuexen "sctp-addr-wq","sctp_addr_wq", MTX_DEF); \ 414f7517433SRandall Stewart } while (0) 415f7517433SRandall Stewart 416f7517433SRandall Stewart #define SCTP_WQ_ADDR_DESTROY() do { \ 417f7517433SRandall Stewart if (mtx_owned(&SCTP_BASE_INFO(wq_addr_mtx))) { \ 418f7517433SRandall Stewart mtx_unlock(&SCTP_BASE_INFO(wq_addr_mtx)); \ 419f7517433SRandall Stewart } \ 420f7517433SRandall Stewart mtx_destroy(&SCTP_BASE_INFO(wq_addr_mtx)); \ 421f7517433SRandall Stewart } while (0) 422f7517433SRandall Stewart 423f7517433SRandall Stewart #define SCTP_WQ_ADDR_LOCK() do { \ 424f7517433SRandall Stewart mtx_lock(&SCTP_BASE_INFO(wq_addr_mtx)); \ 425f7517433SRandall Stewart } while (0) 426d084818dSMichael Tuexen 427f7517433SRandall Stewart #define SCTP_WQ_ADDR_UNLOCK() do { \ 428f7517433SRandall Stewart mtx_unlock(&SCTP_BASE_INFO(wq_addr_mtx)); \ 429f7517433SRandall Stewart } while (0) 430f7517433SRandall Stewart 431d084818dSMichael Tuexen #define SCTP_WQ_ADDR_LOCK_ASSERT() do { \ 432d084818dSMichael Tuexen KASSERT(mtx_owned(&SCTP_BASE_INFO(wq_addr_mtx)), \ 433d084818dSMichael Tuexen ("Don't own the ADDR-WQ lock")); \ 434d084818dSMichael Tuexen } while (0) 435f8829a4aSRandall Stewart 436d084818dSMichael Tuexen #define SCTP_INCR_EP_COUNT() do { \ 437b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \ 438f8829a4aSRandall Stewart } while (0) 439f8829a4aSRandall Stewart 440d084818dSMichael Tuexen #define SCTP_DECR_EP_COUNT() do { \ 441b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \ 442f8829a4aSRandall Stewart } while (0) 443f8829a4aSRandall Stewart 444d084818dSMichael Tuexen #define SCTP_INCR_ASOC_COUNT() do { \ 445b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \ 446f8829a4aSRandall Stewart } while (0) 447f8829a4aSRandall Stewart 448d084818dSMichael Tuexen #define SCTP_DECR_ASOC_COUNT() do { \ 449b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \ 450f8829a4aSRandall Stewart } while (0) 451f8829a4aSRandall Stewart 452d084818dSMichael Tuexen #define SCTP_INCR_LADDR_COUNT() do { \ 453b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \ 454f8829a4aSRandall Stewart } while (0) 455f8829a4aSRandall Stewart 456d084818dSMichael Tuexen #define SCTP_DECR_LADDR_COUNT() do { \ 457b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \ 458f8829a4aSRandall Stewart } while (0) 459f8829a4aSRandall Stewart 460d084818dSMichael Tuexen #define SCTP_INCR_RADDR_COUNT() do { \ 461b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \ 462f8829a4aSRandall Stewart } while (0) 463f8829a4aSRandall Stewart 464d084818dSMichael Tuexen #define SCTP_DECR_RADDR_COUNT() do { \ 465b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr),1); \ 466f8829a4aSRandall Stewart } while (0) 467f8829a4aSRandall Stewart 468d084818dSMichael Tuexen #define SCTP_INCR_CHK_COUNT() do { \ 469b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \ 470f8829a4aSRandall Stewart } while (0) 471d084818dSMichael Tuexen 472d084818dSMichael Tuexen #define SCTP_DECR_CHK_COUNT() do { \ 473d084818dSMichael Tuexen KASSERT(SCTP_BASE_INFO(ipi_count_chunk) > 0, \ 474d084818dSMichael Tuexen ("ipi_count_chunk would become negative")); \ 475df6e0cc3SRandall Stewart if (SCTP_BASE_INFO(ipi_count_chunk) != 0) \ 476d084818dSMichael Tuexen atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), \ 477d084818dSMichael Tuexen 1); \ 478df6e0cc3SRandall Stewart } while (0) 479d084818dSMichael Tuexen 480d084818dSMichael Tuexen #define SCTP_INCR_READQ_COUNT() do { \ 481b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \ 482f8829a4aSRandall Stewart } while (0) 483f8829a4aSRandall Stewart 484d084818dSMichael Tuexen #define SCTP_DECR_READQ_COUNT() do { \ 485b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \ 486f8829a4aSRandall Stewart } while (0) 487f8829a4aSRandall Stewart 488d084818dSMichael Tuexen #define SCTP_INCR_STRMOQ_COUNT() do { \ 489b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \ 490f8829a4aSRandall Stewart } while (0) 491f8829a4aSRandall Stewart 492d084818dSMichael Tuexen #define SCTP_DECR_STRMOQ_COUNT() do { \ 493b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \ 494f8829a4aSRandall Stewart } while (0) 495f8829a4aSRandall Stewart 496ceaad40aSRandall Stewart #if defined(SCTP_SO_LOCK_TESTING) 497d084818dSMichael Tuexen #define SCTP_INP_SO(sctpinp) \ 498d084818dSMichael Tuexen (sctpinp)->ip_inp.inp.inp_socket 499ceaad40aSRandall Stewart #define SCTP_SOCKET_LOCK(so, refcnt) 500ceaad40aSRandall Stewart #define SCTP_SOCKET_UNLOCK(so, refcnt) 501ceaad40aSRandall Stewart #endif 502ceaad40aSRandall Stewart 503f8829a4aSRandall Stewart #endif 504