The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/include/os/linux/spl/sys/rwlock.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
    3  *  Copyright (C) 2007 The Regents of the University of California.
    4  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
    5  *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
    6  *  UCRL-CODE-235197
    7  *
    8  *  This file is part of the SPL, Solaris Porting Layer.
    9  *
   10  *  The SPL is free software; you can redistribute it and/or modify it
   11  *  under the terms of the GNU General Public License as published by the
   12  *  Free Software Foundation; either version 2 of the License, or (at your
   13  *  option) any later version.
   14  *
   15  *  The SPL is distributed in the hope that it will be useful, but WITHOUT
   16  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18  *  for more details.
   19  *
   20  *  You should have received a copy of the GNU General Public License along
   21  *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
   22  */
   23 
   24 #ifndef _SPL_RWLOCK_H
   25 #define _SPL_RWLOCK_H
   26 
   27 #include <sys/types.h>
   28 #include <linux/rwsem.h>
   29 #include <linux/sched.h>
   30 
   31 typedef enum {
   32         RW_DRIVER       = 2,
   33         RW_DEFAULT      = 4,
   34         RW_NOLOCKDEP    = 5
   35 } krw_type_t;
   36 
   37 typedef enum {
   38         RW_NONE         = 0,
   39         RW_WRITER       = 1,
   40         RW_READER       = 2
   41 } krw_t;
   42 
   43 typedef struct {
   44         struct rw_semaphore rw_rwlock;
   45         kthread_t *rw_owner;
   46 #ifdef CONFIG_LOCKDEP
   47         krw_type_t      rw_type;
   48 #endif /* CONFIG_LOCKDEP */
   49 } krwlock_t;
   50 
   51 #define SEM(rwp)        (&(rwp)->rw_rwlock)
   52 
   53 static inline void
   54 spl_rw_set_owner(krwlock_t *rwp)
   55 {
   56         rwp->rw_owner = current;
   57 }
   58 
   59 static inline void
   60 spl_rw_clear_owner(krwlock_t *rwp)
   61 {
   62         rwp->rw_owner = NULL;
   63 }
   64 
   65 static inline kthread_t *
   66 rw_owner(krwlock_t *rwp)
   67 {
   68         return (rwp->rw_owner);
   69 }
   70 
   71 #ifdef CONFIG_LOCKDEP
   72 static inline void
   73 spl_rw_set_type(krwlock_t *rwp, krw_type_t type)
   74 {
   75         rwp->rw_type = type;
   76 }
   77 static inline void
   78 spl_rw_lockdep_off_maybe(krwlock_t *rwp)                \
   79 {                                                       \
   80         if (rwp && rwp->rw_type == RW_NOLOCKDEP)        \
   81                 lockdep_off();                          \
   82 }
   83 static inline void
   84 spl_rw_lockdep_on_maybe(krwlock_t *rwp)                 \
   85 {                                                       \
   86         if (rwp && rwp->rw_type == RW_NOLOCKDEP)        \
   87                 lockdep_on();                           \
   88 }
   89 #else  /* CONFIG_LOCKDEP */
   90 #define spl_rw_set_type(rwp, type)
   91 #define spl_rw_lockdep_off_maybe(rwp)
   92 #define spl_rw_lockdep_on_maybe(rwp)
   93 #endif /* CONFIG_LOCKDEP */
   94 
   95 static inline int
   96 RW_LOCK_HELD(krwlock_t *rwp)
   97 {
   98         return (rwsem_is_locked(SEM(rwp)));
   99 }
  100 
  101 static inline int
  102 RW_WRITE_HELD(krwlock_t *rwp)
  103 {
  104         return (rw_owner(rwp) == current);
  105 }
  106 
  107 static inline int
  108 RW_READ_HELD(krwlock_t *rwp)
  109 {
  110         return (RW_LOCK_HELD(rwp) && rw_owner(rwp) == NULL);
  111 }
  112 
  113 /*
  114  * The following functions must be a #define and not static inline.
  115  * This ensures that the native linux semaphore functions (down/up)
  116  * will be correctly located in the users code which is important
  117  * for the built in kernel lock analysis tools
  118  */
  119 #define rw_init(rwp, name, type, arg) /* CSTYLED */                     \
  120 ({                                                                      \
  121         static struct lock_class_key __key;                             \
  122         ASSERT(type == RW_DEFAULT || type == RW_NOLOCKDEP);             \
  123                                                                         \
  124         __init_rwsem(SEM(rwp), #rwp, &__key);                           \
  125         spl_rw_clear_owner(rwp);                                        \
  126         spl_rw_set_type(rwp, type);                                     \
  127 })
  128 
  129 /*
  130  * The Linux rwsem implementation does not require a matching destroy.
  131  */
  132 #define rw_destroy(rwp)         ((void) 0)
  133 
  134 /*
  135  * Upgrading a rwsem from a reader to a writer is not supported by the
  136  * Linux kernel.  The lock must be dropped and reacquired as a writer.
  137  */
  138 #define rw_tryupgrade(rwp)      RW_WRITE_HELD(rwp)
  139 
  140 #define rw_tryenter(rwp, rw) /* CSTYLED */                              \
  141 ({                                                                      \
  142         int _rc_ = 0;                                                   \
  143                                                                         \
  144         spl_rw_lockdep_off_maybe(rwp);                                  \
  145         switch (rw) {                                                   \
  146         case RW_READER:                                                 \
  147                 _rc_ = down_read_trylock(SEM(rwp));                     \
  148                 break;                                                  \
  149         case RW_WRITER:                                                 \
  150                 if ((_rc_ = down_write_trylock(SEM(rwp))))              \
  151                         spl_rw_set_owner(rwp);                          \
  152                 break;                                                  \
  153         default:                                                        \
  154                 VERIFY(0);                                              \
  155         }                                                               \
  156         spl_rw_lockdep_on_maybe(rwp);                                   \
  157         _rc_;                                                           \
  158 })
  159 
  160 #define rw_enter(rwp, rw) /* CSTYLED */                                 \
  161 ({                                                                      \
  162         spl_rw_lockdep_off_maybe(rwp);                                  \
  163         switch (rw) {                                                   \
  164         case RW_READER:                                                 \
  165                 down_read(SEM(rwp));                                    \
  166                 break;                                                  \
  167         case RW_WRITER:                                                 \
  168                 down_write(SEM(rwp));                                   \
  169                 spl_rw_set_owner(rwp);                                  \
  170                 break;                                                  \
  171         default:                                                        \
  172                 VERIFY(0);                                              \
  173         }                                                               \
  174         spl_rw_lockdep_on_maybe(rwp);                                   \
  175 })
  176 
  177 #define rw_exit(rwp) /* CSTYLED */                                      \
  178 ({                                                                      \
  179         spl_rw_lockdep_off_maybe(rwp);                                  \
  180         if (RW_WRITE_HELD(rwp)) {                                       \
  181                 spl_rw_clear_owner(rwp);                                \
  182                 up_write(SEM(rwp));                                     \
  183         } else {                                                        \
  184                 ASSERT(RW_READ_HELD(rwp));                              \
  185                 up_read(SEM(rwp));                                      \
  186         }                                                               \
  187         spl_rw_lockdep_on_maybe(rwp);                                   \
  188 })
  189 
  190 #define rw_downgrade(rwp) /* CSTYLED */                                 \
  191 ({                                                                      \
  192         spl_rw_lockdep_off_maybe(rwp);                                  \
  193         spl_rw_clear_owner(rwp);                                        \
  194         downgrade_write(SEM(rwp));                                      \
  195         spl_rw_lockdep_on_maybe(rwp);                                   \
  196 })
  197 
  198 #endif /* _SPL_RWLOCK_H */

Cache object: 3d7b0161ac1ab82dfbff7ddc96546db1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.