diff options
Diffstat (limited to 'kernel/rcutree.c')
| -rw-r--r-- | kernel/rcutree.c | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index d5bc43976c5a..5b1c3c231bae 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
| @@ -712,7 +712,7 @@ static void | |||
| 712 | rcu_start_gp(struct rcu_state *rsp, unsigned long flags) | 712 | rcu_start_gp(struct rcu_state *rsp, unsigned long flags) |
| 713 | __releases(rcu_get_root(rsp)->lock) | 713 | __releases(rcu_get_root(rsp)->lock) |
| 714 | { | 714 | { |
| 715 | struct rcu_data *rdp = rsp->rda[smp_processor_id()]; | 715 | struct rcu_data *rdp = this_cpu_ptr(rsp->rda); |
| 716 | struct rcu_node *rnp = rcu_get_root(rsp); | 716 | struct rcu_node *rnp = rcu_get_root(rsp); |
| 717 | 717 | ||
| 718 | if (!cpu_needs_another_gp(rsp, rdp) || rsp->fqs_active) { | 718 | if (!cpu_needs_another_gp(rsp, rdp) || rsp->fqs_active) { |
| @@ -960,7 +960,7 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp) | |||
| 960 | static void rcu_send_cbs_to_orphanage(struct rcu_state *rsp) | 960 | static void rcu_send_cbs_to_orphanage(struct rcu_state *rsp) |
| 961 | { | 961 | { |
| 962 | int i; | 962 | int i; |
| 963 | struct rcu_data *rdp = rsp->rda[smp_processor_id()]; | 963 | struct rcu_data *rdp = this_cpu_ptr(rsp->rda); |
| 964 | 964 | ||
| 965 | if (rdp->nxtlist == NULL) | 965 | if (rdp->nxtlist == NULL) |
| 966 | return; /* irqs disabled, so comparison is stable. */ | 966 | return; /* irqs disabled, so comparison is stable. */ |
| @@ -984,7 +984,7 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) | |||
| 984 | struct rcu_data *rdp; | 984 | struct rcu_data *rdp; |
| 985 | 985 | ||
| 986 | raw_spin_lock_irqsave(&rsp->onofflock, flags); | 986 | raw_spin_lock_irqsave(&rsp->onofflock, flags); |
| 987 | rdp = rsp->rda[smp_processor_id()]; | 987 | rdp = this_cpu_ptr(rsp->rda); |
| 988 | if (rsp->orphan_cbs_list == NULL) { | 988 | if (rsp->orphan_cbs_list == NULL) { |
| 989 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); | 989 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); |
| 990 | return; | 990 | return; |
| @@ -1007,7 +1007,7 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp) | |||
| 1007 | unsigned long flags; | 1007 | unsigned long flags; |
| 1008 | unsigned long mask; | 1008 | unsigned long mask; |
| 1009 | int need_report = 0; | 1009 | int need_report = 0; |
| 1010 | struct rcu_data *rdp = rsp->rda[cpu]; | 1010 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); |
| 1011 | struct rcu_node *rnp; | 1011 | struct rcu_node *rnp; |
| 1012 | 1012 | ||
| 1013 | /* Exclude any attempts to start a new grace period. */ | 1013 | /* Exclude any attempts to start a new grace period. */ |
| @@ -1226,7 +1226,8 @@ static void force_qs_rnp(struct rcu_state *rsp, int (*f)(struct rcu_data *)) | |||
| 1226 | cpu = rnp->grplo; | 1226 | cpu = rnp->grplo; |
| 1227 | bit = 1; | 1227 | bit = 1; |
| 1228 | for (; cpu <= rnp->grphi; cpu++, bit <<= 1) { | 1228 | for (; cpu <= rnp->grphi; cpu++, bit <<= 1) { |
| 1229 | if ((rnp->qsmask & bit) != 0 && f(rsp->rda[cpu])) | 1229 | if ((rnp->qsmask & bit) != 0 && |
| 1230 | f(per_cpu_ptr(rsp->rda, cpu))) | ||
| 1230 | mask |= bit; | 1231 | mask |= bit; |
| 1231 | } | 1232 | } |
| 1232 | if (mask != 0) { | 1233 | if (mask != 0) { |
| @@ -1402,7 +1403,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | |||
| 1402 | * a quiescent state betweentimes. | 1403 | * a quiescent state betweentimes. |
| 1403 | */ | 1404 | */ |
| 1404 | local_irq_save(flags); | 1405 | local_irq_save(flags); |
| 1405 | rdp = rsp->rda[smp_processor_id()]; | 1406 | rdp = this_cpu_ptr(rsp->rda); |
| 1406 | rcu_process_gp_end(rsp, rdp); | 1407 | rcu_process_gp_end(rsp, rdp); |
| 1407 | check_for_new_grace_period(rsp, rdp); | 1408 | check_for_new_grace_period(rsp, rdp); |
| 1408 | 1409 | ||
| @@ -1701,7 +1702,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) | |||
| 1701 | { | 1702 | { |
| 1702 | unsigned long flags; | 1703 | unsigned long flags; |
| 1703 | int i; | 1704 | int i; |
| 1704 | struct rcu_data *rdp = rsp->rda[cpu]; | 1705 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); |
| 1705 | struct rcu_node *rnp = rcu_get_root(rsp); | 1706 | struct rcu_node *rnp = rcu_get_root(rsp); |
| 1706 | 1707 | ||
| 1707 | /* Set up local state, ensuring consistent view of global state. */ | 1708 | /* Set up local state, ensuring consistent view of global state. */ |
| @@ -1729,7 +1730,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable) | |||
| 1729 | { | 1730 | { |
| 1730 | unsigned long flags; | 1731 | unsigned long flags; |
| 1731 | unsigned long mask; | 1732 | unsigned long mask; |
| 1732 | struct rcu_data *rdp = rsp->rda[cpu]; | 1733 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); |
| 1733 | struct rcu_node *rnp = rcu_get_root(rsp); | 1734 | struct rcu_node *rnp = rcu_get_root(rsp); |
| 1734 | 1735 | ||
| 1735 | /* Set up local state, ensuring consistent view of global state. */ | 1736 | /* Set up local state, ensuring consistent view of global state. */ |
| @@ -1865,7 +1866,8 @@ static void __init rcu_init_levelspread(struct rcu_state *rsp) | |||
| 1865 | /* | 1866 | /* |
| 1866 | * Helper function for rcu_init() that initializes one rcu_state structure. | 1867 | * Helper function for rcu_init() that initializes one rcu_state structure. |
| 1867 | */ | 1868 | */ |
| 1868 | static void __init rcu_init_one(struct rcu_state *rsp) | 1869 | static void __init rcu_init_one(struct rcu_state *rsp, |
| 1870 | struct rcu_data __percpu *rda) | ||
| 1869 | { | 1871 | { |
| 1870 | static char *buf[] = { "rcu_node_level_0", | 1872 | static char *buf[] = { "rcu_node_level_0", |
| 1871 | "rcu_node_level_1", | 1873 | "rcu_node_level_1", |
| @@ -1918,37 +1920,23 @@ static void __init rcu_init_one(struct rcu_state *rsp) | |||
| 1918 | } | 1920 | } |
| 1919 | } | 1921 | } |
| 1920 | 1922 | ||
| 1923 | rsp->rda = rda; | ||
| 1921 | rnp = rsp->level[NUM_RCU_LVLS - 1]; | 1924 | rnp = rsp->level[NUM_RCU_LVLS - 1]; |
| 1922 | for_each_possible_cpu(i) { | 1925 | for_each_possible_cpu(i) { |
| 1923 | while (i > rnp->grphi) | 1926 | while (i > rnp->grphi) |
| 1924 | rnp++; | 1927 | rnp++; |
| 1925 | rsp->rda[i]->mynode = rnp; | 1928 | per_cpu_ptr(rsp->rda, i)->mynode = rnp; |
| 1926 | rcu_boot_init_percpu_data(i, rsp); | 1929 | rcu_boot_init_percpu_data(i, rsp); |
| 1927 | } | 1930 | } |
| 1928 | } | 1931 | } |
| 1929 | 1932 | ||
| 1930 | /* | ||
| 1931 | * Helper macro for __rcu_init() and __rcu_init_preempt(). To be used | ||
| 1932 | * nowhere else! Assigns leaf node pointers into each CPU's rcu_data | ||
| 1933 | * structure. | ||
| 1934 | */ | ||
| 1935 | #define RCU_INIT_FLAVOR(rsp, rcu_data) \ | ||
| 1936 | do { \ | ||
| 1937 | int i; \ | ||
| 1938 | \ | ||
| 1939 | for_each_possible_cpu(i) { \ | ||
| 1940 | (rsp)->rda[i] = &per_cpu(rcu_data, i); \ | ||
| 1941 | } \ | ||
| 1942 | rcu_init_one(rsp); \ | ||
| 1943 | } while (0) | ||
| 1944 | |||
| 1945 | void __init rcu_init(void) | 1933 | void __init rcu_init(void) |
| 1946 | { | 1934 | { |
| 1947 | int cpu; | 1935 | int cpu; |
| 1948 | 1936 | ||
| 1949 | rcu_bootup_announce(); | 1937 | rcu_bootup_announce(); |
| 1950 | RCU_INIT_FLAVOR(&rcu_sched_state, rcu_sched_data); | 1938 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); |
| 1951 | RCU_INIT_FLAVOR(&rcu_bh_state, rcu_bh_data); | 1939 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); |
| 1952 | __rcu_init_preempt(); | 1940 | __rcu_init_preempt(); |
| 1953 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); | 1941 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); |
| 1954 | 1942 | ||
