diff options
author | Tejun Heo <tj@kernel.org> | 2013-06-13 22:38:26 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-06-13 22:42:22 -0400 |
commit | 2b0e53a7c8a6972755c0f0152d7fad2289fdc5eb (patch) | |
tree | bf427cbe4b9d85cd5651b01f2f18668e8d12ed45 /kernel | |
parent | ea15f8ccdb430af1e8bc9b4e19a230eb4c356777 (diff) | |
parent | dbece3a0f1ef0b19aff1cc6ed0942fec9ab98de1 (diff) |
Merge branch 'for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu into for-3.11
This is to receive percpu_refcount which will replace atomic_t
reference count in cgroup_subsys_state.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditfilter.c | 3 | ||||
-rw-r--r-- | kernel/cgroup.c | 13 | ||||
-rw-r--r-- | kernel/cpu/idle.c | 2 | ||||
-rw-r--r-- | kernel/events/core.c | 240 | ||||
-rw-r--r-- | kernel/kmod.c | 5 | ||||
-rw-r--r-- | kernel/module.c | 21 | ||||
-rw-r--r-- | kernel/range.c | 8 | ||||
-rw-r--r-- | kernel/rcutree_plugin.h | 4 | ||||
-rw-r--r-- | kernel/time/Kconfig | 5 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 10 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 3 | ||||
-rw-r--r-- | kernel/timer.c | 2 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 3 | ||||
-rw-r--r-- | kernel/trace/trace.c | 9 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 53 | ||||
-rw-r--r-- | kernel/workqueue.c | 19 |
18 files changed, 195 insertions, 213 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 83a2970295d1..6bd4a90d1991 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -1021,9 +1021,6 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re | |||
1021 | * @seq: netlink audit message sequence (serial) number | 1021 | * @seq: netlink audit message sequence (serial) number |
1022 | * @data: payload data | 1022 | * @data: payload data |
1023 | * @datasz: size of payload data | 1023 | * @datasz: size of payload data |
1024 | * @loginuid: loginuid of sender | ||
1025 | * @sessionid: sessionid for netlink audit message | ||
1026 | * @sid: SE Linux Security ID of sender | ||
1027 | */ | 1024 | */ |
1028 | int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz) | 1025 | int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz) |
1029 | { | 1026 | { |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index df6814706cca..ebbfc043153f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1688,11 +1688,14 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, | |||
1688 | */ | 1688 | */ |
1689 | cgroup_free_root(opts.new_root); | 1689 | cgroup_free_root(opts.new_root); |
1690 | 1690 | ||
1691 | if (((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) && | 1691 | if (root->flags != opts.flags) { |
1692 | root->flags != opts.flags) { | 1692 | if ((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) { |
1693 | pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n"); | 1693 | pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n"); |
1694 | ret = -EINVAL; | 1694 | ret = -EINVAL; |
1695 | goto drop_new_super; | 1695 | goto drop_new_super; |
1696 | } else { | ||
1697 | pr_warning("cgroup: new mount options do not match the existing superblock, will be ignored\n"); | ||
1698 | } | ||
1696 | } | 1699 | } |
1697 | 1700 | ||
1698 | /* no subsys rebinding, so refcounts don't change */ | 1701 | /* no subsys rebinding, so refcounts don't change */ |
diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c index 8b86c0c68edf..d5585f5e038e 100644 --- a/kernel/cpu/idle.c +++ b/kernel/cpu/idle.c | |||
@@ -40,11 +40,13 @@ __setup("hlt", cpu_idle_nopoll_setup); | |||
40 | 40 | ||
41 | static inline int cpu_idle_poll(void) | 41 | static inline int cpu_idle_poll(void) |
42 | { | 42 | { |
43 | rcu_idle_enter(); | ||
43 | trace_cpu_idle_rcuidle(0, smp_processor_id()); | 44 | trace_cpu_idle_rcuidle(0, smp_processor_id()); |
44 | local_irq_enable(); | 45 | local_irq_enable(); |
45 | while (!need_resched()) | 46 | while (!need_resched()) |
46 | cpu_relax(); | 47 | cpu_relax(); |
47 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); | 48 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); |
49 | rcu_idle_exit(); | ||
48 | return 1; | 50 | return 1; |
49 | } | 51 | } |
50 | 52 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index 6b41c1899a8b..9dc297faf7c0 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -4394,6 +4394,64 @@ perf_event_read_event(struct perf_event *event, | |||
4394 | perf_output_end(&handle); | 4394 | perf_output_end(&handle); |
4395 | } | 4395 | } |
4396 | 4396 | ||
4397 | typedef int (perf_event_aux_match_cb)(struct perf_event *event, void *data); | ||
4398 | typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data); | ||
4399 | |||
4400 | static void | ||
4401 | perf_event_aux_ctx(struct perf_event_context *ctx, | ||
4402 | perf_event_aux_match_cb match, | ||
4403 | perf_event_aux_output_cb output, | ||
4404 | void *data) | ||
4405 | { | ||
4406 | struct perf_event *event; | ||
4407 | |||
4408 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { | ||
4409 | if (event->state < PERF_EVENT_STATE_INACTIVE) | ||
4410 | continue; | ||
4411 | if (!event_filter_match(event)) | ||
4412 | continue; | ||
4413 | if (match(event, data)) | ||
4414 | output(event, data); | ||
4415 | } | ||
4416 | } | ||
4417 | |||
4418 | static void | ||
4419 | perf_event_aux(perf_event_aux_match_cb match, | ||
4420 | perf_event_aux_output_cb output, | ||
4421 | void *data, | ||
4422 | struct perf_event_context *task_ctx) | ||
4423 | { | ||
4424 | struct perf_cpu_context *cpuctx; | ||
4425 | struct perf_event_context *ctx; | ||
4426 | struct pmu *pmu; | ||
4427 | int ctxn; | ||
4428 | |||
4429 | rcu_read_lock(); | ||
4430 | list_for_each_entry_rcu(pmu, &pmus, entry) { | ||
4431 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | ||
4432 | if (cpuctx->unique_pmu != pmu) | ||
4433 | goto next; | ||
4434 | perf_event_aux_ctx(&cpuctx->ctx, match, output, data); | ||
4435 | if (task_ctx) | ||
4436 | goto next; | ||
4437 | ctxn = pmu->task_ctx_nr; | ||
4438 | if (ctxn < 0) | ||
4439 | goto next; | ||
4440 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
4441 | if (ctx) | ||
4442 | perf_event_aux_ctx(ctx, match, output, data); | ||
4443 | next: | ||
4444 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
4445 | } | ||
4446 | |||
4447 | if (task_ctx) { | ||
4448 | preempt_disable(); | ||
4449 | perf_event_aux_ctx(task_ctx, match, output, data); | ||
4450 | preempt_enable(); | ||
4451 | } | ||
4452 | rcu_read_unlock(); | ||
4453 | } | ||
4454 | |||
4397 | /* | 4455 | /* |
4398 | * task tracking -- fork/exit | 4456 | * task tracking -- fork/exit |
4399 | * | 4457 | * |
@@ -4416,8 +4474,9 @@ struct perf_task_event { | |||
4416 | }; | 4474 | }; |
4417 | 4475 | ||
4418 | static void perf_event_task_output(struct perf_event *event, | 4476 | static void perf_event_task_output(struct perf_event *event, |
4419 | struct perf_task_event *task_event) | 4477 | void *data) |
4420 | { | 4478 | { |
4479 | struct perf_task_event *task_event = data; | ||
4421 | struct perf_output_handle handle; | 4480 | struct perf_output_handle handle; |
4422 | struct perf_sample_data sample; | 4481 | struct perf_sample_data sample; |
4423 | struct task_struct *task = task_event->task; | 4482 | struct task_struct *task = task_event->task; |
@@ -4445,62 +4504,11 @@ out: | |||
4445 | task_event->event_id.header.size = size; | 4504 | task_event->event_id.header.size = size; |
4446 | } | 4505 | } |
4447 | 4506 | ||
4448 | static int perf_event_task_match(struct perf_event *event) | 4507 | static int perf_event_task_match(struct perf_event *event, |
4449 | { | 4508 | void *data __maybe_unused) |
4450 | if (event->state < PERF_EVENT_STATE_INACTIVE) | ||
4451 | return 0; | ||
4452 | |||
4453 | if (!event_filter_match(event)) | ||
4454 | return 0; | ||
4455 | |||
4456 | if (event->attr.comm || event->attr.mmap || | ||
4457 | event->attr.mmap_data || event->attr.task) | ||
4458 | return 1; | ||
4459 | |||
4460 | return 0; | ||
4461 | } | ||
4462 | |||
4463 | static void perf_event_task_ctx(struct perf_event_context *ctx, | ||
4464 | struct perf_task_event *task_event) | ||
4465 | { | 4509 | { |
4466 | struct perf_event *event; | 4510 | return event->attr.comm || event->attr.mmap || |
4467 | 4511 | event->attr.mmap_data || event->attr.task; | |
4468 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { | ||
4469 | if (perf_event_task_match(event)) | ||
4470 | perf_event_task_output(event, task_event); | ||
4471 | } | ||
4472 | } | ||
4473 | |||
4474 | static void perf_event_task_event(struct perf_task_event *task_event) | ||
4475 | { | ||
4476 | struct perf_cpu_context *cpuctx; | ||
4477 | struct perf_event_context *ctx; | ||
4478 | struct pmu *pmu; | ||
4479 | int ctxn; | ||
4480 | |||
4481 | rcu_read_lock(); | ||
4482 | list_for_each_entry_rcu(pmu, &pmus, entry) { | ||
4483 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | ||
4484 | if (cpuctx->unique_pmu != pmu) | ||
4485 | goto next; | ||
4486 | perf_event_task_ctx(&cpuctx->ctx, task_event); | ||
4487 | |||
4488 | ctx = task_event->task_ctx; | ||
4489 | if (!ctx) { | ||
4490 | ctxn = pmu->task_ctx_nr; | ||
4491 | if (ctxn < 0) | ||
4492 | goto next; | ||
4493 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
4494 | if (ctx) | ||
4495 | perf_event_task_ctx(ctx, task_event); | ||
4496 | } | ||
4497 | next: | ||
4498 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
4499 | } | ||
4500 | if (task_event->task_ctx) | ||
4501 | perf_event_task_ctx(task_event->task_ctx, task_event); | ||
4502 | |||
4503 | rcu_read_unlock(); | ||
4504 | } | 4512 | } |
4505 | 4513 | ||
4506 | static void perf_event_task(struct task_struct *task, | 4514 | static void perf_event_task(struct task_struct *task, |
@@ -4531,7 +4539,10 @@ static void perf_event_task(struct task_struct *task, | |||
4531 | }, | 4539 | }, |
4532 | }; | 4540 | }; |
4533 | 4541 | ||
4534 | perf_event_task_event(&task_event); | 4542 | perf_event_aux(perf_event_task_match, |
4543 | perf_event_task_output, | ||
4544 | &task_event, | ||
4545 | task_ctx); | ||
4535 | } | 4546 | } |
4536 | 4547 | ||
4537 | void perf_event_fork(struct task_struct *task) | 4548 | void perf_event_fork(struct task_struct *task) |
@@ -4557,8 +4568,9 @@ struct perf_comm_event { | |||
4557 | }; | 4568 | }; |
4558 | 4569 | ||
4559 | static void perf_event_comm_output(struct perf_event *event, | 4570 | static void perf_event_comm_output(struct perf_event *event, |
4560 | struct perf_comm_event *comm_event) | 4571 | void *data) |
4561 | { | 4572 | { |
4573 | struct perf_comm_event *comm_event = data; | ||
4562 | struct perf_output_handle handle; | 4574 | struct perf_output_handle handle; |
4563 | struct perf_sample_data sample; | 4575 | struct perf_sample_data sample; |
4564 | int size = comm_event->event_id.header.size; | 4576 | int size = comm_event->event_id.header.size; |
@@ -4585,39 +4597,16 @@ out: | |||
4585 | comm_event->event_id.header.size = size; | 4597 | comm_event->event_id.header.size = size; |
4586 | } | 4598 | } |
4587 | 4599 | ||
4588 | static int perf_event_comm_match(struct perf_event *event) | 4600 | static int perf_event_comm_match(struct perf_event *event, |
4589 | { | 4601 | void *data __maybe_unused) |
4590 | if (event->state < PERF_EVENT_STATE_INACTIVE) | ||
4591 | return 0; | ||
4592 | |||
4593 | if (!event_filter_match(event)) | ||
4594 | return 0; | ||
4595 | |||
4596 | if (event->attr.comm) | ||
4597 | return 1; | ||
4598 | |||
4599 | return 0; | ||
4600 | } | ||
4601 | |||
4602 | static void perf_event_comm_ctx(struct perf_event_context *ctx, | ||
4603 | struct perf_comm_event *comm_event) | ||
4604 | { | 4602 | { |
4605 | struct perf_event *event; | 4603 | return event->attr.comm; |
4606 | |||
4607 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { | ||
4608 | if (perf_event_comm_match(event)) | ||
4609 | perf_event_comm_output(event, comm_event); | ||
4610 | } | ||
4611 | } | 4604 | } |
4612 | 4605 | ||
4613 | static void perf_event_comm_event(struct perf_comm_event *comm_event) | 4606 | static void perf_event_comm_event(struct perf_comm_event *comm_event) |
4614 | { | 4607 | { |
4615 | struct perf_cpu_context *cpuctx; | ||
4616 | struct perf_event_context *ctx; | ||
4617 | char comm[TASK_COMM_LEN]; | 4608 | char comm[TASK_COMM_LEN]; |
4618 | unsigned int size; | 4609 | unsigned int size; |
4619 | struct pmu *pmu; | ||
4620 | int ctxn; | ||
4621 | 4610 | ||
4622 | memset(comm, 0, sizeof(comm)); | 4611 | memset(comm, 0, sizeof(comm)); |
4623 | strlcpy(comm, comm_event->task->comm, sizeof(comm)); | 4612 | strlcpy(comm, comm_event->task->comm, sizeof(comm)); |
@@ -4627,24 +4616,11 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) | |||
4627 | comm_event->comm_size = size; | 4616 | comm_event->comm_size = size; |
4628 | 4617 | ||
4629 | comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; | 4618 | comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; |
4630 | rcu_read_lock(); | ||
4631 | list_for_each_entry_rcu(pmu, &pmus, entry) { | ||
4632 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | ||
4633 | if (cpuctx->unique_pmu != pmu) | ||
4634 | goto next; | ||
4635 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); | ||
4636 | 4619 | ||
4637 | ctxn = pmu->task_ctx_nr; | 4620 | perf_event_aux(perf_event_comm_match, |
4638 | if (ctxn < 0) | 4621 | perf_event_comm_output, |
4639 | goto next; | 4622 | comm_event, |
4640 | 4623 | NULL); | |
4641 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
4642 | if (ctx) | ||
4643 | perf_event_comm_ctx(ctx, comm_event); | ||
4644 | next: | ||
4645 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
4646 | } | ||
4647 | rcu_read_unlock(); | ||
4648 | } | 4624 | } |
4649 | 4625 | ||
4650 | void perf_event_comm(struct task_struct *task) | 4626 | void perf_event_comm(struct task_struct *task) |
@@ -4706,8 +4682,9 @@ struct perf_mmap_event { | |||
4706 | }; | 4682 | }; |
4707 | 4683 | ||
4708 | static void perf_event_mmap_output(struct perf_event *event, | 4684 | static void perf_event_mmap_output(struct perf_event *event, |
4709 | struct perf_mmap_event *mmap_event) | 4685 | void *data) |
4710 | { | 4686 | { |
4687 | struct perf_mmap_event *mmap_event = data; | ||
4711 | struct perf_output_handle handle; | 4688 | struct perf_output_handle handle; |
4712 | struct perf_sample_data sample; | 4689 | struct perf_sample_data sample; |
4713 | int size = mmap_event->event_id.header.size; | 4690 | int size = mmap_event->event_id.header.size; |
@@ -4734,46 +4711,24 @@ out: | |||
4734 | } | 4711 | } |
4735 | 4712 | ||
4736 | static int perf_event_mmap_match(struct perf_event *event, | 4713 | static int perf_event_mmap_match(struct perf_event *event, |
4737 | struct perf_mmap_event *mmap_event, | 4714 | void *data) |
4738 | int executable) | ||
4739 | { | ||
4740 | if (event->state < PERF_EVENT_STATE_INACTIVE) | ||
4741 | return 0; | ||
4742 | |||
4743 | if (!event_filter_match(event)) | ||
4744 | return 0; | ||
4745 | |||
4746 | if ((!executable && event->attr.mmap_data) || | ||
4747 | (executable && event->attr.mmap)) | ||
4748 | return 1; | ||
4749 | |||
4750 | return 0; | ||
4751 | } | ||
4752 | |||
4753 | static void perf_event_mmap_ctx(struct perf_event_context *ctx, | ||
4754 | struct perf_mmap_event *mmap_event, | ||
4755 | int executable) | ||
4756 | { | 4715 | { |
4757 | struct perf_event *event; | 4716 | struct perf_mmap_event *mmap_event = data; |
4717 | struct vm_area_struct *vma = mmap_event->vma; | ||
4718 | int executable = vma->vm_flags & VM_EXEC; | ||
4758 | 4719 | ||
4759 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { | 4720 | return (!executable && event->attr.mmap_data) || |
4760 | if (perf_event_mmap_match(event, mmap_event, executable)) | 4721 | (executable && event->attr.mmap); |
4761 | perf_event_mmap_output(event, mmap_event); | ||
4762 | } | ||
4763 | } | 4722 | } |
4764 | 4723 | ||
4765 | static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | 4724 | static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) |
4766 | { | 4725 | { |
4767 | struct perf_cpu_context *cpuctx; | ||
4768 | struct perf_event_context *ctx; | ||
4769 | struct vm_area_struct *vma = mmap_event->vma; | 4726 | struct vm_area_struct *vma = mmap_event->vma; |
4770 | struct file *file = vma->vm_file; | 4727 | struct file *file = vma->vm_file; |
4771 | unsigned int size; | 4728 | unsigned int size; |
4772 | char tmp[16]; | 4729 | char tmp[16]; |
4773 | char *buf = NULL; | 4730 | char *buf = NULL; |
4774 | const char *name; | 4731 | const char *name; |
4775 | struct pmu *pmu; | ||
4776 | int ctxn; | ||
4777 | 4732 | ||
4778 | memset(tmp, 0, sizeof(tmp)); | 4733 | memset(tmp, 0, sizeof(tmp)); |
4779 | 4734 | ||
@@ -4829,27 +4784,10 @@ got_name: | |||
4829 | 4784 | ||
4830 | mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; | 4785 | mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; |
4831 | 4786 | ||
4832 | rcu_read_lock(); | 4787 | perf_event_aux(perf_event_mmap_match, |
4833 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 4788 | perf_event_mmap_output, |
4834 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 4789 | mmap_event, |
4835 | if (cpuctx->unique_pmu != pmu) | 4790 | NULL); |
4836 | goto next; | ||
4837 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, | ||
4838 | vma->vm_flags & VM_EXEC); | ||
4839 | |||
4840 | ctxn = pmu->task_ctx_nr; | ||
4841 | if (ctxn < 0) | ||
4842 | goto next; | ||
4843 | |||
4844 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
4845 | if (ctx) { | ||
4846 | perf_event_mmap_ctx(ctx, mmap_event, | ||
4847 | vma->vm_flags & VM_EXEC); | ||
4848 | } | ||
4849 | next: | ||
4850 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
4851 | } | ||
4852 | rcu_read_unlock(); | ||
4853 | 4791 | ||
4854 | kfree(buf); | 4792 | kfree(buf); |
4855 | } | 4793 | } |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 1296e72e4161..8241906c4b61 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -569,6 +569,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) | |||
569 | int retval = 0; | 569 | int retval = 0; |
570 | 570 | ||
571 | helper_lock(); | 571 | helper_lock(); |
572 | if (!sub_info->path) { | ||
573 | retval = -EINVAL; | ||
574 | goto out; | ||
575 | } | ||
576 | |||
572 | if (sub_info->path[0] == '\0') | 577 | if (sub_info->path[0] == '\0') |
573 | goto out; | 578 | goto out; |
574 | 579 | ||
diff --git a/kernel/module.c b/kernel/module.c index b049939177f6..cab4bce49c23 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2431,10 +2431,10 @@ static void kmemleak_load_module(const struct module *mod, | |||
2431 | kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); | 2431 | kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); |
2432 | 2432 | ||
2433 | for (i = 1; i < info->hdr->e_shnum; i++) { | 2433 | for (i = 1; i < info->hdr->e_shnum; i++) { |
2434 | const char *name = info->secstrings + info->sechdrs[i].sh_name; | 2434 | /* Scan all writable sections that's not executable */ |
2435 | if (!(info->sechdrs[i].sh_flags & SHF_ALLOC)) | 2435 | if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) || |
2436 | continue; | 2436 | !(info->sechdrs[i].sh_flags & SHF_WRITE) || |
2437 | if (!strstarts(name, ".data") && !strstarts(name, ".bss")) | 2437 | (info->sechdrs[i].sh_flags & SHF_EXECINSTR)) |
2438 | continue; | 2438 | continue; |
2439 | 2439 | ||
2440 | kmemleak_scan_area((void *)info->sechdrs[i].sh_addr, | 2440 | kmemleak_scan_area((void *)info->sechdrs[i].sh_addr, |
@@ -2769,24 +2769,11 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
2769 | mod->trace_events = section_objs(info, "_ftrace_events", | 2769 | mod->trace_events = section_objs(info, "_ftrace_events", |
2770 | sizeof(*mod->trace_events), | 2770 | sizeof(*mod->trace_events), |
2771 | &mod->num_trace_events); | 2771 | &mod->num_trace_events); |
2772 | /* | ||
2773 | * This section contains pointers to allocated objects in the trace | ||
2774 | * code and not scanning it leads to false positives. | ||
2775 | */ | ||
2776 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | ||
2777 | mod->num_trace_events, GFP_KERNEL); | ||
2778 | #endif | 2772 | #endif |
2779 | #ifdef CONFIG_TRACING | 2773 | #ifdef CONFIG_TRACING |
2780 | mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt", | 2774 | mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt", |
2781 | sizeof(*mod->trace_bprintk_fmt_start), | 2775 | sizeof(*mod->trace_bprintk_fmt_start), |
2782 | &mod->num_trace_bprintk_fmt); | 2776 | &mod->num_trace_bprintk_fmt); |
2783 | /* | ||
2784 | * This section contains pointers to allocated objects in the trace | ||
2785 | * code and not scanning it leads to false positives. | ||
2786 | */ | ||
2787 | kmemleak_scan_area(mod->trace_bprintk_fmt_start, | ||
2788 | sizeof(*mod->trace_bprintk_fmt_start) * | ||
2789 | mod->num_trace_bprintk_fmt, GFP_KERNEL); | ||
2790 | #endif | 2777 | #endif |
2791 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 2778 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
2792 | /* sechdrs[0].sh_size is always zero */ | 2779 | /* sechdrs[0].sh_size is always zero */ |
diff --git a/kernel/range.c b/kernel/range.c index 071b0ab455cb..eb911dbce267 100644 --- a/kernel/range.c +++ b/kernel/range.c | |||
@@ -48,9 +48,11 @@ int add_range_with_merge(struct range *range, int az, int nr_range, | |||
48 | final_start = min(range[i].start, start); | 48 | final_start = min(range[i].start, start); |
49 | final_end = max(range[i].end, end); | 49 | final_end = max(range[i].end, end); |
50 | 50 | ||
51 | range[i].start = final_start; | 51 | /* clear it and add it back for further merge */ |
52 | range[i].end = final_end; | 52 | range[i].start = 0; |
53 | return nr_range; | 53 | range[i].end = 0; |
54 | return add_range_with_merge(range, az, nr_range, | ||
55 | final_start, final_end); | ||
54 | } | 56 | } |
55 | 57 | ||
56 | /* Need to add it: */ | 58 | /* Need to add it: */ |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 170814dc418f..3db5a375d8dd 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -88,7 +88,7 @@ static void __init rcu_bootup_announce_oddness(void) | |||
88 | #ifdef CONFIG_RCU_NOCB_CPU | 88 | #ifdef CONFIG_RCU_NOCB_CPU |
89 | #ifndef CONFIG_RCU_NOCB_CPU_NONE | 89 | #ifndef CONFIG_RCU_NOCB_CPU_NONE |
90 | if (!have_rcu_nocb_mask) { | 90 | if (!have_rcu_nocb_mask) { |
91 | alloc_bootmem_cpumask_var(&rcu_nocb_mask); | 91 | zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL); |
92 | have_rcu_nocb_mask = true; | 92 | have_rcu_nocb_mask = true; |
93 | } | 93 | } |
94 | #ifdef CONFIG_RCU_NOCB_CPU_ZERO | 94 | #ifdef CONFIG_RCU_NOCB_CPU_ZERO |
@@ -1667,7 +1667,7 @@ int rcu_needs_cpu(int cpu, unsigned long *dj) | |||
1667 | rdtp->last_accelerate = jiffies; | 1667 | rdtp->last_accelerate = jiffies; |
1668 | 1668 | ||
1669 | /* Request timer delay depending on laziness, and round. */ | 1669 | /* Request timer delay depending on laziness, and round. */ |
1670 | if (rdtp->all_lazy) { | 1670 | if (!rdtp->all_lazy) { |
1671 | *dj = round_up(rcu_idle_gp_delay + jiffies, | 1671 | *dj = round_up(rcu_idle_gp_delay + jiffies, |
1672 | rcu_idle_gp_delay) - jiffies; | 1672 | rcu_idle_gp_delay) - jiffies; |
1673 | } else { | 1673 | } else { |
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index e4c07b0692bb..70f27e89012b 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
@@ -12,11 +12,6 @@ config CLOCKSOURCE_WATCHDOG | |||
12 | config ARCH_CLOCKSOURCE_DATA | 12 | config ARCH_CLOCKSOURCE_DATA |
13 | bool | 13 | bool |
14 | 14 | ||
15 | # Platforms has a persistent clock | ||
16 | config ALWAYS_USE_PERSISTENT_CLOCK | ||
17 | bool | ||
18 | default n | ||
19 | |||
20 | # Timekeeping vsyscall support | 15 | # Timekeeping vsyscall support |
21 | config GENERIC_TIME_VSYSCALL | 16 | config GENERIC_TIME_VSYSCALL |
22 | bool | 17 | bool |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 206bbfb34e09..24938d577669 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -786,11 +786,11 @@ bool tick_broadcast_oneshot_available(void) | |||
786 | 786 | ||
787 | void __init tick_broadcast_init(void) | 787 | void __init tick_broadcast_init(void) |
788 | { | 788 | { |
789 | alloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT); | 789 | zalloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT); |
790 | alloc_cpumask_var(&tmpmask, GFP_NOWAIT); | 790 | zalloc_cpumask_var(&tmpmask, GFP_NOWAIT); |
791 | #ifdef CONFIG_TICK_ONESHOT | 791 | #ifdef CONFIG_TICK_ONESHOT |
792 | alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT); | 792 | zalloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT); |
793 | alloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT); | 793 | zalloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT); |
794 | alloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT); | 794 | zalloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT); |
795 | #endif | 795 | #endif |
796 | } | 796 | } |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index bc67d4245e1d..f4208138fbf4 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -717,6 +717,7 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) | |||
717 | if (unlikely(!cpu_online(cpu))) { | 717 | if (unlikely(!cpu_online(cpu))) { |
718 | if (cpu == tick_do_timer_cpu) | 718 | if (cpu == tick_do_timer_cpu) |
719 | tick_do_timer_cpu = TICK_DO_TIMER_NONE; | 719 | tick_do_timer_cpu = TICK_DO_TIMER_NONE; |
720 | return false; | ||
720 | } | 721 | } |
721 | 722 | ||
722 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) | 723 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
@@ -1168,7 +1169,7 @@ void tick_cancel_sched_timer(int cpu) | |||
1168 | hrtimer_cancel(&ts->sched_timer); | 1169 | hrtimer_cancel(&ts->sched_timer); |
1169 | # endif | 1170 | # endif |
1170 | 1171 | ||
1171 | ts->nohz_mode = NOHZ_MODE_INACTIVE; | 1172 | memset(ts, 0, sizeof(*ts)); |
1172 | } | 1173 | } |
1173 | #endif | 1174 | #endif |
1174 | 1175 | ||
diff --git a/kernel/timer.c b/kernel/timer.c index a860bba34412..15ffdb3f1948 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1539,12 +1539,12 @@ static int __cpuinit init_timers_cpu(int cpu) | |||
1539 | boot_done = 1; | 1539 | boot_done = 1; |
1540 | base = &boot_tvec_bases; | 1540 | base = &boot_tvec_bases; |
1541 | } | 1541 | } |
1542 | spin_lock_init(&base->lock); | ||
1542 | tvec_base_done[cpu] = 1; | 1543 | tvec_base_done[cpu] = 1; |
1543 | } else { | 1544 | } else { |
1544 | base = per_cpu(tvec_bases, cpu); | 1545 | base = per_cpu(tvec_bases, cpu); |
1545 | } | 1546 | } |
1546 | 1547 | ||
1547 | spin_lock_init(&base->lock); | ||
1548 | 1548 | ||
1549 | for (j = 0; j < TVN_SIZE; j++) { | 1549 | for (j = 0; j < TVN_SIZE; j++) { |
1550 | INIT_LIST_HEAD(base->tv5.vec + j); | 1550 | INIT_LIST_HEAD(base->tv5.vec + j); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index b59aea2c48c2..e444ff88f0a4 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -620,6 +620,9 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, | |||
620 | if (cpu == RING_BUFFER_ALL_CPUS) | 620 | if (cpu == RING_BUFFER_ALL_CPUS) |
621 | work = &buffer->irq_work; | 621 | work = &buffer->irq_work; |
622 | else { | 622 | else { |
623 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) | ||
624 | return -EINVAL; | ||
625 | |||
623 | cpu_buffer = buffer->buffers[cpu]; | 626 | cpu_buffer = buffer->buffers[cpu]; |
624 | work = &cpu_buffer->irq_work; | 627 | work = &cpu_buffer->irq_work; |
625 | } | 628 | } |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ae6fa2d1cdf7..4d79485b3237 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -6216,10 +6216,15 @@ __init static int tracer_alloc_buffers(void) | |||
6216 | 6216 | ||
6217 | trace_init_cmdlines(); | 6217 | trace_init_cmdlines(); |
6218 | 6218 | ||
6219 | register_tracer(&nop_trace); | 6219 | /* |
6220 | 6220 | * register_tracer() might reference current_trace, so it | |
6221 | * needs to be set before we register anything. This is | ||
6222 | * just a bootstrap of current_trace anyway. | ||
6223 | */ | ||
6221 | global_trace.current_trace = &nop_trace; | 6224 | global_trace.current_trace = &nop_trace; |
6222 | 6225 | ||
6226 | register_tracer(&nop_trace); | ||
6227 | |||
6223 | /* All seems OK, enable tracing */ | 6228 | /* All seems OK, enable tracing */ |
6224 | tracing_disabled = 0; | 6229 | tracing_disabled = 0; |
6225 | 6230 | ||
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 7a0cf68027cc..27963e2bf4bf 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -2072,8 +2072,10 @@ event_enable_func(struct ftrace_hash *hash, | |||
2072 | out_reg: | 2072 | out_reg: |
2073 | /* Don't let event modules unload while probe registered */ | 2073 | /* Don't let event modules unload while probe registered */ |
2074 | ret = try_module_get(file->event_call->mod); | 2074 | ret = try_module_get(file->event_call->mod); |
2075 | if (!ret) | 2075 | if (!ret) { |
2076 | ret = -EBUSY; | ||
2076 | goto out_free; | 2077 | goto out_free; |
2078 | } | ||
2077 | 2079 | ||
2078 | ret = __ftrace_event_enable_disable(file, 1, 1); | 2080 | ret = __ftrace_event_enable_disable(file, 1, 1); |
2079 | if (ret < 0) | 2081 | if (ret < 0) |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index a6361178de5a..e1b653f7e1ca 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -750,7 +750,11 @@ static int filter_set_pred(struct event_filter *filter, | |||
750 | 750 | ||
751 | static void __free_preds(struct event_filter *filter) | 751 | static void __free_preds(struct event_filter *filter) |
752 | { | 752 | { |
753 | int i; | ||
754 | |||
753 | if (filter->preds) { | 755 | if (filter->preds) { |
756 | for (i = 0; i < filter->n_preds; i++) | ||
757 | kfree(filter->preds[i].ops); | ||
754 | kfree(filter->preds); | 758 | kfree(filter->preds); |
755 | filter->preds = NULL; | 759 | filter->preds = NULL; |
756 | } | 760 | } |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 636d45fe69b3..9f46e98ba8f2 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -35,7 +35,7 @@ struct trace_probe { | |||
35 | const char *symbol; /* symbol name */ | 35 | const char *symbol; /* symbol name */ |
36 | struct ftrace_event_class class; | 36 | struct ftrace_event_class class; |
37 | struct ftrace_event_call call; | 37 | struct ftrace_event_call call; |
38 | struct ftrace_event_file **files; | 38 | struct ftrace_event_file * __rcu *files; |
39 | ssize_t size; /* trace entry size */ | 39 | ssize_t size; /* trace entry size */ |
40 | unsigned int nr_args; | 40 | unsigned int nr_args; |
41 | struct probe_arg args[]; | 41 | struct probe_arg args[]; |
@@ -185,9 +185,14 @@ static struct trace_probe *find_trace_probe(const char *event, | |||
185 | 185 | ||
186 | static int trace_probe_nr_files(struct trace_probe *tp) | 186 | static int trace_probe_nr_files(struct trace_probe *tp) |
187 | { | 187 | { |
188 | struct ftrace_event_file **file = tp->files; | 188 | struct ftrace_event_file **file; |
189 | int ret = 0; | 189 | int ret = 0; |
190 | 190 | ||
191 | /* | ||
192 | * Since all tp->files updater is protected by probe_enable_lock, | ||
193 | * we don't need to lock an rcu_read_lock. | ||
194 | */ | ||
195 | file = rcu_dereference_raw(tp->files); | ||
191 | if (file) | 196 | if (file) |
192 | while (*(file++)) | 197 | while (*(file++)) |
193 | ret++; | 198 | ret++; |
@@ -209,9 +214,10 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) | |||
209 | mutex_lock(&probe_enable_lock); | 214 | mutex_lock(&probe_enable_lock); |
210 | 215 | ||
211 | if (file) { | 216 | if (file) { |
212 | struct ftrace_event_file **new, **old = tp->files; | 217 | struct ftrace_event_file **new, **old; |
213 | int n = trace_probe_nr_files(tp); | 218 | int n = trace_probe_nr_files(tp); |
214 | 219 | ||
220 | old = rcu_dereference_raw(tp->files); | ||
215 | /* 1 is for new one and 1 is for stopper */ | 221 | /* 1 is for new one and 1 is for stopper */ |
216 | new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *), | 222 | new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *), |
217 | GFP_KERNEL); | 223 | GFP_KERNEL); |
@@ -251,11 +257,17 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) | |||
251 | static int | 257 | static int |
252 | trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file) | 258 | trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file) |
253 | { | 259 | { |
260 | struct ftrace_event_file **files; | ||
254 | int i; | 261 | int i; |
255 | 262 | ||
256 | if (tp->files) { | 263 | /* |
257 | for (i = 0; tp->files[i]; i++) | 264 | * Since all tp->files updater is protected by probe_enable_lock, |
258 | if (tp->files[i] == file) | 265 | * we don't need to lock an rcu_read_lock. |
266 | */ | ||
267 | files = rcu_dereference_raw(tp->files); | ||
268 | if (files) { | ||
269 | for (i = 0; files[i]; i++) | ||
270 | if (files[i] == file) | ||
259 | return i; | 271 | return i; |
260 | } | 272 | } |
261 | 273 | ||
@@ -274,10 +286,11 @@ disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) | |||
274 | mutex_lock(&probe_enable_lock); | 286 | mutex_lock(&probe_enable_lock); |
275 | 287 | ||
276 | if (file) { | 288 | if (file) { |
277 | struct ftrace_event_file **new, **old = tp->files; | 289 | struct ftrace_event_file **new, **old; |
278 | int n = trace_probe_nr_files(tp); | 290 | int n = trace_probe_nr_files(tp); |
279 | int i, j; | 291 | int i, j; |
280 | 292 | ||
293 | old = rcu_dereference_raw(tp->files); | ||
281 | if (n == 0 || trace_probe_file_index(tp, file) < 0) { | 294 | if (n == 0 || trace_probe_file_index(tp, file) < 0) { |
282 | ret = -EINVAL; | 295 | ret = -EINVAL; |
283 | goto out_unlock; | 296 | goto out_unlock; |
@@ -872,9 +885,16 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, | |||
872 | static __kprobes void | 885 | static __kprobes void |
873 | kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs) | 886 | kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs) |
874 | { | 887 | { |
875 | struct ftrace_event_file **file = tp->files; | 888 | /* |
889 | * Note: preempt is already disabled around the kprobe handler. | ||
890 | * However, we still need an smp_read_barrier_depends() corresponding | ||
891 | * to smp_wmb() in rcu_assign_pointer() to access the pointer. | ||
892 | */ | ||
893 | struct ftrace_event_file **file = rcu_dereference_raw(tp->files); | ||
894 | |||
895 | if (unlikely(!file)) | ||
896 | return; | ||
876 | 897 | ||
877 | /* Note: preempt is already disabled around the kprobe handler */ | ||
878 | while (*file) { | 898 | while (*file) { |
879 | __kprobe_trace_func(tp, regs, *file); | 899 | __kprobe_trace_func(tp, regs, *file); |
880 | file++; | 900 | file++; |
@@ -925,9 +945,16 @@ static __kprobes void | |||
925 | kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, | 945 | kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, |
926 | struct pt_regs *regs) | 946 | struct pt_regs *regs) |
927 | { | 947 | { |
928 | struct ftrace_event_file **file = tp->files; | 948 | /* |
949 | * Note: preempt is already disabled around the kprobe handler. | ||
950 | * However, we still need an smp_read_barrier_depends() corresponding | ||
951 | * to smp_wmb() in rcu_assign_pointer() to access the pointer. | ||
952 | */ | ||
953 | struct ftrace_event_file **file = rcu_dereference_raw(tp->files); | ||
954 | |||
955 | if (unlikely(!file)) | ||
956 | return; | ||
929 | 957 | ||
930 | /* Note: preempt is already disabled around the kprobe handler */ | ||
931 | while (*file) { | 958 | while (*file) { |
932 | __kretprobe_trace_func(tp, ri, regs, *file); | 959 | __kretprobe_trace_func(tp, ri, regs, *file); |
933 | file++; | 960 | file++; |
@@ -935,7 +962,7 @@ kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, | |||
935 | } | 962 | } |
936 | 963 | ||
937 | /* Event entry printers */ | 964 | /* Event entry printers */ |
938 | enum print_line_t | 965 | static enum print_line_t |
939 | print_kprobe_event(struct trace_iterator *iter, int flags, | 966 | print_kprobe_event(struct trace_iterator *iter, int flags, |
940 | struct trace_event *event) | 967 | struct trace_event *event) |
941 | { | 968 | { |
@@ -971,7 +998,7 @@ partial: | |||
971 | return TRACE_TYPE_PARTIAL_LINE; | 998 | return TRACE_TYPE_PARTIAL_LINE; |
972 | } | 999 | } |
973 | 1000 | ||
974 | enum print_line_t | 1001 | static enum print_line_t |
975 | print_kretprobe_event(struct trace_iterator *iter, int flags, | 1002 | print_kretprobe_event(struct trace_iterator *iter, int flags, |
976 | struct trace_event *event) | 1003 | struct trace_event *event) |
977 | { | 1004 | { |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 4aa9f5bc6b2d..ee8e29a2320c 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -296,7 +296,7 @@ static DEFINE_HASHTABLE(unbound_pool_hash, UNBOUND_POOL_HASH_ORDER); | |||
296 | static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS]; | 296 | static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS]; |
297 | 297 | ||
298 | struct workqueue_struct *system_wq __read_mostly; | 298 | struct workqueue_struct *system_wq __read_mostly; |
299 | EXPORT_SYMBOL_GPL(system_wq); | 299 | EXPORT_SYMBOL(system_wq); |
300 | struct workqueue_struct *system_highpri_wq __read_mostly; | 300 | struct workqueue_struct *system_highpri_wq __read_mostly; |
301 | EXPORT_SYMBOL_GPL(system_highpri_wq); | 301 | EXPORT_SYMBOL_GPL(system_highpri_wq); |
302 | struct workqueue_struct *system_long_wq __read_mostly; | 302 | struct workqueue_struct *system_long_wq __read_mostly; |
@@ -1411,7 +1411,7 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq, | |||
1411 | local_irq_restore(flags); | 1411 | local_irq_restore(flags); |
1412 | return ret; | 1412 | return ret; |
1413 | } | 1413 | } |
1414 | EXPORT_SYMBOL_GPL(queue_work_on); | 1414 | EXPORT_SYMBOL(queue_work_on); |
1415 | 1415 | ||
1416 | void delayed_work_timer_fn(unsigned long __data) | 1416 | void delayed_work_timer_fn(unsigned long __data) |
1417 | { | 1417 | { |
@@ -1485,7 +1485,7 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | |||
1485 | local_irq_restore(flags); | 1485 | local_irq_restore(flags); |
1486 | return ret; | 1486 | return ret; |
1487 | } | 1487 | } |
1488 | EXPORT_SYMBOL_GPL(queue_delayed_work_on); | 1488 | EXPORT_SYMBOL(queue_delayed_work_on); |
1489 | 1489 | ||
1490 | /** | 1490 | /** |
1491 | * mod_delayed_work_on - modify delay of or queue a delayed work on specific CPU | 1491 | * mod_delayed_work_on - modify delay of or queue a delayed work on specific CPU |
@@ -2059,6 +2059,7 @@ static bool manage_workers(struct worker *worker) | |||
2059 | if (unlikely(!mutex_trylock(&pool->manager_mutex))) { | 2059 | if (unlikely(!mutex_trylock(&pool->manager_mutex))) { |
2060 | spin_unlock_irq(&pool->lock); | 2060 | spin_unlock_irq(&pool->lock); |
2061 | mutex_lock(&pool->manager_mutex); | 2061 | mutex_lock(&pool->manager_mutex); |
2062 | spin_lock_irq(&pool->lock); | ||
2062 | ret = true; | 2063 | ret = true; |
2063 | } | 2064 | } |
2064 | 2065 | ||
@@ -4311,6 +4312,12 @@ bool current_is_workqueue_rescuer(void) | |||
4311 | * no synchronization around this function and the test result is | 4312 | * no synchronization around this function and the test result is |
4312 | * unreliable and only useful as advisory hints or for debugging. | 4313 | * unreliable and only useful as advisory hints or for debugging. |
4313 | * | 4314 | * |
4315 | * If @cpu is WORK_CPU_UNBOUND, the test is performed on the local CPU. | ||
4316 | * Note that both per-cpu and unbound workqueues may be associated with | ||
4317 | * multiple pool_workqueues which have separate congested states. A | ||
4318 | * workqueue being congested on one CPU doesn't mean the workqueue is also | ||
4319 | * contested on other CPUs / NUMA nodes. | ||
4320 | * | ||
4314 | * RETURNS: | 4321 | * RETURNS: |
4315 | * %true if congested, %false otherwise. | 4322 | * %true if congested, %false otherwise. |
4316 | */ | 4323 | */ |
@@ -4321,6 +4328,9 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) | |||
4321 | 4328 | ||
4322 | rcu_read_lock_sched(); | 4329 | rcu_read_lock_sched(); |
4323 | 4330 | ||
4331 | if (cpu == WORK_CPU_UNBOUND) | ||
4332 | cpu = smp_processor_id(); | ||
4333 | |||
4324 | if (!(wq->flags & WQ_UNBOUND)) | 4334 | if (!(wq->flags & WQ_UNBOUND)) |
4325 | pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); | 4335 | pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); |
4326 | else | 4336 | else |
@@ -4895,7 +4905,8 @@ static void __init wq_numa_init(void) | |||
4895 | BUG_ON(!tbl); | 4905 | BUG_ON(!tbl); |
4896 | 4906 | ||
4897 | for_each_node(node) | 4907 | for_each_node(node) |
4898 | BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL, node)); | 4908 | BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL, |
4909 | node_online(node) ? node : NUMA_NO_NODE)); | ||
4899 | 4910 | ||
4900 | for_each_possible_cpu(cpu) { | 4911 | for_each_possible_cpu(cpu) { |
4901 | node = cpu_to_node(cpu); | 4912 | node = cpu_to_node(cpu); |