aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrank Mayhar <fmayhar@google.com>2008-09-12 12:54:39 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-27 14:04:45 -0400
commit7086efe1c1536f6bc160e7d60a9bfd645b91f279 (patch)
treea5facb5a01052452547ab9a9a47a0260537127fb /kernel
parent31d9284569e38fb97117497af3e8047a6a3c86f0 (diff)
timers: fix itimer/many thread hang, v3
- fix UP lockup - another set of UP/SMP cleanups and simplifications Signed-off-by: Frank Mayhar <fmayhar@google.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c1
-rw-r--r--kernel/sched_stats.h126
2 files changed, 38 insertions, 89 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 260c22cc530a..29a3152c45db 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4046,7 +4046,6 @@ unsigned long long task_delta_exec(struct task_struct *p)
4046 unsigned long flags; 4046 unsigned long flags;
4047 u64 ns = 0; 4047 u64 ns = 0;
4048 4048
4049 rq = task_rq_lock(p, &flags);
4050 if (task_current(rq, p)) { 4049 if (task_current(rq, p)) {
4051 u64 delta_exec; 4050 u64 delta_exec;
4052 4051
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
index d6903bd0c7a8..b8c156979cf2 100644
--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -276,133 +276,83 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
276 * on CONFIG_SCHEDSTATS. 276 * on CONFIG_SCHEDSTATS.
277 */ 277 */
278 278
279#ifdef CONFIG_SMP
280
281/** 279/**
282 * thread_group_cputime_account_user - Maintain utime for a thread group. 280 * account_group_user_time - Maintain utime for a thread group.
283 * 281 *
284 * @tgtimes: Pointer to thread_group_cputime structure. 282 * @tsk: Pointer to task structure.
285 * @cputime: Time value by which to increment the utime field of that 283 * @cputime: Time value by which to increment the utime field of the
286 * structure. 284 * thread_group_cputime structure.
287 * 285 *
288 * If thread group time is being maintained, get the structure for the 286 * If thread group time is being maintained, get the structure for the
289 * running CPU and update the utime field there. 287 * running CPU and update the utime field there.
290 */ 288 */
291static inline void thread_group_cputime_account_user( 289static inline void account_group_user_time(struct task_struct *tsk,
292 struct thread_group_cputime *tgtimes, 290 cputime_t cputime)
293 cputime_t cputime)
294{ 291{
295 if (tgtimes->totals) { 292 struct signal_struct *sig;
293
294 sig = tsk->signal;
295 if (unlikely(!sig))
296 return;
297 if (sig->cputime.totals) {
296 struct task_cputime *times; 298 struct task_cputime *times;
297 299
298 times = per_cpu_ptr(tgtimes->totals, get_cpu()); 300 times = per_cpu_ptr(sig->cputime.totals, get_cpu());
299 times->utime = cputime_add(times->utime, cputime); 301 times->utime = cputime_add(times->utime, cputime);
300 put_cpu_no_resched(); 302 put_cpu_no_resched();
301 } 303 }
302} 304}
303 305
304/** 306/**
305 * thread_group_cputime_account_system - Maintain stime for a thread group. 307 * account_group_system_time - Maintain stime for a thread group.
306 * 308 *
307 * @tgtimes: Pointer to thread_group_cputime structure. 309 * @tsk: Pointer to task structure.
308 * @cputime: Time value by which to increment the stime field of that 310 * @cputime: Time value by which to increment the stime field of the
309 * structure. 311 * thread_group_cputime structure.
310 * 312 *
311 * If thread group time is being maintained, get the structure for the 313 * If thread group time is being maintained, get the structure for the
312 * running CPU and update the stime field there. 314 * running CPU and update the stime field there.
313 */ 315 */
314static inline void thread_group_cputime_account_system( 316static inline void account_group_system_time(struct task_struct *tsk,
315 struct thread_group_cputime *tgtimes, 317 cputime_t cputime)
316 cputime_t cputime)
317{ 318{
318 if (tgtimes->totals) { 319 struct signal_struct *sig;
320
321 sig = tsk->signal;
322 if (unlikely(!sig))
323 return;
324 if (sig->cputime.totals) {
319 struct task_cputime *times; 325 struct task_cputime *times;
320 326
321 times = per_cpu_ptr(tgtimes->totals, get_cpu()); 327 times = per_cpu_ptr(sig->cputime.totals, get_cpu());
322 times->stime = cputime_add(times->stime, cputime); 328 times->stime = cputime_add(times->stime, cputime);
323 put_cpu_no_resched(); 329 put_cpu_no_resched();
324 } 330 }
325} 331}
326 332
327/** 333/**
328 * thread_group_cputime_account_exec_runtime - Maintain exec runtime for a 334 * account_group_exec_runtime - Maintain exec runtime for a thread group.
329 * thread group.
330 * 335 *
331 * @tgtimes: Pointer to thread_group_cputime structure. 336 * @tsk: Pointer to task structure.
332 * @ns: Time value by which to increment the sum_exec_runtime field 337 * @ns: Time value by which to increment the sum_exec_runtime field
333 * of that structure. 338 * of the thread_group_cputime structure.
334 * 339 *
335 * If thread group time is being maintained, get the structure for the 340 * If thread group time is being maintained, get the structure for the
336 * running CPU and update the sum_exec_runtime field there. 341 * running CPU and update the sum_exec_runtime field there.
337 */ 342 */
338static inline void thread_group_cputime_account_exec_runtime( 343static inline void account_group_exec_runtime(struct task_struct *tsk,
339 struct thread_group_cputime *tgtimes, 344 unsigned long long ns)
340 unsigned long long ns)
341{ 345{
342 if (tgtimes->totals) { 346 struct signal_struct *sig;
347
348 sig = tsk->signal;
349 if (unlikely(!sig))
350 return;
351 if (sig->cputime.totals) {
343 struct task_cputime *times; 352 struct task_cputime *times;
344 353
345 times = per_cpu_ptr(tgtimes->totals, get_cpu()); 354 times = per_cpu_ptr(sig->cputime.totals, get_cpu());
346 times->sum_exec_runtime += ns; 355 times->sum_exec_runtime += ns;
347 put_cpu_no_resched(); 356 put_cpu_no_resched();
348 } 357 }
349} 358}
350
351#else /* CONFIG_SMP */
352
353static inline void thread_group_cputime_account_user(
354 struct thread_group_cputime *tgtimes,
355 cputime_t cputime)
356{
357 tgtimes->totals->utime = cputime_add(tgtimes->totals->utime, cputime);
358}
359
360static inline void thread_group_cputime_account_system(
361 struct thread_group_cputime *tgtimes,
362 cputime_t cputime)
363{
364 tgtimes->totals->stime = cputime_add(tgtimes->totals->stime, cputime);
365}
366
367static inline void thread_group_cputime_account_exec_runtime(
368 struct thread_group_cputime *tgtimes,
369 unsigned long long ns)
370{
371 tgtimes->totals->sum_exec_runtime += ns;
372}
373
374#endif /* CONFIG_SMP */
375
376/*
377 * These are the generic time-accounting routines that use the above
378 * functions. They are the functions actually called by the scheduler.
379 */
380static inline void account_group_user_time(struct task_struct *tsk,
381 cputime_t cputime)
382{
383 struct signal_struct *sig;
384
385 sig = tsk->signal;
386 if (likely(sig))
387 thread_group_cputime_account_user(&sig->cputime, cputime);
388}
389
390static inline void account_group_system_time(struct task_struct *tsk,
391 cputime_t cputime)
392{
393 struct signal_struct *sig;
394
395 sig = tsk->signal;
396 if (likely(sig))
397 thread_group_cputime_account_system(&sig->cputime, cputime);
398}
399
400static inline void account_group_exec_runtime(struct task_struct *tsk,
401 unsigned long long ns)
402{
403 struct signal_struct *sig;
404
405 sig = tsk->signal;
406 if (likely(sig))
407 thread_group_cputime_account_exec_runtime(&sig->cputime, ns);
408}