aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpuset.c24
-rw-r--r--kernel/irq/handle.c2
-rw-r--r--kernel/module.c6
-rw-r--r--kernel/sched.c2
-rw-r--r--kernel/signal.c11
-rw-r--r--kernel/spinlock.c8
6 files changed, 40 insertions, 13 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 961d74044deb..00e8f2575512 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -166,9 +166,8 @@ static struct super_block *cpuset_sb = NULL;
166 * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't 166 * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't
167 * (usually) grab cpuset_sem. These are the two most performance 167 * (usually) grab cpuset_sem. These are the two most performance
168 * critical pieces of code here. The exception occurs on exit(), 168 * critical pieces of code here. The exception occurs on exit(),
169 * if the last task using a cpuset exits, and the cpuset was marked 169 * when a task in a notify_on_release cpuset exits. Then cpuset_sem
170 * notify_on_release. In that case, the cpuset_sem is taken, the 170 * is taken, and if the cpuset count is zero, a usermode call made
171 * path to the released cpuset calculated, and a usermode call made
172 * to /sbin/cpuset_release_agent with the name of the cpuset (path 171 * to /sbin/cpuset_release_agent with the name of the cpuset (path
173 * relative to the root of cpuset file system) as the argument. 172 * relative to the root of cpuset file system) as the argument.
174 * 173 *
@@ -1404,6 +1403,18 @@ void cpuset_fork(struct task_struct *tsk)
1404 * 1403 *
1405 * Description: Detach cpuset from @tsk and release it. 1404 * Description: Detach cpuset from @tsk and release it.
1406 * 1405 *
1406 * Note that cpusets marked notify_on_release force every task
1407 * in them to take the global cpuset_sem semaphore when exiting.
1408 * This could impact scaling on very large systems. Be reluctant
1409 * to use notify_on_release cpusets where very high task exit
1410 * scaling is required on large systems.
1411 *
1412 * Don't even think about derefencing 'cs' after the cpuset use
1413 * count goes to zero, except inside a critical section guarded
1414 * by the cpuset_sem semaphore. If you don't hold cpuset_sem,
1415 * then a zero cpuset use count is a license to any other task to
1416 * nuke the cpuset immediately.
1417 *
1407 **/ 1418 **/
1408 1419
1409void cpuset_exit(struct task_struct *tsk) 1420void cpuset_exit(struct task_struct *tsk)
@@ -1415,10 +1426,13 @@ void cpuset_exit(struct task_struct *tsk)
1415 tsk->cpuset = NULL; 1426 tsk->cpuset = NULL;
1416 task_unlock(tsk); 1427 task_unlock(tsk);
1417 1428
1418 if (atomic_dec_and_test(&cs->count)) { 1429 if (notify_on_release(cs)) {
1419 down(&cpuset_sem); 1430 down(&cpuset_sem);
1420 check_for_release(cs); 1431 if (atomic_dec_and_test(&cs->count))
1432 check_for_release(cs);
1421 up(&cpuset_sem); 1433 up(&cpuset_sem);
1434 } else {
1435 atomic_dec(&cs->count);
1422 } 1436 }
1423} 1437}
1424 1438
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 06b5a6323998..436c7d93c00a 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -119,8 +119,6 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
119 */ 119 */
120 desc->handler->ack(irq); 120 desc->handler->ack(irq);
121 action_ret = handle_IRQ_event(irq, regs, desc->action); 121 action_ret = handle_IRQ_event(irq, regs, desc->action);
122 if (!noirqdebug)
123 note_interrupt(irq, desc, action_ret);
124 desc->handler->end(irq); 122 desc->handler->end(irq);
125 return 1; 123 return 1;
126 } 124 }
diff --git a/kernel/module.c b/kernel/module.c
index 5734ab09d3f9..83b3d376708c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1758,6 +1758,7 @@ sys_init_module(void __user *umod,
1758 const char __user *uargs) 1758 const char __user *uargs)
1759{ 1759{
1760 struct module *mod; 1760 struct module *mod;
1761 mm_segment_t old_fs = get_fs();
1761 int ret = 0; 1762 int ret = 0;
1762 1763
1763 /* Must have permission */ 1764 /* Must have permission */
@@ -1775,6 +1776,9 @@ sys_init_module(void __user *umod,
1775 return PTR_ERR(mod); 1776 return PTR_ERR(mod);
1776 } 1777 }
1777 1778
1779 /* flush the icache in correct context */
1780 set_fs(KERNEL_DS);
1781
1778 /* Flush the instruction cache, since we've played with text */ 1782 /* Flush the instruction cache, since we've played with text */
1779 if (mod->module_init) 1783 if (mod->module_init)
1780 flush_icache_range((unsigned long)mod->module_init, 1784 flush_icache_range((unsigned long)mod->module_init,
@@ -1783,6 +1787,8 @@ sys_init_module(void __user *umod,
1783 flush_icache_range((unsigned long)mod->module_core, 1787 flush_icache_range((unsigned long)mod->module_core,
1784 (unsigned long)mod->module_core + mod->core_size); 1788 (unsigned long)mod->module_core + mod->core_size);
1785 1789
1790 set_fs(old_fs);
1791
1786 /* Now sew it into the lists. They won't access us, since 1792 /* Now sew it into the lists. They won't access us, since
1787 strong_try_module_get() will fail. */ 1793 strong_try_module_get() will fail. */
1788 stop_machine_run(__link_module, mod, NR_CPUS); 1794 stop_machine_run(__link_module, mod, NR_CPUS);
diff --git a/kernel/sched.c b/kernel/sched.c
index 0dc3158667a2..66b2ed784822 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4243,7 +4243,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *tsk)
4243 4243
4244 /* No more Mr. Nice Guy. */ 4244 /* No more Mr. Nice Guy. */
4245 if (dest_cpu == NR_CPUS) { 4245 if (dest_cpu == NR_CPUS) {
4246 tsk->cpus_allowed = cpuset_cpus_allowed(tsk); 4246 cpus_setall(tsk->cpus_allowed);
4247 dest_cpu = any_online_cpu(tsk->cpus_allowed); 4247 dest_cpu = any_online_cpu(tsk->cpus_allowed);
4248 4248
4249 /* 4249 /*
diff --git a/kernel/signal.c b/kernel/signal.c
index 293e189d8bc3..c89821b69ae3 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -523,7 +523,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
523{ 523{
524 int sig = 0; 524 int sig = 0;
525 525
526 sig = next_signal(pending, mask); 526 /* SIGKILL must have priority, otherwise it is quite easy
527 * to create an unkillable process, sending sig < SIGKILL
528 * to self */
529 if (unlikely(sigismember(&pending->signal, SIGKILL))) {
530 if (!sigismember(mask, SIGKILL))
531 sig = SIGKILL;
532 }
533
534 if (likely(!sig))
535 sig = next_signal(pending, mask);
527 if (sig) { 536 if (sig) {
528 if (current->notifier) { 537 if (current->notifier) {
529 if (sigismember(current->notifier_mask, sig)) { 538 if (sigismember(current->notifier_mask, sig)) {
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index e15ed17863f1..0c3f9d8bbe17 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -294,7 +294,7 @@ EXPORT_SYMBOL(_spin_unlock_irq);
294void __lockfunc _spin_unlock_bh(spinlock_t *lock) 294void __lockfunc _spin_unlock_bh(spinlock_t *lock)
295{ 295{
296 _raw_spin_unlock(lock); 296 _raw_spin_unlock(lock);
297 preempt_enable(); 297 preempt_enable_no_resched();
298 local_bh_enable(); 298 local_bh_enable();
299} 299}
300EXPORT_SYMBOL(_spin_unlock_bh); 300EXPORT_SYMBOL(_spin_unlock_bh);
@@ -318,7 +318,7 @@ EXPORT_SYMBOL(_read_unlock_irq);
318void __lockfunc _read_unlock_bh(rwlock_t *lock) 318void __lockfunc _read_unlock_bh(rwlock_t *lock)
319{ 319{
320 _raw_read_unlock(lock); 320 _raw_read_unlock(lock);
321 preempt_enable(); 321 preempt_enable_no_resched();
322 local_bh_enable(); 322 local_bh_enable();
323} 323}
324EXPORT_SYMBOL(_read_unlock_bh); 324EXPORT_SYMBOL(_read_unlock_bh);
@@ -342,7 +342,7 @@ EXPORT_SYMBOL(_write_unlock_irq);
342void __lockfunc _write_unlock_bh(rwlock_t *lock) 342void __lockfunc _write_unlock_bh(rwlock_t *lock)
343{ 343{
344 _raw_write_unlock(lock); 344 _raw_write_unlock(lock);
345 preempt_enable(); 345 preempt_enable_no_resched();
346 local_bh_enable(); 346 local_bh_enable();
347} 347}
348EXPORT_SYMBOL(_write_unlock_bh); 348EXPORT_SYMBOL(_write_unlock_bh);
@@ -354,7 +354,7 @@ int __lockfunc _spin_trylock_bh(spinlock_t *lock)
354 if (_raw_spin_trylock(lock)) 354 if (_raw_spin_trylock(lock))
355 return 1; 355 return 1;
356 356
357 preempt_enable(); 357 preempt_enable_no_resched();
358 local_bh_enable(); 358 local_bh_enable();
359 return 0; 359 return 0;
360} 360}