diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/nsproxy.c | 15 | ||||
-rw-r--r-- | kernel/signal.c | 46 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 31 | ||||
-rw-r--r-- | kernel/utsname.c | 6 |
4 files changed, 42 insertions, 56 deletions
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index 8e7811086b82..ef42d0ab3115 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -204,20 +204,13 @@ void switch_task_namespaces(struct task_struct *p, struct nsproxy *new) | |||
204 | 204 | ||
205 | might_sleep(); | 205 | might_sleep(); |
206 | 206 | ||
207 | task_lock(p); | ||
207 | ns = p->nsproxy; | 208 | ns = p->nsproxy; |
209 | p->nsproxy = new; | ||
210 | task_unlock(p); | ||
208 | 211 | ||
209 | rcu_assign_pointer(p->nsproxy, new); | 212 | if (ns && atomic_dec_and_test(&ns->count)) |
210 | |||
211 | if (ns && atomic_dec_and_test(&ns->count)) { | ||
212 | /* | ||
213 | * wait for others to get what they want from this nsproxy. | ||
214 | * | ||
215 | * cannot release this nsproxy via the call_rcu() since | ||
216 | * put_mnt_ns() will want to sleep | ||
217 | */ | ||
218 | synchronize_rcu(); | ||
219 | free_nsproxy(ns); | 213 | free_nsproxy(ns); |
220 | } | ||
221 | } | 214 | } |
222 | 215 | ||
223 | void exit_task_namespaces(struct task_struct *p) | 216 | void exit_task_namespaces(struct task_struct *p) |
diff --git a/kernel/signal.c b/kernel/signal.c index 40b76e351e64..8f0876f9f6dd 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -2170,8 +2170,7 @@ static int ptrace_signal(int signr, siginfo_t *info) | |||
2170 | return signr; | 2170 | return signr; |
2171 | } | 2171 | } |
2172 | 2172 | ||
2173 | int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, | 2173 | int get_signal(struct ksignal *ksig) |
2174 | struct pt_regs *regs, void *cookie) | ||
2175 | { | 2174 | { |
2176 | struct sighand_struct *sighand = current->sighand; | 2175 | struct sighand_struct *sighand = current->sighand; |
2177 | struct signal_struct *signal = current->signal; | 2176 | struct signal_struct *signal = current->signal; |
@@ -2241,13 +2240,13 @@ relock: | |||
2241 | goto relock; | 2240 | goto relock; |
2242 | } | 2241 | } |
2243 | 2242 | ||
2244 | signr = dequeue_signal(current, ¤t->blocked, info); | 2243 | signr = dequeue_signal(current, ¤t->blocked, &ksig->info); |
2245 | 2244 | ||
2246 | if (!signr) | 2245 | if (!signr) |
2247 | break; /* will return 0 */ | 2246 | break; /* will return 0 */ |
2248 | 2247 | ||
2249 | if (unlikely(current->ptrace) && signr != SIGKILL) { | 2248 | if (unlikely(current->ptrace) && signr != SIGKILL) { |
2250 | signr = ptrace_signal(signr, info); | 2249 | signr = ptrace_signal(signr, &ksig->info); |
2251 | if (!signr) | 2250 | if (!signr) |
2252 | continue; | 2251 | continue; |
2253 | } | 2252 | } |
@@ -2255,13 +2254,13 @@ relock: | |||
2255 | ka = &sighand->action[signr-1]; | 2254 | ka = &sighand->action[signr-1]; |
2256 | 2255 | ||
2257 | /* Trace actually delivered signals. */ | 2256 | /* Trace actually delivered signals. */ |
2258 | trace_signal_deliver(signr, info, ka); | 2257 | trace_signal_deliver(signr, &ksig->info, ka); |
2259 | 2258 | ||
2260 | if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ | 2259 | if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ |
2261 | continue; | 2260 | continue; |
2262 | if (ka->sa.sa_handler != SIG_DFL) { | 2261 | if (ka->sa.sa_handler != SIG_DFL) { |
2263 | /* Run the handler. */ | 2262 | /* Run the handler. */ |
2264 | *return_ka = *ka; | 2263 | ksig->ka = *ka; |
2265 | 2264 | ||
2266 | if (ka->sa.sa_flags & SA_ONESHOT) | 2265 | if (ka->sa.sa_flags & SA_ONESHOT) |
2267 | ka->sa.sa_handler = SIG_DFL; | 2266 | ka->sa.sa_handler = SIG_DFL; |
@@ -2311,7 +2310,7 @@ relock: | |||
2311 | spin_lock_irq(&sighand->siglock); | 2310 | spin_lock_irq(&sighand->siglock); |
2312 | } | 2311 | } |
2313 | 2312 | ||
2314 | if (likely(do_signal_stop(info->si_signo))) { | 2313 | if (likely(do_signal_stop(ksig->info.si_signo))) { |
2315 | /* It released the siglock. */ | 2314 | /* It released the siglock. */ |
2316 | goto relock; | 2315 | goto relock; |
2317 | } | 2316 | } |
@@ -2332,7 +2331,7 @@ relock: | |||
2332 | 2331 | ||
2333 | if (sig_kernel_coredump(signr)) { | 2332 | if (sig_kernel_coredump(signr)) { |
2334 | if (print_fatal_signals) | 2333 | if (print_fatal_signals) |
2335 | print_fatal_signal(info->si_signo); | 2334 | print_fatal_signal(ksig->info.si_signo); |
2336 | proc_coredump_connector(current); | 2335 | proc_coredump_connector(current); |
2337 | /* | 2336 | /* |
2338 | * If it was able to dump core, this kills all | 2337 | * If it was able to dump core, this kills all |
@@ -2342,34 +2341,32 @@ relock: | |||
2342 | * first and our do_group_exit call below will use | 2341 | * first and our do_group_exit call below will use |
2343 | * that value and ignore the one we pass it. | 2342 | * that value and ignore the one we pass it. |
2344 | */ | 2343 | */ |
2345 | do_coredump(info); | 2344 | do_coredump(&ksig->info); |
2346 | } | 2345 | } |
2347 | 2346 | ||
2348 | /* | 2347 | /* |
2349 | * Death signals, no core dump. | 2348 | * Death signals, no core dump. |
2350 | */ | 2349 | */ |
2351 | do_group_exit(info->si_signo); | 2350 | do_group_exit(ksig->info.si_signo); |
2352 | /* NOTREACHED */ | 2351 | /* NOTREACHED */ |
2353 | } | 2352 | } |
2354 | spin_unlock_irq(&sighand->siglock); | 2353 | spin_unlock_irq(&sighand->siglock); |
2355 | return signr; | 2354 | |
2355 | ksig->sig = signr; | ||
2356 | return ksig->sig > 0; | ||
2356 | } | 2357 | } |
2357 | 2358 | ||
2358 | /** | 2359 | /** |
2359 | * signal_delivered - | 2360 | * signal_delivered - |
2360 | * @sig: number of signal being delivered | 2361 | * @ksig: kernel signal struct |
2361 | * @info: siginfo_t of signal being delivered | ||
2362 | * @ka: sigaction setting that chose the handler | ||
2363 | * @regs: user register state | ||
2364 | * @stepping: nonzero if debugger single-step or block-step in use | 2362 | * @stepping: nonzero if debugger single-step or block-step in use |
2365 | * | 2363 | * |
2366 | * This function should be called when a signal has successfully been | 2364 | * This function should be called when a signal has successfully been |
2367 | * delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask | 2365 | * delivered. It updates the blocked signals accordingly (@ksig->ka.sa.sa_mask |
2368 | * is always blocked, and the signal itself is blocked unless %SA_NODEFER | 2366 | * is always blocked, and the signal itself is blocked unless %SA_NODEFER |
2369 | * is set in @ka->sa.sa_flags. Tracing is notified. | 2367 | * is set in @ksig->ka.sa.sa_flags. Tracing is notified. |
2370 | */ | 2368 | */ |
2371 | void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, | 2369 | static void signal_delivered(struct ksignal *ksig, int stepping) |
2372 | struct pt_regs *regs, int stepping) | ||
2373 | { | 2370 | { |
2374 | sigset_t blocked; | 2371 | sigset_t blocked; |
2375 | 2372 | ||
@@ -2379,11 +2376,11 @@ void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
2379 | simply clear the restore sigmask flag. */ | 2376 | simply clear the restore sigmask flag. */ |
2380 | clear_restore_sigmask(); | 2377 | clear_restore_sigmask(); |
2381 | 2378 | ||
2382 | sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); | 2379 | sigorsets(&blocked, ¤t->blocked, &ksig->ka.sa.sa_mask); |
2383 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 2380 | if (!(ksig->ka.sa.sa_flags & SA_NODEFER)) |
2384 | sigaddset(&blocked, sig); | 2381 | sigaddset(&blocked, ksig->sig); |
2385 | set_current_blocked(&blocked); | 2382 | set_current_blocked(&blocked); |
2386 | tracehook_signal_handler(sig, info, ka, regs, stepping); | 2383 | tracehook_signal_handler(stepping); |
2387 | } | 2384 | } |
2388 | 2385 | ||
2389 | void signal_setup_done(int failed, struct ksignal *ksig, int stepping) | 2386 | void signal_setup_done(int failed, struct ksignal *ksig, int stepping) |
@@ -2391,8 +2388,7 @@ void signal_setup_done(int failed, struct ksignal *ksig, int stepping) | |||
2391 | if (failed) | 2388 | if (failed) |
2392 | force_sigsegv(ksig->sig, current); | 2389 | force_sigsegv(ksig->sig, current); |
2393 | else | 2390 | else |
2394 | signal_delivered(ksig->sig, &ksig->info, &ksig->ka, | 2391 | signal_delivered(ksig, stepping); |
2395 | signal_pt_regs(), stepping); | ||
2396 | } | 2392 | } |
2397 | 2393 | ||
2398 | /* | 2394 | /* |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 925f629658d6..afb04b9b818a 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -1968,7 +1968,7 @@ rb_add_time_stamp(struct ring_buffer_event *event, u64 delta) | |||
1968 | 1968 | ||
1969 | /** | 1969 | /** |
1970 | * rb_update_event - update event type and data | 1970 | * rb_update_event - update event type and data |
1971 | * @event: the even to update | 1971 | * @event: the event to update |
1972 | * @type: the type of event | 1972 | * @type: the type of event |
1973 | * @length: the size of the event field in the ring buffer | 1973 | * @length: the size of the event field in the ring buffer |
1974 | * | 1974 | * |
@@ -3341,21 +3341,16 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) | |||
3341 | struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; | 3341 | struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; |
3342 | 3342 | ||
3343 | /* Iterator usage is expected to have record disabled */ | 3343 | /* Iterator usage is expected to have record disabled */ |
3344 | if (list_empty(&cpu_buffer->reader_page->list)) { | 3344 | iter->head_page = cpu_buffer->reader_page; |
3345 | iter->head_page = rb_set_head_page(cpu_buffer); | 3345 | iter->head = cpu_buffer->reader_page->read; |
3346 | if (unlikely(!iter->head_page)) | 3346 | |
3347 | return; | 3347 | iter->cache_reader_page = iter->head_page; |
3348 | iter->head = iter->head_page->read; | 3348 | iter->cache_read = iter->head; |
3349 | } else { | 3349 | |
3350 | iter->head_page = cpu_buffer->reader_page; | ||
3351 | iter->head = cpu_buffer->reader_page->read; | ||
3352 | } | ||
3353 | if (iter->head) | 3350 | if (iter->head) |
3354 | iter->read_stamp = cpu_buffer->read_stamp; | 3351 | iter->read_stamp = cpu_buffer->read_stamp; |
3355 | else | 3352 | else |
3356 | iter->read_stamp = iter->head_page->page->time_stamp; | 3353 | iter->read_stamp = iter->head_page->page->time_stamp; |
3357 | iter->cache_reader_page = cpu_buffer->reader_page; | ||
3358 | iter->cache_read = cpu_buffer->read; | ||
3359 | } | 3354 | } |
3360 | 3355 | ||
3361 | /** | 3356 | /** |
@@ -3748,12 +3743,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) | |||
3748 | return NULL; | 3743 | return NULL; |
3749 | 3744 | ||
3750 | /* | 3745 | /* |
3751 | * We repeat when a time extend is encountered. | 3746 | * We repeat when a time extend is encountered or we hit |
3752 | * Since the time extend is always attached to a data event, | 3747 | * the end of the page. Since the time extend is always attached |
3753 | * we should never loop more than once. | 3748 | * to a data event, we should never loop more than three times. |
3754 | * (We never hit the following condition more than twice). | 3749 | * Once for going to next page, once on time extend, and |
3750 | * finally once to get the event. | ||
3751 | * (We never hit the following condition more than thrice). | ||
3755 | */ | 3752 | */ |
3756 | if (RB_WARN_ON(cpu_buffer, ++nr_loops > 2)) | 3753 | if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3)) |
3757 | return NULL; | 3754 | return NULL; |
3758 | 3755 | ||
3759 | if (rb_per_cpu_empty(cpu_buffer)) | 3756 | if (rb_per_cpu_empty(cpu_buffer)) |
diff --git a/kernel/utsname.c b/kernel/utsname.c index fd393124e507..883aaaa7de8a 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c | |||
@@ -93,13 +93,13 @@ static void *utsns_get(struct task_struct *task) | |||
93 | struct uts_namespace *ns = NULL; | 93 | struct uts_namespace *ns = NULL; |
94 | struct nsproxy *nsproxy; | 94 | struct nsproxy *nsproxy; |
95 | 95 | ||
96 | rcu_read_lock(); | 96 | task_lock(task); |
97 | nsproxy = task_nsproxy(task); | 97 | nsproxy = task->nsproxy; |
98 | if (nsproxy) { | 98 | if (nsproxy) { |
99 | ns = nsproxy->uts_ns; | 99 | ns = nsproxy->uts_ns; |
100 | get_uts_ns(ns); | 100 | get_uts_ns(ns); |
101 | } | 101 | } |
102 | rcu_read_unlock(); | 102 | task_unlock(task); |
103 | 103 | ||
104 | return ns; | 104 | return ns; |
105 | } | 105 | } |