aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/srcutree.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcu/srcutree.c')
-rw-r--r--kernel/rcu/srcutree.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index a60b8ba9e1ac..9b761e546de8 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -360,8 +360,14 @@ static unsigned long srcu_get_delay(struct srcu_struct *ssp)
360 return SRCU_INTERVAL; 360 return SRCU_INTERVAL;
361} 361}
362 362
363/* Helper for cleanup_srcu_struct() and cleanup_srcu_struct_quiesced(). */ 363/**
364void _cleanup_srcu_struct(struct srcu_struct *ssp, bool quiesced) 364 * cleanup_srcu_struct - deconstruct a sleep-RCU structure
365 * @ssp: structure to clean up.
366 *
367 * Must invoke this after you are finished using a given srcu_struct that
368 * was initialized via init_srcu_struct(), else you leak memory.
369 */
370void cleanup_srcu_struct(struct srcu_struct *ssp)
365{ 371{
366 int cpu; 372 int cpu;
367 373
@@ -369,24 +375,14 @@ void _cleanup_srcu_struct(struct srcu_struct *ssp, bool quiesced)
369 return; /* Just leak it! */ 375 return; /* Just leak it! */
370 if (WARN_ON(srcu_readers_active(ssp))) 376 if (WARN_ON(srcu_readers_active(ssp)))
371 return; /* Just leak it! */ 377 return; /* Just leak it! */
372 if (quiesced) { 378 flush_delayed_work(&ssp->work);
373 if (WARN_ON(delayed_work_pending(&ssp->work)))
374 return; /* Just leak it! */
375 } else {
376 flush_delayed_work(&ssp->work);
377 }
378 for_each_possible_cpu(cpu) { 379 for_each_possible_cpu(cpu) {
379 struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu); 380 struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
380 381
381 if (quiesced) { 382 del_timer_sync(&sdp->delay_work);
382 if (WARN_ON(timer_pending(&sdp->delay_work))) 383 flush_work(&sdp->work);
383 return; /* Just leak it! */ 384 if (WARN_ON(rcu_segcblist_n_cbs(&sdp->srcu_cblist)))
384 if (WARN_ON(work_pending(&sdp->work))) 385 return; /* Forgot srcu_barrier(), so just leak it! */
385 return; /* Just leak it! */
386 } else {
387 del_timer_sync(&sdp->delay_work);
388 flush_work(&sdp->work);
389 }
390 } 386 }
391 if (WARN_ON(rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) != SRCU_STATE_IDLE) || 387 if (WARN_ON(rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
392 WARN_ON(srcu_readers_active(ssp))) { 388 WARN_ON(srcu_readers_active(ssp))) {
@@ -397,7 +393,7 @@ void _cleanup_srcu_struct(struct srcu_struct *ssp, bool quiesced)
397 free_percpu(ssp->sda); 393 free_percpu(ssp->sda);
398 ssp->sda = NULL; 394 ssp->sda = NULL;
399} 395}
400EXPORT_SYMBOL_GPL(_cleanup_srcu_struct); 396EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
401 397
402/* 398/*
403 * Counts the new reader in the appropriate per-CPU element of the 399 * Counts the new reader in the appropriate per-CPU element of the