mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
srcu: Fill out polled grace-period APIs
This commit adds the get_completed_synchronize_srcu() and the same_state_synchronize_srcu() functions. The first returns a cookie that is always interpreted as corresponding to an expired grace period. The second does an equality comparison of a pair of cookies. Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Cc: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
d7b0615cb8
commit
e206f33e2c
@ -57,6 +57,20 @@ void cleanup_srcu_struct(struct srcu_struct *ssp);
|
||||
int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp);
|
||||
void __srcu_read_unlock(struct srcu_struct *ssp, int idx) __releases(ssp);
|
||||
void synchronize_srcu(struct srcu_struct *ssp);
|
||||
|
||||
#define SRCU_GET_STATE_COMPLETED 0x1
|
||||
|
||||
/**
|
||||
* get_completed_synchronize_srcu - Return a pre-completed polled state cookie
|
||||
*
|
||||
* Returns a value that poll_state_synchronize_srcu() will always treat
|
||||
* as a cookie whose grace period has already completed.
|
||||
*/
|
||||
static inline unsigned long get_completed_synchronize_srcu(void)
|
||||
{
|
||||
return SRCU_GET_STATE_COMPLETED;
|
||||
}
|
||||
|
||||
unsigned long get_state_synchronize_srcu(struct srcu_struct *ssp);
|
||||
unsigned long start_poll_synchronize_srcu(struct srcu_struct *ssp);
|
||||
bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie);
|
||||
@ -65,6 +79,23 @@ bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie);
|
||||
// not-yet-completed SRCU grace periods.
|
||||
#define NUM_ACTIVE_SRCU_POLL_OLDSTATE 2
|
||||
|
||||
/**
|
||||
* same_state_synchronize_srcu - Are two old-state values identical?
|
||||
* @oldstate1: First old-state value.
|
||||
* @oldstate2: Second old-state value.
|
||||
*
|
||||
* The two old-state values must have been obtained from either
|
||||
* get_state_synchronize_srcu(), start_poll_synchronize_srcu(), or
|
||||
* get_completed_synchronize_srcu(). 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.
|
||||
*/
|
||||
static inline bool same_state_synchronize_srcu(unsigned long oldstate1, unsigned long oldstate2)
|
||||
{
|
||||
return oldstate1 == oldstate2;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NEED_SRCU_NMI_SAFE
|
||||
int __srcu_read_lock_nmisafe(struct srcu_struct *ssp) __acquires(ssp);
|
||||
void __srcu_read_unlock_nmisafe(struct srcu_struct *ssp, int idx) __releases(ssp);
|
||||
|
@ -277,7 +277,8 @@ bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie)
|
||||
unsigned long cur_s = READ_ONCE(ssp->srcu_idx);
|
||||
|
||||
barrier();
|
||||
return ULONG_CMP_GE(cur_s, cookie) || ULONG_CMP_LT(cur_s, cookie - 3);
|
||||
return cookie == SRCU_GET_STATE_COMPLETED ||
|
||||
ULONG_CMP_GE(cur_s, cookie) || ULONG_CMP_LT(cur_s, cookie - 3);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poll_state_synchronize_srcu);
|
||||
|
||||
|
@ -1543,7 +1543,8 @@ EXPORT_SYMBOL_GPL(start_poll_synchronize_srcu);
|
||||
*/
|
||||
bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie)
|
||||
{
|
||||
if (!rcu_seq_done(&ssp->srcu_sup->srcu_gp_seq, cookie))
|
||||
if (cookie != SRCU_GET_STATE_COMPLETED &&
|
||||
!rcu_seq_done(&ssp->srcu_sup->srcu_gp_seq, cookie))
|
||||
return false;
|
||||
// Ensure that the end of the SRCU grace period happens before
|
||||
// any subsequent code that the caller might execute.
|
||||
|
Loading…
Reference in New Issue
Block a user