mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 07:23:14 +00:00
bdf56c7580
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEe7vIQRWZI0iWSE3xu+CwddJFiJoFAmbn5g0ACgkQu+CwddJF iJq+Uwf/aqnLNEpjUBzwUUhSojCpPnTtiyjv+AILTxoSTHmbu8OvN0W79+Rpbdmk O4QapAK+BCs+VL2VATwCCufcJ75Z78txO+buQE0DgwluFTIYZ+IwpUMPsK04ln6A FD1/uvP1QFx60heqcp2c4zWFBUpg4DE6ufx2A5kieO268lFcWLxyVlcdgRU79ZCt uAcV2yDLk3GvPGfxZwPKEmZUo/FmuSoBv0XgT+eWxmTu/R7hcpFse49OyjBH8Tvb 8d/RCIFgXOr8dTIjtds7eenwB/is4TkRlctezEQ0jO9/JwL/BVOgXZjD1qCtNWqz is4TWK7VV+vdq1RD+0xC2hV/+uGEwQ== =+WAm -----END PGP SIGNATURE----- Merge tag 'slab-for-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab Pull slab updates from Vlastimil Babka: "This time it's mostly refactoring and improving APIs for slab users in the kernel, along with some debugging improvements. - kmem_cache_create() refactoring (Christian Brauner) Over the years have been growing new parameters to kmem_cache_create() where most of them are needed only for a small number of caches - most recently the rcu_freeptr_offset parameter. To avoid adding new parameters to kmem_cache_create() and adjusting all its callers, or creating new wrappers such as kmem_cache_create_rcu(), we can now pass extra parameters using the new struct kmem_cache_args. Not explicitly initialized fields default to values interpreted as unused. kmem_cache_create() is for now a wrapper that works both with the new form: kmem_cache_create(name, object_size, args, flags) and the legacy form: kmem_cache_create(name, object_size, align, flags, ctor) - kmem_cache_destroy() waits for kfree_rcu()'s in flight (Vlastimil Babka, Uladislau Rezki) Since SLOB removal, kfree() is allowed for freeing objects allocated by kmem_cache_create(). By extension kfree_rcu() as allowed as well, which can allow converting simple call_rcu() callbacks that only do kmem_cache_free(), as there was never a kmem_cache_free_rcu() variant. However, for caches that can be destroyed e.g. on module removal, the cache owners knew to issue rcu_barrier() first to wait for the pending call_rcu()'s, and this is not sufficient for pending kfree_rcu()'s due to its internal batching optimizations. Ulad has provided a new kvfree_rcu_barrier() and to make the usage less error-prone, kmem_cache_destroy() calls it. Additionally, destroying SLAB_TYPESAFE_BY_RCU caches now again issues rcu_barrier() synchronously instead of using an async work, because the past motivation for async work no longer applies. Users of custom call_rcu() callbacks should however keep calling rcu_barrier() before cache destruction. - Debugging use-after-free in SLAB_TYPESAFE_BY_RCU caches (Jann Horn) Currently, KASAN cannot catch UAFs in such caches as it is legal to access them within a grace period, and we only track the grace period when trying to free the underlying slab page. The new CONFIG_SLUB_RCU_DEBUG option changes the freeing of individual object to be RCU-delayed, after which KASAN can poison them. - Delayed memcg charging (Shakeel Butt) In some cases, the memcg is uknown at allocation time, such as receiving network packets in softirq context. With kmem_cache_charge() these may be now charged later when the user and its memcg is known. - Misc fixes and improvements (Pedro Falcato, Axel Rasmussen, Christoph Lameter, Yan Zhen, Peng Fan, Xavier)" * tag 'slab-for-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab: (34 commits) mm, slab: restore kerneldoc for kmem_cache_create() io_uring: port to struct kmem_cache_args slab: make __kmem_cache_create() static inline slab: make kmem_cache_create_usercopy() static inline slab: remove kmem_cache_create_rcu() file: port to struct kmem_cache_args slab: create kmem_cache_create() compatibility layer slab: port KMEM_CACHE_USERCOPY() to struct kmem_cache_args slab: port KMEM_CACHE() to struct kmem_cache_args slab: remove rcu_freeptr_offset from struct kmem_cache slab: pass struct kmem_cache_args to do_kmem_cache_create() slab: pull kmem_cache_open() into do_kmem_cache_create() slab: pass struct kmem_cache_args to create_cache() slab: port kmem_cache_create_usercopy() to struct kmem_cache_args slab: port kmem_cache_create_rcu() to struct kmem_cache_args slab: port kmem_cache_create() to struct kmem_cache_args slab: add struct kmem_cache_args slab: s/__kmem_cache_create/do_kmem_cache_create/g memcg: add charging of already allocated slab objects mm/slab: Optimize the code logic in find_mergeable() ...
132 lines
4.4 KiB
C
132 lines
4.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* Read-Copy Update mechanism for mutual exclusion (tree-based version)
|
|
*
|
|
* Copyright IBM Corporation, 2008
|
|
*
|
|
* Author: Dipankar Sarma <dipankar@in.ibm.com>
|
|
* Paul E. McKenney <paulmck@linux.ibm.com> Hierarchical algorithm
|
|
*
|
|
* Based on the original work by Paul McKenney <paulmck@linux.ibm.com>
|
|
* and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
|
|
*
|
|
* For detailed explanation of Read-Copy Update mechanism see -
|
|
* Documentation/RCU
|
|
*/
|
|
|
|
#ifndef __LINUX_RCUTREE_H
|
|
#define __LINUX_RCUTREE_H
|
|
|
|
void rcu_softirq_qs(void);
|
|
void rcu_note_context_switch(bool preempt);
|
|
int rcu_needs_cpu(void);
|
|
void rcu_cpu_stall_reset(void);
|
|
void rcu_request_urgent_qs_task(struct task_struct *t);
|
|
|
|
/*
|
|
* Note a virtualization-based context switch. This is simply a
|
|
* wrapper around rcu_note_context_switch(), which allows TINY_RCU
|
|
* to save a few bytes. The caller must have disabled interrupts.
|
|
*/
|
|
static inline void rcu_virt_note_context_switch(void)
|
|
{
|
|
rcu_note_context_switch(false);
|
|
}
|
|
|
|
void synchronize_rcu_expedited(void);
|
|
void kvfree_call_rcu(struct rcu_head *head, void *ptr);
|
|
void kvfree_rcu_barrier(void);
|
|
|
|
void rcu_barrier(void);
|
|
void rcu_momentary_eqs(void);
|
|
void kfree_rcu_scheduler_running(void);
|
|
bool rcu_gp_might_be_stalled(void);
|
|
|
|
struct rcu_gp_oldstate {
|
|
unsigned long rgos_norm;
|
|
unsigned long rgos_exp;
|
|
};
|
|
|
|
// Maximum number of rcu_gp_oldstate values corresponding to
|
|
// not-yet-completed RCU grace periods.
|
|
#define NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE 4
|
|
|
|
/**
|
|
* same_state_synchronize_rcu_full - Are two old-state values identical?
|
|
* @rgosp1: First old-state value.
|
|
* @rgosp2: Second old-state value.
|
|
*
|
|
* The two old-state values must have been obtained from either
|
|
* get_state_synchronize_rcu_full(), start_poll_synchronize_rcu_full(),
|
|
* or get_completed_synchronize_rcu_full(). Returns @true if the two
|
|
* values are identical and @false otherwise. This allows structures
|
|
* whose lifetimes are tracked by old-state values to push these values
|
|
* to a list header, allowing those structures to be slightly smaller.
|
|
*
|
|
* Note that equality is judged on a bitwise basis, so that an
|
|
* @rcu_gp_oldstate structure with an already-completed state in one field
|
|
* will compare not-equal to a structure with an already-completed state
|
|
* in the other field. After all, the @rcu_gp_oldstate structure is opaque
|
|
* so how did such a situation come to pass in the first place?
|
|
*/
|
|
static inline bool same_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp1,
|
|
struct rcu_gp_oldstate *rgosp2)
|
|
{
|
|
return rgosp1->rgos_norm == rgosp2->rgos_norm && rgosp1->rgos_exp == rgosp2->rgos_exp;
|
|
}
|
|
|
|
unsigned long start_poll_synchronize_rcu_expedited(void);
|
|
void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp);
|
|
void cond_synchronize_rcu_expedited(unsigned long oldstate);
|
|
void cond_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp);
|
|
unsigned long get_state_synchronize_rcu(void);
|
|
void get_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
|
|
unsigned long start_poll_synchronize_rcu(void);
|
|
void start_poll_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
|
|
bool poll_state_synchronize_rcu(unsigned long oldstate);
|
|
bool poll_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
|
|
void cond_synchronize_rcu(unsigned long oldstate);
|
|
void cond_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
|
|
|
|
#ifdef CONFIG_PROVE_RCU
|
|
void rcu_irq_exit_check_preempt(void);
|
|
#else
|
|
static inline void rcu_irq_exit_check_preempt(void) { }
|
|
#endif
|
|
|
|
struct task_struct;
|
|
void rcu_preempt_deferred_qs(struct task_struct *t);
|
|
|
|
void exit_rcu(void);
|
|
|
|
void rcu_scheduler_starting(void);
|
|
extern int rcu_scheduler_active;
|
|
void rcu_end_inkernel_boot(void);
|
|
bool rcu_inkernel_boot_has_ended(void);
|
|
bool rcu_is_watching(void);
|
|
#ifndef CONFIG_PREEMPTION
|
|
void rcu_all_qs(void);
|
|
#endif
|
|
|
|
/* RCUtree hotplug events */
|
|
int rcutree_prepare_cpu(unsigned int cpu);
|
|
int rcutree_online_cpu(unsigned int cpu);
|
|
void rcutree_report_cpu_starting(unsigned int cpu);
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
int rcutree_dead_cpu(unsigned int cpu);
|
|
int rcutree_dying_cpu(unsigned int cpu);
|
|
int rcutree_offline_cpu(unsigned int cpu);
|
|
#else
|
|
#define rcutree_dead_cpu NULL
|
|
#define rcutree_dying_cpu NULL
|
|
#define rcutree_offline_cpu NULL
|
|
#endif
|
|
|
|
void rcutree_migrate_callbacks(int cpu);
|
|
|
|
/* Called from hotplug and also arm64 early secondary boot failure */
|
|
void rcutree_report_cpu_dead(void);
|
|
|
|
#endif /* __LINUX_RCUTREE_H */
|