Skip to contentSkip to conversation

: scheduler complex macros fixes

PATCH mgross 4 participants 9 messages Jul 19, 2002 – Jul 20, 2002

Subsystems (3)
lore
Share & tools
lore

mgross

author
#0 lore raw
Quoted 6 lines · Linus Torvalds
Quoted 4 lines · Ingo Molnar

 well, SCHED_BATCH is in fact ready, so we might as well put it in. All the suggestions mentioned on lkml (or in private) are now included, there are no pending (known) problems, no objections, and a number of people are using it with success.

Quoted 6 lines

Well, I do actually have objections, mainly because I think it modifies code that I'd rather have cleaned up in other ways _first_ (ie the return path to user mode, which has pending irq_count/bh_count/preempt issues that I consider to be about a million times more important than batch scheduling).

Thats too bad. I've been looking at Ingo's SCHED_BATCH design to help suspend processes with out lock problems while doing multithreaded core dumps.

Is there any ETA on the return path to user mode clean up?

--mgross

#1 lore raw

Hmmm, somebody must have forwarded the patch from LKML to linux-ia64... I would like to clarify that my last O(1) scheduler patch for IA64 already contains the fixes. That patch was for 2.4.18 kernels. The patch which I've sent to LKML is for the 2.5.26 kernel, which we don't have on IA64, yet.

Regards,
Erich

#2 lore raw
In reply to mgross

Hi Ingo,

Quoted 4 lines · Ingo Molnar
Quoted 2 lines · Erich Focht

The attached patch fixes problems with the "complex" macros in the scheduler, as discussed about a week ago with Ingo on this mailing list.

Quoted 8 lines

the fix has been in my tree for some time, the latest version, against 2.5.26 is at:

http://people.redhat.com/mingo/O(1)-scheduler/sched-2.5.26-B7

it has a number of other fixes as well, plus the SCHED_BATCH feature.

Ingo

Thanks. But as long as SCHED_BATCH ins't in 2.5.X, we need this separate fix. And if it's in the main tree, you don't need it additionally in your patches. The fix is O(1) specific and I thought it should not hide inside the SCHED_BATCH patches, some people might encounter these problems...

Regards,
Erich

#3 lore raw
In reply to mgross
Quoted 5 lines · Ingo Molnar

well, SCHED_BATCH is in fact ready, so we might as well put it in. All the suggestions mentioned on lkml (or in private) are now included, there are no pending (known) problems, no objections, and a number of people are using it with success.

Well, I do actually have objections, mainly because I think it modifies code that I'd rather have cleaned up in other ways _first_ (ie the return path to user mode, which has pending irq_count/bh_count/preempt issues that I consider to be about a million times more important than batch scheduling).

So I'd rather have the non-batch stuff done first and independently.

Linus

#4 lore raw
In reply to mgross

Hi Ingo,

Quoted 7 lines · Ingo Molnar
Quoted 1 line · Linus Torvalds

So I'd rather have the non-batch stuff done first and independently.

sure - all the non-batch bits are attached, against 2.5.26-vanilla. It compiles & boots just fine on UP & SMP as well.

Ingo

thanks for the complete update without the SCHED_BATCH! I was too lazy to strip out all your changes and I'm sure I would have made mistakes...

Best regards,
Erich

#6 lore raw
In reply to mgross
Quoted 5 lines · Erich Focht

Thanks. But as long as SCHED_BATCH ins't in 2.5.X, we need this separate fix. And if it's in the main tree, you don't need it additionally in your patches. The fix is O(1) specific and I thought it should not hide inside the SCHED_BATCH patches, some people might encounter these problems...

well, SCHED_BATCH is in fact ready, so we might as well put it in. All the suggestions mentioned on lkml (or in private) are now included, there are no pending (known) problems, no objections, and a number of people are using it with success.

Ingo

#7 lore raw
In reply to mgross
Quoted 1 line · Linus Torvalds

So I'd rather have the non-batch stuff done first and independently.

sure - all the non-batch bits are attached, against 2.5.26-vanilla. It compiles & boots just fine on UP & SMP as well.

Ingo

include/linux/sched.h renamed from include/linux/sched.h.orig +7 -3
@@ -116,10 +116,11 @@
 /*
  * Scheduling policies
  */
-#define SCHED_OTHER		0
+#define SCHED_NORMAL		0
 #define SCHED_FIFO		1
 #define SCHED_RR		2
 
+
 struct sched_param {
 	int sched_priority;
 };
@@ -207,7 +209,7 @@
 
 /*
  * Priority of a process goes from 0..MAX_PRIO-1, valid RT
- * priority is 0..MAX_RT_PRIO-1, and SCHED_OTHER tasks are
+ * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL tasks are
  * in the range MAX_RT_PRIO..MAX_PRIO-1. Priority values
  * are inverted: lower p->prio value means higher priority.
  *
@@ -264,7 +266,7 @@
 
 	unsigned long policy;
 	unsigned long cpus_allowed;
-	unsigned int time_slice;
+	unsigned int time_slice, first_time_slice;
 
 	struct list_head tasks;
 
@@ -359,6 +361,8 @@
    	u32 self_exec_id;
 /* Protection of (de-)allocation: mm, files, fs, tty */
 	spinlock_t alloc_lock;
+/* context-switch lock */
+	spinlock_t switch_lock;
 
 /* journalling filesystem info */
 	void *journal_info;
@@ -391,6 +395,7 @@
 #define PF_IOTHREAD	0x00020000	/* this thread is needed for doing I/O to swap */
 #define PF_FROZEN	0x00040000	/* frozen for system suspend */
 #define PF_INVALIDATE	0x00080000	/* debug: unmounting an fs. killme. */
+
 /*
  * Ptrace flags
  */
include/linux/init_task.h renamed from include/linux/init_task.h.orig +2 -1
@@ -47,7 +47,7 @@
     lock_depth:		-1,						\
     prio:		MAX_PRIO-20,					\
     static_prio:	MAX_PRIO-20,					\
-    policy:		SCHED_OTHER,					\
+    policy:		SCHED_NORMAL,					\
     cpus_allowed:	-1,						\
     mm:			NULL,						\
     active_mm:		&init_mm,					\
@@ -78,6 +78,7 @@
     pending:		{ NULL, &tsk.pending.head, {{0}}},		\
     blocked:		{{0}},						\
     alloc_lock:		SPIN_LOCK_UNLOCKED,				\
+    switch_lock:	SPIN_LOCK_UNLOCKED,				\
     journal_info:	NULL,						\
 }
 
include/asm-x86_64/system.h renamed from include/asm-x86_64/system.h.orig +0 -5
@@ -13,11 +13,6 @@
 #define LOCK_PREFIX ""
 #endif
 
-#define prepare_arch_schedule(prev)            do { } while(0)
-#define finish_arch_schedule(prev)             do { } while(0)
-#define prepare_arch_switch(rq)                        do { } while(0)
-#define finish_arch_switch(rq)                 spin_unlock_irq(&(rq)->lock)
-
 #define __STR(x) #x
 #define STR(x) __STR(x)
 
include/asm-ppc/system.h renamed from include/asm-ppc/system.h.orig +0 -5
@@ -83,11 +83,6 @@
 struct device_node;
 extern void note_scsi_host(struct device_node *, void *);
 
-#define prepare_arch_schedule(prev)		do { } while(0)
-#define finish_arch_schedule(prev)		do { } while(0)
-#define prepare_arch_switch(rq)			do { } while(0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 struct task_struct;
 extern void __switch_to(struct task_struct *, struct task_struct *);
 #define switch_to(prev, next, last)	__switch_to((prev), (next))
include/asm-s390x/system.h renamed from include/asm-s390x/system.h.orig +0 -5
@@ -18,11 +18,6 @@
 #endif
 #include <linux/kernel.h>
 
-#define prepare_arch_schedule(prev)		do { } while (0)
-#define finish_arch_schedule(prev)		do { } while (0)
-#define prepare_arch_switch(rq)			do { } while (0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 #define switch_to(prev,next),last do {					     \
 	if (prev = next)						     \
 		break;							     \
include/asm-s390/system.h renamed from include/asm-s390/system.h.orig +0 -5
@@ -18,11 +18,6 @@
 #endif
 #include <linux/kernel.h>
 
-#define prepare_arch_schedule(prev)		do { } while (0)
-#define finish_arch_schedule(prev)		do { } while (0)
-#define prepare_arch_switch(rq)			do { } while (0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 #define switch_to(prev,next,last) do {					     \
 	if (prev = next)						     \
 		break;							     \
include/asm-sparc64/system.h renamed from include/asm-sparc64/system.h.orig +8 -6
@@ -144,13 +144,15 @@
 #define flush_user_windows flushw_user
 #define flush_register_windows flushw_all
 
-#define prepare_arch_schedule(prev)	task_lock(prev)
-#define finish_arch_schedule(prev)	task_unlock(prev)
-#define prepare_arch_switch(rq)		\
-do {	spin_unlock(&(rq)->lock);	\
-	flushw_all();			\
+#define prepare_arch_switch(rq, next)		\
+do {	spin_lock(&(next)->switch_lock);	\
+	spin_unlock(&(rq)->lock);		\
+	flushw_all();				\
+} while (0)
+
+#define finish_arch_switch(rq, prev)		\
+do {	spin_unlock_irq(&(prev)->switch_lock);	\
 } while (0)
-#define finish_arch_switch(rq)		__sti()
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 #define CHECK_LOCKS(PREV)	do { } while(0)
include/asm-i386/system.h renamed from include/asm-i386/system.h.orig +0 -5
@@ -11,11 +11,6 @@
 struct task_struct;	/* one of the stranger aspects of C forward declarations.. */
 extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
 
-#define prepare_arch_schedule(prev)		do { } while(0)
-#define finish_arch_schedule(prev)		do { } while(0)
-#define prepare_arch_switch(rq)			do { } while(0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 #define switch_to(prev,next,last) do {					\
 	asm volatile("pushl %%esi\n\t"					\
 		     "pushl %%edi\n\t"					\
kernel/timer.c renamed from kernel/timer.c.orig +1 -1
@@ -888,7 +888,7 @@
 
 
 	if (t.tv_sec = 0 && t.tv_nsec <= 2000000L &&
-	    current->policy != SCHED_OTHER)
+	    current->policy != SCHED_NORMAL)
 	{
 		/*
 		 * Short delay requests up to 2 ms will be handled with
kernel/fork.c renamed from kernel/fork.c.orig +7 -3
@@ -615,7 +615,6 @@
 			    unsigned long stack_size)
 {
 	int retval;
-	unsigned long flags;
 	struct task_struct *p = NULL;
 	struct completion vfork;
 
@@ -675,6 +674,7 @@
 		init_completion(&vfork);
 	}
 	spin_lock_init(&p->alloc_lock);
+	spin_lock_init(&p->switch_lock);
 
 	clear_tsk_thread_flag(p,TIF_SIGPENDING);
 	init_sigpending(&p->pending);
@@ -737,9 +737,13 @@
 	 * total amount of pending timeslices in the system doesnt change,
 	 * resulting in more scheduling fairness.
 	 */
-	__save_flags(flags);
 	__cli();
 	p->time_slice = (current->time_slice + 1) >> 1;
+	/*
+	 * The remainder of the first timeslice might be recovered by
+	 * the parent if the child exits early enough.
+	 */
+	p->first_time_slice = 1;
 	current->time_slice >>= 1;
 	if (!current->time_slice) {
 		/*
@@ -751,7 +755,7 @@
 		scheduler_tick(0, 0);
 	}
 	p->sleep_timestamp = jiffies;
-	__restore_flags(flags);
+	__sti();
 
 	/*
 	 * Ok, add it to the run-queues and make it
kernel/sched.c renamed from kernel/sched.c.orig +218 -194

678 lines not on this page · raw message

kernel/signal.c renamed from kernel/signal.c.orig +1 -3
@@ -500,7 +500,6 @@
 {
 	set_tsk_thread_flag(t,TIF_SIGPENDING);
 
-#ifdef CONFIG_SMP
 	/*
 	 * If the task is running on a different CPU 
 	 * force a reschedule on the other CPU to make
@@ -511,9 +510,8 @@
 	 * process of changing - but no harm is done by that
 	 * other than doing an extra (lightweight) IPI interrupt.
 	 */
-	if ((t->state = TASK_RUNNING) && (t->thread_info->cpu != smp_processor_id()))
+	if (t->state = TASK_RUNNING)
 		kick_if_running(t);
-#endif
 	if (t->state & TASK_INTERRUPTIBLE) {
 		wake_up_process(t);
 		return;
kernel/exit.c renamed from kernel/exit.c.orig +1 -1
@@ -182,7 +182,7 @@
 	current->exit_signal = SIGCHLD;
 
 	current->ptrace = 0;
-	if ((current->policy = SCHED_OTHER) && (task_nice(current) < 0))
+	if ((current->policy = SCHED_NORMAL) && (task_nice(current) < 0))
 		set_user_nice(current, 0);
 	/* cpus_allowed? */
 	/* rt_priority? */
#8 lore raw
In reply to mgross
Quoted 5 lines · mgross

Thats too bad. I've been looking at Ingo's SCHED_BATCH design to help suspend processes with out lock problems while doing multithreaded core dumps.

Is there any ETA on the return path to user mode clean up?

oh, there's no fundamental problem here, i'm doing the return-path-cleanup patch too :-) [which, as a side-effect, also removes the global irq lock.] I temporarily suspended it for the sake of the SCHED_BATCH feature and other scheduler maintainance work. But it just got higher priority, so ...

Ingo