@@ -41,6 +41,7 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func);
4141void rcu_barrier_tasks (void );
4242void rcu_barrier_tasks_rude (void );
4343void synchronize_rcu (void );
44+ unsigned long get_completed_synchronize_rcu (void );
4445
4546#ifdef CONFIG_PREEMPT_RCU
4647
@@ -169,13 +170,24 @@ void synchronize_rcu_tasks(void);
169170# endif
170171
171172# ifdef CONFIG_TASKS_TRACE_RCU
172- # define rcu_tasks_trace_qs (t ) \
173- do { \
174- if (!likely(READ_ONCE((t)->trc_reader_checked)) && \
175- !unlikely(READ_ONCE((t)->trc_reader_nesting))) { \
176- smp_store_release(&(t)->trc_reader_checked, true); \
177- smp_mb(); /* Readers partitioned by store. */ \
178- } \
173+ // Bits for ->trc_reader_special.b.need_qs field.
174+ #define TRC_NEED_QS 0x1 // Task needs a quiescent state.
175+ #define TRC_NEED_QS_CHECKED 0x2 // Task has been checked for needing quiescent state.
176+
177+ u8 rcu_trc_cmpxchg_need_qs (struct task_struct * t , u8 old , u8 new );
178+ void rcu_tasks_trace_qs_blkd (struct task_struct * t );
179+
180+ # define rcu_tasks_trace_qs (t ) \
181+ do { \
182+ int ___rttq_nesting = READ_ONCE((t)->trc_reader_nesting); \
183+ \
184+ if (likely(!READ_ONCE((t)->trc_reader_special.b.need_qs)) && \
185+ likely(!___rttq_nesting)) { \
186+ rcu_trc_cmpxchg_need_qs((t), 0, TRC_NEED_QS_CHECKED); \
187+ } else if (___rttq_nesting && ___rttq_nesting != INT_MIN && \
188+ !READ_ONCE((t)->trc_reader_special.b.blocked)) { \
189+ rcu_tasks_trace_qs_blkd(t); \
190+ } \
179191 } while (0)
180192# else
181193# define rcu_tasks_trace_qs (t ) do { } while (0)
@@ -184,7 +196,7 @@ void synchronize_rcu_tasks(void);
184196#define rcu_tasks_qs (t , preempt ) \
185197do { \
186198 rcu_tasks_classic_qs((t), (preempt)); \
187- rcu_tasks_trace_qs((t)); \
199+ rcu_tasks_trace_qs(t); \
188200} while (0)
189201
190202# ifdef CONFIG_TASKS_RUDE_RCU
0 commit comments