Skip to content

Commit 1853824

Browse files
committed
rcu: Add functions to compare grace-period state values
This commit adds same_state_synchronize_rcu() and same_state_synchronize_rcu_full() functions to compare grace-period state values, for example, those obtained from get_state_synchronize_rcu() and get_state_synchronize_rcu_full(). These functions allow small structures to omit these state values by placing them in list headers for lists containing structures with the same token value. Presumably the per-structure list pointers are the same ones used to link the structures into whatever reader-accessible data structure was used. This commit also adds both NUM_ACTIVE_RCU_POLL_OLDSTATE and NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE, which define the maximum number of distinct unsigned long values and rcu_gp_oldstate values, respectively, corresponding to not-yet-completed grace periods. These values can be used to size arrays of the list headers described above. Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 5d7801f commit 1853824

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

include/linux/rcupdate.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,27 @@ struct rcu_gp_oldstate;
4747
unsigned long get_completed_synchronize_rcu(void);
4848
void get_completed_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
4949

50+
// Maximum number of unsigned long values corresponding to
51+
// not-yet-completed RCU grace periods.
52+
#define NUM_ACTIVE_RCU_POLL_OLDSTATE 2
53+
54+
/**
55+
* same_state_synchronize_rcu - Are two old-state values identical?
56+
* @oldstate1: First old-state value.
57+
* @oldstate2: Second old-state value.
58+
*
59+
* The two old-state values must have been obtained from either
60+
* get_state_synchronize_rcu(), start_poll_synchronize_rcu(), or
61+
* get_completed_synchronize_rcu(). Returns @true if the two values are
62+
* identical and @false otherwise. This allows structures whose lifetimes
63+
* are tracked by old-state values to push these values to a list header,
64+
* allowing those structures to be slightly smaller.
65+
*/
66+
static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned long oldstate2)
67+
{
68+
return oldstate1 == oldstate2;
69+
}
70+
5071
#ifdef CONFIG_PREEMPT_RCU
5172

5273
void __rcu_read_lock(void);

include/linux/rcutiny.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ struct rcu_gp_oldstate {
1818
unsigned long rgos_norm;
1919
};
2020

21+
// Maximum number of rcu_gp_oldstate values corresponding to
22+
// not-yet-completed RCU grace periods.
23+
#define NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE 2
24+
25+
/*
26+
* Are the two oldstate values the same? See the Tree RCU version for
27+
* docbook header.
28+
*/
29+
static inline bool same_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp1,
30+
struct rcu_gp_oldstate *rgosp2)
31+
{
32+
return rgosp1->rgos_norm == rgosp2->rgos_norm;
33+
}
34+
2135
unsigned long get_state_synchronize_rcu(void);
2236

2337
static inline void get_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp)

include/linux/rcutree.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,34 @@ struct rcu_gp_oldstate {
4646
unsigned long rgos_exp;
4747
};
4848

49+
// Maximum number of rcu_gp_oldstate values corresponding to
50+
// not-yet-completed RCU grace periods.
51+
#define NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE 4
52+
53+
/**
54+
* same_state_synchronize_rcu_full - Are two old-state values identical?
55+
* @rgosp1: First old-state value.
56+
* @rgosp2: Second old-state value.
57+
*
58+
* The two old-state values must have been obtained from either
59+
* get_state_synchronize_rcu_full(), start_poll_synchronize_rcu_full(),
60+
* or get_completed_synchronize_rcu_full(). Returns @true if the two
61+
* values are identical and @false otherwise. This allows structures
62+
* whose lifetimes are tracked by old-state values to push these values
63+
* to a list header, allowing those structures to be slightly smaller.
64+
*
65+
* Note that equality is judged on a bitwise basis, so that an
66+
* @rcu_gp_oldstate structure with an already-completed state in one field
67+
* will compare not-equal to a structure with an already-completed state
68+
* in the other field. After all, the @rcu_gp_oldstate structure is opaque
69+
* so how did such a situation come to pass in the first place?
70+
*/
71+
static inline bool same_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp1,
72+
struct rcu_gp_oldstate *rgosp2)
73+
{
74+
return rgosp1->rgos_norm == rgosp2->rgos_norm && rgosp1->rgos_exp == rgosp2->rgos_exp;
75+
}
76+
4977
unsigned long start_poll_synchronize_rcu_expedited(void);
5078
void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp);
5179
void cond_synchronize_rcu_expedited(unsigned long oldstate);

0 commit comments

Comments
 (0)