Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Queued spinlock
0004  *
0005  * (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
0006  *
0007  * Authors: Waiman Long <waiman.long@hp.com>
0008  */
0009 #ifndef __ASM_GENERIC_QSPINLOCK_TYPES_H
0010 #define __ASM_GENERIC_QSPINLOCK_TYPES_H
0011 
0012 #include <linux/types.h>
0013 
0014 typedef struct qspinlock {
0015     union {
0016         atomic_t val;
0017 
0018         /*
0019          * By using the whole 2nd least significant byte for the
0020          * pending bit, we can allow better optimization of the lock
0021          * acquisition for the pending bit holder.
0022          */
0023 #ifdef __LITTLE_ENDIAN
0024         struct {
0025             u8  locked;
0026             u8  pending;
0027         };
0028         struct {
0029             u16 locked_pending;
0030             u16 tail;
0031         };
0032 #else
0033         struct {
0034             u16 tail;
0035             u16 locked_pending;
0036         };
0037         struct {
0038             u8  reserved[2];
0039             u8  pending;
0040             u8  locked;
0041         };
0042 #endif
0043     };
0044 } arch_spinlock_t;
0045 
0046 /*
0047  * Initializier
0048  */
0049 #define __ARCH_SPIN_LOCK_UNLOCKED   { { .val = ATOMIC_INIT(0) } }
0050 
0051 /*
0052  * Bitfields in the atomic value:
0053  *
0054  * When NR_CPUS < 16K
0055  *  0- 7: locked byte
0056  *     8: pending
0057  *  9-15: not used
0058  * 16-17: tail index
0059  * 18-31: tail cpu (+1)
0060  *
0061  * When NR_CPUS >= 16K
0062  *  0- 7: locked byte
0063  *     8: pending
0064  *  9-10: tail index
0065  * 11-31: tail cpu (+1)
0066  */
0067 #define _Q_SET_MASK(type)   (((1U << _Q_ ## type ## _BITS) - 1)\
0068                       << _Q_ ## type ## _OFFSET)
0069 #define _Q_LOCKED_OFFSET    0
0070 #define _Q_LOCKED_BITS      8
0071 #define _Q_LOCKED_MASK      _Q_SET_MASK(LOCKED)
0072 
0073 #define _Q_PENDING_OFFSET   (_Q_LOCKED_OFFSET + _Q_LOCKED_BITS)
0074 #if CONFIG_NR_CPUS < (1U << 14)
0075 #define _Q_PENDING_BITS     8
0076 #else
0077 #define _Q_PENDING_BITS     1
0078 #endif
0079 #define _Q_PENDING_MASK     _Q_SET_MASK(PENDING)
0080 
0081 #define _Q_TAIL_IDX_OFFSET  (_Q_PENDING_OFFSET + _Q_PENDING_BITS)
0082 #define _Q_TAIL_IDX_BITS    2
0083 #define _Q_TAIL_IDX_MASK    _Q_SET_MASK(TAIL_IDX)
0084 
0085 #define _Q_TAIL_CPU_OFFSET  (_Q_TAIL_IDX_OFFSET + _Q_TAIL_IDX_BITS)
0086 #define _Q_TAIL_CPU_BITS    (32 - _Q_TAIL_CPU_OFFSET)
0087 #define _Q_TAIL_CPU_MASK    _Q_SET_MASK(TAIL_CPU)
0088 
0089 #define _Q_TAIL_OFFSET      _Q_TAIL_IDX_OFFSET
0090 #define _Q_TAIL_MASK        (_Q_TAIL_IDX_MASK | _Q_TAIL_CPU_MASK)
0091 
0092 #define _Q_LOCKED_VAL       (1U << _Q_LOCKED_OFFSET)
0093 #define _Q_PENDING_VAL      (1U << _Q_PENDING_OFFSET)
0094 
0095 #endif /* __ASM_GENERIC_QSPINLOCK_TYPES_H */