diff options
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 4 | ||||
-rw-r--r-- | include/linux/sched.h | 8 | ||||
-rw-r--r-- | kernel/kthread.c | 2 | ||||
-rw-r--r-- | kernel/ptrace.c | 2 | ||||
-rw-r--r-- | kernel/sched.c | 29 |
5 files changed, 37 insertions, 8 deletions
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 19d4493c6193..fc8f3509df27 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -2626,7 +2626,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task) | |||
2626 | /* | 2626 | /* |
2627 | * make sure the task is off any CPU | 2627 | * make sure the task is off any CPU |
2628 | */ | 2628 | */ |
2629 | wait_task_inactive(task); | 2629 | wait_task_inactive(task, 0); |
2630 | 2630 | ||
2631 | /* more to come... */ | 2631 | /* more to come... */ |
2632 | 2632 | ||
@@ -4774,7 +4774,7 @@ recheck: | |||
4774 | 4774 | ||
4775 | UNPROTECT_CTX(ctx, flags); | 4775 | UNPROTECT_CTX(ctx, flags); |
4776 | 4776 | ||
4777 | wait_task_inactive(task); | 4777 | wait_task_inactive(task, 0); |
4778 | 4778 | ||
4779 | PROTECT_CTX(ctx, flags); | 4779 | PROTECT_CTX(ctx, flags); |
4780 | 4780 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index a95d84d0da95..f59318a0099b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1882,9 +1882,13 @@ extern void set_task_comm(struct task_struct *tsk, char *from); | |||
1882 | extern char *get_task_comm(char *to, struct task_struct *tsk); | 1882 | extern char *get_task_comm(char *to, struct task_struct *tsk); |
1883 | 1883 | ||
1884 | #ifdef CONFIG_SMP | 1884 | #ifdef CONFIG_SMP |
1885 | extern void wait_task_inactive(struct task_struct * p); | 1885 | extern unsigned long wait_task_inactive(struct task_struct *, long match_state); |
1886 | #else | 1886 | #else |
1887 | #define wait_task_inactive(p) do { } while (0) | 1887 | static inline unsigned long wait_task_inactive(struct task_struct *p, |
1888 | long match_state) | ||
1889 | { | ||
1890 | return 1; | ||
1891 | } | ||
1888 | #endif | 1892 | #endif |
1889 | 1893 | ||
1890 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) | 1894 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) |
diff --git a/kernel/kthread.c b/kernel/kthread.c index 6111c27491b1..96cff2f8710b 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -176,7 +176,7 @@ void kthread_bind(struct task_struct *k, unsigned int cpu) | |||
176 | return; | 176 | return; |
177 | } | 177 | } |
178 | /* Must have done schedule() in kthread() before we set_task_cpu */ | 178 | /* Must have done schedule() in kthread() before we set_task_cpu */ |
179 | wait_task_inactive(k); | 179 | wait_task_inactive(k, 0); |
180 | set_task_cpu(k, cpu); | 180 | set_task_cpu(k, cpu); |
181 | k->cpus_allowed = cpumask_of_cpu(cpu); | 181 | k->cpus_allowed = cpumask_of_cpu(cpu); |
182 | k->rt.nr_cpus_allowed = 1; | 182 | k->rt.nr_cpus_allowed = 1; |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 8392a9da6450..082b3fcb32a0 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -107,7 +107,7 @@ int ptrace_check_attach(struct task_struct *child, int kill) | |||
107 | read_unlock(&tasklist_lock); | 107 | read_unlock(&tasklist_lock); |
108 | 108 | ||
109 | if (!ret && !kill) | 109 | if (!ret && !kill) |
110 | wait_task_inactive(child); | 110 | ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; |
111 | 111 | ||
112 | /* All systems go.. */ | 112 | /* All systems go.. */ |
113 | return ret; | 113 | return ret; |
diff --git a/kernel/sched.c b/kernel/sched.c index fde1a1026359..0236958addcb 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -1867,16 +1867,24 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) | |||
1867 | /* | 1867 | /* |
1868 | * wait_task_inactive - wait for a thread to unschedule. | 1868 | * wait_task_inactive - wait for a thread to unschedule. |
1869 | * | 1869 | * |
1870 | * If @match_state is nonzero, it's the @p->state value just checked and | ||
1871 | * not expected to change. If it changes, i.e. @p might have woken up, | ||
1872 | * then return zero. When we succeed in waiting for @p to be off its CPU, | ||
1873 | * we return a positive number (its total switch count). If a second call | ||
1874 | * a short while later returns the same number, the caller can be sure that | ||
1875 | * @p has remained unscheduled the whole time. | ||
1876 | * | ||
1870 | * The caller must ensure that the task *will* unschedule sometime soon, | 1877 | * The caller must ensure that the task *will* unschedule sometime soon, |
1871 | * else this function might spin for a *long* time. This function can't | 1878 | * else this function might spin for a *long* time. This function can't |
1872 | * be called with interrupts off, or it may introduce deadlock with | 1879 | * be called with interrupts off, or it may introduce deadlock with |
1873 | * smp_call_function() if an IPI is sent by the same process we are | 1880 | * smp_call_function() if an IPI is sent by the same process we are |
1874 | * waiting to become inactive. | 1881 | * waiting to become inactive. |
1875 | */ | 1882 | */ |
1876 | void wait_task_inactive(struct task_struct *p) | 1883 | unsigned long wait_task_inactive(struct task_struct *p, long match_state) |
1877 | { | 1884 | { |
1878 | unsigned long flags; | 1885 | unsigned long flags; |
1879 | int running, on_rq; | 1886 | int running, on_rq; |
1887 | unsigned long ncsw; | ||
1880 | struct rq *rq; | 1888 | struct rq *rq; |
1881 | 1889 | ||
1882 | for (;;) { | 1890 | for (;;) { |
@@ -1899,8 +1907,11 @@ void wait_task_inactive(struct task_struct *p) | |||
1899 | * return false if the runqueue has changed and p | 1907 | * return false if the runqueue has changed and p |
1900 | * is actually now running somewhere else! | 1908 | * is actually now running somewhere else! |
1901 | */ | 1909 | */ |
1902 | while (task_running(rq, p)) | 1910 | while (task_running(rq, p)) { |
1911 | if (match_state && unlikely(p->state != match_state)) | ||
1912 | return 0; | ||
1903 | cpu_relax(); | 1913 | cpu_relax(); |
1914 | } | ||
1904 | 1915 | ||
1905 | /* | 1916 | /* |
1906 | * Ok, time to look more closely! We need the rq | 1917 | * Ok, time to look more closely! We need the rq |
@@ -1910,9 +1921,21 @@ void wait_task_inactive(struct task_struct *p) | |||
1910 | rq = task_rq_lock(p, &flags); | 1921 | rq = task_rq_lock(p, &flags); |
1911 | running = task_running(rq, p); | 1922 | running = task_running(rq, p); |
1912 | on_rq = p->se.on_rq; | 1923 | on_rq = p->se.on_rq; |
1924 | ncsw = 0; | ||
1925 | if (!match_state || p->state == match_state) { | ||
1926 | ncsw = p->nivcsw + p->nvcsw; | ||
1927 | if (unlikely(!ncsw)) | ||
1928 | ncsw = 1; | ||
1929 | } | ||
1913 | task_rq_unlock(rq, &flags); | 1930 | task_rq_unlock(rq, &flags); |
1914 | 1931 | ||
1915 | /* | 1932 | /* |
1933 | * If it changed from the expected state, bail out now. | ||
1934 | */ | ||
1935 | if (unlikely(!ncsw)) | ||
1936 | break; | ||
1937 | |||
1938 | /* | ||
1916 | * Was it really running after all now that we | 1939 | * Was it really running after all now that we |
1917 | * checked with the proper locks actually held? | 1940 | * checked with the proper locks actually held? |
1918 | * | 1941 | * |
@@ -1944,6 +1967,8 @@ void wait_task_inactive(struct task_struct *p) | |||
1944 | */ | 1967 | */ |
1945 | break; | 1968 | break; |
1946 | } | 1969 | } |
1970 | |||
1971 | return ncsw; | ||
1947 | } | 1972 | } |
1948 | 1973 | ||
1949 | /*** | 1974 | /*** |