qspinlock_types.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Queued spinlock
  4. *
  5. * (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
  6. *
  7. * Authors: Waiman Long <waiman.long@hp.com>
  8. */
  9. #ifndef __ASM_GENERIC_QSPINLOCK_TYPES_H
  10. #define __ASM_GENERIC_QSPINLOCK_TYPES_H
  11. #include <linux/types.h>
  12. typedef struct qspinlock {
  13. union {
  14. atomic_t val;
  15. /*
  16. * By using the whole 2nd least significant byte for the
  17. * pending bit, we can allow better optimization of the lock
  18. * acquisition for the pending bit holder.
  19. */
  20. #ifdef __LITTLE_ENDIAN
  21. struct {
  22. u8 locked;
  23. u8 pending;
  24. };
  25. struct {
  26. u16 locked_pending;
  27. u16 tail;
  28. };
  29. #else
  30. struct {
  31. u16 tail;
  32. u16 locked_pending;
  33. };
  34. struct {
  35. u8 reserved[2];
  36. u8 pending;
  37. u8 locked;
  38. };
  39. #endif
  40. };
  41. } arch_spinlock_t;
  42. /*
  43. * Initializier
  44. */
  45. #define __ARCH_SPIN_LOCK_UNLOCKED { { .val = ATOMIC_INIT(0) } }
  46. /*
  47. * Bitfields in the atomic value:
  48. *
  49. * When NR_CPUS < 16K
  50. * 0- 7: locked byte
  51. * 8: pending
  52. * 9-15: not used
  53. * 16-17: tail index
  54. * 18-31: tail cpu (+1)
  55. *
  56. * When NR_CPUS >= 16K
  57. * 0- 7: locked byte
  58. * 8: pending
  59. * 9-10: tail index
  60. * 11-31: tail cpu (+1)
  61. */
  62. #define _Q_SET_MASK(type) (((1U << _Q_ ## type ## _BITS) - 1)\
  63. << _Q_ ## type ## _OFFSET)
  64. #define _Q_LOCKED_OFFSET 0
  65. #define _Q_LOCKED_BITS 8
  66. #define _Q_LOCKED_MASK _Q_SET_MASK(LOCKED)
  67. #define _Q_PENDING_OFFSET (_Q_LOCKED_OFFSET + _Q_LOCKED_BITS)
  68. #if CONFIG_NR_CPUS < (1U << 14)
  69. #define _Q_PENDING_BITS 8
  70. #else
  71. #define _Q_PENDING_BITS 1
  72. #endif
  73. #define _Q_PENDING_MASK _Q_SET_MASK(PENDING)
  74. #define _Q_TAIL_IDX_OFFSET (_Q_PENDING_OFFSET + _Q_PENDING_BITS)
  75. #define _Q_TAIL_IDX_BITS 2
  76. #define _Q_TAIL_IDX_MASK _Q_SET_MASK(TAIL_IDX)
  77. #define _Q_TAIL_CPU_OFFSET (_Q_TAIL_IDX_OFFSET + _Q_TAIL_IDX_BITS)
  78. #define _Q_TAIL_CPU_BITS (32 - _Q_TAIL_CPU_OFFSET)
  79. #define _Q_TAIL_CPU_MASK _Q_SET_MASK(TAIL_CPU)
  80. #define _Q_TAIL_OFFSET _Q_TAIL_IDX_OFFSET
  81. #define _Q_TAIL_MASK (_Q_TAIL_IDX_MASK | _Q_TAIL_CPU_MASK)
  82. #define _Q_LOCKED_VAL (1U << _Q_LOCKED_OFFSET)
  83. #define _Q_PENDING_VAL (1U << _Q_PENDING_OFFSET)
  84. #endif /* __ASM_GENERIC_QSPINLOCK_TYPES_H */