hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/include/linux/rwsem.h
....@@ -19,51 +19,55 @@
1919 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
2020 #include <linux/osq_lock.h>
2121 #endif
22
+#include <linux/android_vendor.h>
2223
23
-struct rw_semaphore;
24
-
25
-#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
26
-#include <linux/rwsem-spinlock.h> /* use a generic implementation */
27
-#define __RWSEM_INIT_COUNT(name) .count = RWSEM_UNLOCKED_VALUE
28
-#else
29
-/* All arch specific implementations share the same struct */
24
+/*
25
+ * For an uncontended rwsem, count and owner are the only fields a task
26
+ * needs to touch when acquiring the rwsem. So they are put next to each
27
+ * other to increase the chance that they will share the same cacheline.
28
+ *
29
+ * In a contended rwsem, the owner is likely the most frequently accessed
30
+ * field in the structure as the optimistic waiter that holds the osq lock
31
+ * will spin on owner. For an embedded rwsem, other hot fields in the
32
+ * containing structure should be moved further away from the rwsem to
33
+ * reduce the chance that they will share the same cacheline causing
34
+ * cacheline bouncing problem.
35
+ */
3036 struct rw_semaphore {
3137 atomic_long_t count;
32
- struct list_head wait_list;
33
- raw_spinlock_t wait_lock;
38
+ /*
39
+ * Write owner or one of the read owners as well flags regarding
40
+ * the current state of the rwsem. Can be used as a speculative
41
+ * check to see if the write owner is running on the cpu.
42
+ */
43
+ atomic_long_t owner;
3444 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
3545 struct optimistic_spin_queue osq; /* spinner MCS lock */
36
- /*
37
- * Write owner. Used as a speculative check to see
38
- * if the owner is running on the cpu.
39
- */
40
- struct task_struct *owner;
46
+#endif
47
+ raw_spinlock_t wait_lock;
48
+ struct list_head wait_list;
49
+#ifdef CONFIG_DEBUG_RWSEMS
50
+ void *magic;
4151 #endif
4252 #ifdef CONFIG_DEBUG_LOCK_ALLOC
4353 struct lockdep_map dep_map;
4454 #endif
45
- /* NOTICE: m_count is a vendor variable used for the config
46
- * CONFIG_RWSEM_PRIO_AWARE. This is included here to maintain ABI
47
- * compatibility with our vendors */
48
- /* count for waiters preempt to queue in wait list */
49
- long m_count;
55
+ ANDROID_VENDOR_DATA(1);
56
+ ANDROID_OEM_DATA_ARRAY(1, 2);
5057 };
5158
52
-/*
53
- * Setting bit 0 of the owner field with other non-zero bits will indicate
54
- * that the rwsem is writer-owned with an unknown owner.
55
- */
56
-#define RWSEM_OWNER_UNKNOWN ((struct task_struct *)-1L)
59
+enum rwsem_waiter_type {
60
+ RWSEM_WAITING_FOR_WRITE,
61
+ RWSEM_WAITING_FOR_READ
62
+};
5763
58
-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
59
-extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem);
60
-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
61
-extern struct rw_semaphore *rwsem_down_write_failed_killable(struct rw_semaphore *sem);
62
-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
63
-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
64
-
65
-/* Include the arch specific part */
66
-#include <asm/rwsem.h>
64
+struct rwsem_waiter {
65
+ struct list_head list;
66
+ struct task_struct *task;
67
+ enum rwsem_waiter_type type;
68
+ unsigned long timeout;
69
+ unsigned long last_rowner;
70
+};
6771
6872 /* In all implementations count != 0 means locked */
6973 static inline int rwsem_is_locked(struct rw_semaphore *sem)
....@@ -71,28 +75,40 @@
7175 return atomic_long_read(&sem->count) != 0;
7276 }
7377
74
-#define __RWSEM_INIT_COUNT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE)
75
-#endif
78
+#define RWSEM_UNLOCKED_VALUE 0L
79
+#define __RWSEM_COUNT_INIT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE)
7680
7781 /* Common initializer macros and functions */
7882
7983 #ifdef CONFIG_DEBUG_LOCK_ALLOC
80
-# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
84
+# define __RWSEM_DEP_MAP_INIT(lockname) \
85
+ .dep_map = { \
86
+ .name = #lockname, \
87
+ .wait_type_inner = LD_WAIT_SLEEP, \
88
+ },
8189 #else
8290 # define __RWSEM_DEP_MAP_INIT(lockname)
8391 #endif
8492
93
+#ifdef CONFIG_DEBUG_RWSEMS
94
+# define __RWSEM_DEBUG_INIT(lockname) .magic = &lockname,
95
+#else
96
+# define __RWSEM_DEBUG_INIT(lockname)
97
+#endif
98
+
8599 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
86
-#define __RWSEM_OPT_INIT(lockname) , .osq = OSQ_LOCK_UNLOCKED, .owner = NULL
100
+#define __RWSEM_OPT_INIT(lockname) .osq = OSQ_LOCK_UNLOCKED,
87101 #else
88102 #define __RWSEM_OPT_INIT(lockname)
89103 #endif
90104
91105 #define __RWSEM_INITIALIZER(name) \
92
- { __RWSEM_INIT_COUNT(name), \
93
- .wait_list = LIST_HEAD_INIT((name).wait_list), \
94
- .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \
106
+ { __RWSEM_COUNT_INIT(name), \
107
+ .owner = ATOMIC_LONG_INIT(0), \
95108 __RWSEM_OPT_INIT(name) \
109
+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock),\
110
+ .wait_list = LIST_HEAD_INIT((name).wait_list), \
111
+ __RWSEM_DEBUG_INIT(name) \
96112 __RWSEM_DEP_MAP_INIT(name) }
97113
98114 #define DECLARE_RWSEM(name) \
....@@ -123,6 +139,7 @@
123139 * lock for reading
124140 */
125141 extern void down_read(struct rw_semaphore *sem);
142
+extern int __must_check down_read_interruptible(struct rw_semaphore *sem);
126143 extern int __must_check down_read_killable(struct rw_semaphore *sem);
127144
128145 /*
....@@ -168,9 +185,10 @@
168185 * static then another method for expressing nested locking is
169186 * the explicit definition of lock class keys and the use of
170187 * lockdep_set_class() at lock initialization time.
171
- * See Documentation/locking/lockdep-design.txt for more details.)
188
+ * See Documentation/locking/lockdep-design.rst for more details.)
172189 */
173190 extern void down_read_nested(struct rw_semaphore *sem, int subclass);
191
+extern int __must_check down_read_killable_nested(struct rw_semaphore *sem, int subclass);
174192 extern void down_write_nested(struct rw_semaphore *sem, int subclass);
175193 extern int down_write_killable_nested(struct rw_semaphore *sem, int subclass);
176194 extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock);
....@@ -191,6 +209,7 @@
191209 extern void up_read_non_owner(struct rw_semaphore *sem);
192210 #else
193211 # define down_read_nested(sem, subclass) down_read(sem)
212
+# define down_read_killable_nested(sem, subclass) down_read_killable(sem)
194213 # define down_write_nest_lock(sem, nest_lock) down_write(sem)
195214 # define down_write_nested(sem, subclass) down_write(sem)
196215 # define down_write_killable_nested(sem, subclass) down_write_killable(sem)