Locking changes for v6.5:
- Introduce cmpxchg128() -- aka. the demise of cmpxchg_double().
The cmpxchg128() family of functions is basically & functionally
the same as cmpxchg_double(), but with a saner interface: instead
of a 6-parameter horror that forced u128 - u64/u64-halves layout
details on the interface and exposed users to complexity,
fragility & bugs, use a natural 3-parameter interface with u128 types.
- Restructure the generated atomic headers, and add
kerneldoc comments for all of the generic atomic{,64,_long}_t
operations. Generated definitions are much cleaner now,
and come with documentation.
- Implement lock_set_cmp_fn() on lockdep, for defining an ordering
when taking multiple locks of the same type. This gets rid of
one use of lockdep_set_novalidate_class() in the bcache code.
- Fix raw_cpu_generic_try_cmpxchg() bug due to an unintended
variable shadowing generating garbage code on Clang on certain
ARM builds.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmSav3wRHG1pbmdvQGtl
cm5lbC5vcmcACgkQEnMQ0APhK1gDyxAAjCHQjpolrre7fRpyiTDwqzIKT27H04vQ
zrQVlVc42WBnn9pe8LthGy43/RvYvqlZvLoLONA4fMkuYriM6nSMsoZjeUmE+6Rs
QAElQC74P5YvEBOa67VNY3/M7sj22ftDe7ODtVV8OrnPjMk1sQNRvaK025Cs3yig
8MAI//hHGNmyVAp1dPYZMJNqxGCvluReLZ4SaUJFCMrg7YgUXgCBj/5Gi07TlKxn
sT8BFCssoEW/B9FXkh59B1t6FBCZoSy4XSZfsZe0uVAUJ4XDEOO+zBgaWFCedNQT
wP323ryBgMrkzUKA8j2/o5d3QnMA1GcBfHNNlvAl/fOfrxWXzDZnOEY26YcaLMa0
YIuRF/JNbPZlt6DCUVBUEvMPpfNYi18dFN0rat1a6xL2L4w+tm55y3mFtSsg76Ka
r7L2nWlRrAGXnuA+VEPqkqbSWRUSWOv5hT2Mcyb5BqqZRsxBETn6G8GVAzIO6j6v
giyfUdA8Z9wmMZ7NtB6usxe3p1lXtnZ/shCE7ZHXm6xstyZrSXaHgOSgAnB9DcuJ
7KpGIhhSODQSwC/h/J0KEpb9Pr/5jCWmXAQ2DWnZK6ndt1jUfFi8pfK58wm0AuAM
o9t8Mx3o8wZjbMdt6up9OIM1HyFiMx2BSaZK+8f/bWemHQ0xwez5g4k5O5AwVOaC
x9Nt+Tp0Ze4=
=DsYj
-----END PGP SIGNATURE-----
Merge tag 'locking-core-2023-06-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking updates from Ingo Molnar:
- Introduce cmpxchg128() -- aka. the demise of cmpxchg_double()
The cmpxchg128() family of functions is basically & functionally the
same as cmpxchg_double(), but with a saner interface.
Instead of a 6-parameter horror that forced u128 - u64/u64-halves
layout details on the interface and exposed users to complexity,
fragility & bugs, use a natural 3-parameter interface with u128
types.
- Restructure the generated atomic headers, and add kerneldoc comments
for all of the generic atomic{,64,_long}_t operations.
The generated definitions are much cleaner now, and come with
documentation.
- Implement lock_set_cmp_fn() on lockdep, for defining an ordering when
taking multiple locks of the same type.
This gets rid of one use of lockdep_set_novalidate_class() in the
bcache code.
- Fix raw_cpu_generic_try_cmpxchg() bug due to an unintended variable
shadowing generating garbage code on Clang on certain ARM builds.
* tag 'locking-core-2023-06-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (43 commits)
locking/atomic: scripts: fix ${atomic}_dec_if_positive() kerneldoc
percpu: Fix self-assignment of __old in raw_cpu_generic_try_cmpxchg()
locking/atomic: treewide: delete arch_atomic_*() kerneldoc
locking/atomic: docs: Add atomic operations to the driver basic API documentation
locking/atomic: scripts: generate kerneldoc comments
docs: scripts: kernel-doc: accept bitwise negation like ~@var
locking/atomic: scripts: simplify raw_atomic*() definitions
locking/atomic: scripts: simplify raw_atomic_long*() definitions
locking/atomic: scripts: split pfx/name/sfx/order
locking/atomic: scripts: restructure fallback ifdeffery
locking/atomic: scripts: build raw_atomic_long*() directly
locking/atomic: treewide: use raw_atomic*_<op>()
locking/atomic: scripts: add trivial raw_atomic*_<op>()
locking/atomic: scripts: factor out order template generation
locking/atomic: scripts: remove leftover "${mult}"
locking/atomic: scripts: remove bogus order parameter
locking/atomic: xtensa: add preprocessor symbols
locking/atomic: x86: add preprocessor symbols
locking/atomic: sparc: add preprocessor symbols
locking/atomic: sh: add preprocessor symbols
...
This commit is contained in:
commit
bc6cb4d5bc
136 changed files with 10107 additions and 4346 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -119,7 +119,7 @@ extern void ct_idle_exit(void);
|
|||
*/
|
||||
static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void)
|
||||
{
|
||||
return !(arch_atomic_read(this_cpu_ptr(&context_tracking.state)) & RCU_DYNTICKS_IDX);
|
||||
return !(raw_atomic_read(this_cpu_ptr(&context_tracking.state)) & RCU_DYNTICKS_IDX);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -128,7 +128,7 @@ static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void)
|
|||
*/
|
||||
static __always_inline unsigned long ct_state_inc(int incby)
|
||||
{
|
||||
return arch_atomic_add_return(incby, this_cpu_ptr(&context_tracking.state));
|
||||
return raw_atomic_add_return(incby, this_cpu_ptr(&context_tracking.state));
|
||||
}
|
||||
|
||||
static __always_inline bool warn_rcu_enter(void)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ DECLARE_PER_CPU(struct context_tracking, context_tracking);
|
|||
#ifdef CONFIG_CONTEXT_TRACKING_USER
|
||||
static __always_inline int __ct_state(void)
|
||||
{
|
||||
return arch_atomic_read(this_cpu_ptr(&context_tracking.state)) & CT_STATE_MASK;
|
||||
return raw_atomic_read(this_cpu_ptr(&context_tracking.state)) & CT_STATE_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1071,7 +1071,7 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu)
|
|||
*/
|
||||
static __always_inline unsigned int num_online_cpus(void)
|
||||
{
|
||||
return arch_atomic_read(&__num_online_cpus);
|
||||
return raw_atomic_read(&__num_online_cpus);
|
||||
}
|
||||
#define num_possible_cpus() cpumask_weight(cpu_possible_mask)
|
||||
#define num_present_cpus() cpumask_weight(cpu_present_mask)
|
||||
|
|
|
|||
|
|
@ -202,67 +202,74 @@ static inline void detect_intel_iommu(void)
|
|||
|
||||
struct irte {
|
||||
union {
|
||||
/* Shared between remapped and posted mode*/
|
||||
struct {
|
||||
__u64 present : 1, /* 0 */
|
||||
fpd : 1, /* 1 */
|
||||
__res0 : 6, /* 2 - 6 */
|
||||
avail : 4, /* 8 - 11 */
|
||||
__res1 : 3, /* 12 - 14 */
|
||||
pst : 1, /* 15 */
|
||||
vector : 8, /* 16 - 23 */
|
||||
__res2 : 40; /* 24 - 63 */
|
||||
};
|
||||
union {
|
||||
/* Shared between remapped and posted mode*/
|
||||
struct {
|
||||
__u64 present : 1, /* 0 */
|
||||
fpd : 1, /* 1 */
|
||||
__res0 : 6, /* 2 - 6 */
|
||||
avail : 4, /* 8 - 11 */
|
||||
__res1 : 3, /* 12 - 14 */
|
||||
pst : 1, /* 15 */
|
||||
vector : 8, /* 16 - 23 */
|
||||
__res2 : 40; /* 24 - 63 */
|
||||
};
|
||||
|
||||
/* Remapped mode */
|
||||
struct {
|
||||
__u64 r_present : 1, /* 0 */
|
||||
r_fpd : 1, /* 1 */
|
||||
dst_mode : 1, /* 2 */
|
||||
redir_hint : 1, /* 3 */
|
||||
trigger_mode : 1, /* 4 */
|
||||
dlvry_mode : 3, /* 5 - 7 */
|
||||
r_avail : 4, /* 8 - 11 */
|
||||
r_res0 : 4, /* 12 - 15 */
|
||||
r_vector : 8, /* 16 - 23 */
|
||||
r_res1 : 8, /* 24 - 31 */
|
||||
dest_id : 32; /* 32 - 63 */
|
||||
};
|
||||
/* Remapped mode */
|
||||
struct {
|
||||
__u64 r_present : 1, /* 0 */
|
||||
r_fpd : 1, /* 1 */
|
||||
dst_mode : 1, /* 2 */
|
||||
redir_hint : 1, /* 3 */
|
||||
trigger_mode : 1, /* 4 */
|
||||
dlvry_mode : 3, /* 5 - 7 */
|
||||
r_avail : 4, /* 8 - 11 */
|
||||
r_res0 : 4, /* 12 - 15 */
|
||||
r_vector : 8, /* 16 - 23 */
|
||||
r_res1 : 8, /* 24 - 31 */
|
||||
dest_id : 32; /* 32 - 63 */
|
||||
};
|
||||
|
||||
/* Posted mode */
|
||||
struct {
|
||||
__u64 p_present : 1, /* 0 */
|
||||
p_fpd : 1, /* 1 */
|
||||
p_res0 : 6, /* 2 - 7 */
|
||||
p_avail : 4, /* 8 - 11 */
|
||||
p_res1 : 2, /* 12 - 13 */
|
||||
p_urgent : 1, /* 14 */
|
||||
p_pst : 1, /* 15 */
|
||||
p_vector : 8, /* 16 - 23 */
|
||||
p_res2 : 14, /* 24 - 37 */
|
||||
pda_l : 26; /* 38 - 63 */
|
||||
};
|
||||
__u64 low;
|
||||
};
|
||||
/* Posted mode */
|
||||
struct {
|
||||
__u64 p_present : 1, /* 0 */
|
||||
p_fpd : 1, /* 1 */
|
||||
p_res0 : 6, /* 2 - 7 */
|
||||
p_avail : 4, /* 8 - 11 */
|
||||
p_res1 : 2, /* 12 - 13 */
|
||||
p_urgent : 1, /* 14 */
|
||||
p_pst : 1, /* 15 */
|
||||
p_vector : 8, /* 16 - 23 */
|
||||
p_res2 : 14, /* 24 - 37 */
|
||||
pda_l : 26; /* 38 - 63 */
|
||||
};
|
||||
__u64 low;
|
||||
};
|
||||
|
||||
union {
|
||||
/* Shared between remapped and posted mode*/
|
||||
struct {
|
||||
__u64 sid : 16, /* 64 - 79 */
|
||||
sq : 2, /* 80 - 81 */
|
||||
svt : 2, /* 82 - 83 */
|
||||
__res3 : 44; /* 84 - 127 */
|
||||
};
|
||||
union {
|
||||
/* Shared between remapped and posted mode*/
|
||||
struct {
|
||||
__u64 sid : 16, /* 64 - 79 */
|
||||
sq : 2, /* 80 - 81 */
|
||||
svt : 2, /* 82 - 83 */
|
||||
__res3 : 44; /* 84 - 127 */
|
||||
};
|
||||
|
||||
/* Posted mode*/
|
||||
struct {
|
||||
__u64 p_sid : 16, /* 64 - 79 */
|
||||
p_sq : 2, /* 80 - 81 */
|
||||
p_svt : 2, /* 82 - 83 */
|
||||
p_res3 : 12, /* 84 - 95 */
|
||||
pda_h : 32; /* 96 - 127 */
|
||||
/* Posted mode*/
|
||||
struct {
|
||||
__u64 p_sid : 16, /* 64 - 79 */
|
||||
p_sq : 2, /* 80 - 81 */
|
||||
p_svt : 2, /* 82 - 83 */
|
||||
p_res3 : 12, /* 84 - 95 */
|
||||
pda_h : 32; /* 96 - 127 */
|
||||
};
|
||||
__u64 high;
|
||||
};
|
||||
};
|
||||
__u64 high;
|
||||
#ifdef CONFIG_IRQ_REMAP
|
||||
__u128 irte;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ extern enum jump_label_type jump_label_init_type(struct jump_entry *entry);
|
|||
|
||||
static __always_inline int static_key_count(struct static_key *key)
|
||||
{
|
||||
return arch_atomic_read(&key->enabled);
|
||||
return raw_atomic_read(&key->enabled);
|
||||
}
|
||||
|
||||
static __always_inline void jump_label_init(void)
|
||||
|
|
|
|||
|
|
@ -447,6 +447,14 @@ extern int lockdep_is_held(const void *);
|
|||
|
||||
#endif /* !LOCKDEP */
|
||||
|
||||
#ifdef CONFIG_PROVE_LOCKING
|
||||
void lockdep_set_lock_cmp_fn(struct lockdep_map *, lock_cmp_fn, lock_print_fn);
|
||||
|
||||
#define lock_set_cmp_fn(lock, ...) lockdep_set_lock_cmp_fn(&(lock)->dep_map, __VA_ARGS__)
|
||||
#else
|
||||
#define lock_set_cmp_fn(lock, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
enum xhlock_context_t {
|
||||
XHLOCK_HARD,
|
||||
XHLOCK_SOFT,
|
||||
|
|
|
|||
|
|
@ -85,6 +85,11 @@ struct lock_trace;
|
|||
|
||||
#define LOCKSTAT_POINTS 4
|
||||
|
||||
struct lockdep_map;
|
||||
typedef int (*lock_cmp_fn)(const struct lockdep_map *a,
|
||||
const struct lockdep_map *b);
|
||||
typedef void (*lock_print_fn)(const struct lockdep_map *map);
|
||||
|
||||
/*
|
||||
* The lock-class itself. The order of the structure members matters.
|
||||
* reinit_class() zeroes the key member and all subsequent members.
|
||||
|
|
@ -110,6 +115,9 @@ struct lock_class {
|
|||
struct list_head locks_after, locks_before;
|
||||
|
||||
const struct lockdep_subclass_key *key;
|
||||
lock_cmp_fn cmp_fn;
|
||||
lock_print_fn print_fn;
|
||||
|
||||
unsigned int subclass;
|
||||
unsigned int dep_gen_id;
|
||||
|
||||
|
|
|
|||
|
|
@ -343,31 +343,19 @@ static __always_inline void __this_cpu_preempt_check(const char *op) { }
|
|||
pscr2_ret__; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Special handling for cmpxchg_double. cmpxchg_double is passed two
|
||||
* percpu variables. The first has to be aligned to a double word
|
||||
* boundary and the second has to follow directly thereafter.
|
||||
* We enforce this on all architectures even if they don't support
|
||||
* a double cmpxchg instruction, since it's a cheap requirement, and it
|
||||
* avoids breaking the requirement for architectures with the instruction.
|
||||
*/
|
||||
#define __pcpu_double_call_return_bool(stem, pcp1, pcp2, ...) \
|
||||
#define __pcpu_size_call_return2bool(stem, variable, ...) \
|
||||
({ \
|
||||
bool pdcrb_ret__; \
|
||||
__verify_pcpu_ptr(&(pcp1)); \
|
||||
BUILD_BUG_ON(sizeof(pcp1) != sizeof(pcp2)); \
|
||||
VM_BUG_ON((unsigned long)(&(pcp1)) % (2 * sizeof(pcp1))); \
|
||||
VM_BUG_ON((unsigned long)(&(pcp2)) != \
|
||||
(unsigned long)(&(pcp1)) + sizeof(pcp1)); \
|
||||
switch(sizeof(pcp1)) { \
|
||||
case 1: pdcrb_ret__ = stem##1(pcp1, pcp2, __VA_ARGS__); break; \
|
||||
case 2: pdcrb_ret__ = stem##2(pcp1, pcp2, __VA_ARGS__); break; \
|
||||
case 4: pdcrb_ret__ = stem##4(pcp1, pcp2, __VA_ARGS__); break; \
|
||||
case 8: pdcrb_ret__ = stem##8(pcp1, pcp2, __VA_ARGS__); break; \
|
||||
bool pscr2_ret__; \
|
||||
__verify_pcpu_ptr(&(variable)); \
|
||||
switch(sizeof(variable)) { \
|
||||
case 1: pscr2_ret__ = stem##1(variable, __VA_ARGS__); break; \
|
||||
case 2: pscr2_ret__ = stem##2(variable, __VA_ARGS__); break; \
|
||||
case 4: pscr2_ret__ = stem##4(variable, __VA_ARGS__); break; \
|
||||
case 8: pscr2_ret__ = stem##8(variable, __VA_ARGS__); break; \
|
||||
default: \
|
||||
__bad_size_call_parameter(); break; \
|
||||
} \
|
||||
pdcrb_ret__; \
|
||||
pscr2_ret__; \
|
||||
})
|
||||
|
||||
#define __pcpu_size_call(stem, variable, ...) \
|
||||
|
|
@ -426,9 +414,8 @@ do { \
|
|||
#define raw_cpu_xchg(pcp, nval) __pcpu_size_call_return2(raw_cpu_xchg_, pcp, nval)
|
||||
#define raw_cpu_cmpxchg(pcp, oval, nval) \
|
||||
__pcpu_size_call_return2(raw_cpu_cmpxchg_, pcp, oval, nval)
|
||||
#define raw_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
|
||||
__pcpu_double_call_return_bool(raw_cpu_cmpxchg_double_, pcp1, pcp2, oval1, oval2, nval1, nval2)
|
||||
|
||||
#define raw_cpu_try_cmpxchg(pcp, ovalp, nval) \
|
||||
__pcpu_size_call_return2bool(raw_cpu_try_cmpxchg_, pcp, ovalp, nval)
|
||||
#define raw_cpu_sub(pcp, val) raw_cpu_add(pcp, -(val))
|
||||
#define raw_cpu_inc(pcp) raw_cpu_add(pcp, 1)
|
||||
#define raw_cpu_dec(pcp) raw_cpu_sub(pcp, 1)
|
||||
|
|
@ -488,11 +475,6 @@ do { \
|
|||
raw_cpu_cmpxchg(pcp, oval, nval); \
|
||||
})
|
||||
|
||||
#define __this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
|
||||
({ __this_cpu_preempt_check("cmpxchg_double"); \
|
||||
raw_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2); \
|
||||
})
|
||||
|
||||
#define __this_cpu_sub(pcp, val) __this_cpu_add(pcp, -(typeof(pcp))(val))
|
||||
#define __this_cpu_inc(pcp) __this_cpu_add(pcp, 1)
|
||||
#define __this_cpu_dec(pcp) __this_cpu_sub(pcp, 1)
|
||||
|
|
@ -513,9 +495,8 @@ do { \
|
|||
#define this_cpu_xchg(pcp, nval) __pcpu_size_call_return2(this_cpu_xchg_, pcp, nval)
|
||||
#define this_cpu_cmpxchg(pcp, oval, nval) \
|
||||
__pcpu_size_call_return2(this_cpu_cmpxchg_, pcp, oval, nval)
|
||||
#define this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
|
||||
__pcpu_double_call_return_bool(this_cpu_cmpxchg_double_, pcp1, pcp2, oval1, oval2, nval1, nval2)
|
||||
|
||||
#define this_cpu_try_cmpxchg(pcp, ovalp, nval) \
|
||||
__pcpu_size_call_return2bool(this_cpu_try_cmpxchg_, pcp, ovalp, nval)
|
||||
#define this_cpu_sub(pcp, val) this_cpu_add(pcp, -(typeof(pcp))(val))
|
||||
#define this_cpu_inc(pcp) this_cpu_add(pcp, 1)
|
||||
#define this_cpu_dec(pcp) this_cpu_sub(pcp, 1)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ enum stat_item {
|
|||
CPU_PARTIAL_FREE, /* Refill cpu partial on free */
|
||||
CPU_PARTIAL_NODE, /* Refill cpu partial from node partial */
|
||||
CPU_PARTIAL_DRAIN, /* Drain cpu partial to node partial */
|
||||
NR_SLUB_STAT_ITEMS };
|
||||
NR_SLUB_STAT_ITEMS
|
||||
};
|
||||
|
||||
#ifndef CONFIG_SLUB_TINY
|
||||
/*
|
||||
|
|
@ -47,8 +48,13 @@ enum stat_item {
|
|||
* with this_cpu_cmpxchg_double() alignment requirements.
|
||||
*/
|
||||
struct kmem_cache_cpu {
|
||||
void **freelist; /* Pointer to next available object */
|
||||
unsigned long tid; /* Globally unique transaction id */
|
||||
union {
|
||||
struct {
|
||||
void **freelist; /* Pointer to next available object */
|
||||
unsigned long tid; /* Globally unique transaction id */
|
||||
};
|
||||
freelist_aba_t freelist_tid;
|
||||
};
|
||||
struct slab *slab; /* The slab from which we are allocating */
|
||||
#ifdef CONFIG_SLUB_CPU_PARTIAL
|
||||
struct slab *partial; /* Partially allocated frozen slabs */
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@
|
|||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
typedef __s128 s128;
|
||||
typedef __u128 u128;
|
||||
#endif
|
||||
|
||||
typedef u32 __kernel_dev_t;
|
||||
|
||||
typedef __kernel_fd_set fd_set;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue