aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpuset.c68
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/module.c15
-rw-r--r--kernel/posix-timers.c1
-rw-r--r--kernel/softirq.c4
-rw-r--r--kernel/sys.c2
-rw-r--r--kernel/sys_ni.c1
-rw-r--r--kernel/workqueue.c2
8 files changed, 64 insertions, 33 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 805fb9097318..21a4e3b2cbda 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -398,21 +398,31 @@ static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
398 * to continue to serve a useful existence. Next time it's released, 398 * to continue to serve a useful existence. Next time it's released,
399 * we will get notified again, if it still has 'notify_on_release' set. 399 * we will get notified again, if it still has 'notify_on_release' set.
400 * 400 *
401 * Note final arg to call_usermodehelper() is 0 - that means 401 * The final arg to call_usermodehelper() is 0, which means don't
402 * don't wait. Since we are holding the global cpuset_sem here, 402 * wait. The separate /sbin/cpuset_release_agent task is forked by
403 * and we are asking another thread (started from keventd) to rmdir a 403 * call_usermodehelper(), then control in this thread returns here,
404 * cpuset, we can't wait - or we'd deadlock with the removing thread 404 * without waiting for the release agent task. We don't bother to
405 * on cpuset_sem. 405 * wait because the caller of this routine has no use for the exit
406 * status of the /sbin/cpuset_release_agent task, so no sense holding
407 * our caller up for that.
408 *
409 * The simple act of forking that task might require more memory,
410 * which might need cpuset_sem. So this routine must be called while
411 * cpuset_sem is not held, to avoid a possible deadlock. See also
412 * comments for check_for_release(), below.
406 */ 413 */
407 414
408static int cpuset_release_agent(char *cpuset_str) 415static void cpuset_release_agent(const char *pathbuf)
409{ 416{
410 char *argv[3], *envp[3]; 417 char *argv[3], *envp[3];
411 int i; 418 int i;
412 419
420 if (!pathbuf)
421 return;
422
413 i = 0; 423 i = 0;
414 argv[i++] = "/sbin/cpuset_release_agent"; 424 argv[i++] = "/sbin/cpuset_release_agent";
415 argv[i++] = cpuset_str; 425 argv[i++] = (char *)pathbuf;
416 argv[i] = NULL; 426 argv[i] = NULL;
417 427
418 i = 0; 428 i = 0;
@@ -421,17 +431,29 @@ static int cpuset_release_agent(char *cpuset_str)
421 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 431 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
422 envp[i] = NULL; 432 envp[i] = NULL;
423 433
424 return call_usermodehelper(argv[0], argv, envp, 0); 434 call_usermodehelper(argv[0], argv, envp, 0);
435 kfree(pathbuf);
425} 436}
426 437
427/* 438/*
428 * Either cs->count of using tasks transitioned to zero, or the 439 * Either cs->count of using tasks transitioned to zero, or the
429 * cs->children list of child cpusets just became empty. If this 440 * cs->children list of child cpusets just became empty. If this
430 * cs is notify_on_release() and now both the user count is zero and 441 * cs is notify_on_release() and now both the user count is zero and
431 * the list of children is empty, send notice to user land. 442 * the list of children is empty, prepare cpuset path in a kmalloc'd
443 * buffer, to be returned via ppathbuf, so that the caller can invoke
444 * cpuset_release_agent() with it later on, once cpuset_sem is dropped.
445 * Call here with cpuset_sem held.
446 *
447 * This check_for_release() routine is responsible for kmalloc'ing
448 * pathbuf. The above cpuset_release_agent() is responsible for
449 * kfree'ing pathbuf. The caller of these routines is responsible
450 * for providing a pathbuf pointer, initialized to NULL, then
451 * calling check_for_release() with cpuset_sem held and the address
452 * of the pathbuf pointer, then dropping cpuset_sem, then calling
453 * cpuset_release_agent() with pathbuf, as set by check_for_release().
432 */ 454 */
433 455
434static void check_for_release(struct cpuset *cs) 456static void check_for_release(struct cpuset *cs, char **ppathbuf)
435{ 457{
436 if (notify_on_release(cs) && atomic_read(&cs->count) == 0 && 458 if (notify_on_release(cs) && atomic_read(&cs->count) == 0 &&
437 list_empty(&cs->children)) { 459 list_empty(&cs->children)) {
@@ -441,10 +463,9 @@ static void check_for_release(struct cpuset *cs)
441 if (!buf) 463 if (!buf)
442 return; 464 return;
443 if (cpuset_path(cs, buf, PAGE_SIZE) < 0) 465 if (cpuset_path(cs, buf, PAGE_SIZE) < 0)
444 goto out; 466 kfree(buf);
445 cpuset_release_agent(buf); 467 else
446out: 468 *ppathbuf = buf;
447 kfree(buf);
448 } 469 }
449} 470}
450 471
@@ -727,14 +748,14 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
727 return 0; 748 return 0;
728} 749}
729 750
730static int attach_task(struct cpuset *cs, char *buf) 751static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
731{ 752{
732 pid_t pid; 753 pid_t pid;
733 struct task_struct *tsk; 754 struct task_struct *tsk;
734 struct cpuset *oldcs; 755 struct cpuset *oldcs;
735 cpumask_t cpus; 756 cpumask_t cpus;
736 757
737 if (sscanf(buf, "%d", &pid) != 1) 758 if (sscanf(pidbuf, "%d", &pid) != 1)
738 return -EIO; 759 return -EIO;
739 if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) 760 if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
740 return -ENOSPC; 761 return -ENOSPC;
@@ -777,7 +798,7 @@ static int attach_task(struct cpuset *cs, char *buf)
777 798
778 put_task_struct(tsk); 799 put_task_struct(tsk);
779 if (atomic_dec_and_test(&oldcs->count)) 800 if (atomic_dec_and_test(&oldcs->count))
780 check_for_release(oldcs); 801 check_for_release(oldcs, ppathbuf);
781 return 0; 802 return 0;
782} 803}
783 804
@@ -801,6 +822,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
801 struct cftype *cft = __d_cft(file->f_dentry); 822 struct cftype *cft = __d_cft(file->f_dentry);
802 cpuset_filetype_t type = cft->private; 823 cpuset_filetype_t type = cft->private;
803 char *buffer; 824 char *buffer;
825 char *pathbuf = NULL;
804 int retval = 0; 826 int retval = 0;
805 827
806 /* Crude upper limit on largest legitimate cpulist user might write. */ 828 /* Crude upper limit on largest legitimate cpulist user might write. */
@@ -841,7 +863,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
841 retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer); 863 retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
842 break; 864 break;
843 case FILE_TASKLIST: 865 case FILE_TASKLIST:
844 retval = attach_task(cs, buffer); 866 retval = attach_task(cs, buffer, &pathbuf);
845 break; 867 break;
846 default: 868 default:
847 retval = -EINVAL; 869 retval = -EINVAL;
@@ -852,6 +874,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
852 retval = nbytes; 874 retval = nbytes;
853out2: 875out2:
854 up(&cpuset_sem); 876 up(&cpuset_sem);
877 cpuset_release_agent(pathbuf);
855out1: 878out1:
856 kfree(buffer); 879 kfree(buffer);
857 return retval; 880 return retval;
@@ -1357,6 +1380,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1357 struct cpuset *cs = dentry->d_fsdata; 1380 struct cpuset *cs = dentry->d_fsdata;
1358 struct dentry *d; 1381 struct dentry *d;
1359 struct cpuset *parent; 1382 struct cpuset *parent;
1383 char *pathbuf = NULL;
1360 1384
1361 /* the vfs holds both inode->i_sem already */ 1385 /* the vfs holds both inode->i_sem already */
1362 1386
@@ -1376,7 +1400,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1376 update_cpu_domains(cs); 1400 update_cpu_domains(cs);
1377 list_del(&cs->sibling); /* delete my sibling from parent->children */ 1401 list_del(&cs->sibling); /* delete my sibling from parent->children */
1378 if (list_empty(&parent->children)) 1402 if (list_empty(&parent->children))
1379 check_for_release(parent); 1403 check_for_release(parent, &pathbuf);
1380 spin_lock(&cs->dentry->d_lock); 1404 spin_lock(&cs->dentry->d_lock);
1381 d = dget(cs->dentry); 1405 d = dget(cs->dentry);
1382 cs->dentry = NULL; 1406 cs->dentry = NULL;
@@ -1384,6 +1408,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1384 cpuset_d_remove_dir(d); 1408 cpuset_d_remove_dir(d);
1385 dput(d); 1409 dput(d);
1386 up(&cpuset_sem); 1410 up(&cpuset_sem);
1411 cpuset_release_agent(pathbuf);
1387 return 0; 1412 return 0;
1388} 1413}
1389 1414
@@ -1483,10 +1508,13 @@ void cpuset_exit(struct task_struct *tsk)
1483 task_unlock(tsk); 1508 task_unlock(tsk);
1484 1509
1485 if (notify_on_release(cs)) { 1510 if (notify_on_release(cs)) {
1511 char *pathbuf = NULL;
1512
1486 down(&cpuset_sem); 1513 down(&cpuset_sem);
1487 if (atomic_dec_and_test(&cs->count)) 1514 if (atomic_dec_and_test(&cs->count))
1488 check_for_release(cs); 1515 check_for_release(cs, &pathbuf);
1489 up(&cpuset_sem); 1516 up(&cpuset_sem);
1517 cpuset_release_agent(pathbuf);
1490 } else { 1518 } else {
1491 atomic_dec(&cs->count); 1519 atomic_dec(&cs->count);
1492 } 1520 }
diff --git a/kernel/exit.c b/kernel/exit.c
index 9d1b10ed0135..5b0fb9f09f21 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -829,8 +829,10 @@ fastcall NORET_TYPE void do_exit(long code)
829 acct_update_integrals(tsk); 829 acct_update_integrals(tsk);
830 update_mem_hiwater(tsk); 830 update_mem_hiwater(tsk);
831 group_dead = atomic_dec_and_test(&tsk->signal->live); 831 group_dead = atomic_dec_and_test(&tsk->signal->live);
832 if (group_dead) 832 if (group_dead) {
833 del_timer_sync(&tsk->signal->real_timer);
833 acct_process(code); 834 acct_process(code);
835 }
834 exit_mm(tsk); 836 exit_mm(tsk);
835 837
836 exit_sem(tsk); 838 exit_sem(tsk);
diff --git a/kernel/module.c b/kernel/module.c
index 068e271ab3a5..c32995fbd8fd 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -250,13 +250,18 @@ static inline unsigned int block_size(int val)
250/* Created by linker magic */ 250/* Created by linker magic */
251extern char __per_cpu_start[], __per_cpu_end[]; 251extern char __per_cpu_start[], __per_cpu_end[];
252 252
253static void *percpu_modalloc(unsigned long size, unsigned long align) 253static void *percpu_modalloc(unsigned long size, unsigned long align,
254 const char *name)
254{ 255{
255 unsigned long extra; 256 unsigned long extra;
256 unsigned int i; 257 unsigned int i;
257 void *ptr; 258 void *ptr;
258 259
259 BUG_ON(align > SMP_CACHE_BYTES); 260 if (align > SMP_CACHE_BYTES) {
261 printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n",
262 name, align, SMP_CACHE_BYTES);
263 align = SMP_CACHE_BYTES;
264 }
260 265
261 ptr = __per_cpu_start; 266 ptr = __per_cpu_start;
262 for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { 267 for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) {
@@ -348,7 +353,8 @@ static int percpu_modinit(void)
348} 353}
349__initcall(percpu_modinit); 354__initcall(percpu_modinit);
350#else /* ... !CONFIG_SMP */ 355#else /* ... !CONFIG_SMP */
351static inline void *percpu_modalloc(unsigned long size, unsigned long align) 356static inline void *percpu_modalloc(unsigned long size, unsigned long align,
357 const char *name)
352{ 358{
353 return NULL; 359 return NULL;
354} 360}
@@ -1644,7 +1650,8 @@ static struct module *load_module(void __user *umod,
1644 if (pcpuindex) { 1650 if (pcpuindex) {
1645 /* We have a special allocation for this section. */ 1651 /* We have a special allocation for this section. */
1646 percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, 1652 percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
1647 sechdrs[pcpuindex].sh_addralign); 1653 sechdrs[pcpuindex].sh_addralign,
1654 mod->name);
1648 if (!percpu) { 1655 if (!percpu) {
1649 err = -ENOMEM; 1656 err = -ENOMEM;
1650 goto free_mod; 1657 goto free_mod;
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 10b2ad749d14..38798a2ff994 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1166,7 +1166,6 @@ void exit_itimers(struct signal_struct *sig)
1166 tmr = list_entry(sig->posix_timers.next, struct k_itimer, list); 1166 tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
1167 itimer_delete(tmr); 1167 itimer_delete(tmr);
1168 } 1168 }
1169 del_timer_sync(&sig->real_timer);
1170} 1169}
1171 1170
1172/* 1171/*
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 31007d6542cc..b4ab6af1dea8 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -86,7 +86,7 @@ restart:
86 /* Reset the pending bitmask before enabling irqs */ 86 /* Reset the pending bitmask before enabling irqs */
87 local_softirq_pending() = 0; 87 local_softirq_pending() = 0;
88 88
89 //local_irq_enable(); 89 local_irq_enable();
90 90
91 h = softirq_vec; 91 h = softirq_vec;
92 92
@@ -99,7 +99,7 @@ restart:
99 pending >>= 1; 99 pending >>= 1;
100 } while (pending); 100 } while (pending);
101 101
102 //local_irq_disable(); 102 local_irq_disable();
103 103
104 pending = local_softirq_pending(); 104 pending = local_softirq_pending();
105 if (pending && --max_restart) 105 if (pending && --max_restart)
diff --git a/kernel/sys.c b/kernel/sys.c
index 000e81ad2c1d..0bcaed6560ac 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -404,7 +404,6 @@ void kernel_halt(void)
404{ 404{
405 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); 405 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
406 system_state = SYSTEM_HALT; 406 system_state = SYSTEM_HALT;
407 device_suspend(PMSG_SUSPEND);
408 device_shutdown(); 407 device_shutdown();
409 printk(KERN_EMERG "System halted.\n"); 408 printk(KERN_EMERG "System halted.\n");
410 machine_halt(); 409 machine_halt();
@@ -415,7 +414,6 @@ void kernel_power_off(void)
415{ 414{
416 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); 415 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
417 system_state = SYSTEM_POWER_OFF; 416 system_state = SYSTEM_POWER_OFF;
418 device_suspend(PMSG_SUSPEND);
419 device_shutdown(); 417 device_shutdown();
420 printk(KERN_EMERG "Power down.\n"); 418 printk(KERN_EMERG "Power down.\n");
421 machine_power_off(); 419 machine_power_off();
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 42b40ae5eada..1ab2370e2efa 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -79,7 +79,6 @@ cond_syscall(sys_request_key);
79cond_syscall(sys_keyctl); 79cond_syscall(sys_keyctl);
80cond_syscall(compat_sys_keyctl); 80cond_syscall(compat_sys_keyctl);
81cond_syscall(compat_sys_socketcall); 81cond_syscall(compat_sys_socketcall);
82cond_syscall(sys_set_zone_reclaim);
83cond_syscall(sys_inotify_init); 82cond_syscall(sys_inotify_init);
84cond_syscall(sys_inotify_add_watch); 83cond_syscall(sys_inotify_add_watch);
85cond_syscall(sys_inotify_rm_watch); 84cond_syscall(sys_inotify_rm_watch);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 259cf55da3c9..c7e36d4a70ca 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -308,8 +308,6 @@ struct workqueue_struct *__create_workqueue(const char *name,
308 struct workqueue_struct *wq; 308 struct workqueue_struct *wq;
309 struct task_struct *p; 309 struct task_struct *p;
310 310
311 BUG_ON(strlen(name) > 10);
312
313 wq = kmalloc(sizeof(*wq), GFP_KERNEL); 311 wq = kmalloc(sizeof(*wq), GFP_KERNEL);
314 if (!wq) 312 if (!wq)
315 return NULL; 313 return NULL;