diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2019-03-11 15:37:55 -0400 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2019-03-11 15:37:55 -0400 |
| commit | 4083014e32699af04a8e6eaa4855b08dba36a47a (patch) | |
| tree | fa37f9f9691fe64ca8a3c0cdc0315dc12462e6e4 /kernel/sched/psi.c | |
| parent | 6fd96ff557963de8e62842a0dc360a6e3610d2bb (diff) | |
| parent | 78153dd45e7e0596ba32b15d02bda08e1513111e (diff) | |
Merge branch 'for-5.1/nfit/ars' into libnvdimm-for-next
Merge several updates to the ARS implementation. Highlights include:
* Support retrieval of short-ARS results if the ARS state is "requires
continuation", and even if the "no_init_ars" module parameter is
specified.
* Allow busy-polling of the kernel ARS state by allowing root to reset
the exponential back-off timer.
* Filter potentially stale ARS results by tracking query-ARS relative to
the previous start-ARS.
Diffstat (limited to 'kernel/sched/psi.c')
| -rw-r--r-- | kernel/sched/psi.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index fe24de3fbc93..c3484785b179 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c | |||
| @@ -124,6 +124,7 @@ | |||
| 124 | * sampling of the aggregate task states would be. | 124 | * sampling of the aggregate task states would be. |
| 125 | */ | 125 | */ |
| 126 | 126 | ||
| 127 | #include "../workqueue_internal.h" | ||
| 127 | #include <linux/sched/loadavg.h> | 128 | #include <linux/sched/loadavg.h> |
| 128 | #include <linux/seq_file.h> | 129 | #include <linux/seq_file.h> |
| 129 | #include <linux/proc_fs.h> | 130 | #include <linux/proc_fs.h> |
| @@ -480,9 +481,6 @@ static void psi_group_change(struct psi_group *group, int cpu, | |||
| 480 | groupc->tasks[t]++; | 481 | groupc->tasks[t]++; |
| 481 | 482 | ||
| 482 | write_seqcount_end(&groupc->seq); | 483 | write_seqcount_end(&groupc->seq); |
| 483 | |||
| 484 | if (!delayed_work_pending(&group->clock_work)) | ||
| 485 | schedule_delayed_work(&group->clock_work, PSI_FREQ); | ||
| 486 | } | 484 | } |
| 487 | 485 | ||
| 488 | static struct psi_group *iterate_groups(struct task_struct *task, void **iter) | 486 | static struct psi_group *iterate_groups(struct task_struct *task, void **iter) |
| @@ -513,6 +511,7 @@ void psi_task_change(struct task_struct *task, int clear, int set) | |||
| 513 | { | 511 | { |
| 514 | int cpu = task_cpu(task); | 512 | int cpu = task_cpu(task); |
| 515 | struct psi_group *group; | 513 | struct psi_group *group; |
| 514 | bool wake_clock = true; | ||
| 516 | void *iter = NULL; | 515 | void *iter = NULL; |
| 517 | 516 | ||
| 518 | if (!task->pid) | 517 | if (!task->pid) |
| @@ -530,8 +529,22 @@ void psi_task_change(struct task_struct *task, int clear, int set) | |||
| 530 | task->psi_flags &= ~clear; | 529 | task->psi_flags &= ~clear; |
| 531 | task->psi_flags |= set; | 530 | task->psi_flags |= set; |
| 532 | 531 | ||
| 533 | while ((group = iterate_groups(task, &iter))) | 532 | /* |
| 533 | * Periodic aggregation shuts off if there is a period of no | ||
| 534 | * task changes, so we wake it back up if necessary. However, | ||
| 535 | * don't do this if the task change is the aggregation worker | ||
| 536 | * itself going to sleep, or we'll ping-pong forever. | ||
| 537 | */ | ||
| 538 | if (unlikely((clear & TSK_RUNNING) && | ||
| 539 | (task->flags & PF_WQ_WORKER) && | ||
| 540 | wq_worker_last_func(task) == psi_update_work)) | ||
| 541 | wake_clock = false; | ||
| 542 | |||
| 543 | while ((group = iterate_groups(task, &iter))) { | ||
| 534 | psi_group_change(group, cpu, clear, set); | 544 | psi_group_change(group, cpu, clear, set); |
| 545 | if (wake_clock && !delayed_work_pending(&group->clock_work)) | ||
| 546 | schedule_delayed_work(&group->clock_work, PSI_FREQ); | ||
| 547 | } | ||
| 535 | } | 548 | } |
| 536 | 549 | ||
| 537 | void psi_memstall_tick(struct task_struct *task, int cpu) | 550 | void psi_memstall_tick(struct task_struct *task, int cpu) |
