diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cpu.c | 28 | ||||
| -rw-r--r-- | kernel/cpuset.c | 58 | ||||
| -rw-r--r-- | kernel/exit.c | 2 | ||||
| -rw-r--r-- | kernel/module.c | 2 | ||||
| -rw-r--r-- | kernel/sysctl.c | 25 | ||||
| -rw-r--r-- | kernel/sysctl_binary.c | 9 |
6 files changed, 108 insertions, 16 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 545777574779..124ad9d6be16 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -326,6 +326,12 @@ out_notify: | |||
| 326 | int __cpuinit cpu_up(unsigned int cpu) | 326 | int __cpuinit cpu_up(unsigned int cpu) |
| 327 | { | 327 | { |
| 328 | int err = 0; | 328 | int err = 0; |
| 329 | |||
| 330 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 331 | int nid; | ||
| 332 | pg_data_t *pgdat; | ||
| 333 | #endif | ||
| 334 | |||
| 329 | if (!cpu_possible(cpu)) { | 335 | if (!cpu_possible(cpu)) { |
| 330 | printk(KERN_ERR "can't online cpu %d because it is not " | 336 | printk(KERN_ERR "can't online cpu %d because it is not " |
| 331 | "configured as may-hotadd at boot time\n", cpu); | 337 | "configured as may-hotadd at boot time\n", cpu); |
| @@ -336,6 +342,28 @@ int __cpuinit cpu_up(unsigned int cpu) | |||
| 336 | return -EINVAL; | 342 | return -EINVAL; |
| 337 | } | 343 | } |
| 338 | 344 | ||
| 345 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 346 | nid = cpu_to_node(cpu); | ||
| 347 | if (!node_online(nid)) { | ||
| 348 | err = mem_online_node(nid); | ||
| 349 | if (err) | ||
| 350 | return err; | ||
| 351 | } | ||
| 352 | |||
| 353 | pgdat = NODE_DATA(nid); | ||
| 354 | if (!pgdat) { | ||
| 355 | printk(KERN_ERR | ||
| 356 | "Can't online cpu %d due to NULL pgdat\n", cpu); | ||
| 357 | return -ENOMEM; | ||
| 358 | } | ||
| 359 | |||
| 360 | if (pgdat->node_zonelists->_zonerefs->zone == NULL) { | ||
| 361 | mutex_lock(&zonelists_mutex); | ||
| 362 | build_all_zonelists(NULL); | ||
| 363 | mutex_unlock(&zonelists_mutex); | ||
| 364 | } | ||
| 365 | #endif | ||
| 366 | |||
| 339 | cpu_maps_update_begin(); | 367 | cpu_maps_update_begin(); |
| 340 | 368 | ||
| 341 | if (cpu_hotplug_disabled) { | 369 | if (cpu_hotplug_disabled) { |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 9a50c5f6e727..61d6af7fa676 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -946,16 +946,62 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | |||
| 946 | * In order to avoid seeing no nodes if the old and new nodes are disjoint, | 946 | * In order to avoid seeing no nodes if the old and new nodes are disjoint, |
| 947 | * we structure updates as setting all new allowed nodes, then clearing newly | 947 | * we structure updates as setting all new allowed nodes, then clearing newly |
| 948 | * disallowed ones. | 948 | * disallowed ones. |
| 949 | * | ||
| 950 | * Called with task's alloc_lock held | ||
| 951 | */ | 949 | */ |
| 952 | static void cpuset_change_task_nodemask(struct task_struct *tsk, | 950 | static void cpuset_change_task_nodemask(struct task_struct *tsk, |
| 953 | nodemask_t *newmems) | 951 | nodemask_t *newmems) |
| 954 | { | 952 | { |
| 953 | repeat: | ||
| 954 | /* | ||
| 955 | * Allow tasks that have access to memory reserves because they have | ||
| 956 | * been OOM killed to get memory anywhere. | ||
| 957 | */ | ||
| 958 | if (unlikely(test_thread_flag(TIF_MEMDIE))) | ||
| 959 | return; | ||
| 960 | if (current->flags & PF_EXITING) /* Let dying task have memory */ | ||
| 961 | return; | ||
| 962 | |||
| 963 | task_lock(tsk); | ||
| 955 | nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); | 964 | nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); |
| 956 | mpol_rebind_task(tsk, &tsk->mems_allowed); | 965 | mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); |
| 957 | mpol_rebind_task(tsk, newmems); | 966 | |
| 967 | |||
| 968 | /* | ||
| 969 | * ensure checking ->mems_allowed_change_disable after setting all new | ||
| 970 | * allowed nodes. | ||
| 971 | * | ||
| 972 | * the read-side task can see an nodemask with new allowed nodes and | ||
| 973 | * old allowed nodes. and if it allocates page when cpuset clears newly | ||
| 974 | * disallowed ones continuous, it can see the new allowed bits. | ||
| 975 | * | ||
| 976 | * And if setting all new allowed nodes is after the checking, setting | ||
| 977 | * all new allowed nodes and clearing newly disallowed ones will be done | ||
| 978 | * continuous, and the read-side task may find no node to alloc page. | ||
| 979 | */ | ||
| 980 | smp_mb(); | ||
| 981 | |||
| 982 | /* | ||
| 983 | * Allocation of memory is very fast, we needn't sleep when waiting | ||
| 984 | * for the read-side. | ||
| 985 | */ | ||
| 986 | while (ACCESS_ONCE(tsk->mems_allowed_change_disable)) { | ||
| 987 | task_unlock(tsk); | ||
| 988 | if (!task_curr(tsk)) | ||
| 989 | yield(); | ||
| 990 | goto repeat; | ||
| 991 | } | ||
| 992 | |||
| 993 | /* | ||
| 994 | * ensure checking ->mems_allowed_change_disable before clearing all new | ||
| 995 | * disallowed nodes. | ||
| 996 | * | ||
| 997 | * if clearing newly disallowed bits before the checking, the read-side | ||
| 998 | * task may find no node to alloc page. | ||
| 999 | */ | ||
| 1000 | smp_mb(); | ||
| 1001 | |||
| 1002 | mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2); | ||
| 958 | tsk->mems_allowed = *newmems; | 1003 | tsk->mems_allowed = *newmems; |
| 1004 | task_unlock(tsk); | ||
| 959 | } | 1005 | } |
| 960 | 1006 | ||
| 961 | /* | 1007 | /* |
| @@ -978,9 +1024,7 @@ static void cpuset_change_nodemask(struct task_struct *p, | |||
| 978 | cs = cgroup_cs(scan->cg); | 1024 | cs = cgroup_cs(scan->cg); |
| 979 | guarantee_online_mems(cs, newmems); | 1025 | guarantee_online_mems(cs, newmems); |
| 980 | 1026 | ||
| 981 | task_lock(p); | ||
| 982 | cpuset_change_task_nodemask(p, newmems); | 1027 | cpuset_change_task_nodemask(p, newmems); |
| 983 | task_unlock(p); | ||
| 984 | 1028 | ||
| 985 | NODEMASK_FREE(newmems); | 1029 | NODEMASK_FREE(newmems); |
| 986 | 1030 | ||
| @@ -1383,9 +1427,7 @@ static void cpuset_attach_task(struct task_struct *tsk, nodemask_t *to, | |||
| 1383 | err = set_cpus_allowed_ptr(tsk, cpus_attach); | 1427 | err = set_cpus_allowed_ptr(tsk, cpus_attach); |
| 1384 | WARN_ON_ONCE(err); | 1428 | WARN_ON_ONCE(err); |
| 1385 | 1429 | ||
| 1386 | task_lock(tsk); | ||
| 1387 | cpuset_change_task_nodemask(tsk, to); | 1430 | cpuset_change_task_nodemask(tsk, to); |
| 1388 | task_unlock(tsk); | ||
| 1389 | cpuset_update_task_spread_flag(cs, tsk); | 1431 | cpuset_update_task_spread_flag(cs, tsk); |
| 1390 | 1432 | ||
| 1391 | } | 1433 | } |
diff --git a/kernel/exit.c b/kernel/exit.c index eabca5a73a85..019a2843bf95 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -1002,8 +1002,10 @@ NORET_TYPE void do_exit(long code) | |||
| 1002 | 1002 | ||
| 1003 | exit_notify(tsk, group_dead); | 1003 | exit_notify(tsk, group_dead); |
| 1004 | #ifdef CONFIG_NUMA | 1004 | #ifdef CONFIG_NUMA |
| 1005 | task_lock(tsk); | ||
| 1005 | mpol_put(tsk->mempolicy); | 1006 | mpol_put(tsk->mempolicy); |
| 1006 | tsk->mempolicy = NULL; | 1007 | tsk->mempolicy = NULL; |
| 1008 | task_unlock(tsk); | ||
| 1007 | #endif | 1009 | #endif |
| 1008 | #ifdef CONFIG_FUTEX | 1010 | #ifdef CONFIG_FUTEX |
| 1009 | if (unlikely(current->pi_state_cache)) | 1011 | if (unlikely(current->pi_state_cache)) |
diff --git a/kernel/module.c b/kernel/module.c index a8014bfb5a4e..625985e70e9d 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -180,8 +180,6 @@ extern const struct kernel_symbol __start___ksymtab_gpl[]; | |||
| 180 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; | 180 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; |
| 181 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | 181 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; |
| 182 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | 182 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; |
| 183 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | ||
| 184 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | ||
| 185 | extern const unsigned long __start___kcrctab[]; | 183 | extern const unsigned long __start___kcrctab[]; |
| 186 | extern const unsigned long __start___kcrctab_gpl[]; | 184 | extern const unsigned long __start___kcrctab_gpl[]; |
| 187 | extern const unsigned long __start___kcrctab_gpl_future[]; | 185 | extern const unsigned long __start___kcrctab_gpl_future[]; |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4c93486b45d1..84ff5e75c084 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/highuid.h> | 37 | #include <linux/highuid.h> |
| 38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
| 39 | #include <linux/ratelimit.h> | 39 | #include <linux/ratelimit.h> |
| 40 | #include <linux/compaction.h> | ||
| 40 | #include <linux/hugetlb.h> | 41 | #include <linux/hugetlb.h> |
| 41 | #include <linux/initrd.h> | 42 | #include <linux/initrd.h> |
| 42 | #include <linux/key.h> | 43 | #include <linux/key.h> |
| @@ -262,6 +263,11 @@ static int min_sched_shares_ratelimit = 100000; /* 100 usec */ | |||
| 262 | static int max_sched_shares_ratelimit = NSEC_PER_SEC; /* 1 second */ | 263 | static int max_sched_shares_ratelimit = NSEC_PER_SEC; /* 1 second */ |
| 263 | #endif | 264 | #endif |
| 264 | 265 | ||
| 266 | #ifdef CONFIG_COMPACTION | ||
| 267 | static int min_extfrag_threshold; | ||
| 268 | static int max_extfrag_threshold = 1000; | ||
| 269 | #endif | ||
| 270 | |||
| 265 | static struct ctl_table kern_table[] = { | 271 | static struct ctl_table kern_table[] = { |
| 266 | { | 272 | { |
| 267 | .procname = "sched_child_runs_first", | 273 | .procname = "sched_child_runs_first", |
| @@ -1121,6 +1127,25 @@ static struct ctl_table vm_table[] = { | |||
| 1121 | .mode = 0644, | 1127 | .mode = 0644, |
| 1122 | .proc_handler = drop_caches_sysctl_handler, | 1128 | .proc_handler = drop_caches_sysctl_handler, |
| 1123 | }, | 1129 | }, |
| 1130 | #ifdef CONFIG_COMPACTION | ||
| 1131 | { | ||
| 1132 | .procname = "compact_memory", | ||
| 1133 | .data = &sysctl_compact_memory, | ||
| 1134 | .maxlen = sizeof(int), | ||
| 1135 | .mode = 0200, | ||
| 1136 | .proc_handler = sysctl_compaction_handler, | ||
| 1137 | }, | ||
| 1138 | { | ||
| 1139 | .procname = "extfrag_threshold", | ||
| 1140 | .data = &sysctl_extfrag_threshold, | ||
| 1141 | .maxlen = sizeof(int), | ||
| 1142 | .mode = 0644, | ||
| 1143 | .proc_handler = sysctl_extfrag_handler, | ||
| 1144 | .extra1 = &min_extfrag_threshold, | ||
| 1145 | .extra2 = &max_extfrag_threshold, | ||
| 1146 | }, | ||
| 1147 | |||
| 1148 | #endif /* CONFIG_COMPACTION */ | ||
| 1124 | { | 1149 | { |
| 1125 | .procname = "min_free_kbytes", | 1150 | .procname = "min_free_kbytes", |
| 1126 | .data = &min_free_kbytes, | 1151 | .data = &min_free_kbytes, |
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 937d31dc8566..1357c5786064 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/file.h> | 13 | #include <linux/file.h> |
| 14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
| 15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
| 16 | #include <linux/kernel.h> | ||
| 16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 17 | 18 | ||
| 18 | #ifdef CONFIG_SYSCTL_SYSCALL | 19 | #ifdef CONFIG_SYSCTL_SYSCALL |
| @@ -1124,11 +1125,6 @@ out: | |||
| 1124 | return result; | 1125 | return result; |
| 1125 | } | 1126 | } |
| 1126 | 1127 | ||
| 1127 | static unsigned hex_value(int ch) | ||
| 1128 | { | ||
| 1129 | return isdigit(ch) ? ch - '0' : ((ch | 0x20) - 'a') + 10; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | static ssize_t bin_uuid(struct file *file, | 1128 | static ssize_t bin_uuid(struct file *file, |
| 1133 | void __user *oldval, size_t oldlen, void __user *newval, size_t newlen) | 1129 | void __user *oldval, size_t oldlen, void __user *newval, size_t newlen) |
| 1134 | { | 1130 | { |
| @@ -1156,7 +1152,8 @@ static ssize_t bin_uuid(struct file *file, | |||
| 1156 | if (!isxdigit(str[0]) || !isxdigit(str[1])) | 1152 | if (!isxdigit(str[0]) || !isxdigit(str[1])) |
| 1157 | goto out; | 1153 | goto out; |
| 1158 | 1154 | ||
| 1159 | uuid[i] = (hex_value(str[0]) << 4) | hex_value(str[1]); | 1155 | uuid[i] = (hex_to_bin(str[0]) << 4) | |
| 1156 | hex_to_bin(str[1]); | ||
| 1160 | str += 2; | 1157 | str += 2; |
| 1161 | if (*str == '-') | 1158 | if (*str == '-') |
| 1162 | str++; | 1159 | str++; |
