diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:27 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:27 -0400 |
| commit | 092f4c56c1927e4b61a41ee8055005f1cb437009 (patch) | |
| tree | 616ceb54b7671ccc13922ae9e002b8b972f6e09e /kernel | |
| parent | 80c2861672bbf000f6af838656959ee937e4ee4d (diff) | |
| parent | c1e2ee2dc436574880758b3836fc96935b774c32 (diff) | |
Merge branch 'akpm' (Andrew's incoming - part two)
Says Andrew:
"60 patches. That's good enough for -rc1 I guess. I have quite a lot
of detritus to be rechecked, work through maintainers, etc.
- most of the remains of MM
- rtc
- various misc
- cgroups
- memcg
- cpusets
- procfs
- ipc
- rapidio
- sysctl
- pps
- w1
- drivers/misc
- aio"
* akpm: (60 commits)
memcg: replace ss->id_lock with a rwlock
aio: allocate kiocbs in batches
drivers/misc/vmw_balloon.c: fix typo in code comment
drivers/misc/vmw_balloon.c: determine page allocation flag can_sleep outside loop
w1: disable irqs in critical section
drivers/w1/w1_int.c: multiple masters used same init_name
drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal
drivers/power/ds2780_battery.c: add a nolock function to w1 interface
drivers/power/ds2780_battery.c: create central point for calling w1 interface
w1: ds2760 and ds2780, use ida for id and ida_simple_get() to get it
pps gpio client: add missing dependency
pps: new client driver using GPIO
pps: default echo function
include/linux/dma-mapping.h: add dma_zalloc_coherent()
sysctl: make CONFIG_SYSCTL_SYSCALL default to n
sysctl: add support for poll()
RapidIO: documentation update
drivers/net/rionet.c: fix ethernet address macros for LE platforms
RapidIO: fix potential null deref in rio_setup_device()
RapidIO: add mport driver for Tsi721 bridge
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cgroup.c | 39 | ||||
| -rw-r--r-- | kernel/cpuset.c | 9 | ||||
| -rw-r--r-- | kernel/sys.c | 2 | ||||
| -rw-r--r-- | kernel/utsname_sysctl.c | 23 |
4 files changed, 52 insertions, 21 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 453100a4159d..d9d5648f3cdc 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -2027,7 +2027,7 @@ int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) | |||
| 2027 | goto out_free_group_list; | 2027 | goto out_free_group_list; |
| 2028 | 2028 | ||
| 2029 | /* prevent changes to the threadgroup list while we take a snapshot. */ | 2029 | /* prevent changes to the threadgroup list while we take a snapshot. */ |
| 2030 | rcu_read_lock(); | 2030 | read_lock(&tasklist_lock); |
| 2031 | if (!thread_group_leader(leader)) { | 2031 | if (!thread_group_leader(leader)) { |
| 2032 | /* | 2032 | /* |
| 2033 | * a race with de_thread from another thread's exec() may strip | 2033 | * a race with de_thread from another thread's exec() may strip |
| @@ -2036,7 +2036,7 @@ int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) | |||
| 2036 | * throw this task away and try again (from cgroup_procs_write); | 2036 | * throw this task away and try again (from cgroup_procs_write); |
| 2037 | * this is "double-double-toil-and-trouble-check locking". | 2037 | * this is "double-double-toil-and-trouble-check locking". |
| 2038 | */ | 2038 | */ |
| 2039 | rcu_read_unlock(); | 2039 | read_unlock(&tasklist_lock); |
| 2040 | retval = -EAGAIN; | 2040 | retval = -EAGAIN; |
| 2041 | goto out_free_group_list; | 2041 | goto out_free_group_list; |
| 2042 | } | 2042 | } |
| @@ -2057,7 +2057,7 @@ int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) | |||
| 2057 | } while_each_thread(leader, tsk); | 2057 | } while_each_thread(leader, tsk); |
| 2058 | /* remember the number of threads in the array for later. */ | 2058 | /* remember the number of threads in the array for later. */ |
| 2059 | group_size = i; | 2059 | group_size = i; |
| 2060 | rcu_read_unlock(); | 2060 | read_unlock(&tasklist_lock); |
| 2061 | 2061 | ||
| 2062 | /* | 2062 | /* |
| 2063 | * step 1: check that we can legitimately attach to the cgroup. | 2063 | * step 1: check that we can legitimately attach to the cgroup. |
| @@ -2135,14 +2135,17 @@ int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) | |||
| 2135 | oldcgrp = task_cgroup_from_root(tsk, root); | 2135 | oldcgrp = task_cgroup_from_root(tsk, root); |
| 2136 | if (cgrp == oldcgrp) | 2136 | if (cgrp == oldcgrp) |
| 2137 | continue; | 2137 | continue; |
| 2138 | /* attach each task to each subsystem */ | ||
| 2139 | for_each_subsys(root, ss) { | ||
| 2140 | if (ss->attach_task) | ||
| 2141 | ss->attach_task(cgrp, tsk); | ||
| 2142 | } | ||
| 2143 | /* if the thread is PF_EXITING, it can just get skipped. */ | 2138 | /* if the thread is PF_EXITING, it can just get skipped. */ |
| 2144 | retval = cgroup_task_migrate(cgrp, oldcgrp, tsk, true); | 2139 | retval = cgroup_task_migrate(cgrp, oldcgrp, tsk, true); |
| 2145 | BUG_ON(retval != 0 && retval != -ESRCH); | 2140 | if (retval == 0) { |
| 2141 | /* attach each task to each subsystem */ | ||
| 2142 | for_each_subsys(root, ss) { | ||
| 2143 | if (ss->attach_task) | ||
| 2144 | ss->attach_task(cgrp, tsk); | ||
| 2145 | } | ||
| 2146 | } else { | ||
| 2147 | BUG_ON(retval != -ESRCH); | ||
| 2148 | } | ||
| 2146 | } | 2149 | } |
| 2147 | /* nothing is sensitive to fork() after this point. */ | 2150 | /* nothing is sensitive to fork() after this point. */ |
| 2148 | 2151 | ||
| @@ -4880,9 +4883,9 @@ void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css) | |||
| 4880 | 4883 | ||
| 4881 | rcu_assign_pointer(id->css, NULL); | 4884 | rcu_assign_pointer(id->css, NULL); |
| 4882 | rcu_assign_pointer(css->id, NULL); | 4885 | rcu_assign_pointer(css->id, NULL); |
| 4883 | spin_lock(&ss->id_lock); | 4886 | write_lock(&ss->id_lock); |
| 4884 | idr_remove(&ss->idr, id->id); | 4887 | idr_remove(&ss->idr, id->id); |
| 4885 | spin_unlock(&ss->id_lock); | 4888 | write_unlock(&ss->id_lock); |
| 4886 | kfree_rcu(id, rcu_head); | 4889 | kfree_rcu(id, rcu_head); |
| 4887 | } | 4890 | } |
| 4888 | EXPORT_SYMBOL_GPL(free_css_id); | 4891 | EXPORT_SYMBOL_GPL(free_css_id); |
| @@ -4908,10 +4911,10 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth) | |||
| 4908 | error = -ENOMEM; | 4911 | error = -ENOMEM; |
| 4909 | goto err_out; | 4912 | goto err_out; |
| 4910 | } | 4913 | } |
| 4911 | spin_lock(&ss->id_lock); | 4914 | write_lock(&ss->id_lock); |
| 4912 | /* Don't use 0. allocates an ID of 1-65535 */ | 4915 | /* Don't use 0. allocates an ID of 1-65535 */ |
| 4913 | error = idr_get_new_above(&ss->idr, newid, 1, &myid); | 4916 | error = idr_get_new_above(&ss->idr, newid, 1, &myid); |
| 4914 | spin_unlock(&ss->id_lock); | 4917 | write_unlock(&ss->id_lock); |
| 4915 | 4918 | ||
| 4916 | /* Returns error when there are no free spaces for new ID.*/ | 4919 | /* Returns error when there are no free spaces for new ID.*/ |
| 4917 | if (error) { | 4920 | if (error) { |
| @@ -4926,9 +4929,9 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth) | |||
| 4926 | return newid; | 4929 | return newid; |
| 4927 | remove_idr: | 4930 | remove_idr: |
| 4928 | error = -ENOSPC; | 4931 | error = -ENOSPC; |
| 4929 | spin_lock(&ss->id_lock); | 4932 | write_lock(&ss->id_lock); |
| 4930 | idr_remove(&ss->idr, myid); | 4933 | idr_remove(&ss->idr, myid); |
| 4931 | spin_unlock(&ss->id_lock); | 4934 | write_unlock(&ss->id_lock); |
| 4932 | err_out: | 4935 | err_out: |
| 4933 | kfree(newid); | 4936 | kfree(newid); |
| 4934 | return ERR_PTR(error); | 4937 | return ERR_PTR(error); |
| @@ -4940,7 +4943,7 @@ static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss, | |||
| 4940 | { | 4943 | { |
| 4941 | struct css_id *newid; | 4944 | struct css_id *newid; |
| 4942 | 4945 | ||
| 4943 | spin_lock_init(&ss->id_lock); | 4946 | rwlock_init(&ss->id_lock); |
| 4944 | idr_init(&ss->idr); | 4947 | idr_init(&ss->idr); |
| 4945 | 4948 | ||
| 4946 | newid = get_new_cssid(ss, 0); | 4949 | newid = get_new_cssid(ss, 0); |
| @@ -5035,9 +5038,9 @@ css_get_next(struct cgroup_subsys *ss, int id, | |||
| 5035 | * scan next entry from bitmap(tree), tmpid is updated after | 5038 | * scan next entry from bitmap(tree), tmpid is updated after |
| 5036 | * idr_get_next(). | 5039 | * idr_get_next(). |
| 5037 | */ | 5040 | */ |
| 5038 | spin_lock(&ss->id_lock); | 5041 | read_lock(&ss->id_lock); |
| 5039 | tmp = idr_get_next(&ss->idr, &tmpid); | 5042 | tmp = idr_get_next(&ss->idr, &tmpid); |
| 5040 | spin_unlock(&ss->id_lock); | 5043 | read_unlock(&ss->id_lock); |
| 5041 | 5044 | ||
| 5042 | if (!tmp) | 5045 | if (!tmp) |
| 5043 | break; | 5046 | break; |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 10131fdaff70..ed0ff443f036 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -949,6 +949,8 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | |||
| 949 | static void cpuset_change_task_nodemask(struct task_struct *tsk, | 949 | static void cpuset_change_task_nodemask(struct task_struct *tsk, |
| 950 | nodemask_t *newmems) | 950 | nodemask_t *newmems) |
| 951 | { | 951 | { |
| 952 | bool masks_disjoint = !nodes_intersects(*newmems, tsk->mems_allowed); | ||
| 953 | |||
| 952 | repeat: | 954 | repeat: |
| 953 | /* | 955 | /* |
| 954 | * Allow tasks that have access to memory reserves because they have | 956 | * Allow tasks that have access to memory reserves because they have |
| @@ -963,7 +965,6 @@ repeat: | |||
| 963 | nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); | 965 | nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); |
| 964 | mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); | 966 | mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); |
| 965 | 967 | ||
| 966 | |||
| 967 | /* | 968 | /* |
| 968 | * ensure checking ->mems_allowed_change_disable after setting all new | 969 | * ensure checking ->mems_allowed_change_disable after setting all new |
| 969 | * allowed nodes. | 970 | * allowed nodes. |
| @@ -980,9 +981,11 @@ repeat: | |||
| 980 | 981 | ||
| 981 | /* | 982 | /* |
| 982 | * Allocation of memory is very fast, we needn't sleep when waiting | 983 | * Allocation of memory is very fast, we needn't sleep when waiting |
| 983 | * for the read-side. | 984 | * for the read-side. No wait is necessary, however, if at least one |
| 985 | * node remains unchanged. | ||
| 984 | */ | 986 | */ |
| 985 | while (ACCESS_ONCE(tsk->mems_allowed_change_disable)) { | 987 | while (masks_disjoint && |
| 988 | ACCESS_ONCE(tsk->mems_allowed_change_disable)) { | ||
| 986 | task_unlock(tsk); | 989 | task_unlock(tsk); |
| 987 | if (!task_curr(tsk)) | 990 | if (!task_curr(tsk)) |
| 988 | yield(); | 991 | yield(); |
diff --git a/kernel/sys.c b/kernel/sys.c index 58459509b14c..d06c091e0345 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1286,6 +1286,7 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len) | |||
| 1286 | memset(u->nodename + len, 0, sizeof(u->nodename) - len); | 1286 | memset(u->nodename + len, 0, sizeof(u->nodename) - len); |
| 1287 | errno = 0; | 1287 | errno = 0; |
| 1288 | } | 1288 | } |
| 1289 | uts_proc_notify(UTS_PROC_HOSTNAME); | ||
| 1289 | up_write(&uts_sem); | 1290 | up_write(&uts_sem); |
| 1290 | return errno; | 1291 | return errno; |
| 1291 | } | 1292 | } |
| @@ -1336,6 +1337,7 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len) | |||
| 1336 | memset(u->domainname + len, 0, sizeof(u->domainname) - len); | 1337 | memset(u->domainname + len, 0, sizeof(u->domainname) - len); |
| 1337 | errno = 0; | 1338 | errno = 0; |
| 1338 | } | 1339 | } |
| 1340 | uts_proc_notify(UTS_PROC_DOMAINNAME); | ||
| 1339 | up_write(&uts_sem); | 1341 | up_write(&uts_sem); |
| 1340 | return errno; | 1342 | return errno; |
| 1341 | } | 1343 | } |
diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c index a2cd77e70d4d..3b0d48ebf81d 100644 --- a/kernel/utsname_sysctl.c +++ b/kernel/utsname_sysctl.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/uts.h> | 13 | #include <linux/uts.h> |
| 14 | #include <linux/utsname.h> | 14 | #include <linux/utsname.h> |
| 15 | #include <linux/sysctl.h> | 15 | #include <linux/sysctl.h> |
| 16 | #include <linux/wait.h> | ||
| 16 | 17 | ||
| 17 | static void *get_uts(ctl_table *table, int write) | 18 | static void *get_uts(ctl_table *table, int write) |
| 18 | { | 19 | { |
| @@ -51,12 +52,19 @@ static int proc_do_uts_string(ctl_table *table, int write, | |||
| 51 | uts_table.data = get_uts(table, write); | 52 | uts_table.data = get_uts(table, write); |
| 52 | r = proc_dostring(&uts_table,write,buffer,lenp, ppos); | 53 | r = proc_dostring(&uts_table,write,buffer,lenp, ppos); |
| 53 | put_uts(table, write, uts_table.data); | 54 | put_uts(table, write, uts_table.data); |
| 55 | |||
| 56 | if (write) | ||
| 57 | proc_sys_poll_notify(table->poll); | ||
| 58 | |||
| 54 | return r; | 59 | return r; |
| 55 | } | 60 | } |
| 56 | #else | 61 | #else |
| 57 | #define proc_do_uts_string NULL | 62 | #define proc_do_uts_string NULL |
| 58 | #endif | 63 | #endif |
| 59 | 64 | ||
| 65 | static DEFINE_CTL_TABLE_POLL(hostname_poll); | ||
| 66 | static DEFINE_CTL_TABLE_POLL(domainname_poll); | ||
| 67 | |||
| 60 | static struct ctl_table uts_kern_table[] = { | 68 | static struct ctl_table uts_kern_table[] = { |
| 61 | { | 69 | { |
| 62 | .procname = "ostype", | 70 | .procname = "ostype", |
| @@ -85,6 +93,7 @@ static struct ctl_table uts_kern_table[] = { | |||
| 85 | .maxlen = sizeof(init_uts_ns.name.nodename), | 93 | .maxlen = sizeof(init_uts_ns.name.nodename), |
| 86 | .mode = 0644, | 94 | .mode = 0644, |
| 87 | .proc_handler = proc_do_uts_string, | 95 | .proc_handler = proc_do_uts_string, |
| 96 | .poll = &hostname_poll, | ||
| 88 | }, | 97 | }, |
| 89 | { | 98 | { |
| 90 | .procname = "domainname", | 99 | .procname = "domainname", |
| @@ -92,6 +101,7 @@ static struct ctl_table uts_kern_table[] = { | |||
| 92 | .maxlen = sizeof(init_uts_ns.name.domainname), | 101 | .maxlen = sizeof(init_uts_ns.name.domainname), |
| 93 | .mode = 0644, | 102 | .mode = 0644, |
| 94 | .proc_handler = proc_do_uts_string, | 103 | .proc_handler = proc_do_uts_string, |
| 104 | .poll = &domainname_poll, | ||
| 95 | }, | 105 | }, |
| 96 | {} | 106 | {} |
| 97 | }; | 107 | }; |
| @@ -105,6 +115,19 @@ static struct ctl_table uts_root_table[] = { | |||
| 105 | {} | 115 | {} |
| 106 | }; | 116 | }; |
| 107 | 117 | ||
| 118 | #ifdef CONFIG_PROC_SYSCTL | ||
| 119 | /* | ||
| 120 | * Notify userspace about a change in a certain entry of uts_kern_table, | ||
| 121 | * identified by the parameter proc. | ||
| 122 | */ | ||
| 123 | void uts_proc_notify(enum uts_proc proc) | ||
| 124 | { | ||
| 125 | struct ctl_table *table = &uts_kern_table[proc]; | ||
| 126 | |||
| 127 | proc_sys_poll_notify(table->poll); | ||
| 128 | } | ||
| 129 | #endif | ||
| 130 | |||
| 108 | static int __init utsname_sysctl_init(void) | 131 | static int __init utsname_sysctl_init(void) |
| 109 | { | 132 | { |
| 110 | register_sysctl_table(uts_root_table); | 133 | register_sysctl_table(uts_root_table); |
