aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sched.h
diff options
context:
space:
mode:
authorFrank Mayhar <fmayhar@google.com>2008-09-12 12:54:39 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-23 07:38:44 -0400
commitbb34d92f643086d546b49cef680f6f305ed84414 (patch)
tree275887040c96971e133fa20d99517c1fcea76415 /include/linux/sched.h
parent5ce73a4a5a4893a1aa4cdeed1b1a5a6de42c43b6 (diff)
timers: fix itimer/many thread hang, v2
This is the second resubmission of the posix timer rework patch, posted a few days ago. This includes the changes from the previous resubmittion, which addressed Oleg Nesterov's comments, removing the RCU stuff from the patch and un-inlining the thread_group_cputime() function for SMP. In addition, per Ingo Molnar it simplifies the UP code, consolidating much of it with the SMP version and depending on lower-level SMP/UP handling to take care of the differences. It also cleans up some UP compile errors, moves the scheduler stats-related macros into kernel/sched_stats.h, cleans up a merge error in kernel/fork.c and has a few other minor fixes and cleanups as suggested by Oleg and Ingo. Thanks for the review, guys. Signed-off-by: Frank Mayhar <fmayhar@google.com> Cc: Roland McGrath <roland@redhat.com> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/sched.h')
-rw-r--r--include/linux/sched.h183
1 files changed, 5 insertions, 178 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7ce8d4e53565..b982fb48c8f0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -454,15 +454,9 @@ struct task_cputime {
454 * This structure contains the version of task_cputime, above, that is 454 * This structure contains the version of task_cputime, above, that is
455 * used for thread group CPU clock calculations. 455 * used for thread group CPU clock calculations.
456 */ 456 */
457#ifdef CONFIG_SMP
458struct thread_group_cputime { 457struct thread_group_cputime {
459 struct task_cputime *totals; 458 struct task_cputime *totals;
460}; 459};
461#else
462struct thread_group_cputime {
463 struct task_cputime totals;
464};
465#endif
466 460
467/* 461/*
468 * NOTE! "signal_struct" does not have it's own 462 * NOTE! "signal_struct" does not have it's own
@@ -2124,193 +2118,26 @@ static inline int spin_needbreak(spinlock_t *lock)
2124/* 2118/*
2125 * Thread group CPU time accounting. 2119 * Thread group CPU time accounting.
2126 */ 2120 */
2127#ifdef CONFIG_SMP
2128 2121
2129extern int thread_group_cputime_alloc_smp(struct task_struct *); 2122extern int thread_group_cputime_alloc(struct task_struct *);
2130extern void thread_group_cputime_smp(struct task_struct *, struct task_cputime *); 2123extern void thread_group_cputime(struct task_struct *, struct task_cputime *);
2131 2124
2132static inline void thread_group_cputime_init(struct signal_struct *sig) 2125static inline void thread_group_cputime_init(struct signal_struct *sig)
2133{ 2126{
2134 sig->cputime.totals = NULL; 2127 sig->cputime.totals = NULL;
2135} 2128}
2136 2129
2137static inline int thread_group_cputime_clone_thread(struct task_struct *curr, 2130static inline int thread_group_cputime_clone_thread(struct task_struct *curr)
2138 struct task_struct *new)
2139{ 2131{
2140 if (curr->signal->cputime.totals) 2132 if (curr->signal->cputime.totals)
2141 return 0; 2133 return 0;
2142 return thread_group_cputime_alloc_smp(curr); 2134 return thread_group_cputime_alloc(curr);
2143} 2135}
2144 2136
2145static inline void thread_group_cputime_free(struct signal_struct *sig)
2146{
2147 free_percpu(sig->cputime.totals);
2148}
2149
2150/**
2151 * thread_group_cputime - Sum the thread group time fields across all CPUs.
2152 *
2153 * This is a wrapper for the real routine, thread_group_cputime_smp(). See
2154 * that routine for details.
2155 */
2156static inline void thread_group_cputime(
2157 struct task_struct *tsk,
2158 struct task_cputime *times)
2159{
2160 thread_group_cputime_smp(tsk, times);
2161}
2162
2163/**
2164 * thread_group_cputime_account_user - Maintain utime for a thread group.
2165 *
2166 * @tgtimes: Pointer to thread_group_cputime structure.
2167 * @cputime: Time value by which to increment the utime field of that
2168 * structure.
2169 *
2170 * If thread group time is being maintained, get the structure for the
2171 * running CPU and update the utime field there.
2172 */
2173static inline void thread_group_cputime_account_user(
2174 struct thread_group_cputime *tgtimes,
2175 cputime_t cputime)
2176{
2177 if (tgtimes->totals) {
2178 struct task_cputime *times;
2179
2180 times = per_cpu_ptr(tgtimes->totals, get_cpu());
2181 times->utime = cputime_add(times->utime, cputime);
2182 put_cpu_no_resched();
2183 }
2184}
2185
2186/**
2187 * thread_group_cputime_account_system - Maintain stime for a thread group.
2188 *
2189 * @tgtimes: Pointer to thread_group_cputime structure.
2190 * @cputime: Time value by which to increment the stime field of that
2191 * structure.
2192 *
2193 * If thread group time is being maintained, get the structure for the
2194 * running CPU and update the stime field there.
2195 */
2196static inline void thread_group_cputime_account_system(
2197 struct thread_group_cputime *tgtimes,
2198 cputime_t cputime)
2199{
2200 if (tgtimes->totals) {
2201 struct task_cputime *times;
2202
2203 times = per_cpu_ptr(tgtimes->totals, get_cpu());
2204 times->stime = cputime_add(times->stime, cputime);
2205 put_cpu_no_resched();
2206 }
2207}
2208
2209/**
2210 * thread_group_cputime_account_exec_runtime - Maintain exec runtime for a
2211 * thread group.
2212 *
2213 * @tgtimes: Pointer to thread_group_cputime structure.
2214 * @ns: Time value by which to increment the sum_exec_runtime field
2215 * of that structure.
2216 *
2217 * If thread group time is being maintained, get the structure for the
2218 * running CPU and update the sum_exec_runtime field there.
2219 */
2220static inline void thread_group_cputime_account_exec_runtime(
2221 struct thread_group_cputime *tgtimes,
2222 unsigned long long ns)
2223{
2224 if (tgtimes->totals) {
2225 struct task_cputime *times;
2226
2227 times = per_cpu_ptr(tgtimes->totals, get_cpu());
2228 times->sum_exec_runtime += ns;
2229 put_cpu_no_resched();
2230 }
2231}
2232
2233#else /* CONFIG_SMP */
2234
2235static inline void thread_group_cputime_init(struct signal_struct *sig)
2236{
2237 sig->cputime.totals.utime = cputime_zero;
2238 sig->cputime.totals.stime = cputime_zero;
2239 sig->cputime.totals.sum_exec_runtime = 0;
2240}
2241
2242static inline int thread_group_cputime_alloc(struct task_struct *tsk)
2243{
2244 return 0;
2245}
2246 2137
2247static inline void thread_group_cputime_free(struct signal_struct *sig) 2138static inline void thread_group_cputime_free(struct signal_struct *sig)
2248{ 2139{
2249} 2140 free_percpu(sig->cputime.totals);
2250
2251static inline int thread_group_cputime_clone_thread(struct task_struct *curr,
2252 struct task_struct *tsk)
2253{
2254 return 0;
2255}
2256
2257static inline void thread_group_cputime(struct task_struct *tsk,
2258 struct task_cputime *cputime)
2259{
2260 *cputime = tsk->signal->cputime.totals;
2261}
2262
2263static inline void thread_group_cputime_account_user(
2264 struct thread_group_cputime *tgtimes,
2265 cputime_t cputime)
2266{
2267 tgtimes->totals.utime = cputime_add(tgtimes->totals.utime, cputime);
2268}
2269
2270static inline void thread_group_cputime_account_system(
2271 struct thread_group_cputime *tgtimes,
2272 cputime_t cputime)
2273{
2274 tgtimes->totals.stime = cputime_add(tgtimes->totals.stime, cputime);
2275}
2276
2277static inline void thread_group_cputime_account_exec_runtime(
2278 struct thread_group_cputime *tgtimes,
2279 unsigned long long ns)
2280{
2281 tgtimes->totals.sum_exec_runtime += ns;
2282}
2283
2284#endif /* CONFIG_SMP */
2285
2286static inline void account_group_user_time(struct task_struct *tsk,
2287 cputime_t cputime)
2288{
2289 struct signal_struct *sig;
2290
2291 sig = tsk->signal;
2292 if (likely(sig))
2293 thread_group_cputime_account_user(&sig->cputime, cputime);
2294}
2295
2296static inline void account_group_system_time(struct task_struct *tsk,
2297 cputime_t cputime)
2298{
2299 struct signal_struct *sig;
2300
2301 sig = tsk->signal;
2302 if (likely(sig))
2303 thread_group_cputime_account_system(&sig->cputime, cputime);
2304}
2305
2306static inline void account_group_exec_runtime(struct task_struct *tsk,
2307 unsigned long long ns)
2308{
2309 struct signal_struct *sig;
2310
2311 sig = tsk->signal;
2312 if (likely(sig))
2313 thread_group_cputime_account_exec_runtime(&sig->cputime, ns);
2314} 2141}
2315 2142
2316/* 2143/*