[patch] preempt-cleanup.patch, 2.6.9-rc2

Ingo Molnar
2004-09-14T09:17:00Z

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

the attached patch is ontop of preempt-smp.patch. This is another
generic fallout from the voluntary-preempt patchset: a cleanup of the
cond_resched() infrastructure, in preparation of the latency reduction
patches. The changes:

- uninline cond_resched() - this makes the footprint smaller,
especially once the number of cond_resched() points increase.

- add a 'was rescheduled' return value to cond_resched. This makes it
symmetric to cond_resched_lock() and later latency reduction patches
rely on the ability to tell whether there was any preemption.

- make cond_resched() more robust by using the same mechanism as
preempt_kernel(): by using PREEMPT_ACTIVE. This preserves the task's
state - e.g. if the task is in TASK_ZOMBIE but gets preempted via
cond_resched() just prior scheduling off then this approach preserves
TASK_ZOMBIE.

- the patch also adds need_lockbreak() which critical sections can use
to detect lock-break requests.

i've tested the patch on x86 SMP and UP.

Ingo

[-- Attachment #2: preempt-cleanup.patch --]
[-- Type: text/plain, Size: 2972 bytes --]

the attached patch is ontop of preempt-smp.patch. This is another
generic fallout from the voluntary-preempt patchset: a cleanup of the
cond_resched() infrastructure, in preparation of the latency reduction
patches. The changes:

- uninline cond_resched() - this makes the footprint smaller,
especially once the number of cond_resched() points increase.

- add a 'was rescheduled' return value to cond_resched. This makes it
symmetric to cond_resched_lock() and later latency reduction patches
rely on the ability to tell whether there was any preemption.

- make cond_resched() more robust by using the same mechanism as
preempt_kernel(): by using PREEMPT_ACTIVE. This preserves the task's
state - e.g. if the task is in TASK_ZOMBIE but gets preempted via
cond_resched() just prior scheduling off then this approach preserves
TASK_ZOMBIE.

- the patch also adds need_lockbreak() which critical sections can use
to detect lock-break requests.

i've tested the patch on x86 SMP and UP.

Signed-off-by: Ingo Molnar <mingo@elte.hu>

--- linux/include/linux/sched.h.orig
+++ linux/include/linux/sched.h
@@ -951,15 +951,24 @@ static inline int need_resched(void)
return unlikely(test_thread_flag(TIF_NEED_RESCHED));
}

-extern void __cond_resched(void);
-static inline void cond_resched(void)
-{
- if (need_resched())
- __cond_resched();
-}
-
+/*
+ * cond_resched() and cond_resched_lock(): latency reduction via
+ * explicit rescheduling in places that are safe. The return
+ * value indicates whether a reschedule was done in fact.
+ */
+extern int cond_resched(void);
extern int cond_resched_lock(spinlock_t * lock);

+/*
+ * Does a critical section need to be broken due to another
+ * task waiting?:
+ */
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
+# define need_lockbreak(lock) ((lock)->break_lock)
+#else
+# define need_lockbreak(lock) 0
+#endif
+
/* Reevaluate whether the task has signals pending delivery.
This is required every time the blocked sigset_t changes.
callers must hold sighand->siglock. */
--- linux/kernel/sched.c.orig
+++ linux/kernel/sched.c
@@ -3539,13 +3539,25 @@ asmlinkage long sys_sched_yield(void)
return 0;
}

-void __sched __cond_resched(void)
+static inline void __cond_resched(void)
{
- set_current_state(TASK_RUNNING);
- schedule();
+ do {
+ preempt_count() += PREEMPT_ACTIVE;
+ schedule();
+ preempt_count() -= PREEMPT_ACTIVE;
+ } while (need_resched());
}

-EXPORT_SYMBOL(__cond_resched);
+int __sched cond_resched(void)
+{
+ if (need_resched()) {
+ __cond_resched();
+ return 1;
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL(cond_resched);

/*
* cond_resched_lock() - if a reschedule is pending, drop the given lock,
@@ -3568,8 +3580,7 @@ int cond_resched_lock(spinlock_t * lock)
if (need_resched()) {
_raw_spin_unlock(lock);
preempt_enable_no_resched();
- set_current_state(TASK_RUNNING);
- schedule();
+ __cond_resched();
spin_lock(lock);
return 1;
}