diff options
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r-- | kernel/rcutree.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 7717b95c2027..f3e43274ed53 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1325,22 +1325,40 @@ int rcu_needs_cpu(int cpu) | |||
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | /* | 1327 | /* |
1328 | * Initialize a CPU's per-CPU RCU data. We take this "scorched earth" | 1328 | * Do boot-time initialization of a CPU's per-CPU RCU data. |
1329 | * approach so that we don't have to worry about how long the CPU has | 1329 | */ |
1330 | * been gone, or whether it ever was online previously. We do trust the | 1330 | static void __init |
1331 | * ->mynode field, as it is constant for a given struct rcu_data and | 1331 | rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) |
1332 | * initialized during early boot. | 1332 | { |
1333 | * | 1333 | unsigned long flags; |
1334 | * Note that only one online or offline event can be happening at a given | 1334 | int i; |
1335 | * time. Note also that we can accept some slop in the rsp->completed | 1335 | struct rcu_data *rdp = rsp->rda[cpu]; |
1336 | * access due to the fact that this CPU cannot possibly have any RCU | 1336 | struct rcu_node *rnp = rcu_get_root(rsp); |
1337 | * callbacks in flight yet. | 1337 | |
1338 | /* Set up local state, ensuring consistent view of global state. */ | ||
1339 | spin_lock_irqsave(&rnp->lock, flags); | ||
1340 | rdp->grpmask = 1UL << (cpu - rdp->mynode->grplo); | ||
1341 | rdp->nxtlist = NULL; | ||
1342 | for (i = 0; i < RCU_NEXT_SIZE; i++) | ||
1343 | rdp->nxttail[i] = &rdp->nxtlist; | ||
1344 | rdp->qlen = 0; | ||
1345 | #ifdef CONFIG_NO_HZ | ||
1346 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); | ||
1347 | #endif /* #ifdef CONFIG_NO_HZ */ | ||
1348 | rdp->cpu = cpu; | ||
1349 | spin_unlock_irqrestore(&rnp->lock, flags); | ||
1350 | } | ||
1351 | |||
1352 | /* | ||
1353 | * Initialize a CPU's per-CPU RCU data. Note that only one online or | ||
1354 | * offline event can be happening at a given time. Note also that we | ||
1355 | * can accept some slop in the rsp->completed access due to the fact | ||
1356 | * that this CPU cannot possibly have any RCU callbacks in flight yet. | ||
1338 | */ | 1357 | */ |
1339 | static void __cpuinit | 1358 | static void __cpuinit |
1340 | rcu_init_percpu_data(int cpu, struct rcu_state *rsp) | 1359 | rcu_init_percpu_data(int cpu, struct rcu_state *rsp) |
1341 | { | 1360 | { |
1342 | unsigned long flags; | 1361 | unsigned long flags; |
1343 | int i; | ||
1344 | long lastcomp; | 1362 | long lastcomp; |
1345 | unsigned long mask; | 1363 | unsigned long mask; |
1346 | struct rcu_data *rdp = rsp->rda[cpu]; | 1364 | struct rcu_data *rdp = rsp->rda[cpu]; |
@@ -1355,16 +1373,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp) | |||
1355 | rdp->qs_pending = 1; /* so set up to respond to current GP. */ | 1373 | rdp->qs_pending = 1; /* so set up to respond to current GP. */ |
1356 | rdp->beenonline = 1; /* We have now been online. */ | 1374 | rdp->beenonline = 1; /* We have now been online. */ |
1357 | rdp->passed_quiesc_completed = lastcomp - 1; | 1375 | rdp->passed_quiesc_completed = lastcomp - 1; |
1358 | rdp->grpmask = 1UL << (cpu - rdp->mynode->grplo); | ||
1359 | rdp->nxtlist = NULL; | ||
1360 | for (i = 0; i < RCU_NEXT_SIZE; i++) | ||
1361 | rdp->nxttail[i] = &rdp->nxtlist; | ||
1362 | rdp->qlen = 0; | ||
1363 | rdp->blimit = blimit; | 1376 | rdp->blimit = blimit; |
1364 | #ifdef CONFIG_NO_HZ | ||
1365 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); | ||
1366 | #endif /* #ifdef CONFIG_NO_HZ */ | ||
1367 | rdp->cpu = cpu; | ||
1368 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ | 1377 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ |
1369 | 1378 | ||
1370 | /* | 1379 | /* |
@@ -1539,8 +1548,12 @@ void __init __rcu_init(void) | |||
1539 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | 1548 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ |
1540 | rcu_init_one(&rcu_state); | 1549 | rcu_init_one(&rcu_state); |
1541 | RCU_DATA_PTR_INIT(&rcu_state, rcu_data); | 1550 | RCU_DATA_PTR_INIT(&rcu_state, rcu_data); |
1551 | for_each_possible_cpu(i) | ||
1552 | rcu_boot_init_percpu_data(i, &rcu_state); | ||
1542 | rcu_init_one(&rcu_bh_state); | 1553 | rcu_init_one(&rcu_bh_state); |
1543 | RCU_DATA_PTR_INIT(&rcu_bh_state, rcu_bh_data); | 1554 | RCU_DATA_PTR_INIT(&rcu_bh_state, rcu_bh_data); |
1555 | for_each_possible_cpu(i) | ||
1556 | rcu_boot_init_percpu_data(i, &rcu_bh_state); | ||
1544 | 1557 | ||
1545 | for_each_online_cpu(i) | 1558 | for_each_online_cpu(i) |
1546 | rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i); | 1559 | rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i); |