diff options
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 13 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 14 |
2 files changed, 24 insertions, 3 deletions
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 376fcbc3f8da..fd4f3be6e856 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -1265,6 +1265,8 @@ out: | |||
1265 | } | 1265 | } |
1266 | EXPORT_SYMBOL(pfm_unregister_buffer_fmt); | 1266 | EXPORT_SYMBOL(pfm_unregister_buffer_fmt); |
1267 | 1267 | ||
1268 | extern void update_pal_halt_status(int); | ||
1269 | |||
1268 | static int | 1270 | static int |
1269 | pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | 1271 | pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) |
1270 | { | 1272 | { |
@@ -1311,6 +1313,11 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | |||
1311 | is_syswide, | 1313 | is_syswide, |
1312 | cpu)); | 1314 | cpu)); |
1313 | 1315 | ||
1316 | /* | ||
1317 | * disable default_idle() to go to PAL_HALT | ||
1318 | */ | ||
1319 | update_pal_halt_status(0); | ||
1320 | |||
1314 | UNLOCK_PFS(flags); | 1321 | UNLOCK_PFS(flags); |
1315 | 1322 | ||
1316 | return 0; | 1323 | return 0; |
@@ -1366,6 +1373,12 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) | |||
1366 | is_syswide, | 1373 | is_syswide, |
1367 | cpu)); | 1374 | cpu)); |
1368 | 1375 | ||
1376 | /* | ||
1377 | * if possible, enable default_idle() to go into PAL_HALT | ||
1378 | */ | ||
1379 | if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0) | ||
1380 | update_pal_halt_status(1); | ||
1381 | |||
1369 | UNLOCK_PFS(flags); | 1382 | UNLOCK_PFS(flags); |
1370 | 1383 | ||
1371 | return 0; | 1384 | return 0; |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index c0140f4235e4..474d75f9de8a 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -173,7 +173,9 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall | |||
173 | ia64_do_signal(oldset, scr, in_syscall); | 173 | ia64_do_signal(oldset, scr, in_syscall); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int pal_halt = 1; | 176 | static int pal_halt = 1; |
177 | static int can_do_pal_halt = 1; | ||
178 | |||
177 | static int __init nohalt_setup(char * str) | 179 | static int __init nohalt_setup(char * str) |
178 | { | 180 | { |
179 | pal_halt = 0; | 181 | pal_halt = 0; |
@@ -181,16 +183,22 @@ static int __init nohalt_setup(char * str) | |||
181 | } | 183 | } |
182 | __setup("nohalt", nohalt_setup); | 184 | __setup("nohalt", nohalt_setup); |
183 | 185 | ||
186 | int | ||
187 | update_pal_halt_status(int status) | ||
188 | { | ||
189 | can_do_pal_halt = pal_halt && status; | ||
190 | } | ||
191 | |||
184 | /* | 192 | /* |
185 | * We use this if we don't have any better idle routine.. | 193 | * We use this if we don't have any better idle routine.. |
186 | */ | 194 | */ |
187 | void | 195 | void |
188 | default_idle (void) | 196 | default_idle (void) |
189 | { | 197 | { |
190 | unsigned long pmu_active = ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_PP | IA64_PSR_UP); | 198 | int can_do_pal; |
191 | 199 | ||
192 | while (!need_resched()) | 200 | while (!need_resched()) |
193 | if (pal_halt && !pmu_active) | 201 | if (can_do_pal_halt) |
194 | safe_halt(); | 202 | safe_halt(); |
195 | else | 203 | else |
196 | cpu_relax(); | 204 | cpu_relax(); |