ladder.c (99e98d3fb1008ef7416e16a1fd355cb73a253502) ladder.c (c1d51f684c72b5eb2aecbbd47be3a2977a2dc903)
1/*
2 * ladder.c - the residency ladder algorithm
3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de>
7 *
8 * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>

--- 13 unchanged lines hidden (view full) ---

22
23#define PROMOTION_COUNT 4
24#define DEMOTION_COUNT 1
25
26struct ladder_device_state {
27 struct {
28 u32 promotion_count;
29 u32 demotion_count;
1/*
2 * ladder.c - the residency ladder algorithm
3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de>
7 *
8 * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>

--- 13 unchanged lines hidden (view full) ---

22
23#define PROMOTION_COUNT 4
24#define DEMOTION_COUNT 1
25
26struct ladder_device_state {
27 struct {
28 u32 promotion_count;
29 u32 demotion_count;
30 u32 promotion_time;
31 u32 demotion_time;
30 u64 promotion_time_ns;
31 u64 demotion_time_ns;
32 } threshold;
33 struct {
34 int promotion_count;
35 int demotion_count;
36 } stats;
37};
38
39struct ladder_device {

--- 23 unchanged lines hidden (view full) ---

63 * @dev: the CPU
64 * @dummy: not used
65 */
66static int ladder_select_state(struct cpuidle_driver *drv,
67 struct cpuidle_device *dev, bool *dummy)
68{
69 struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
70 struct ladder_device_state *last_state;
32 } threshold;
33 struct {
34 int promotion_count;
35 int demotion_count;
36 } stats;
37};
38
39struct ladder_device {

--- 23 unchanged lines hidden (view full) ---

63 * @dev: the CPU
64 * @dummy: not used
65 */
66static int ladder_select_state(struct cpuidle_driver *drv,
67 struct cpuidle_device *dev, bool *dummy)
68{
69 struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
70 struct ladder_device_state *last_state;
71 int last_residency, last_idx = dev->last_state_idx;
71 int last_idx = dev->last_state_idx;
72 int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
72 int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
73 int latency_req = cpuidle_governor_latency_req(dev->cpu);
73 s64 latency_req = cpuidle_governor_latency_req(dev->cpu);
74 s64 last_residency;
74
75 /* Special case when user has set very strict latency requirement */
76 if (unlikely(latency_req == 0)) {
77 ladder_do_selection(dev, ldev, last_idx, 0);
78 return 0;
79 }
80
81 last_state = &ldev->states[last_idx];
82
75
76 /* Special case when user has set very strict latency requirement */
77 if (unlikely(latency_req == 0)) {
78 ladder_do_selection(dev, ldev, last_idx, 0);
79 return 0;
80 }
81
82 last_state = &ldev->states[last_idx];
83
83 last_residency = dev->last_residency - drv->states[last_idx].exit_latency;
84 last_residency = dev->last_residency_ns - drv->states[last_idx].exit_latency_ns;
84
85 /* consider promotion */
86 if (last_idx < drv->state_count - 1 &&
87 !dev->states_usage[last_idx + 1].disable &&
85
86 /* consider promotion */
87 if (last_idx < drv->state_count - 1 &&
88 !dev->states_usage[last_idx + 1].disable &&
88 last_residency > last_state->threshold.promotion_time &&
89 drv->states[last_idx + 1].exit_latency <= latency_req) {
89 last_residency > last_state->threshold.promotion_time_ns &&
90 drv->states[last_idx + 1].exit_latency_ns <= latency_req) {
90 last_state->stats.promotion_count++;
91 last_state->stats.demotion_count = 0;
92 if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
93 ladder_do_selection(dev, ldev, last_idx, last_idx + 1);
94 return last_idx + 1;
95 }
96 }
97
98 /* consider demotion */
99 if (last_idx > first_idx &&
100 (dev->states_usage[last_idx].disable ||
91 last_state->stats.promotion_count++;
92 last_state->stats.demotion_count = 0;
93 if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
94 ladder_do_selection(dev, ldev, last_idx, last_idx + 1);
95 return last_idx + 1;
96 }
97 }
98
99 /* consider demotion */
100 if (last_idx > first_idx &&
101 (dev->states_usage[last_idx].disable ||
101 drv->states[last_idx].exit_latency > latency_req)) {
102 drv->states[last_idx].exit_latency_ns > latency_req)) {
102 int i;
103
104 for (i = last_idx - 1; i > first_idx; i--) {
103 int i;
104
105 for (i = last_idx - 1; i > first_idx; i--) {
105 if (drv->states[i].exit_latency <= latency_req)
106 if (drv->states[i].exit_latency_ns <= latency_req)
106 break;
107 }
108 ladder_do_selection(dev, ldev, last_idx, i);
109 return i;
110 }
111
112 if (last_idx > first_idx &&
107 break;
108 }
109 ladder_do_selection(dev, ldev, last_idx, i);
110 return i;
111 }
112
113 if (last_idx > first_idx &&
113 last_residency < last_state->threshold.demotion_time) {
114 last_residency < last_state->threshold.demotion_time_ns) {
114 last_state->stats.demotion_count++;
115 last_state->stats.promotion_count = 0;
116 if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) {
117 ladder_do_selection(dev, ldev, last_idx, last_idx - 1);
118 return last_idx - 1;
119 }
120 }
121

--- 23 unchanged lines hidden (view full) ---

145
146 lstate->stats.promotion_count = 0;
147 lstate->stats.demotion_count = 0;
148
149 lstate->threshold.promotion_count = PROMOTION_COUNT;
150 lstate->threshold.demotion_count = DEMOTION_COUNT;
151
152 if (i < drv->state_count - 1)
115 last_state->stats.demotion_count++;
116 last_state->stats.promotion_count = 0;
117 if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) {
118 ladder_do_selection(dev, ldev, last_idx, last_idx - 1);
119 return last_idx - 1;
120 }
121 }
122

--- 23 unchanged lines hidden (view full) ---

146
147 lstate->stats.promotion_count = 0;
148 lstate->stats.demotion_count = 0;
149
150 lstate->threshold.promotion_count = PROMOTION_COUNT;
151 lstate->threshold.demotion_count = DEMOTION_COUNT;
152
153 if (i < drv->state_count - 1)
153 lstate->threshold.promotion_time = state->exit_latency;
154 lstate->threshold.promotion_time_ns = state->exit_latency_ns;
154 if (i > first_idx)
155 if (i > first_idx)
155 lstate->threshold.demotion_time = state->exit_latency;
156 lstate->threshold.demotion_time_ns = state->exit_latency_ns;
156 }
157
158 return 0;
159}
160
161/**
162 * ladder_reflect - update the correct last_state_idx
163 * @dev: the CPU

--- 33 unchanged lines hidden ---
157 }
158
159 return 0;
160}
161
162/**
163 * ladder_reflect - update the correct last_state_idx
164 * @dev: the CPU

--- 33 unchanged lines hidden ---