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 #ifndef _NETINET_SCTP_LOCK_BSD_H_ 36807aad63SMichael Tuexen #define _NETINET_SCTP_LOCK_BSD_H_ 37807aad63SMichael Tuexen 38f8829a4aSRandall Stewart /* 39f8829a4aSRandall Stewart * General locking concepts: The goal of our locking is to of course provide 40f8829a4aSRandall Stewart * consistency and yet minimize overhead. We will attempt to use 41f8829a4aSRandall Stewart * non-recursive locks which are supposed to be quite inexpensive. Now in 42f8829a4aSRandall Stewart * order to do this the goal is that most functions are not aware of locking. 43f8829a4aSRandall Stewart * Once we have a TCB we lock it and unlock when we are through. This means 44f8829a4aSRandall Stewart * that the TCB lock is kind-of a "global" lock when working on an 45f8829a4aSRandall Stewart * association. Caution must be used when asserting a TCB_LOCK since if we 46f8829a4aSRandall Stewart * recurse we deadlock. 47f8829a4aSRandall Stewart * 48f8829a4aSRandall Stewart * Most other locks (INP and INFO) attempt to localize the locking i.e. we try 49f8829a4aSRandall Stewart * to contain the lock and unlock within the function that needs to lock it. 50f8829a4aSRandall Stewart * This sometimes mean we do extra locks and unlocks and lose a bit of 51cd0a4ff6SPedro F. Giffuni * efficiency, but if the performance statements about non-recursive locks are 52f8829a4aSRandall Stewart * true this should not be a problem. One issue that arises with this only 53f8829a4aSRandall Stewart * lock when needed is that if an implicit association setup is done we have 54f8829a4aSRandall Stewart * a problem. If at the time I lookup an association I have NULL in the tcb 55f8829a4aSRandall Stewart * return, by the time I call to create the association some other processor 56f8829a4aSRandall Stewart * could have created it. This is what the CREATE lock on the endpoint. 57f8829a4aSRandall Stewart * Places where we will be implicitly creating the association OR just 58f8829a4aSRandall Stewart * creating an association (the connect call) will assert the CREATE_INP 59f8829a4aSRandall Stewart * lock. This will assure us that during all the lookup of INP and INFO if 60f8829a4aSRandall Stewart * another creator is also locking/looking up we can gate the two to 61f8829a4aSRandall Stewart * synchronize. So the CREATE_INP lock is also another one we must use 62f8829a4aSRandall Stewart * extreme caution in locking to make sure we don't hit a re-entrancy issue. 63f8829a4aSRandall Stewart * 64f8829a4aSRandall Stewart */ 65f8829a4aSRandall Stewart 66f8829a4aSRandall Stewart /* 67f8829a4aSRandall Stewart * When working with the global SCTP lists we lock and unlock the INP_INFO 68f8829a4aSRandall Stewart * lock. So when we go to lookup an association we will want to do a 69f8829a4aSRandall Stewart * SCTP_INP_INFO_RLOCK() and then when we want to add a new association to 70b3f1ea41SRandall Stewart * the SCTP_BASE_INFO() list's we will do a SCTP_INP_INFO_WLOCK(). 71f8829a4aSRandall Stewart */ 72a5d547adSRandall Stewart 73f8829a4aSRandall Stewart #define SCTP_IPI_COUNT_INIT() 74f8829a4aSRandall Stewart 75f8829a4aSRandall Stewart #define SCTP_STATLOG_INIT_LOCK() 76d084818dSMichael Tuexen #define SCTP_STATLOG_DESTROY() 77f8829a4aSRandall Stewart #define SCTP_STATLOG_LOCK() 78f8829a4aSRandall Stewart #define SCTP_STATLOG_UNLOCK() 79d084818dSMichael Tuexen 80d084818dSMichael Tuexen #define SCTP_INP_INFO_LOCK_INIT() do { \ 81d084818dSMichael Tuexen rw_init(&SCTP_BASE_INFO(ipi_ep_mtx), "sctp-info"); \ 82d084818dSMichael Tuexen } while (0) 83f8829a4aSRandall Stewart 84c99efcf6SRandall Stewart #define SCTP_INP_INFO_LOCK_DESTROY() do { \ 85b3f1ea41SRandall Stewart if (rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx))) { \ 86b3f1ea41SRandall Stewart rw_wunlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 87c99efcf6SRandall Stewart } \ 88b3f1ea41SRandall Stewart rw_destroy(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 89c99efcf6SRandall Stewart } while (0) 90a5d547adSRandall Stewart 91f8829a4aSRandall Stewart #define SCTP_INP_INFO_RLOCK() do { \ 92b3f1ea41SRandall Stewart rw_rlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 93f8829a4aSRandall Stewart } while (0) 94f8829a4aSRandall Stewart 95d084818dSMichael Tuexen #define SCTP_INP_INFO_WLOCK() do { \ 96d084818dSMichael Tuexen rw_wlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 97d084818dSMichael Tuexen } while (0) 98d084818dSMichael Tuexen 99d084818dSMichael Tuexen #define SCTP_INP_INFO_RUNLOCK() do { \ 100d084818dSMichael Tuexen rw_runlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 101d084818dSMichael Tuexen } while (0) 102d084818dSMichael Tuexen 103d084818dSMichael Tuexen #define SCTP_INP_INFO_WUNLOCK() do { \ 104d084818dSMichael Tuexen rw_wunlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ 105d084818dSMichael Tuexen } while (0) 106d084818dSMichael Tuexen 107be8ee77eSMark Johnston #define SCTP_INP_INFO_LOCK_ASSERT() do { \ 108be8ee77eSMark Johnston rw_assert(&SCTP_BASE_INFO(ipi_ep_mtx), RA_LOCKED); \ 109be8ee77eSMark Johnston } while (0) 110be8ee77eSMark Johnston 111be8ee77eSMark Johnston #define SCTP_INP_INFO_RLOCK_ASSERT() do { \ 112be8ee77eSMark Johnston rw_assert(&SCTP_BASE_INFO(ipi_ep_mtx), RA_RLOCKED); \ 113be8ee77eSMark Johnston } while (0) 114be8ee77eSMark Johnston 115be8ee77eSMark Johnston #define SCTP_INP_INFO_WLOCK_ASSERT() do { \ 116be8ee77eSMark Johnston rw_assert(&SCTP_BASE_INFO(ipi_ep_mtx), RA_WLOCKED); \ 117be8ee77eSMark Johnston } while (0) 118be8ee77eSMark Johnston 119bfc46083SRandall Stewart #define SCTP_MCORE_QLOCK_INIT(cpstr) do { \ 120d084818dSMichael Tuexen mtx_init(&(cpstr)->que_mtx, "sctp-mcore_queue","queue_lock", \ 121bfc46083SRandall Stewart MTX_DEF | MTX_DUPOK); \ 122bfc46083SRandall Stewart } while (0) 123bfc46083SRandall Stewart 124d084818dSMichael Tuexen #define SCTP_MCORE_QDESTROY(cpstr) do { \ 125d084818dSMichael Tuexen if (mtx_owned(&(cpstr)->core_mtx)) { \ 126d084818dSMichael Tuexen mtx_unlock(&(cpstr)->que_mtx); \ 127d084818dSMichael Tuexen } \ 128d084818dSMichael Tuexen mtx_destroy(&(cpstr)->que_mtx); \ 129d084818dSMichael Tuexen } while (0) 130d084818dSMichael Tuexen 131bfc46083SRandall Stewart #define SCTP_MCORE_QLOCK(cpstr) do { \ 132bfc46083SRandall Stewart mtx_lock(&(cpstr)->que_mtx); \ 133bfc46083SRandall Stewart } while (0) 134bfc46083SRandall Stewart 135bfc46083SRandall Stewart #define SCTP_MCORE_QUNLOCK(cpstr) do { \ 136bfc46083SRandall Stewart mtx_unlock(&(cpstr)->que_mtx); \ 137bfc46083SRandall Stewart } while (0) 138bfc46083SRandall Stewart 139bfc46083SRandall Stewart #define SCTP_MCORE_LOCK_INIT(cpstr) do { \ 140d084818dSMichael Tuexen mtx_init(&(cpstr)->core_mtx, "sctp-cpulck","cpu_proc_lock", \ 141bfc46083SRandall Stewart MTX_DEF | MTX_DUPOK); \ 142bfc46083SRandall Stewart } while (0) 143bfc46083SRandall Stewart 144d084818dSMichael Tuexen #define SCTP_MCORE_DESTROY(cpstr) do { \ 145d084818dSMichael Tuexen if (mtx_owned(&(cpstr)->core_mtx)) { \ 146d084818dSMichael Tuexen mtx_unlock(&(cpstr)->core_mtx); \ 147d084818dSMichael Tuexen } \ 148d084818dSMichael Tuexen mtx_destroy(&(cpstr)->core_mtx); \ 149d084818dSMichael Tuexen } while (0) 150d084818dSMichael Tuexen 151bfc46083SRandall Stewart #define SCTP_MCORE_LOCK(cpstr) do { \ 152bfc46083SRandall Stewart mtx_lock(&(cpstr)->core_mtx); \ 153bfc46083SRandall Stewart } while (0) 154bfc46083SRandall Stewart 155bfc46083SRandall Stewart #define SCTP_MCORE_UNLOCK(cpstr) do { \ 156bfc46083SRandall Stewart mtx_unlock(&(cpstr)->core_mtx); \ 157bfc46083SRandall Stewart } while (0) 158bfc46083SRandall Stewart 159d084818dSMichael Tuexen #define SCTP_IPI_ADDR_INIT() do { \ 160d084818dSMichael Tuexen rw_init(&SCTP_BASE_INFO(ipi_addr_mtx), "sctp-addr"); \ 161bfc46083SRandall Stewart } while (0) 162f8829a4aSRandall Stewart 163c99efcf6SRandall Stewart #define SCTP_IPI_ADDR_DESTROY() do { \ 164b3f1ea41SRandall Stewart if (rw_wowned(&SCTP_BASE_INFO(ipi_addr_mtx))) { \ 165b3f1ea41SRandall Stewart rw_wunlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 166c99efcf6SRandall Stewart } \ 167b3f1ea41SRandall Stewart rw_destroy(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 168f8829a4aSRandall Stewart } while (0) 169d084818dSMichael Tuexen 170c99efcf6SRandall Stewart #define SCTP_IPI_ADDR_RLOCK() do { \ 171b3f1ea41SRandall Stewart rw_rlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 172c99efcf6SRandall Stewart } while (0) 173d084818dSMichael Tuexen 174c99efcf6SRandall Stewart #define SCTP_IPI_ADDR_WLOCK() do { \ 175b3f1ea41SRandall Stewart rw_wlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 176c99efcf6SRandall Stewart } while (0) 177c99efcf6SRandall Stewart 178d084818dSMichael Tuexen #define SCTP_IPI_ADDR_RUNLOCK() do { \ 179d084818dSMichael Tuexen rw_runlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 180d084818dSMichael Tuexen } while (0) 181d084818dSMichael Tuexen 182d084818dSMichael Tuexen #define SCTP_IPI_ADDR_WUNLOCK() do { \ 183d084818dSMichael Tuexen rw_wunlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ 184d084818dSMichael Tuexen } while (0) 185c99efcf6SRandall Stewart 1867f0ad227SMichael Tuexen #define SCTP_IPI_ADDR_LOCK_ASSERT() do { \ 1877f0ad227SMichael Tuexen rw_assert(&SCTP_BASE_INFO(ipi_addr_mtx), RA_LOCKED); \ 1887f0ad227SMichael Tuexen } while (0) 1897f0ad227SMichael Tuexen 1907f0ad227SMichael Tuexen #define SCTP_IPI_ADDR_WLOCK_ASSERT() do { \ 1917f0ad227SMichael Tuexen rw_assert(&SCTP_BASE_INFO(ipi_addr_mtx), RA_WLOCKED); \ 1927f0ad227SMichael Tuexen } while (0) 19342551e99SRandall Stewart 194d084818dSMichael Tuexen #define SCTP_IPI_ITERATOR_WQ_INIT() do { \ 195d084818dSMichael Tuexen mtx_init(&sctp_it_ctl.ipi_iterator_wq_mtx, "sctp-it-wq", \ 196d084818dSMichael Tuexen "sctp_it_wq", MTX_DEF); \ 197d084818dSMichael Tuexen } while (0) 19842551e99SRandall Stewart 199d084818dSMichael Tuexen #define SCTP_IPI_ITERATOR_WQ_DESTROY() do { \ 200d084818dSMichael Tuexen mtx_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx); \ 201d084818dSMichael Tuexen } while (0) 20242551e99SRandall Stewart 20342551e99SRandall Stewart #define SCTP_IPI_ITERATOR_WQ_LOCK() do { \ 204f7517433SRandall Stewart mtx_lock(&sctp_it_ctl.ipi_iterator_wq_mtx); \ 20542551e99SRandall Stewart } while (0) 20642551e99SRandall Stewart 207d084818dSMichael Tuexen #define SCTP_IPI_ITERATOR_WQ_UNLOCK() do { \ 208d084818dSMichael Tuexen mtx_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx); \ 209d084818dSMichael Tuexen } while (0) 21042551e99SRandall Stewart 211d084818dSMichael Tuexen #define SCTP_IP_PKTLOG_INIT() do { \ 212d084818dSMichael Tuexen mtx_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), "sctp-pktlog", \ 213d084818dSMichael Tuexen "packetlog", MTX_DEF); \ 214d084818dSMichael Tuexen } while (0) 215207304d4SRandall Stewart 216d084818dSMichael Tuexen #define SCTP_IP_PKTLOG_DESTROY() do { \ 217d084818dSMichael Tuexen mtx_destroy(&SCTP_BASE_INFO(ipi_pktlog_mtx)); \ 218d084818dSMichael Tuexen } while (0) 219207304d4SRandall Stewart 220207304d4SRandall Stewart #define SCTP_IP_PKTLOG_LOCK() do { \ 221b3f1ea41SRandall Stewart mtx_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx)); \ 222207304d4SRandall Stewart } while (0) 223207304d4SRandall Stewart 224d084818dSMichael Tuexen #define SCTP_IP_PKTLOG_UNLOCK() do { \ 225d084818dSMichael Tuexen mtx_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx)); \ 226d084818dSMichael Tuexen } while (0) 22742551e99SRandall Stewart 228f8829a4aSRandall Stewart /* 229f8829a4aSRandall Stewart * The INP locks we will use for locking an SCTP endpoint, so for example if 230f8829a4aSRandall Stewart * we want to change something at the endpoint level for example random_store 231f8829a4aSRandall Stewart * or cookie secrets we lock the INP level. 232f8829a4aSRandall Stewart */ 233f8829a4aSRandall Stewart 234*6cb8b3b5SMichael Tuexen #define SCTP_INP_READ_LOCK_INIT(_inp) do { \ 235d084818dSMichael Tuexen mtx_init(&(_inp)->inp_rdata_mtx, "sctp-read", "inpr", \ 236d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 237d084818dSMichael Tuexen } while (0) 238f8829a4aSRandall Stewart 239*6cb8b3b5SMichael Tuexen #define SCTP_INP_READ_LOCK_DESTROY(_inp) do { \ 240d084818dSMichael Tuexen mtx_destroy(&(_inp)->inp_rdata_mtx); \ 241d084818dSMichael Tuexen } while (0) 242f8829a4aSRandall Stewart 243f8829a4aSRandall Stewart #define SCTP_INP_READ_LOCK(_inp) do { \ 244f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_rdata_mtx); \ 245f8829a4aSRandall Stewart } while (0) 246f8829a4aSRandall Stewart 247d084818dSMichael Tuexen #define SCTP_INP_READ_UNLOCK(_inp) do { \ 248d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_rdata_mtx); \ 249d084818dSMichael Tuexen } while (0) 250f8829a4aSRandall Stewart 251*6cb8b3b5SMichael Tuexen #define SCTP_INP_READ_LOCK_ASSERT(_inp) do { \ 252*6cb8b3b5SMichael Tuexen KASSERT(mtx_owned(&(_inp)->inp_rdata_mtx), \ 253*6cb8b3b5SMichael Tuexen ("Don't own INP read queue lock")); \ 254*6cb8b3b5SMichael Tuexen } while (0) 255*6cb8b3b5SMichael Tuexen 256d084818dSMichael Tuexen #define SCTP_INP_LOCK_INIT(_inp) do { \ 257d084818dSMichael Tuexen mtx_init(&(_inp)->inp_mtx, "sctp-inp", "inp", \ 258d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 259d084818dSMichael Tuexen } while (0) 260f8829a4aSRandall Stewart 261d084818dSMichael Tuexen #define SCTP_INP_LOCK_DESTROY(_inp) do { \ 262d084818dSMichael Tuexen mtx_destroy(&(_inp)->inp_mtx); \ 263d084818dSMichael Tuexen } while (0) 264f8829a4aSRandall Stewart 265d084818dSMichael Tuexen #define SCTP_INP_LOCK_CONTENDED(_inp) \ 266d084818dSMichael Tuexen ((_inp)->inp_mtx.mtx_lock & MTX_CONTESTED) 2678ce4a9a2SRandall Stewart 268d084818dSMichael Tuexen #define SCTP_INP_READ_CONTENDED(_inp) \ 269d084818dSMichael Tuexen ((_inp)->inp_rdata_mtx.mtx_lock & MTX_CONTESTED) 270f8829a4aSRandall Stewart 271f8829a4aSRandall Stewart #ifdef SCTP_LOCK_LOGGING 272f8829a4aSRandall Stewart #define SCTP_INP_RLOCK(_inp) do { \ 273d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 274d084818dSMichael Tuexen sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \ 275f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 276f8829a4aSRandall Stewart } while (0) 277f8829a4aSRandall Stewart 278f8829a4aSRandall Stewart #define SCTP_INP_WLOCK(_inp) do { \ 279d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 280d084818dSMichael Tuexen sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \ 281f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 282f8829a4aSRandall Stewart } while (0) 283f8829a4aSRandall Stewart #else 284f8829a4aSRandall Stewart #define SCTP_INP_RLOCK(_inp) do { \ 285f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 286f8829a4aSRandall Stewart } while (0) 287f8829a4aSRandall Stewart 288f8829a4aSRandall Stewart #define SCTP_INP_WLOCK(_inp) do { \ 289f8829a4aSRandall Stewart mtx_lock(&(_inp)->inp_mtx); \ 290f8829a4aSRandall Stewart } while (0) 291f8829a4aSRandall Stewart #endif 292f8829a4aSRandall Stewart 293d084818dSMichael Tuexen #define SCTP_INP_RUNLOCK(_inp) do { \ 294d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_mtx); \ 295d084818dSMichael Tuexen } while (0) 296f8829a4aSRandall Stewart 297d084818dSMichael Tuexen #define SCTP_INP_WUNLOCK(_inp) do { \ 298d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_mtx); \ 299d084818dSMichael Tuexen } while (0) 300f8829a4aSRandall Stewart 301d084818dSMichael Tuexen #define SCTP_INP_RLOCK_ASSERT(_inp) do { \ 302d084818dSMichael Tuexen KASSERT(mtx_owned(&(_inp)->inp_mtx), \ 303d084818dSMichael Tuexen ("Don't own INP read lock")); \ 304d084818dSMichael Tuexen } while (0) 305d084818dSMichael Tuexen 306d084818dSMichael Tuexen #define SCTP_INP_WLOCK_ASSERT(_inp) do { \ 307d084818dSMichael Tuexen KASSERT(mtx_owned(&(_inp)->inp_mtx), \ 308d084818dSMichael Tuexen ("Don't own INP write lock")); \ 309d084818dSMichael Tuexen } while (0) 310d084818dSMichael Tuexen 311d084818dSMichael Tuexen #define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1) 312d084818dSMichael Tuexen #define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1) 313d084818dSMichael Tuexen 314d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) do { \ 315d084818dSMichael Tuexen mtx_init(&(_inp)->inp_create_mtx, "sctp-create", "inp_create", \ 316d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 317d084818dSMichael Tuexen } while (0) 318d084818dSMichael Tuexen 319d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) do { \ 320d084818dSMichael Tuexen mtx_destroy(&(_inp)->inp_create_mtx); \ 321d084818dSMichael Tuexen } while (0) 322d084818dSMichael Tuexen 323d084818dSMichael Tuexen #ifdef SCTP_LOCK_LOGGING 324d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK(_inp) do { \ 325d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 326d084818dSMichael Tuexen sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_CREATE); \ 327d084818dSMichael Tuexen mtx_lock(&(_inp)->inp_create_mtx); \ 328d084818dSMichael Tuexen } while (0) 329d084818dSMichael Tuexen #else 330d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK(_inp) do { \ 331d084818dSMichael Tuexen mtx_lock(&(_inp)->inp_create_mtx); \ 332d084818dSMichael Tuexen } while (0) 333d084818dSMichael Tuexen #endif 334d084818dSMichael Tuexen 335d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_UNLOCK(_inp) do { \ 336d084818dSMichael Tuexen mtx_unlock(&(_inp)->inp_create_mtx); \ 337d084818dSMichael Tuexen } while (0) 338d084818dSMichael Tuexen 339d084818dSMichael Tuexen #define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) \ 340d084818dSMichael Tuexen ((_inp)->inp_create_mtx.mtx_lock & MTX_CONTESTED) 341d084818dSMichael Tuexen 342f8829a4aSRandall Stewart /* 343f8829a4aSRandall Stewart * For the majority of things (once we have found the association) we will 344f8829a4aSRandall Stewart * lock the actual association mutex. This will protect all the assoiciation 345f8829a4aSRandall Stewart * level queues and streams and such. We will need to lock the socket layer 346f8829a4aSRandall Stewart * when we stuff data up into the receiving sb_mb. I.e. we will need to do an 347f8829a4aSRandall Stewart * extra SOCKBUF_LOCK(&so->so_rcv) even though the association is locked. 348f8829a4aSRandall Stewart */ 349f8829a4aSRandall Stewart 350d084818dSMichael Tuexen #define SCTP_TCB_LOCK_INIT(_tcb) do { \ 351d084818dSMichael Tuexen mtx_init(&(_tcb)->tcb_mtx, "sctp-tcb", "tcb", \ 352d084818dSMichael Tuexen MTX_DEF | MTX_DUPOK); \ 353d084818dSMichael Tuexen } while (0) 354f8829a4aSRandall Stewart 355d084818dSMichael Tuexen #define SCTP_TCB_LOCK_DESTROY(_tcb) do { \ 356d084818dSMichael Tuexen mtx_destroy(&(_tcb)->tcb_mtx); \ 357d084818dSMichael Tuexen } while (0) 358f8829a4aSRandall Stewart 359f8829a4aSRandall Stewart #ifdef SCTP_LOCK_LOGGING 360f8829a4aSRandall Stewart #define SCTP_TCB_LOCK(_tcb) do { \ 361d084818dSMichael Tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \ 362d084818dSMichael Tuexen sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \ 363f8829a4aSRandall Stewart mtx_lock(&(_tcb)->tcb_mtx); \ 364f8829a4aSRandall Stewart } while (0) 365f8829a4aSRandall Stewart #else 366f8829a4aSRandall Stewart #define SCTP_TCB_LOCK(_tcb) do { \ 367f8829a4aSRandall Stewart mtx_lock(&(_tcb)->tcb_mtx); \ 368f8829a4aSRandall Stewart } while (0) 369f8829a4aSRandall Stewart 370f8829a4aSRandall Stewart #endif 371f8829a4aSRandall Stewart 372d084818dSMichael Tuexen #define SCTP_TCB_TRYLOCK(_tcb) \ 373d084818dSMichael Tuexen mtx_trylock(&(_tcb)->tcb_mtx) 374f8829a4aSRandall Stewart 375d084818dSMichael Tuexen #define SCTP_TCB_UNLOCK(_tcb) do { \ 376d084818dSMichael Tuexen mtx_unlock(&(_tcb)->tcb_mtx); \ 377d084818dSMichael Tuexen } while (0) 378f8829a4aSRandall Stewart 379f8829a4aSRandall Stewart #define SCTP_TCB_UNLOCK_IFOWNED(_tcb) do { \ 380f8829a4aSRandall Stewart if (mtx_owned(&(_tcb)->tcb_mtx)) \ 381f8829a4aSRandall Stewart mtx_unlock(&(_tcb)->tcb_mtx); \ 382f8829a4aSRandall Stewart } while (0) 383f8829a4aSRandall Stewart 384f8829a4aSRandall Stewart #define SCTP_TCB_LOCK_ASSERT(_tcb) do { \ 385d084818dSMichael Tuexen KASSERT(mtx_owned(&(_tcb)->tcb_mtx), \ 386d084818dSMichael Tuexen ("Don't own TCB lock")); \ 387f8829a4aSRandall Stewart } while (0) 388f8829a4aSRandall Stewart 389d084818dSMichael Tuexen #define SCTP_ITERATOR_LOCK_INIT() do { \ 390d084818dSMichael Tuexen mtx_init(&sctp_it_ctl.it_mtx, "sctp-it", "iterator", MTX_DEF); \ 391d084818dSMichael Tuexen } while (0) 392d084818dSMichael Tuexen 393d084818dSMichael Tuexen #define SCTP_ITERATOR_LOCK_DESTROY() do { \ 394d084818dSMichael Tuexen mtx_destroy(&sctp_it_ctl.it_mtx); \ 395d084818dSMichael Tuexen } while (0) 396d084818dSMichael Tuexen 397f8829a4aSRandall Stewart #define SCTP_ITERATOR_LOCK() \ 398f8829a4aSRandall Stewart do { \ 399d084818dSMichael Tuexen KASSERT(!mtx_owned(&sctp_it_ctl.it_mtx), \ 400d084818dSMichael Tuexen ("Own the iterator lock")); \ 401f7517433SRandall Stewart mtx_lock(&sctp_it_ctl.it_mtx); \ 402f8829a4aSRandall Stewart } while (0) 403f8829a4aSRandall Stewart 404d084818dSMichael Tuexen #define SCTP_ITERATOR_UNLOCK() do { \ 405d084818dSMichael Tuexen mtx_unlock(&sctp_it_ctl.it_mtx); \ 406d084818dSMichael Tuexen } while (0) 407f7517433SRandall Stewart 408f7517433SRandall Stewart #define SCTP_WQ_ADDR_INIT() do { \ 409d084818dSMichael Tuexen mtx_init(&SCTP_BASE_INFO(wq_addr_mtx), \ 410d084818dSMichael Tuexen "sctp-addr-wq","sctp_addr_wq", MTX_DEF); \ 411f7517433SRandall Stewart } while (0) 412f7517433SRandall Stewart 413f7517433SRandall Stewart #define SCTP_WQ_ADDR_DESTROY() do { \ 414f7517433SRandall Stewart if (mtx_owned(&SCTP_BASE_INFO(wq_addr_mtx))) { \ 415f7517433SRandall Stewart mtx_unlock(&SCTP_BASE_INFO(wq_addr_mtx)); \ 416f7517433SRandall Stewart } \ 417f7517433SRandall Stewart mtx_destroy(&SCTP_BASE_INFO(wq_addr_mtx)); \ 418f7517433SRandall Stewart } while (0) 419f7517433SRandall Stewart 420f7517433SRandall Stewart #define SCTP_WQ_ADDR_LOCK() do { \ 421f7517433SRandall Stewart mtx_lock(&SCTP_BASE_INFO(wq_addr_mtx)); \ 422f7517433SRandall Stewart } while (0) 423d084818dSMichael Tuexen 424f7517433SRandall Stewart #define SCTP_WQ_ADDR_UNLOCK() do { \ 425f7517433SRandall Stewart mtx_unlock(&SCTP_BASE_INFO(wq_addr_mtx)); \ 426f7517433SRandall Stewart } while (0) 427f7517433SRandall Stewart 428d084818dSMichael Tuexen #define SCTP_WQ_ADDR_LOCK_ASSERT() do { \ 429d084818dSMichael Tuexen KASSERT(mtx_owned(&SCTP_BASE_INFO(wq_addr_mtx)), \ 430d084818dSMichael Tuexen ("Don't own the ADDR-WQ lock")); \ 431d084818dSMichael Tuexen } while (0) 432f8829a4aSRandall Stewart 433d084818dSMichael Tuexen #define SCTP_INCR_EP_COUNT() do { \ 434b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \ 435f8829a4aSRandall Stewart } while (0) 436f8829a4aSRandall Stewart 437d084818dSMichael Tuexen #define SCTP_DECR_EP_COUNT() do { \ 438b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \ 439f8829a4aSRandall Stewart } while (0) 440f8829a4aSRandall Stewart 441d084818dSMichael Tuexen #define SCTP_INCR_ASOC_COUNT() do { \ 442b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \ 443f8829a4aSRandall Stewart } while (0) 444f8829a4aSRandall Stewart 445d084818dSMichael Tuexen #define SCTP_DECR_ASOC_COUNT() do { \ 446b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \ 447f8829a4aSRandall Stewart } while (0) 448f8829a4aSRandall Stewart 449d084818dSMichael Tuexen #define SCTP_INCR_LADDR_COUNT() do { \ 450b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \ 451f8829a4aSRandall Stewart } while (0) 452f8829a4aSRandall Stewart 453d084818dSMichael Tuexen #define SCTP_DECR_LADDR_COUNT() do { \ 454b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \ 455f8829a4aSRandall Stewart } while (0) 456f8829a4aSRandall Stewart 457d084818dSMichael Tuexen #define SCTP_INCR_RADDR_COUNT() do { \ 458b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \ 459f8829a4aSRandall Stewart } while (0) 460f8829a4aSRandall Stewart 461d084818dSMichael Tuexen #define SCTP_DECR_RADDR_COUNT() do { \ 462b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr),1); \ 463f8829a4aSRandall Stewart } while (0) 464f8829a4aSRandall Stewart 465d084818dSMichael Tuexen #define SCTP_INCR_CHK_COUNT() do { \ 466b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \ 467f8829a4aSRandall Stewart } while (0) 468d084818dSMichael Tuexen 469d084818dSMichael Tuexen #define SCTP_DECR_CHK_COUNT() do { \ 470d084818dSMichael Tuexen KASSERT(SCTP_BASE_INFO(ipi_count_chunk) > 0, \ 471d084818dSMichael Tuexen ("ipi_count_chunk would become negative")); \ 472df6e0cc3SRandall Stewart if (SCTP_BASE_INFO(ipi_count_chunk) != 0) \ 473d084818dSMichael Tuexen atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), \ 474d084818dSMichael Tuexen 1); \ 475df6e0cc3SRandall Stewart } while (0) 476d084818dSMichael Tuexen 477d084818dSMichael Tuexen #define SCTP_INCR_READQ_COUNT() do { \ 478b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \ 479f8829a4aSRandall Stewart } while (0) 480f8829a4aSRandall Stewart 481d084818dSMichael Tuexen #define SCTP_DECR_READQ_COUNT() do { \ 482b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \ 483f8829a4aSRandall Stewart } while (0) 484f8829a4aSRandall Stewart 485d084818dSMichael Tuexen #define SCTP_INCR_STRMOQ_COUNT() do { \ 486b3f1ea41SRandall Stewart atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \ 487f8829a4aSRandall Stewart } while (0) 488f8829a4aSRandall Stewart 489d084818dSMichael Tuexen #define SCTP_DECR_STRMOQ_COUNT() do { \ 490b3f1ea41SRandall Stewart atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \ 491f8829a4aSRandall Stewart } while (0) 492f8829a4aSRandall Stewart 493ceaad40aSRandall Stewart #if defined(SCTP_SO_LOCK_TESTING) 494d084818dSMichael Tuexen #define SCTP_INP_SO(sctpinp) \ 495d084818dSMichael Tuexen (sctpinp)->ip_inp.inp.inp_socket 496ceaad40aSRandall Stewart #define SCTP_SOCKET_LOCK(so, refcnt) 497ceaad40aSRandall Stewart #define SCTP_SOCKET_UNLOCK(so, refcnt) 498ceaad40aSRandall Stewart #endif 499ceaad40aSRandall Stewart 500f8829a4aSRandall Stewart #endif 501