Skip to content

Commit e206f33

Browse files
committed
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 <[email protected]> Cc: Kent Overstreet <[email protected]>
1 parent d7b0615 commit e206f33

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

include/linux/srcu.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ void cleanup_srcu_struct(struct srcu_struct *ssp);
5757
int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp);
5858
void __srcu_read_unlock(struct srcu_struct *ssp, int idx) __releases(ssp);
5959
void synchronize_srcu(struct srcu_struct *ssp);
60+
61+
#define SRCU_GET_STATE_COMPLETED 0x1
62+
63+
/**
64+
* get_completed_synchronize_srcu - Return a pre-completed polled state cookie
65+
*
66+
* Returns a value that poll_state_synchronize_srcu() will always treat
67+
* as a cookie whose grace period has already completed.
68+
*/
69+
static inline unsigned long get_completed_synchronize_srcu(void)
70+
{
71+
return SRCU_GET_STATE_COMPLETED;
72+
}
73+
6074
unsigned long get_state_synchronize_srcu(struct srcu_struct *ssp);
6175
unsigned long start_poll_synchronize_srcu(struct srcu_struct *ssp);
6276
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);
6579
// not-yet-completed SRCU grace periods.
6680
#define NUM_ACTIVE_SRCU_POLL_OLDSTATE 2
6781

82+
/**
83+
* same_state_synchronize_srcu - Are two old-state values identical?
84+
* @oldstate1: First old-state value.
85+
* @oldstate2: Second old-state value.
86+
*
87+
* The two old-state values must have been obtained from either
88+
* get_state_synchronize_srcu(), start_poll_synchronize_srcu(), or
89+
* get_completed_synchronize_srcu(). Returns @true if the two values are
90+
* identical and @false otherwise. This allows structures whose lifetimes
91+
* are tracked by old-state values to push these values to a list header,
92+
* allowing those structures to be slightly smaller.
93+
*/
94+
static inline bool same_state_synchronize_srcu(unsigned long oldstate1, unsigned long oldstate2)
95+
{
96+
return oldstate1 == oldstate2;
97+
}
98+
6899
#ifdef CONFIG_NEED_SRCU_NMI_SAFE
69100
int __srcu_read_lock_nmisafe(struct srcu_struct *ssp) __acquires(ssp);
70101
void __srcu_read_unlock_nmisafe(struct srcu_struct *ssp, int idx) __releases(ssp);

kernel/rcu/srcutiny.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@ bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie)
277277
unsigned long cur_s = READ_ONCE(ssp->srcu_idx);
278278

279279
barrier();
280-
return ULONG_CMP_GE(cur_s, cookie) || ULONG_CMP_LT(cur_s, cookie - 3);
280+
return cookie == SRCU_GET_STATE_COMPLETED ||
281+
ULONG_CMP_GE(cur_s, cookie) || ULONG_CMP_LT(cur_s, cookie - 3);
281282
}
282283
EXPORT_SYMBOL_GPL(poll_state_synchronize_srcu);
283284

kernel/rcu/srcutree.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,8 @@ EXPORT_SYMBOL_GPL(start_poll_synchronize_srcu);
15431543
*/
15441544
bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie)
15451545
{
1546-
if (!rcu_seq_done(&ssp->srcu_sup->srcu_gp_seq, cookie))
1546+
if (cookie != SRCU_GET_STATE_COMPLETED &&
1547+
!rcu_seq_done(&ssp->srcu_sup->srcu_gp_seq, cookie))
15471548
return false;
15481549
// Ensure that the end of the SRCU grace period happens before
15491550
// any subsequent code that the caller might execute.

0 commit comments

Comments
 (0)