diff options
| -rw-r--r-- | kernel/cgroup/cpuset.c | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index cab5fd1ee767..f7efa7b4d825 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c | |||
| @@ -812,18 +812,6 @@ done: | |||
| 812 | return ndoms; | 812 | return ndoms; |
| 813 | } | 813 | } |
| 814 | 814 | ||
| 815 | static void cpuset_sched_change_begin(void) | ||
| 816 | { | ||
| 817 | cpus_read_lock(); | ||
| 818 | mutex_lock(&cpuset_mutex); | ||
| 819 | } | ||
| 820 | |||
| 821 | static void cpuset_sched_change_end(void) | ||
| 822 | { | ||
| 823 | mutex_unlock(&cpuset_mutex); | ||
| 824 | cpus_read_unlock(); | ||
| 825 | } | ||
| 826 | |||
| 827 | /* | 815 | /* |
| 828 | * Rebuild scheduler domains. | 816 | * Rebuild scheduler domains. |
| 829 | * | 817 | * |
| @@ -833,14 +821,16 @@ static void cpuset_sched_change_end(void) | |||
| 833 | * 'cpus' is removed, then call this routine to rebuild the | 821 | * 'cpus' is removed, then call this routine to rebuild the |
| 834 | * scheduler's dynamic sched domains. | 822 | * scheduler's dynamic sched domains. |
| 835 | * | 823 | * |
| 824 | * Call with cpuset_mutex held. Takes get_online_cpus(). | ||
| 836 | */ | 825 | */ |
| 837 | static void rebuild_sched_domains_cpuslocked(void) | 826 | static void rebuild_sched_domains_locked(void) |
| 838 | { | 827 | { |
| 839 | struct sched_domain_attr *attr; | 828 | struct sched_domain_attr *attr; |
| 840 | cpumask_var_t *doms; | 829 | cpumask_var_t *doms; |
| 841 | int ndoms; | 830 | int ndoms; |
| 842 | 831 | ||
| 843 | lockdep_assert_held(&cpuset_mutex); | 832 | lockdep_assert_held(&cpuset_mutex); |
| 833 | get_online_cpus(); | ||
| 844 | 834 | ||
| 845 | /* | 835 | /* |
| 846 | * We have raced with CPU hotplug. Don't do anything to avoid | 836 | * We have raced with CPU hotplug. Don't do anything to avoid |
| @@ -848,25 +838,27 @@ static void rebuild_sched_domains_cpuslocked(void) | |||
| 848 | * Anyways, hotplug work item will rebuild sched domains. | 838 | * Anyways, hotplug work item will rebuild sched domains. |
| 849 | */ | 839 | */ |
| 850 | if (!cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask)) | 840 | if (!cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask)) |
| 851 | return; | 841 | goto out; |
| 852 | 842 | ||
| 853 | /* Generate domain masks and attrs */ | 843 | /* Generate domain masks and attrs */ |
| 854 | ndoms = generate_sched_domains(&doms, &attr); | 844 | ndoms = generate_sched_domains(&doms, &attr); |
| 855 | 845 | ||
| 856 | /* Have scheduler rebuild the domains */ | 846 | /* Have scheduler rebuild the domains */ |
| 857 | partition_sched_domains(ndoms, doms, attr); | 847 | partition_sched_domains(ndoms, doms, attr); |
| 848 | out: | ||
| 849 | put_online_cpus(); | ||
| 858 | } | 850 | } |
| 859 | #else /* !CONFIG_SMP */ | 851 | #else /* !CONFIG_SMP */ |
| 860 | static void rebuild_sched_domains_cpuslocked(void) | 852 | static void rebuild_sched_domains_locked(void) |
| 861 | { | 853 | { |
| 862 | } | 854 | } |
| 863 | #endif /* CONFIG_SMP */ | 855 | #endif /* CONFIG_SMP */ |
| 864 | 856 | ||
| 865 | void rebuild_sched_domains(void) | 857 | void rebuild_sched_domains(void) |
| 866 | { | 858 | { |
| 867 | cpuset_sched_change_begin(); | 859 | mutex_lock(&cpuset_mutex); |
| 868 | rebuild_sched_domains_cpuslocked(); | 860 | rebuild_sched_domains_locked(); |
| 869 | cpuset_sched_change_end(); | 861 | mutex_unlock(&cpuset_mutex); |
| 870 | } | 862 | } |
| 871 | 863 | ||
| 872 | /** | 864 | /** |
| @@ -952,7 +944,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) | |||
| 952 | rcu_read_unlock(); | 944 | rcu_read_unlock(); |
| 953 | 945 | ||
| 954 | if (need_rebuild_sched_domains) | 946 | if (need_rebuild_sched_domains) |
| 955 | rebuild_sched_domains_cpuslocked(); | 947 | rebuild_sched_domains_locked(); |
| 956 | } | 948 | } |
| 957 | 949 | ||
| 958 | /** | 950 | /** |
| @@ -1284,7 +1276,7 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) | |||
| 1284 | cs->relax_domain_level = val; | 1276 | cs->relax_domain_level = val; |
| 1285 | if (!cpumask_empty(cs->cpus_allowed) && | 1277 | if (!cpumask_empty(cs->cpus_allowed) && |
| 1286 | is_sched_load_balance(cs)) | 1278 | is_sched_load_balance(cs)) |
| 1287 | rebuild_sched_domains_cpuslocked(); | 1279 | rebuild_sched_domains_locked(); |
| 1288 | } | 1280 | } |
| 1289 | 1281 | ||
| 1290 | return 0; | 1282 | return 0; |
| @@ -1317,6 +1309,7 @@ static void update_tasks_flags(struct cpuset *cs) | |||
| 1317 | * | 1309 | * |
| 1318 | * Call with cpuset_mutex held. | 1310 | * Call with cpuset_mutex held. |
| 1319 | */ | 1311 | */ |
| 1312 | |||
| 1320 | static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | 1313 | static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, |
| 1321 | int turning_on) | 1314 | int turning_on) |
| 1322 | { | 1315 | { |
| @@ -1349,7 +1342,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
| 1349 | spin_unlock_irq(&callback_lock); | 1342 | spin_unlock_irq(&callback_lock); |
| 1350 | 1343 | ||
| 1351 | if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) | 1344 | if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) |
| 1352 | rebuild_sched_domains_cpuslocked(); | 1345 | rebuild_sched_domains_locked(); |
| 1353 | 1346 | ||
| 1354 | if (spread_flag_changed) | 1347 | if (spread_flag_changed) |
| 1355 | update_tasks_flags(cs); | 1348 | update_tasks_flags(cs); |
| @@ -1617,7 +1610,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, | |||
| 1617 | cpuset_filetype_t type = cft->private; | 1610 | cpuset_filetype_t type = cft->private; |
| 1618 | int retval = 0; | 1611 | int retval = 0; |
| 1619 | 1612 | ||
| 1620 | cpuset_sched_change_begin(); | 1613 | mutex_lock(&cpuset_mutex); |
| 1621 | if (!is_cpuset_online(cs)) { | 1614 | if (!is_cpuset_online(cs)) { |
| 1622 | retval = -ENODEV; | 1615 | retval = -ENODEV; |
| 1623 | goto out_unlock; | 1616 | goto out_unlock; |
| @@ -1653,7 +1646,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, | |||
| 1653 | break; | 1646 | break; |
| 1654 | } | 1647 | } |
| 1655 | out_unlock: | 1648 | out_unlock: |
| 1656 | cpuset_sched_change_end(); | 1649 | mutex_unlock(&cpuset_mutex); |
| 1657 | return retval; | 1650 | return retval; |
| 1658 | } | 1651 | } |
| 1659 | 1652 | ||
| @@ -1664,7 +1657,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, | |||
| 1664 | cpuset_filetype_t type = cft->private; | 1657 | cpuset_filetype_t type = cft->private; |
| 1665 | int retval = -ENODEV; | 1658 | int retval = -ENODEV; |
| 1666 | 1659 | ||
| 1667 | cpuset_sched_change_begin(); | 1660 | mutex_lock(&cpuset_mutex); |
| 1668 | if (!is_cpuset_online(cs)) | 1661 | if (!is_cpuset_online(cs)) |
| 1669 | goto out_unlock; | 1662 | goto out_unlock; |
| 1670 | 1663 | ||
| @@ -1677,7 +1670,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, | |||
| 1677 | break; | 1670 | break; |
| 1678 | } | 1671 | } |
| 1679 | out_unlock: | 1672 | out_unlock: |
| 1680 | cpuset_sched_change_end(); | 1673 | mutex_unlock(&cpuset_mutex); |
| 1681 | return retval; | 1674 | return retval; |
| 1682 | } | 1675 | } |
| 1683 | 1676 | ||
| @@ -1716,7 +1709,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, | |||
| 1716 | kernfs_break_active_protection(of->kn); | 1709 | kernfs_break_active_protection(of->kn); |
| 1717 | flush_work(&cpuset_hotplug_work); | 1710 | flush_work(&cpuset_hotplug_work); |
| 1718 | 1711 | ||
| 1719 | cpuset_sched_change_begin(); | 1712 | mutex_lock(&cpuset_mutex); |
| 1720 | if (!is_cpuset_online(cs)) | 1713 | if (!is_cpuset_online(cs)) |
| 1721 | goto out_unlock; | 1714 | goto out_unlock; |
| 1722 | 1715 | ||
| @@ -1740,7 +1733,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, | |||
| 1740 | 1733 | ||
| 1741 | free_trial_cpuset(trialcs); | 1734 | free_trial_cpuset(trialcs); |
| 1742 | out_unlock: | 1735 | out_unlock: |
| 1743 | cpuset_sched_change_end(); | 1736 | mutex_unlock(&cpuset_mutex); |
| 1744 | kernfs_unbreak_active_protection(of->kn); | 1737 | kernfs_unbreak_active_protection(of->kn); |
| 1745 | css_put(&cs->css); | 1738 | css_put(&cs->css); |
| 1746 | flush_workqueue(cpuset_migrate_mm_wq); | 1739 | flush_workqueue(cpuset_migrate_mm_wq); |
| @@ -2041,14 +2034,14 @@ out_unlock: | |||
| 2041 | /* | 2034 | /* |
| 2042 | * If the cpuset being removed has its flag 'sched_load_balance' | 2035 | * If the cpuset being removed has its flag 'sched_load_balance' |
| 2043 | * enabled, then simulate turning sched_load_balance off, which | 2036 | * enabled, then simulate turning sched_load_balance off, which |
| 2044 | * will call rebuild_sched_domains_cpuslocked(). | 2037 | * will call rebuild_sched_domains_locked(). |
| 2045 | */ | 2038 | */ |
| 2046 | 2039 | ||
| 2047 | static void cpuset_css_offline(struct cgroup_subsys_state *css) | 2040 | static void cpuset_css_offline(struct cgroup_subsys_state *css) |
| 2048 | { | 2041 | { |
| 2049 | struct cpuset *cs = css_cs(css); | 2042 | struct cpuset *cs = css_cs(css); |
| 2050 | 2043 | ||
| 2051 | cpuset_sched_change_begin(); | 2044 | mutex_lock(&cpuset_mutex); |
| 2052 | 2045 | ||
| 2053 | if (is_sched_load_balance(cs)) | 2046 | if (is_sched_load_balance(cs)) |
| 2054 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); | 2047 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); |
| @@ -2056,7 +2049,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) | |||
| 2056 | cpuset_dec(); | 2049 | cpuset_dec(); |
| 2057 | clear_bit(CS_ONLINE, &cs->flags); | 2050 | clear_bit(CS_ONLINE, &cs->flags); |
| 2058 | 2051 | ||
| 2059 | cpuset_sched_change_end(); | 2052 | mutex_unlock(&cpuset_mutex); |
| 2060 | } | 2053 | } |
| 2061 | 2054 | ||
| 2062 | static void cpuset_css_free(struct cgroup_subsys_state *css) | 2055 | static void cpuset_css_free(struct cgroup_subsys_state *css) |
