~ubuntu-branches/ubuntu/lucid/linux-rt/lucid

« back to all changes in this revision

Viewing changes to kernel/rcupdate.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-08-05 23:00:52 UTC
  • Revision ID: james.westby@ubuntu.com-20090805230052-7xedvqcyk9dnnxb2
Tags: 2.6.31-1.1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
static struct completion rcu_barrier_completion;
59
59
int rcu_scheduler_active __read_mostly;
60
60
 
 
61
static atomic_t rcu_migrate_type_count = ATOMIC_INIT(0);
 
62
static struct rcu_head rcu_migrate_head[3];
 
63
static DECLARE_WAIT_QUEUE_HEAD(rcu_migrate_wq);
 
64
 
61
65
/*
62
66
 * Awaken the corresponding synchronize_rcu() instance now that a
63
67
 * grace period has elapsed.
122
126
        }
123
127
}
124
128
 
 
129
static inline void wait_migrated_callbacks(void)
 
130
{
 
131
        wait_event(rcu_migrate_wq, !atomic_read(&rcu_migrate_type_count));
 
132
}
 
133
 
125
134
/*
126
135
 * Orchestrate the specified type of RCU barrier, waiting for all
127
136
 * RCU callbacks of the specified type to complete.
147
156
                complete(&rcu_barrier_completion);
148
157
        wait_for_completion(&rcu_barrier_completion);
149
158
        mutex_unlock(&rcu_barrier_mutex);
 
159
        wait_migrated_callbacks();
150
160
}
151
161
 
152
162
/**
176
186
}
177
187
EXPORT_SYMBOL_GPL(rcu_barrier_sched);
178
188
 
 
189
static void rcu_migrate_callback(struct rcu_head *notused)
 
190
{
 
191
        if (atomic_dec_and_test(&rcu_migrate_type_count))
 
192
                wake_up(&rcu_migrate_wq);
 
193
}
 
194
 
 
195
static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
 
196
                unsigned long action, void *hcpu)
 
197
{
 
198
        if (action == CPU_DYING) {
 
199
                /*
 
200
                 * preempt_disable() in on_each_cpu() prevents stop_machine(),
 
201
                 * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
 
202
                 * returns, all online cpus have queued rcu_barrier_func(),
 
203
                 * and the dead cpu(if it exist) queues rcu_migrate_callback()s.
 
204
                 *
 
205
                 * These callbacks ensure _rcu_barrier() waits for all
 
206
                 * RCU callbacks of the specified type to complete.
 
207
                 */
 
208
                atomic_set(&rcu_migrate_type_count, 3);
 
209
                call_rcu_bh(rcu_migrate_head, rcu_migrate_callback);
 
210
                call_rcu_sched(rcu_migrate_head + 1, rcu_migrate_callback);
 
211
                call_rcu(rcu_migrate_head + 2, rcu_migrate_callback);
 
212
        } else if (action == CPU_POST_DEAD) {
 
213
                /* rcu_migrate_head is protected by cpu_add_remove_lock */
 
214
                wait_migrated_callbacks();
 
215
        }
 
216
 
 
217
        return NOTIFY_OK;
 
218
}
 
219
 
179
220
void __init rcu_init(void)
180
221
{
181
222
        __rcu_init();
 
223
        hotcpu_notifier(rcu_barrier_cpu_hotplug, 0);
182
224
}
183
225
 
184
226
void rcu_scheduler_starting(void)