diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/async.c | 12 | ||||
| -rw-r--r-- | kernel/fork.c | 1 | ||||
| -rw-r--r-- | kernel/irq/numa_migrate.c | 7 | ||||
| -rw-r--r-- | kernel/sched.c | 4 | ||||
| -rw-r--r-- | kernel/sys.c | 16 | ||||
| -rw-r--r-- | kernel/time/clockevents.c | 20 | ||||
| -rw-r--r-- | kernel/trace/ftrace.c | 5 | ||||
| -rw-r--r-- | kernel/wait.c | 59 |
8 files changed, 89 insertions, 35 deletions
diff --git a/kernel/async.c b/kernel/async.c index 608b32b42812..67a2be71f517 100644 --- a/kernel/async.c +++ b/kernel/async.c | |||
| @@ -138,15 +138,18 @@ static void run_one_entry(void) | |||
| 138 | 138 | ||
| 139 | /* 3) run it (and print duration)*/ | 139 | /* 3) run it (and print duration)*/ |
| 140 | if (initcall_debug && system_state == SYSTEM_BOOTING) { | 140 | if (initcall_debug && system_state == SYSTEM_BOOTING) { |
| 141 | printk("calling %lli_%pF @ %i\n", entry->cookie, entry->func, task_pid_nr(current)); | 141 | printk("calling %lli_%pF @ %i\n", (long long)entry->cookie, |
| 142 | entry->func, task_pid_nr(current)); | ||
| 142 | calltime = ktime_get(); | 143 | calltime = ktime_get(); |
| 143 | } | 144 | } |
| 144 | entry->func(entry->data, entry->cookie); | 145 | entry->func(entry->data, entry->cookie); |
| 145 | if (initcall_debug && system_state == SYSTEM_BOOTING) { | 146 | if (initcall_debug && system_state == SYSTEM_BOOTING) { |
| 146 | rettime = ktime_get(); | 147 | rettime = ktime_get(); |
| 147 | delta = ktime_sub(rettime, calltime); | 148 | delta = ktime_sub(rettime, calltime); |
| 148 | printk("initcall %lli_%pF returned 0 after %lld usecs\n", entry->cookie, | 149 | printk("initcall %lli_%pF returned 0 after %lld usecs\n", |
| 149 | entry->func, ktime_to_ns(delta) >> 10); | 150 | (long long)entry->cookie, |
| 151 | entry->func, | ||
| 152 | (long long)ktime_to_ns(delta) >> 10); | ||
| 150 | } | 153 | } |
| 151 | 154 | ||
| 152 | /* 4) remove it from the running queue */ | 155 | /* 4) remove it from the running queue */ |
| @@ -247,7 +250,8 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r | |||
| 247 | delta = ktime_sub(endtime, starttime); | 250 | delta = ktime_sub(endtime, starttime); |
| 248 | 251 | ||
| 249 | printk("async_continuing @ %i after %lli usec\n", | 252 | printk("async_continuing @ %i after %lli usec\n", |
| 250 | task_pid_nr(current), ktime_to_ns(delta) >> 10); | 253 | task_pid_nr(current), |
| 254 | (long long)ktime_to_ns(delta) >> 10); | ||
| 251 | } | 255 | } |
| 252 | } | 256 | } |
| 253 | EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); | 257 | EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); |
diff --git a/kernel/fork.c b/kernel/fork.c index e8e854a04ad2..bb5fe56a7a9c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -1006,6 +1006,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1006 | * triggers too late. This doesn't hurt, the check is only there | 1006 | * triggers too late. This doesn't hurt, the check is only there |
| 1007 | * to stop root fork bombs. | 1007 | * to stop root fork bombs. |
| 1008 | */ | 1008 | */ |
| 1009 | retval = -EAGAIN; | ||
| 1009 | if (nr_threads >= max_threads) | 1010 | if (nr_threads >= max_threads) |
| 1010 | goto bad_fork_cleanup_count; | 1011 | goto bad_fork_cleanup_count; |
| 1011 | 1012 | ||
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c index ecf765c6a77a..acd88356ac76 100644 --- a/kernel/irq/numa_migrate.c +++ b/kernel/irq/numa_migrate.c | |||
| @@ -71,7 +71,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
| 71 | desc = irq_desc_ptrs[irq]; | 71 | desc = irq_desc_ptrs[irq]; |
| 72 | 72 | ||
| 73 | if (desc && old_desc != desc) | 73 | if (desc && old_desc != desc) |
| 74 | goto out_unlock; | 74 | goto out_unlock; |
| 75 | 75 | ||
| 76 | node = cpu_to_node(cpu); | 76 | node = cpu_to_node(cpu); |
| 77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); | 77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); |
| @@ -84,10 +84,15 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
| 84 | init_copy_one_irq_desc(irq, old_desc, desc, cpu); | 84 | init_copy_one_irq_desc(irq, old_desc, desc, cpu); |
| 85 | 85 | ||
| 86 | irq_desc_ptrs[irq] = desc; | 86 | irq_desc_ptrs[irq] = desc; |
| 87 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | ||
| 87 | 88 | ||
| 88 | /* free the old one */ | 89 | /* free the old one */ |
| 89 | free_one_irq_desc(old_desc, desc); | 90 | free_one_irq_desc(old_desc, desc); |
| 91 | spin_unlock(&old_desc->lock); | ||
| 90 | kfree(old_desc); | 92 | kfree(old_desc); |
| 93 | spin_lock(&desc->lock); | ||
| 94 | |||
| 95 | return desc; | ||
| 91 | 96 | ||
| 92 | out_unlock: | 97 | out_unlock: |
| 93 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | 98 | spin_unlock_irqrestore(&sparse_irq_lock, flags); |
diff --git a/kernel/sched.c b/kernel/sched.c index e1fc67d0674c..e72485033c48 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -4702,8 +4702,8 @@ EXPORT_SYMBOL(default_wake_function); | |||
| 4702 | * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns | 4702 | * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns |
| 4703 | * zero in this (rare) case, and we handle it by continuing to scan the queue. | 4703 | * zero in this (rare) case, and we handle it by continuing to scan the queue. |
| 4704 | */ | 4704 | */ |
| 4705 | static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, | 4705 | void __wake_up_common(wait_queue_head_t *q, unsigned int mode, |
| 4706 | int nr_exclusive, int sync, void *key) | 4706 | int nr_exclusive, int sync, void *key) |
| 4707 | { | 4707 | { |
| 4708 | wait_queue_t *curr, *next; | 4708 | wait_queue_t *curr, *next; |
| 4709 | 4709 | ||
diff --git a/kernel/sys.c b/kernel/sys.c index e7dc0e10a485..f145c415bc16 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1525,22 +1525,14 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) | |||
| 1525 | return -EINVAL; | 1525 | return -EINVAL; |
| 1526 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) | 1526 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) |
| 1527 | return -EFAULT; | 1527 | return -EFAULT; |
| 1528 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
| 1529 | return -EINVAL; | ||
| 1528 | old_rlim = current->signal->rlim + resource; | 1530 | old_rlim = current->signal->rlim + resource; |
| 1529 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && | 1531 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && |
| 1530 | !capable(CAP_SYS_RESOURCE)) | 1532 | !capable(CAP_SYS_RESOURCE)) |
| 1531 | return -EPERM; | 1533 | return -EPERM; |
| 1532 | 1534 | if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) | |
| 1533 | if (resource == RLIMIT_NOFILE) { | 1535 | return -EPERM; |
| 1534 | if (new_rlim.rlim_max == RLIM_INFINITY) | ||
| 1535 | new_rlim.rlim_max = sysctl_nr_open; | ||
| 1536 | if (new_rlim.rlim_cur == RLIM_INFINITY) | ||
| 1537 | new_rlim.rlim_cur = sysctl_nr_open; | ||
| 1538 | if (new_rlim.rlim_max > sysctl_nr_open) | ||
| 1539 | return -EPERM; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
| 1543 | return -EINVAL; | ||
| 1544 | 1536 | ||
| 1545 | retval = security_task_setrlimit(resource, &new_rlim); | 1537 | retval = security_task_setrlimit(resource, &new_rlim); |
| 1546 | if (retval) | 1538 | if (retval) |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index ea2f48af83cf..d13be216a790 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
| @@ -68,6 +68,17 @@ void clockevents_set_mode(struct clock_event_device *dev, | |||
| 68 | if (dev->mode != mode) { | 68 | if (dev->mode != mode) { |
| 69 | dev->set_mode(mode, dev); | 69 | dev->set_mode(mode, dev); |
| 70 | dev->mode = mode; | 70 | dev->mode = mode; |
| 71 | |||
| 72 | /* | ||
| 73 | * A nsec2cyc multiplicator of 0 is invalid and we'd crash | ||
| 74 | * on it, so fix it up and emit a warning: | ||
| 75 | */ | ||
| 76 | if (mode == CLOCK_EVT_MODE_ONESHOT) { | ||
| 77 | if (unlikely(!dev->mult)) { | ||
| 78 | dev->mult = 1; | ||
| 79 | WARN_ON(1); | ||
| 80 | } | ||
| 81 | } | ||
| 71 | } | 82 | } |
| 72 | } | 83 | } |
| 73 | 84 | ||
| @@ -168,15 +179,6 @@ void clockevents_register_device(struct clock_event_device *dev) | |||
| 168 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); | 179 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); |
| 169 | BUG_ON(!dev->cpumask); | 180 | BUG_ON(!dev->cpumask); |
| 170 | 181 | ||
| 171 | /* | ||
| 172 | * A nsec2cyc multiplicator of 0 is invalid and we'd crash | ||
| 173 | * on it, so fix it up and emit a warning: | ||
| 174 | */ | ||
| 175 | if (unlikely(!dev->mult)) { | ||
| 176 | dev->mult = 1; | ||
| 177 | WARN_ON(1); | ||
| 178 | } | ||
| 179 | |||
| 180 | spin_lock(&clockevents_lock); | 182 | spin_lock(&clockevents_lock); |
| 181 | 183 | ||
| 182 | list_add(&dev->list, &clockevent_devices); | 184 | list_add(&dev->list, &clockevent_devices); |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 7dcf6e9f2b04..9a236ffe2aa4 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -1737,9 +1737,12 @@ static void clear_ftrace_pid(struct pid *pid) | |||
| 1737 | { | 1737 | { |
| 1738 | struct task_struct *p; | 1738 | struct task_struct *p; |
| 1739 | 1739 | ||
| 1740 | rcu_read_lock(); | ||
| 1740 | do_each_pid_task(pid, PIDTYPE_PID, p) { | 1741 | do_each_pid_task(pid, PIDTYPE_PID, p) { |
| 1741 | clear_tsk_trace_trace(p); | 1742 | clear_tsk_trace_trace(p); |
| 1742 | } while_each_pid_task(pid, PIDTYPE_PID, p); | 1743 | } while_each_pid_task(pid, PIDTYPE_PID, p); |
| 1744 | rcu_read_unlock(); | ||
| 1745 | |||
| 1743 | put_pid(pid); | 1746 | put_pid(pid); |
| 1744 | } | 1747 | } |
| 1745 | 1748 | ||
| @@ -1747,9 +1750,11 @@ static void set_ftrace_pid(struct pid *pid) | |||
| 1747 | { | 1750 | { |
| 1748 | struct task_struct *p; | 1751 | struct task_struct *p; |
| 1749 | 1752 | ||
| 1753 | rcu_read_lock(); | ||
| 1750 | do_each_pid_task(pid, PIDTYPE_PID, p) { | 1754 | do_each_pid_task(pid, PIDTYPE_PID, p) { |
| 1751 | set_tsk_trace_trace(p); | 1755 | set_tsk_trace_trace(p); |
| 1752 | } while_each_pid_task(pid, PIDTYPE_PID, p); | 1756 | } while_each_pid_task(pid, PIDTYPE_PID, p); |
| 1757 | rcu_read_unlock(); | ||
| 1753 | } | 1758 | } |
| 1754 | 1759 | ||
| 1755 | static void clear_ftrace_pid_task(struct pid **pid) | 1760 | static void clear_ftrace_pid_task(struct pid **pid) |
diff --git a/kernel/wait.c b/kernel/wait.c index cd87131f2fc2..42a2dbc181c8 100644 --- a/kernel/wait.c +++ b/kernel/wait.c | |||
| @@ -91,6 +91,15 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state) | |||
| 91 | } | 91 | } |
| 92 | EXPORT_SYMBOL(prepare_to_wait_exclusive); | 92 | EXPORT_SYMBOL(prepare_to_wait_exclusive); |
| 93 | 93 | ||
| 94 | /* | ||
| 95 | * finish_wait - clean up after waiting in a queue | ||
| 96 | * @q: waitqueue waited on | ||
| 97 | * @wait: wait descriptor | ||
| 98 | * | ||
| 99 | * Sets current thread back to running state and removes | ||
| 100 | * the wait descriptor from the given waitqueue if still | ||
| 101 | * queued. | ||
| 102 | */ | ||
| 94 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) | 103 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
| 95 | { | 104 | { |
| 96 | unsigned long flags; | 105 | unsigned long flags; |
| @@ -117,6 +126,39 @@ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) | |||
| 117 | } | 126 | } |
| 118 | EXPORT_SYMBOL(finish_wait); | 127 | EXPORT_SYMBOL(finish_wait); |
| 119 | 128 | ||
| 129 | /* | ||
| 130 | * abort_exclusive_wait - abort exclusive waiting in a queue | ||
| 131 | * @q: waitqueue waited on | ||
| 132 | * @wait: wait descriptor | ||
| 133 | * @state: runstate of the waiter to be woken | ||
| 134 | * @key: key to identify a wait bit queue or %NULL | ||
| 135 | * | ||
| 136 | * Sets current thread back to running state and removes | ||
| 137 | * the wait descriptor from the given waitqueue if still | ||
| 138 | * queued. | ||
| 139 | * | ||
| 140 | * Wakes up the next waiter if the caller is concurrently | ||
| 141 | * woken up through the queue. | ||
| 142 | * | ||
| 143 | * This prevents waiter starvation where an exclusive waiter | ||
| 144 | * aborts and is woken up concurrently and noone wakes up | ||
| 145 | * the next waiter. | ||
| 146 | */ | ||
| 147 | void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, | ||
| 148 | unsigned int mode, void *key) | ||
| 149 | { | ||
| 150 | unsigned long flags; | ||
| 151 | |||
| 152 | __set_current_state(TASK_RUNNING); | ||
| 153 | spin_lock_irqsave(&q->lock, flags); | ||
| 154 | if (!list_empty(&wait->task_list)) | ||
| 155 | list_del_init(&wait->task_list); | ||
| 156 | else if (waitqueue_active(q)) | ||
| 157 | __wake_up_common(q, mode, 1, 0, key); | ||
| 158 | spin_unlock_irqrestore(&q->lock, flags); | ||
| 159 | } | ||
| 160 | EXPORT_SYMBOL(abort_exclusive_wait); | ||
| 161 | |||
| 120 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) | 162 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
| 121 | { | 163 | { |
| 122 | int ret = default_wake_function(wait, mode, sync, key); | 164 | int ret = default_wake_function(wait, mode, sync, key); |
| @@ -177,17 +219,20 @@ int __sched | |||
| 177 | __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, | 219 | __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, |
| 178 | int (*action)(void *), unsigned mode) | 220 | int (*action)(void *), unsigned mode) |
| 179 | { | 221 | { |
| 180 | int ret = 0; | ||
| 181 | |||
| 182 | do { | 222 | do { |
| 223 | int ret; | ||
| 224 | |||
| 183 | prepare_to_wait_exclusive(wq, &q->wait, mode); | 225 | prepare_to_wait_exclusive(wq, &q->wait, mode); |
| 184 | if (test_bit(q->key.bit_nr, q->key.flags)) { | 226 | if (!test_bit(q->key.bit_nr, q->key.flags)) |
| 185 | if ((ret = (*action)(q->key.flags))) | 227 | continue; |
| 186 | break; | 228 | ret = action(q->key.flags); |
| 187 | } | 229 | if (!ret) |
| 230 | continue; | ||
| 231 | abort_exclusive_wait(wq, &q->wait, mode, &q->key); | ||
| 232 | return ret; | ||
| 188 | } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); | 233 | } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); |
| 189 | finish_wait(wq, &q->wait); | 234 | finish_wait(wq, &q->wait); |
| 190 | return ret; | 235 | return 0; |
| 191 | } | 236 | } |
| 192 | EXPORT_SYMBOL(__wait_on_bit_lock); | 237 | EXPORT_SYMBOL(__wait_on_bit_lock); |
| 193 | 238 | ||
