diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 21:42:52 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 21:42:52 -0400 |
| commit | 17bb51d56cdc8cbf252031db3107de034cfeb44c (patch) | |
| tree | f9fb2c16b29a152d3413fa0028e660e3b6146584 /kernel | |
| parent | 0671b7674f42ab3a200401ea0e48d6f47d34acae (diff) | |
| parent | 95aac7b1cd224f568fb83937044cd303ff11b029 (diff) | |
Merge branch 'akpm-incoming-2'
* akpm-incoming-2: (139 commits)
epoll: make epoll_wait() use the hrtimer range feature
select: rename estimate_accuracy() to select_estimate_accuracy()
Remove duplicate includes from many files
ramoops: use the platform data structure instead of module params
kernel/resource.c: handle reinsertion of an already-inserted resource
kfifo: fix kfifo_alloc() to return a signed int value
w1: don't allow arbitrary users to remove w1 devices
alpha: remove dma64_addr_t usage
mips: remove dma64_addr_t usage
sparc: remove dma64_addr_t usage
fuse: use release_pages()
taskstats: use real microsecond granularity for CPU times
taskstats: split fill_pid function
taskstats: separate taskstats commands
delayacct: align to 8 byte boundary on 64-bit systems
delay-accounting: reimplement -c for getdelays.c to report information on a target command
namespaces Kconfig: move namespace menu location after the cgroup
namespaces Kconfig: remove the cgroup device whitelist experimental tag
namespaces Kconfig: remove pointless cgroup dependency
namespaces Kconfig: make namespace a submenu
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cgroup.c | 129 | ||||
| -rw-r--r-- | kernel/cgroup_freezer.c | 72 | ||||
| -rw-r--r-- | kernel/cred.c | 4 | ||||
| -rw-r--r-- | kernel/exit.c | 2 | ||||
| -rw-r--r-- | kernel/fork.c | 2 | ||||
| -rw-r--r-- | kernel/irq/irqdesc.c | 15 | ||||
| -rw-r--r-- | kernel/ns_cgroup.c | 8 | ||||
| -rw-r--r-- | kernel/ptrace.c | 36 | ||||
| -rw-r--r-- | kernel/resource.c | 2 | ||||
| -rw-r--r-- | kernel/signal.c | 5 | ||||
| -rw-r--r-- | kernel/taskstats.c | 172 | ||||
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 1 | ||||
| -rw-r--r-- | kernel/tsacct.c | 10 |
13 files changed, 295 insertions, 163 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9270d532ec3c..5cf366965d0c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -243,6 +243,11 @@ static int notify_on_release(const struct cgroup *cgrp) | |||
| 243 | return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); | 243 | return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | static int clone_children(const struct cgroup *cgrp) | ||
| 247 | { | ||
| 248 | return test_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
| 249 | } | ||
| 250 | |||
| 246 | /* | 251 | /* |
| 247 | * for_each_subsys() allows you to iterate on each subsystem attached to | 252 | * for_each_subsys() allows you to iterate on each subsystem attached to |
| 248 | * an active hierarchy | 253 | * an active hierarchy |
| @@ -1040,6 +1045,8 @@ static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 1040 | seq_puts(seq, ",noprefix"); | 1045 | seq_puts(seq, ",noprefix"); |
| 1041 | if (strlen(root->release_agent_path)) | 1046 | if (strlen(root->release_agent_path)) |
| 1042 | seq_printf(seq, ",release_agent=%s", root->release_agent_path); | 1047 | seq_printf(seq, ",release_agent=%s", root->release_agent_path); |
| 1048 | if (clone_children(&root->top_cgroup)) | ||
| 1049 | seq_puts(seq, ",clone_children"); | ||
| 1043 | if (strlen(root->name)) | 1050 | if (strlen(root->name)) |
| 1044 | seq_printf(seq, ",name=%s", root->name); | 1051 | seq_printf(seq, ",name=%s", root->name); |
| 1045 | mutex_unlock(&cgroup_mutex); | 1052 | mutex_unlock(&cgroup_mutex); |
| @@ -1050,6 +1057,7 @@ struct cgroup_sb_opts { | |||
| 1050 | unsigned long subsys_bits; | 1057 | unsigned long subsys_bits; |
| 1051 | unsigned long flags; | 1058 | unsigned long flags; |
| 1052 | char *release_agent; | 1059 | char *release_agent; |
| 1060 | bool clone_children; | ||
| 1053 | char *name; | 1061 | char *name; |
| 1054 | /* User explicitly requested empty subsystem */ | 1062 | /* User explicitly requested empty subsystem */ |
| 1055 | bool none; | 1063 | bool none; |
| @@ -1066,7 +1074,8 @@ struct cgroup_sb_opts { | |||
| 1066 | */ | 1074 | */ |
| 1067 | static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | 1075 | static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) |
| 1068 | { | 1076 | { |
| 1069 | char *token, *o = data ?: "all"; | 1077 | char *token, *o = data; |
| 1078 | bool all_ss = false, one_ss = false; | ||
| 1070 | unsigned long mask = (unsigned long)-1; | 1079 | unsigned long mask = (unsigned long)-1; |
| 1071 | int i; | 1080 | int i; |
| 1072 | bool module_pin_failed = false; | 1081 | bool module_pin_failed = false; |
| @@ -1082,22 +1091,27 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
| 1082 | while ((token = strsep(&o, ",")) != NULL) { | 1091 | while ((token = strsep(&o, ",")) != NULL) { |
| 1083 | if (!*token) | 1092 | if (!*token) |
| 1084 | return -EINVAL; | 1093 | return -EINVAL; |
| 1085 | if (!strcmp(token, "all")) { | 1094 | if (!strcmp(token, "none")) { |
| 1086 | /* Add all non-disabled subsystems */ | ||
| 1087 | opts->subsys_bits = 0; | ||
| 1088 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | ||
| 1089 | struct cgroup_subsys *ss = subsys[i]; | ||
| 1090 | if (ss == NULL) | ||
| 1091 | continue; | ||
| 1092 | if (!ss->disabled) | ||
| 1093 | opts->subsys_bits |= 1ul << i; | ||
| 1094 | } | ||
| 1095 | } else if (!strcmp(token, "none")) { | ||
| 1096 | /* Explicitly have no subsystems */ | 1095 | /* Explicitly have no subsystems */ |
| 1097 | opts->none = true; | 1096 | opts->none = true; |
| 1098 | } else if (!strcmp(token, "noprefix")) { | 1097 | continue; |
| 1098 | } | ||
| 1099 | if (!strcmp(token, "all")) { | ||
| 1100 | /* Mutually exclusive option 'all' + subsystem name */ | ||
| 1101 | if (one_ss) | ||
| 1102 | return -EINVAL; | ||
| 1103 | all_ss = true; | ||
| 1104 | continue; | ||
| 1105 | } | ||
| 1106 | if (!strcmp(token, "noprefix")) { | ||
| 1099 | set_bit(ROOT_NOPREFIX, &opts->flags); | 1107 | set_bit(ROOT_NOPREFIX, &opts->flags); |
| 1100 | } else if (!strncmp(token, "release_agent=", 14)) { | 1108 | continue; |
| 1109 | } | ||
| 1110 | if (!strcmp(token, "clone_children")) { | ||
| 1111 | opts->clone_children = true; | ||
| 1112 | continue; | ||
| 1113 | } | ||
| 1114 | if (!strncmp(token, "release_agent=", 14)) { | ||
| 1101 | /* Specifying two release agents is forbidden */ | 1115 | /* Specifying two release agents is forbidden */ |
| 1102 | if (opts->release_agent) | 1116 | if (opts->release_agent) |
| 1103 | return -EINVAL; | 1117 | return -EINVAL; |
| @@ -1105,7 +1119,9 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
| 1105 | kstrndup(token + 14, PATH_MAX - 1, GFP_KERNEL); | 1119 | kstrndup(token + 14, PATH_MAX - 1, GFP_KERNEL); |
| 1106 | if (!opts->release_agent) | 1120 | if (!opts->release_agent) |
| 1107 | return -ENOMEM; | 1121 | return -ENOMEM; |
| 1108 | } else if (!strncmp(token, "name=", 5)) { | 1122 | continue; |
| 1123 | } | ||
| 1124 | if (!strncmp(token, "name=", 5)) { | ||
| 1109 | const char *name = token + 5; | 1125 | const char *name = token + 5; |
| 1110 | /* Can't specify an empty name */ | 1126 | /* Can't specify an empty name */ |
| 1111 | if (!strlen(name)) | 1127 | if (!strlen(name)) |
| @@ -1127,20 +1143,44 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
| 1127 | GFP_KERNEL); | 1143 | GFP_KERNEL); |
| 1128 | if (!opts->name) | 1144 | if (!opts->name) |
| 1129 | return -ENOMEM; | 1145 | return -ENOMEM; |
| 1130 | } else { | 1146 | |
| 1131 | struct cgroup_subsys *ss; | 1147 | continue; |
| 1132 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1148 | } |
| 1133 | ss = subsys[i]; | 1149 | |
| 1134 | if (ss == NULL) | 1150 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { |
| 1135 | continue; | 1151 | struct cgroup_subsys *ss = subsys[i]; |
| 1136 | if (!strcmp(token, ss->name)) { | 1152 | if (ss == NULL) |
| 1137 | if (!ss->disabled) | 1153 | continue; |
| 1138 | set_bit(i, &opts->subsys_bits); | 1154 | if (strcmp(token, ss->name)) |
| 1139 | break; | 1155 | continue; |
| 1140 | } | 1156 | if (ss->disabled) |
| 1141 | } | 1157 | continue; |
| 1142 | if (i == CGROUP_SUBSYS_COUNT) | 1158 | |
| 1143 | return -ENOENT; | 1159 | /* Mutually exclusive option 'all' + subsystem name */ |
| 1160 | if (all_ss) | ||
| 1161 | return -EINVAL; | ||
| 1162 | set_bit(i, &opts->subsys_bits); | ||
| 1163 | one_ss = true; | ||
| 1164 | |||
| 1165 | break; | ||
| 1166 | } | ||
| 1167 | if (i == CGROUP_SUBSYS_COUNT) | ||
| 1168 | return -ENOENT; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | /* | ||
| 1172 | * If the 'all' option was specified select all the subsystems, | ||
| 1173 | * otherwise 'all, 'none' and a subsystem name options were not | ||
| 1174 | * specified, let's default to 'all' | ||
| 1175 | */ | ||
| 1176 | if (all_ss || (!all_ss && !one_ss && !opts->none)) { | ||
| 1177 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | ||
| 1178 | struct cgroup_subsys *ss = subsys[i]; | ||
| 1179 | if (ss == NULL) | ||
| 1180 | continue; | ||
| 1181 | if (ss->disabled) | ||
| 1182 | continue; | ||
| 1183 | set_bit(i, &opts->subsys_bits); | ||
| 1144 | } | 1184 | } |
| 1145 | } | 1185 | } |
| 1146 | 1186 | ||
| @@ -1355,6 +1395,8 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts) | |||
| 1355 | strcpy(root->release_agent_path, opts->release_agent); | 1395 | strcpy(root->release_agent_path, opts->release_agent); |
| 1356 | if (opts->name) | 1396 | if (opts->name) |
| 1357 | strcpy(root->name, opts->name); | 1397 | strcpy(root->name, opts->name); |
| 1398 | if (opts->clone_children) | ||
| 1399 | set_bit(CGRP_CLONE_CHILDREN, &root->top_cgroup.flags); | ||
| 1358 | return root; | 1400 | return root; |
| 1359 | } | 1401 | } |
| 1360 | 1402 | ||
| @@ -1880,6 +1922,8 @@ static int cgroup_release_agent_write(struct cgroup *cgrp, struct cftype *cft, | |||
| 1880 | const char *buffer) | 1922 | const char *buffer) |
| 1881 | { | 1923 | { |
| 1882 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); | 1924 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); |
| 1925 | if (strlen(buffer) >= PATH_MAX) | ||
| 1926 | return -EINVAL; | ||
| 1883 | if (!cgroup_lock_live_group(cgrp)) | 1927 | if (!cgroup_lock_live_group(cgrp)) |
| 1884 | return -ENODEV; | 1928 | return -ENODEV; |
| 1885 | strcpy(cgrp->root->release_agent_path, buffer); | 1929 | strcpy(cgrp->root->release_agent_path, buffer); |
| @@ -3173,6 +3217,23 @@ fail: | |||
| 3173 | return ret; | 3217 | return ret; |
| 3174 | } | 3218 | } |
| 3175 | 3219 | ||
| 3220 | static u64 cgroup_clone_children_read(struct cgroup *cgrp, | ||
| 3221 | struct cftype *cft) | ||
| 3222 | { | ||
| 3223 | return clone_children(cgrp); | ||
| 3224 | } | ||
| 3225 | |||
| 3226 | static int cgroup_clone_children_write(struct cgroup *cgrp, | ||
| 3227 | struct cftype *cft, | ||
| 3228 | u64 val) | ||
| 3229 | { | ||
| 3230 | if (val) | ||
| 3231 | set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
| 3232 | else | ||
| 3233 | clear_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
| 3234 | return 0; | ||
| 3235 | } | ||
| 3236 | |||
| 3176 | /* | 3237 | /* |
| 3177 | * for the common functions, 'private' gives the type of file | 3238 | * for the common functions, 'private' gives the type of file |
| 3178 | */ | 3239 | */ |
| @@ -3203,6 +3264,11 @@ static struct cftype files[] = { | |||
| 3203 | .write_string = cgroup_write_event_control, | 3264 | .write_string = cgroup_write_event_control, |
| 3204 | .mode = S_IWUGO, | 3265 | .mode = S_IWUGO, |
| 3205 | }, | 3266 | }, |
| 3267 | { | ||
| 3268 | .name = "cgroup.clone_children", | ||
| 3269 | .read_u64 = cgroup_clone_children_read, | ||
| 3270 | .write_u64 = cgroup_clone_children_write, | ||
| 3271 | }, | ||
| 3206 | }; | 3272 | }; |
| 3207 | 3273 | ||
| 3208 | static struct cftype cft_release_agent = { | 3274 | static struct cftype cft_release_agent = { |
| @@ -3332,6 +3398,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
| 3332 | if (notify_on_release(parent)) | 3398 | if (notify_on_release(parent)) |
| 3333 | set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); | 3399 | set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); |
| 3334 | 3400 | ||
| 3401 | if (clone_children(parent)) | ||
| 3402 | set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
| 3403 | |||
| 3335 | for_each_subsys(root, ss) { | 3404 | for_each_subsys(root, ss) { |
| 3336 | struct cgroup_subsys_state *css = ss->create(ss, cgrp); | 3405 | struct cgroup_subsys_state *css = ss->create(ss, cgrp); |
| 3337 | 3406 | ||
| @@ -3346,6 +3415,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
| 3346 | goto err_destroy; | 3415 | goto err_destroy; |
| 3347 | } | 3416 | } |
| 3348 | /* At error, ->destroy() callback has to free assigned ID. */ | 3417 | /* At error, ->destroy() callback has to free assigned ID. */ |
| 3418 | if (clone_children(parent) && ss->post_clone) | ||
| 3419 | ss->post_clone(ss, cgrp); | ||
| 3349 | } | 3420 | } |
| 3350 | 3421 | ||
| 3351 | cgroup_lock_hierarchy(root); | 3422 | cgroup_lock_hierarchy(root); |
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index ce71ed53e88f..e7bebb7c6c38 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
| @@ -48,20 +48,19 @@ static inline struct freezer *task_freezer(struct task_struct *task) | |||
| 48 | struct freezer, css); | 48 | struct freezer, css); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | int cgroup_freezing_or_frozen(struct task_struct *task) | 51 | static inline int __cgroup_freezing_or_frozen(struct task_struct *task) |
| 52 | { | 52 | { |
| 53 | struct freezer *freezer; | 53 | enum freezer_state state = task_freezer(task)->state; |
| 54 | enum freezer_state state; | 54 | return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); |
| 55 | } | ||
| 55 | 56 | ||
| 57 | int cgroup_freezing_or_frozen(struct task_struct *task) | ||
| 58 | { | ||
| 59 | int result; | ||
| 56 | task_lock(task); | 60 | task_lock(task); |
| 57 | freezer = task_freezer(task); | 61 | result = __cgroup_freezing_or_frozen(task); |
| 58 | if (!freezer->css.cgroup->parent) | ||
| 59 | state = CGROUP_THAWED; /* root cgroup can't be frozen */ | ||
| 60 | else | ||
| 61 | state = freezer->state; | ||
| 62 | task_unlock(task); | 62 | task_unlock(task); |
| 63 | 63 | return result; | |
| 64 | return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); | ||
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | /* | 66 | /* |
| @@ -154,13 +153,6 @@ static void freezer_destroy(struct cgroup_subsys *ss, | |||
| 154 | kfree(cgroup_freezer(cgroup)); | 153 | kfree(cgroup_freezer(cgroup)); |
| 155 | } | 154 | } |
| 156 | 155 | ||
| 157 | /* Task is frozen or will freeze immediately when next it gets woken */ | ||
| 158 | static bool is_task_frozen_enough(struct task_struct *task) | ||
| 159 | { | ||
| 160 | return frozen(task) || | ||
| 161 | (task_is_stopped_or_traced(task) && freezing(task)); | ||
| 162 | } | ||
| 163 | |||
| 164 | /* | 156 | /* |
| 165 | * The call to cgroup_lock() in the freezer.state write method prevents | 157 | * The call to cgroup_lock() in the freezer.state write method prevents |
| 166 | * a write to that file racing against an attach, and hence the | 158 | * a write to that file racing against an attach, and hence the |
| @@ -174,24 +166,25 @@ static int freezer_can_attach(struct cgroup_subsys *ss, | |||
| 174 | 166 | ||
| 175 | /* | 167 | /* |
| 176 | * Anything frozen can't move or be moved to/from. | 168 | * Anything frozen can't move or be moved to/from. |
| 177 | * | ||
| 178 | * Since orig_freezer->state == FROZEN means that @task has been | ||
| 179 | * frozen, so it's sufficient to check the latter condition. | ||
| 180 | */ | 169 | */ |
| 181 | 170 | ||
| 182 | if (is_task_frozen_enough(task)) | 171 | freezer = cgroup_freezer(new_cgroup); |
| 172 | if (freezer->state != CGROUP_THAWED) | ||
| 183 | return -EBUSY; | 173 | return -EBUSY; |
| 184 | 174 | ||
| 185 | freezer = cgroup_freezer(new_cgroup); | 175 | rcu_read_lock(); |
| 186 | if (freezer->state == CGROUP_FROZEN) | 176 | if (__cgroup_freezing_or_frozen(task)) { |
| 177 | rcu_read_unlock(); | ||
| 187 | return -EBUSY; | 178 | return -EBUSY; |
| 179 | } | ||
| 180 | rcu_read_unlock(); | ||
| 188 | 181 | ||
| 189 | if (threadgroup) { | 182 | if (threadgroup) { |
| 190 | struct task_struct *c; | 183 | struct task_struct *c; |
| 191 | 184 | ||
| 192 | rcu_read_lock(); | 185 | rcu_read_lock(); |
| 193 | list_for_each_entry_rcu(c, &task->thread_group, thread_group) { | 186 | list_for_each_entry_rcu(c, &task->thread_group, thread_group) { |
| 194 | if (is_task_frozen_enough(c)) { | 187 | if (__cgroup_freezing_or_frozen(c)) { |
| 195 | rcu_read_unlock(); | 188 | rcu_read_unlock(); |
| 196 | return -EBUSY; | 189 | return -EBUSY; |
| 197 | } | 190 | } |
| @@ -236,31 +229,30 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task) | |||
| 236 | /* | 229 | /* |
| 237 | * caller must hold freezer->lock | 230 | * caller must hold freezer->lock |
| 238 | */ | 231 | */ |
| 239 | static void update_freezer_state(struct cgroup *cgroup, | 232 | static void update_if_frozen(struct cgroup *cgroup, |
| 240 | struct freezer *freezer) | 233 | struct freezer *freezer) |
| 241 | { | 234 | { |
| 242 | struct cgroup_iter it; | 235 | struct cgroup_iter it; |
| 243 | struct task_struct *task; | 236 | struct task_struct *task; |
| 244 | unsigned int nfrozen = 0, ntotal = 0; | 237 | unsigned int nfrozen = 0, ntotal = 0; |
| 238 | enum freezer_state old_state = freezer->state; | ||
| 245 | 239 | ||
| 246 | cgroup_iter_start(cgroup, &it); | 240 | cgroup_iter_start(cgroup, &it); |
| 247 | while ((task = cgroup_iter_next(cgroup, &it))) { | 241 | while ((task = cgroup_iter_next(cgroup, &it))) { |
| 248 | ntotal++; | 242 | ntotal++; |
| 249 | if (is_task_frozen_enough(task)) | 243 | if (frozen(task)) |
| 250 | nfrozen++; | 244 | nfrozen++; |
| 251 | } | 245 | } |
| 252 | 246 | ||
| 253 | /* | 247 | if (old_state == CGROUP_THAWED) { |
| 254 | * Transition to FROZEN when no new tasks can be added ensures | 248 | BUG_ON(nfrozen > 0); |
| 255 | * that we never exist in the FROZEN state while there are unfrozen | 249 | } else if (old_state == CGROUP_FREEZING) { |
| 256 | * tasks. | 250 | if (nfrozen == ntotal) |
| 257 | */ | 251 | freezer->state = CGROUP_FROZEN; |
| 258 | if (nfrozen == ntotal) | 252 | } else { /* old_state == CGROUP_FROZEN */ |
| 259 | freezer->state = CGROUP_FROZEN; | 253 | BUG_ON(nfrozen != ntotal); |
| 260 | else if (nfrozen > 0) | 254 | } |
| 261 | freezer->state = CGROUP_FREEZING; | 255 | |
| 262 | else | ||
| 263 | freezer->state = CGROUP_THAWED; | ||
| 264 | cgroup_iter_end(cgroup, &it); | 256 | cgroup_iter_end(cgroup, &it); |
| 265 | } | 257 | } |
| 266 | 258 | ||
| @@ -279,7 +271,7 @@ static int freezer_read(struct cgroup *cgroup, struct cftype *cft, | |||
| 279 | if (state == CGROUP_FREEZING) { | 271 | if (state == CGROUP_FREEZING) { |
| 280 | /* We change from FREEZING to FROZEN lazily if the cgroup was | 272 | /* We change from FREEZING to FROZEN lazily if the cgroup was |
| 281 | * only partially frozen when we exitted write. */ | 273 | * only partially frozen when we exitted write. */ |
| 282 | update_freezer_state(cgroup, freezer); | 274 | update_if_frozen(cgroup, freezer); |
| 283 | state = freezer->state; | 275 | state = freezer->state; |
| 284 | } | 276 | } |
| 285 | spin_unlock_irq(&freezer->lock); | 277 | spin_unlock_irq(&freezer->lock); |
| @@ -301,7 +293,7 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) | |||
| 301 | while ((task = cgroup_iter_next(cgroup, &it))) { | 293 | while ((task = cgroup_iter_next(cgroup, &it))) { |
| 302 | if (!freeze_task(task, true)) | 294 | if (!freeze_task(task, true)) |
| 303 | continue; | 295 | continue; |
| 304 | if (is_task_frozen_enough(task)) | 296 | if (frozen(task)) |
| 305 | continue; | 297 | continue; |
| 306 | if (!freezing(task) && !freezer_should_skip(task)) | 298 | if (!freezing(task) && !freezer_should_skip(task)) |
| 307 | num_cant_freeze_now++; | 299 | num_cant_freeze_now++; |
| @@ -335,7 +327,7 @@ static int freezer_change_state(struct cgroup *cgroup, | |||
| 335 | 327 | ||
| 336 | spin_lock_irq(&freezer->lock); | 328 | spin_lock_irq(&freezer->lock); |
| 337 | 329 | ||
| 338 | update_freezer_state(cgroup, freezer); | 330 | update_if_frozen(cgroup, freezer); |
| 339 | if (goal_state == freezer->state) | 331 | if (goal_state == freezer->state) |
| 340 | goto out; | 332 | goto out; |
| 341 | 333 | ||
diff --git a/kernel/cred.c b/kernel/cred.c index 9a3e22641fe7..6a1aa004e376 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
| @@ -325,7 +325,7 @@ EXPORT_SYMBOL(prepare_creds); | |||
| 325 | 325 | ||
| 326 | /* | 326 | /* |
| 327 | * Prepare credentials for current to perform an execve() | 327 | * Prepare credentials for current to perform an execve() |
| 328 | * - The caller must hold current->cred_guard_mutex | 328 | * - The caller must hold ->cred_guard_mutex |
| 329 | */ | 329 | */ |
| 330 | struct cred *prepare_exec_creds(void) | 330 | struct cred *prepare_exec_creds(void) |
| 331 | { | 331 | { |
| @@ -384,8 +384,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) | |||
| 384 | struct cred *new; | 384 | struct cred *new; |
| 385 | int ret; | 385 | int ret; |
| 386 | 386 | ||
| 387 | mutex_init(&p->cred_guard_mutex); | ||
| 388 | |||
| 389 | if ( | 387 | if ( |
| 390 | #ifdef CONFIG_KEYS | 388 | #ifdef CONFIG_KEYS |
| 391 | !p->cred->thread_keyring && | 389 | !p->cred->thread_keyring && |
diff --git a/kernel/exit.c b/kernel/exit.c index 894179a32ec1..b194febf5799 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -703,6 +703,8 @@ static void exit_mm(struct task_struct * tsk) | |||
| 703 | * space. | 703 | * space. |
| 704 | */ | 704 | */ |
| 705 | static struct task_struct *find_new_reaper(struct task_struct *father) | 705 | static struct task_struct *find_new_reaper(struct task_struct *father) |
| 706 | __releases(&tasklist_lock) | ||
| 707 | __acquires(&tasklist_lock) | ||
| 706 | { | 708 | { |
| 707 | struct pid_namespace *pid_ns = task_active_pid_ns(father); | 709 | struct pid_namespace *pid_ns = task_active_pid_ns(father); |
| 708 | struct task_struct *thread; | 710 | struct task_struct *thread; |
diff --git a/kernel/fork.c b/kernel/fork.c index e87aaaaf5131..3b159c5991b7 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -908,6 +908,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 908 | sig->oom_adj = current->signal->oom_adj; | 908 | sig->oom_adj = current->signal->oom_adj; |
| 909 | sig->oom_score_adj = current->signal->oom_score_adj; | 909 | sig->oom_score_adj = current->signal->oom_score_adj; |
| 910 | 910 | ||
| 911 | mutex_init(&sig->cred_guard_mutex); | ||
| 912 | |||
| 911 | return 0; | 913 | return 0; |
| 912 | } | 914 | } |
| 913 | 915 | ||
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 9d917ff72675..9988d03797f5 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
| @@ -393,3 +393,18 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) | |||
| 393 | struct irq_desc *desc = irq_to_desc(irq); | 393 | struct irq_desc *desc = irq_to_desc(irq); |
| 394 | return desc ? desc->kstat_irqs[cpu] : 0; | 394 | return desc ? desc->kstat_irqs[cpu] : 0; |
| 395 | } | 395 | } |
| 396 | |||
| 397 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
| 398 | unsigned int kstat_irqs(unsigned int irq) | ||
| 399 | { | ||
| 400 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 401 | int cpu; | ||
| 402 | int sum = 0; | ||
| 403 | |||
| 404 | if (!desc) | ||
| 405 | return 0; | ||
| 406 | for_each_possible_cpu(cpu) | ||
| 407 | sum += desc->kstat_irqs[cpu]; | ||
| 408 | return sum; | ||
| 409 | } | ||
| 410 | #endif /* CONFIG_GENERIC_HARDIRQS */ | ||
diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c index 2a5dfec8efe0..2c98ad94ba0e 100644 --- a/kernel/ns_cgroup.c +++ b/kernel/ns_cgroup.c | |||
| @@ -85,6 +85,14 @@ static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss, | |||
| 85 | return ERR_PTR(-EPERM); | 85 | return ERR_PTR(-EPERM); |
| 86 | if (!cgroup_is_descendant(cgroup, current)) | 86 | if (!cgroup_is_descendant(cgroup, current)) |
| 87 | return ERR_PTR(-EPERM); | 87 | return ERR_PTR(-EPERM); |
| 88 | if (test_bit(CGRP_CLONE_CHILDREN, &cgroup->flags)) { | ||
| 89 | printk("ns_cgroup can't be created with parent " | ||
| 90 | "'clone_children' set.\n"); | ||
| 91 | return ERR_PTR(-EINVAL); | ||
| 92 | } | ||
| 93 | |||
| 94 | printk_once("ns_cgroup deprecated: consider using the " | ||
| 95 | "'clone_children' flag without the ns_cgroup.\n"); | ||
| 88 | 96 | ||
| 89 | ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); | 97 | ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); |
| 90 | if (!ns_cgroup) | 98 | if (!ns_cgroup) |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index f34d798ef4a2..99bbaa3e5b0d 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -181,7 +181,7 @@ int ptrace_attach(struct task_struct *task) | |||
| 181 | * under ptrace. | 181 | * under ptrace. |
| 182 | */ | 182 | */ |
| 183 | retval = -ERESTARTNOINTR; | 183 | retval = -ERESTARTNOINTR; |
| 184 | if (mutex_lock_interruptible(&task->cred_guard_mutex)) | 184 | if (mutex_lock_interruptible(&task->signal->cred_guard_mutex)) |
| 185 | goto out; | 185 | goto out; |
| 186 | 186 | ||
| 187 | task_lock(task); | 187 | task_lock(task); |
| @@ -208,7 +208,7 @@ int ptrace_attach(struct task_struct *task) | |||
| 208 | unlock_tasklist: | 208 | unlock_tasklist: |
| 209 | write_unlock_irq(&tasklist_lock); | 209 | write_unlock_irq(&tasklist_lock); |
| 210 | unlock_creds: | 210 | unlock_creds: |
| 211 | mutex_unlock(&task->cred_guard_mutex); | 211 | mutex_unlock(&task->signal->cred_guard_mutex); |
| 212 | out: | 212 | out: |
| 213 | return retval; | 213 | return retval; |
| 214 | } | 214 | } |
| @@ -329,6 +329,8 @@ int ptrace_detach(struct task_struct *child, unsigned int data) | |||
| 329 | * and reacquire the lock. | 329 | * and reacquire the lock. |
| 330 | */ | 330 | */ |
| 331 | void exit_ptrace(struct task_struct *tracer) | 331 | void exit_ptrace(struct task_struct *tracer) |
| 332 | __releases(&tasklist_lock) | ||
| 333 | __acquires(&tasklist_lock) | ||
| 332 | { | 334 | { |
| 333 | struct task_struct *p, *n; | 335 | struct task_struct *p, *n; |
| 334 | LIST_HEAD(ptrace_dead); | 336 | LIST_HEAD(ptrace_dead); |
| @@ -402,7 +404,7 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds | |||
| 402 | return copied; | 404 | return copied; |
| 403 | } | 405 | } |
| 404 | 406 | ||
| 405 | static int ptrace_setoptions(struct task_struct *child, long data) | 407 | static int ptrace_setoptions(struct task_struct *child, unsigned long data) |
| 406 | { | 408 | { |
| 407 | child->ptrace &= ~PT_TRACE_MASK; | 409 | child->ptrace &= ~PT_TRACE_MASK; |
| 408 | 410 | ||
| @@ -481,7 +483,8 @@ static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) | |||
| 481 | #define is_sysemu_singlestep(request) 0 | 483 | #define is_sysemu_singlestep(request) 0 |
| 482 | #endif | 484 | #endif |
| 483 | 485 | ||
| 484 | static int ptrace_resume(struct task_struct *child, long request, long data) | 486 | static int ptrace_resume(struct task_struct *child, long request, |
| 487 | unsigned long data) | ||
| 485 | { | 488 | { |
| 486 | if (!valid_signal(data)) | 489 | if (!valid_signal(data)) |
| 487 | return -EIO; | 490 | return -EIO; |
| @@ -558,10 +561,12 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type, | |||
| 558 | #endif | 561 | #endif |
| 559 | 562 | ||
| 560 | int ptrace_request(struct task_struct *child, long request, | 563 | int ptrace_request(struct task_struct *child, long request, |
| 561 | long addr, long data) | 564 | unsigned long addr, unsigned long data) |
| 562 | { | 565 | { |
| 563 | int ret = -EIO; | 566 | int ret = -EIO; |
| 564 | siginfo_t siginfo; | 567 | siginfo_t siginfo; |
| 568 | void __user *datavp = (void __user *) data; | ||
| 569 | unsigned long __user *datalp = datavp; | ||
| 565 | 570 | ||
| 566 | switch (request) { | 571 | switch (request) { |
| 567 | case PTRACE_PEEKTEXT: | 572 | case PTRACE_PEEKTEXT: |
| @@ -578,19 +583,17 @@ int ptrace_request(struct task_struct *child, long request, | |||
| 578 | ret = ptrace_setoptions(child, data); | 583 | ret = ptrace_setoptions(child, data); |
| 579 | break; | 584 | break; |
| 580 | case PTRACE_GETEVENTMSG: | 585 | case PTRACE_GETEVENTMSG: |
| 581 | ret = put_user(child->ptrace_message, (unsigned long __user *) data); | 586 | ret = put_user(child->ptrace_message, datalp); |
| 582 | break; | 587 | break; |
| 583 | 588 | ||
| 584 | case PTRACE_GETSIGINFO: | 589 | case PTRACE_GETSIGINFO: |
| 585 | ret = ptrace_getsiginfo(child, &siginfo); | 590 | ret = ptrace_getsiginfo(child, &siginfo); |
| 586 | if (!ret) | 591 | if (!ret) |
| 587 | ret = copy_siginfo_to_user((siginfo_t __user *) data, | 592 | ret = copy_siginfo_to_user(datavp, &siginfo); |
| 588 | &siginfo); | ||
| 589 | break; | 593 | break; |
| 590 | 594 | ||
| 591 | case PTRACE_SETSIGINFO: | 595 | case PTRACE_SETSIGINFO: |
| 592 | if (copy_from_user(&siginfo, (siginfo_t __user *) data, | 596 | if (copy_from_user(&siginfo, datavp, sizeof siginfo)) |
| 593 | sizeof siginfo)) | ||
| 594 | ret = -EFAULT; | 597 | ret = -EFAULT; |
| 595 | else | 598 | else |
| 596 | ret = ptrace_setsiginfo(child, &siginfo); | 599 | ret = ptrace_setsiginfo(child, &siginfo); |
| @@ -621,7 +624,7 @@ int ptrace_request(struct task_struct *child, long request, | |||
| 621 | } | 624 | } |
| 622 | mmput(mm); | 625 | mmput(mm); |
| 623 | 626 | ||
| 624 | ret = put_user(tmp, (unsigned long __user *) data); | 627 | ret = put_user(tmp, datalp); |
| 625 | break; | 628 | break; |
| 626 | } | 629 | } |
| 627 | #endif | 630 | #endif |
| @@ -650,7 +653,7 @@ int ptrace_request(struct task_struct *child, long request, | |||
| 650 | case PTRACE_SETREGSET: | 653 | case PTRACE_SETREGSET: |
| 651 | { | 654 | { |
| 652 | struct iovec kiov; | 655 | struct iovec kiov; |
| 653 | struct iovec __user *uiov = (struct iovec __user *) data; | 656 | struct iovec __user *uiov = datavp; |
| 654 | 657 | ||
| 655 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) | 658 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) |
| 656 | return -EFAULT; | 659 | return -EFAULT; |
| @@ -691,7 +694,8 @@ static struct task_struct *ptrace_get_task_struct(pid_t pid) | |||
| 691 | #define arch_ptrace_attach(child) do { } while (0) | 694 | #define arch_ptrace_attach(child) do { } while (0) |
| 692 | #endif | 695 | #endif |
| 693 | 696 | ||
| 694 | SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | 697 | SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, |
| 698 | unsigned long, data) | ||
| 695 | { | 699 | { |
| 696 | struct task_struct *child; | 700 | struct task_struct *child; |
| 697 | long ret; | 701 | long ret; |
| @@ -732,7 +736,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | |||
| 732 | return ret; | 736 | return ret; |
| 733 | } | 737 | } |
| 734 | 738 | ||
| 735 | int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) | 739 | int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
| 740 | unsigned long data) | ||
| 736 | { | 741 | { |
| 737 | unsigned long tmp; | 742 | unsigned long tmp; |
| 738 | int copied; | 743 | int copied; |
| @@ -743,7 +748,8 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) | |||
| 743 | return put_user(tmp, (unsigned long __user *)data); | 748 | return put_user(tmp, (unsigned long __user *)data); |
| 744 | } | 749 | } |
| 745 | 750 | ||
| 746 | int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data) | 751 | int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, |
| 752 | unsigned long data) | ||
| 747 | { | 753 | { |
| 748 | int copied; | 754 | int copied; |
| 749 | 755 | ||
diff --git a/kernel/resource.c b/kernel/resource.c index 7b36976e5dea..9c9841cb6902 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
| @@ -453,6 +453,8 @@ static struct resource * __insert_resource(struct resource *parent, struct resou | |||
| 453 | 453 | ||
| 454 | if (first == parent) | 454 | if (first == parent) |
| 455 | return first; | 455 | return first; |
| 456 | if (WARN_ON(first == new)) /* duplicated insertion */ | ||
| 457 | return first; | ||
| 456 | 458 | ||
| 457 | if ((first->start > new->start) || (first->end < new->end)) | 459 | if ((first->start > new->start) || (first->end < new->end)) |
| 458 | break; | 460 | break; |
diff --git a/kernel/signal.c b/kernel/signal.c index 919562c3d6b7..4e3cff10fdce 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -1105,7 +1105,8 @@ int zap_other_threads(struct task_struct *p) | |||
| 1105 | return count; | 1105 | return count; |
| 1106 | } | 1106 | } |
| 1107 | 1107 | ||
| 1108 | struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) | 1108 | struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, |
| 1109 | unsigned long *flags) | ||
| 1109 | { | 1110 | { |
| 1110 | struct sighand_struct *sighand; | 1111 | struct sighand_struct *sighand; |
| 1111 | 1112 | ||
| @@ -1617,6 +1618,8 @@ static int sigkill_pending(struct task_struct *tsk) | |||
| 1617 | * is gone, we keep current->exit_code unless clear_code. | 1618 | * is gone, we keep current->exit_code unless clear_code. |
| 1618 | */ | 1619 | */ |
| 1619 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) | 1620 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) |
| 1621 | __releases(¤t->sighand->siglock) | ||
| 1622 | __acquires(¤t->sighand->siglock) | ||
| 1620 | { | 1623 | { |
| 1621 | if (arch_ptrace_stop_needed(exit_code, info)) { | 1624 | if (arch_ptrace_stop_needed(exit_code, info)) { |
| 1622 | /* | 1625 | /* |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 11281d5792bd..c8231fb15708 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
| @@ -175,22 +175,8 @@ static void send_cpu_listeners(struct sk_buff *skb, | |||
| 175 | up_write(&listeners->sem); | 175 | up_write(&listeners->sem); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static int fill_pid(pid_t pid, struct task_struct *tsk, | 178 | static void fill_stats(struct task_struct *tsk, struct taskstats *stats) |
| 179 | struct taskstats *stats) | ||
| 180 | { | 179 | { |
| 181 | int rc = 0; | ||
| 182 | |||
| 183 | if (!tsk) { | ||
| 184 | rcu_read_lock(); | ||
| 185 | tsk = find_task_by_vpid(pid); | ||
| 186 | if (tsk) | ||
| 187 | get_task_struct(tsk); | ||
| 188 | rcu_read_unlock(); | ||
| 189 | if (!tsk) | ||
| 190 | return -ESRCH; | ||
| 191 | } else | ||
| 192 | get_task_struct(tsk); | ||
| 193 | |||
| 194 | memset(stats, 0, sizeof(*stats)); | 180 | memset(stats, 0, sizeof(*stats)); |
| 195 | /* | 181 | /* |
| 196 | * Each accounting subsystem adds calls to its functions to | 182 | * Each accounting subsystem adds calls to its functions to |
| @@ -209,17 +195,27 @@ static int fill_pid(pid_t pid, struct task_struct *tsk, | |||
| 209 | 195 | ||
| 210 | /* fill in extended acct fields */ | 196 | /* fill in extended acct fields */ |
| 211 | xacct_add_tsk(stats, tsk); | 197 | xacct_add_tsk(stats, tsk); |
| 198 | } | ||
| 212 | 199 | ||
| 213 | /* Define err: label here if needed */ | 200 | static int fill_stats_for_pid(pid_t pid, struct taskstats *stats) |
| 214 | put_task_struct(tsk); | 201 | { |
| 215 | return rc; | 202 | struct task_struct *tsk; |
| 216 | 203 | ||
| 204 | rcu_read_lock(); | ||
| 205 | tsk = find_task_by_vpid(pid); | ||
| 206 | if (tsk) | ||
| 207 | get_task_struct(tsk); | ||
| 208 | rcu_read_unlock(); | ||
| 209 | if (!tsk) | ||
| 210 | return -ESRCH; | ||
| 211 | fill_stats(tsk, stats); | ||
| 212 | put_task_struct(tsk); | ||
| 213 | return 0; | ||
| 217 | } | 214 | } |
| 218 | 215 | ||
| 219 | static int fill_tgid(pid_t tgid, struct task_struct *first, | 216 | static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats) |
| 220 | struct taskstats *stats) | ||
| 221 | { | 217 | { |
| 222 | struct task_struct *tsk; | 218 | struct task_struct *tsk, *first; |
| 223 | unsigned long flags; | 219 | unsigned long flags; |
| 224 | int rc = -ESRCH; | 220 | int rc = -ESRCH; |
| 225 | 221 | ||
| @@ -228,8 +224,7 @@ static int fill_tgid(pid_t tgid, struct task_struct *first, | |||
| 228 | * leaders who are already counted with the dead tasks | 224 | * leaders who are already counted with the dead tasks |
| 229 | */ | 225 | */ |
| 230 | rcu_read_lock(); | 226 | rcu_read_lock(); |
| 231 | if (!first) | 227 | first = find_task_by_vpid(tgid); |
| 232 | first = find_task_by_vpid(tgid); | ||
| 233 | 228 | ||
| 234 | if (!first || !lock_task_sighand(first, &flags)) | 229 | if (!first || !lock_task_sighand(first, &flags)) |
| 235 | goto out; | 230 | goto out; |
| @@ -268,7 +263,6 @@ out: | |||
| 268 | return rc; | 263 | return rc; |
| 269 | } | 264 | } |
| 270 | 265 | ||
| 271 | |||
| 272 | static void fill_tgid_exit(struct task_struct *tsk) | 266 | static void fill_tgid_exit(struct task_struct *tsk) |
| 273 | { | 267 | { |
| 274 | unsigned long flags; | 268 | unsigned long flags; |
| @@ -360,6 +354,12 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) | |||
| 360 | struct nlattr *na, *ret; | 354 | struct nlattr *na, *ret; |
| 361 | int aggr; | 355 | int aggr; |
| 362 | 356 | ||
| 357 | /* If we don't pad, we end up with alignment on a 4 byte boundary. | ||
| 358 | * This causes lots of runtime warnings on systems requiring 8 byte | ||
| 359 | * alignment */ | ||
| 360 | u32 pids[2] = { pid, 0 }; | ||
| 361 | int pid_size = ALIGN(sizeof(pid), sizeof(long)); | ||
| 362 | |||
| 363 | aggr = (type == TASKSTATS_TYPE_PID) | 363 | aggr = (type == TASKSTATS_TYPE_PID) |
| 364 | ? TASKSTATS_TYPE_AGGR_PID | 364 | ? TASKSTATS_TYPE_AGGR_PID |
| 365 | : TASKSTATS_TYPE_AGGR_TGID; | 365 | : TASKSTATS_TYPE_AGGR_TGID; |
| @@ -367,7 +367,7 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) | |||
| 367 | na = nla_nest_start(skb, aggr); | 367 | na = nla_nest_start(skb, aggr); |
| 368 | if (!na) | 368 | if (!na) |
| 369 | goto err; | 369 | goto err; |
| 370 | if (nla_put(skb, type, sizeof(pid), &pid) < 0) | 370 | if (nla_put(skb, type, pid_size, pids) < 0) |
| 371 | goto err; | 371 | goto err; |
| 372 | ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); | 372 | ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); |
| 373 | if (!ret) | 373 | if (!ret) |
| @@ -424,39 +424,46 @@ err: | |||
| 424 | return rc; | 424 | return rc; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | 427 | static int cmd_attr_register_cpumask(struct genl_info *info) |
| 428 | { | 428 | { |
| 429 | int rc; | ||
| 430 | struct sk_buff *rep_skb; | ||
| 431 | struct taskstats *stats; | ||
| 432 | size_t size; | ||
| 433 | cpumask_var_t mask; | 429 | cpumask_var_t mask; |
| 430 | int rc; | ||
| 434 | 431 | ||
| 435 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | 432 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
| 436 | return -ENOMEM; | 433 | return -ENOMEM; |
| 437 | |||
| 438 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); | 434 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); |
| 439 | if (rc < 0) | 435 | if (rc < 0) |
| 440 | goto free_return_rc; | 436 | goto out; |
| 441 | if (rc == 0) { | 437 | rc = add_del_listener(info->snd_pid, mask, REGISTER); |
| 442 | rc = add_del_listener(info->snd_pid, mask, REGISTER); | 438 | out: |
| 443 | goto free_return_rc; | 439 | free_cpumask_var(mask); |
| 444 | } | 440 | return rc; |
| 441 | } | ||
| 442 | |||
| 443 | static int cmd_attr_deregister_cpumask(struct genl_info *info) | ||
| 444 | { | ||
| 445 | cpumask_var_t mask; | ||
| 446 | int rc; | ||
| 445 | 447 | ||
| 448 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | ||
| 449 | return -ENOMEM; | ||
| 446 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); | 450 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); |
| 447 | if (rc < 0) | 451 | if (rc < 0) |
| 448 | goto free_return_rc; | 452 | goto out; |
| 449 | if (rc == 0) { | 453 | rc = add_del_listener(info->snd_pid, mask, DEREGISTER); |
| 450 | rc = add_del_listener(info->snd_pid, mask, DEREGISTER); | 454 | out: |
| 451 | free_return_rc: | ||
| 452 | free_cpumask_var(mask); | ||
| 453 | return rc; | ||
| 454 | } | ||
| 455 | free_cpumask_var(mask); | 455 | free_cpumask_var(mask); |
| 456 | return rc; | ||
| 457 | } | ||
| 458 | |||
| 459 | static int cmd_attr_pid(struct genl_info *info) | ||
| 460 | { | ||
| 461 | struct taskstats *stats; | ||
| 462 | struct sk_buff *rep_skb; | ||
| 463 | size_t size; | ||
| 464 | u32 pid; | ||
| 465 | int rc; | ||
| 456 | 466 | ||
| 457 | /* | ||
| 458 | * Size includes space for nested attributes | ||
| 459 | */ | ||
| 460 | size = nla_total_size(sizeof(u32)) + | 467 | size = nla_total_size(sizeof(u32)) + |
| 461 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | 468 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); |
| 462 | 469 | ||
| @@ -465,33 +472,64 @@ free_return_rc: | |||
| 465 | return rc; | 472 | return rc; |
| 466 | 473 | ||
| 467 | rc = -EINVAL; | 474 | rc = -EINVAL; |
| 468 | if (info->attrs[TASKSTATS_CMD_ATTR_PID]) { | 475 | pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); |
| 469 | u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); | 476 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); |
| 470 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); | 477 | if (!stats) |
| 471 | if (!stats) | 478 | goto err; |
| 472 | goto err; | 479 | |
| 473 | 480 | rc = fill_stats_for_pid(pid, stats); | |
| 474 | rc = fill_pid(pid, NULL, stats); | 481 | if (rc < 0) |
| 475 | if (rc < 0) | 482 | goto err; |
| 476 | goto err; | 483 | return send_reply(rep_skb, info); |
| 477 | } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) { | 484 | err: |
| 478 | u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); | 485 | nlmsg_free(rep_skb); |
| 479 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); | 486 | return rc; |
| 480 | if (!stats) | 487 | } |
| 481 | goto err; | 488 | |
| 482 | 489 | static int cmd_attr_tgid(struct genl_info *info) | |
| 483 | rc = fill_tgid(tgid, NULL, stats); | 490 | { |
| 484 | if (rc < 0) | 491 | struct taskstats *stats; |
| 485 | goto err; | 492 | struct sk_buff *rep_skb; |
| 486 | } else | 493 | size_t size; |
| 494 | u32 tgid; | ||
| 495 | int rc; | ||
| 496 | |||
| 497 | size = nla_total_size(sizeof(u32)) + | ||
| 498 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||
| 499 | |||
| 500 | rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); | ||
| 501 | if (rc < 0) | ||
| 502 | return rc; | ||
| 503 | |||
| 504 | rc = -EINVAL; | ||
| 505 | tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); | ||
| 506 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); | ||
| 507 | if (!stats) | ||
| 487 | goto err; | 508 | goto err; |
| 488 | 509 | ||
| 510 | rc = fill_stats_for_tgid(tgid, stats); | ||
| 511 | if (rc < 0) | ||
| 512 | goto err; | ||
| 489 | return send_reply(rep_skb, info); | 513 | return send_reply(rep_skb, info); |
| 490 | err: | 514 | err: |
| 491 | nlmsg_free(rep_skb); | 515 | nlmsg_free(rep_skb); |
| 492 | return rc; | 516 | return rc; |
| 493 | } | 517 | } |
| 494 | 518 | ||
| 519 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | ||
| 520 | { | ||
| 521 | if (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK]) | ||
| 522 | return cmd_attr_register_cpumask(info); | ||
| 523 | else if (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK]) | ||
| 524 | return cmd_attr_deregister_cpumask(info); | ||
| 525 | else if (info->attrs[TASKSTATS_CMD_ATTR_PID]) | ||
| 526 | return cmd_attr_pid(info); | ||
| 527 | else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) | ||
| 528 | return cmd_attr_tgid(info); | ||
| 529 | else | ||
| 530 | return -EINVAL; | ||
| 531 | } | ||
| 532 | |||
| 495 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) | 533 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) |
| 496 | { | 534 | { |
| 497 | struct signal_struct *sig = tsk->signal; | 535 | struct signal_struct *sig = tsk->signal; |
| @@ -555,9 +593,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
| 555 | if (!stats) | 593 | if (!stats) |
| 556 | goto err; | 594 | goto err; |
| 557 | 595 | ||
| 558 | rc = fill_pid(-1, tsk, stats); | 596 | fill_stats(tsk, stats); |
| 559 | if (rc < 0) | ||
| 560 | goto err; | ||
| 561 | 597 | ||
| 562 | /* | 598 | /* |
| 563 | * Doesn't matter if tsk is the leader or the last group member leaving | 599 | * Doesn't matter if tsk is the leader or the last group member leaving |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index b8d2852baa4a..2dec9bcde8b4 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/perf_event.h> | 31 | #include <linux/perf_event.h> |
| 32 | #include <linux/stringify.h> | 32 | #include <linux/stringify.h> |
| 33 | #include <linux/limits.h> | 33 | #include <linux/limits.h> |
| 34 | #include <linux/uaccess.h> | ||
| 35 | #include <asm/bitsperlong.h> | 34 | #include <asm/bitsperlong.h> |
| 36 | 35 | ||
| 37 | #include "trace.h" | 36 | #include "trace.h" |
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index 0a67e041edf8..24dc60d9fa1f 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
| @@ -63,12 +63,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | |||
| 63 | stats->ac_ppid = pid_alive(tsk) ? | 63 | stats->ac_ppid = pid_alive(tsk) ? |
| 64 | rcu_dereference(tsk->real_parent)->tgid : 0; | 64 | rcu_dereference(tsk->real_parent)->tgid : 0; |
| 65 | rcu_read_unlock(); | 65 | rcu_read_unlock(); |
| 66 | stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; | 66 | stats->ac_utime = cputime_to_usecs(tsk->utime); |
| 67 | stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; | 67 | stats->ac_stime = cputime_to_usecs(tsk->stime); |
| 68 | stats->ac_utimescaled = | 68 | stats->ac_utimescaled = cputime_to_usecs(tsk->utimescaled); |
| 69 | cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC; | 69 | stats->ac_stimescaled = cputime_to_usecs(tsk->stimescaled); |
| 70 | stats->ac_stimescaled = | ||
| 71 | cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC; | ||
| 72 | stats->ac_minflt = tsk->min_flt; | 70 | stats->ac_minflt = tsk->min_flt; |
| 73 | stats->ac_majflt = tsk->maj_flt; | 71 | stats->ac_majflt = tsk->maj_flt; |
| 74 | 72 | ||
