FreeBSD boots with modified FW RR-scheduler.
authorJens Krieg <jkrieg@mailbox.tu-berlin.de>
Wed, 8 Jan 2014 12:02:51 +0000 (13:02 +0100)
committerJens Krieg <jkrieg@mailbox.tu-berlin.de>
Wed, 8 Jan 2014 12:02:51 +0000 (13:02 +0100)
sys/amd64/conf/kernel_x86_64-conf
sys/conf/files
sys/kern/sched_ule.c
sys/kern/sched_ule_org.c [moved from sys/kern/sched_ule_orig.c with 99% similarity]
sys/kern/subr_sleepqueue.c
sys/sys/proc.h

index 84e27c4..1f5e5e8 100644 (file)
@@ -70,7 +70,7 @@ options       KDB                     # Kernel debugger related code
 options        KDB_TRACE               # Print a stack trace for a panic
 
 # Make an SMP-capable kernel by default
-options        SMP                     # Symmetric MultiProcessor Kernel
+#options       SMP                     # Symmetric MultiProcessor Kernel
 
 # CPU frequency control
 device         cpufreq
index 577cb46..6898601 100644 (file)
@@ -3547,6 +3547,7 @@ framework/lib/fw.c                      optional fw_mod_sched
 framework/lib/fw_modules.c              optional fw_mod_sched
 framework/lib/fw_comm.c                 optional fw_mod_sched
 framework/lib/fw_list.c                 optional fw_mod_sched
+framework/lib/fw_sched.c                optional fw_mod_sched
 framework/modules/round_robin.c         optional fw_mod_sched
 framework/os/freebsd/os.c               optional fw_mod_sched
 framework/os/freebsd/os_kdb.c           optional fw_mod_sched
index 2bf6c3c..0894425 100644 (file)
@@ -106,6 +106,9 @@ struct td_sched {
        int             ts_ltick;       /* Last tick that we were running on */
        int             ts_ftick;       /* First tick that we were running on */
        int             ts_ticks;       /* Tick count */
+
+       struct fw_task fw_task;
+
 #ifdef KTR
        char            ts_name[TS_NAME_LEN];
 #endif
@@ -448,6 +451,8 @@ static __inline void
 tdq_runq_add(struct tdq *tdq, struct thread *td, int flags)
 {
        struct td_sched *ts;
+       struct fw_queues *q = cpu_queue(0);
+       struct fw_task *p = &td->td_sched->fw_task;
 //     u_char pri;
 
        TDQ_LOCK_ASSERT(tdq, MA_OWNED);
@@ -461,6 +466,7 @@ tdq_runq_add(struct tdq *tdq, struct thread *td, int flags)
                tdq->tdq_transferable++;
                ts->ts_flags |= TSF_XFERABLE;
        }
+
 //     if (pri < PRI_MIN_BATCH) {
 //             ts->ts_runq = &tdq->tdq_realtime;
 //     } else if (pri <= PRI_MAX_BATCH) {
@@ -501,7 +507,14 @@ tdq_runq_add(struct tdq *tdq, struct thread *td, int flags)
                runq_add_pri(ts->ts_runq, td, 0, flags);
        }
        else {
-               if (td->td_flags & TDF_IDLETD) printf("IDLE incomming\n");
+
+               /*
+                * Announce task to framework.
+                */
+               p->real_task = td;
+               p->state = FW_READY;
+               fw_notify(FW_ADMIT, (void*)p);
+
                ts->ts_runq = &tdq->tdq_timeshare;
                runq_add_pri(ts->ts_runq, td, 0, flags);
        }
@@ -526,6 +539,13 @@ tdq_runq_rem(struct tdq *tdq, struct thread *td)
                tdq->tdq_transferable--;
                ts->ts_flags &= ~TSF_XFERABLE;
        }
+
+       /**
+        * Remove framework task.
+        */
+//     fw_notify(FW_RELEASE, (void*)&td->td_sched->fw_task);
+//     fw_notify(FW_EVENT_WAIT, (void*)&td->td_sched->fw_task);
+
        if (ts->ts_runq == &tdq->tdq_timeshare) {
                if (tdq->tdq_idx != tdq->tdq_ridx)
                        runq_remove_idx(ts->ts_runq, td, &tdq->tdq_ridx);
@@ -1609,7 +1629,6 @@ sched_initticks(void *dummy)
 void
 schedinit(void)
 {
-
        /*
         * Set up the scheduler specific parts of proc0.
         */
@@ -1882,6 +1901,9 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
        int srqflag;
        int cpuid;
 
+       struct fw_queues *q = cpu_queue(0);
+
+
        THREAD_LOCK_ASSERT(td, MA_OWNED);
        KASSERT(newtd == NULL, ("sched_switch: Unsupported newtd argument"));
 
@@ -1917,6 +1939,7 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
 #endif
                if (ts->ts_cpu == cpuid)
                        tdq_runq_add(tdq, td, srqflag);
+//                     printf("");
                else {
                        KASSERT(THREAD_CAN_MIGRATE(td) ||
                            (ts->ts_flags & TSF_BOUND) != 0,
@@ -1928,6 +1951,7 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
                TDQ_LOCK(tdq);
                mtx = thread_lock_block(td);
                tdq_load_rem(tdq, td);
+
        }
        /*
         * We enter here with the thread blocked and assigned to the
@@ -1935,7 +1959,16 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
         * thread-queue locked.
         */
        TDQ_LOCK_ASSERT(tdq, MA_OWNED | MA_NOTRECURSED);
-       newtd = choosethread();
+
+//     tdq_print(0);
+//     rr_print_ready_list();
+
+       fw_notify(FW_DISPATCH, NULL);
+
+//     newtd = choosethread();
+       newtd = (struct thread*)q->fw_current->real_task;
+       TD_SET_RUNNING(newtd);
+
        /*
         * Call the MD code to switch contexts if necessary.
         */
@@ -2052,6 +2085,8 @@ sched_wakeup(struct thread *td)
 //     }
        /* Reset the slice value after we sleep. */
        ts->ts_slice = sched_slice;
+
+
        sched_add(td, SRQ_BORING);
 }
 
@@ -2083,7 +2118,6 @@ sched_fork_thread(struct thread *td, struct thread *child)
 {
        struct td_sched *ts;
        struct td_sched *ts2;
-       struct fw_task *new_task = &child->fw_task;
 
        THREAD_LOCK_ASSERT(td, MA_OWNED);
        /*
@@ -2122,8 +2156,20 @@ sched_fork_thread(struct thread *td, struct thread *child)
 void
 sched_class(struct thread *td, int class)
 {
+       struct fw_queues *q;
+       struct fw_task *p = &td->td_sched->fw_task;
+       int i;
 
        THREAD_LOCK_ASSERT(td, MA_OWNED);
+
+       if (class == PRI_IDLE) {
+               FW_FOREACH_CPU(i) {
+                       q = cpu_queue(i);
+                       q->fw_idle = p;
+                       p->real_task = td;
+               }
+       }
+
        if (td->td_pri_class == class)
                return;
        td->td_pri_class = class;
@@ -2399,6 +2445,7 @@ void
 sched_add(struct thread *td, int flags)
 {
        struct tdq *tdq;
+
 #ifdef SMP
        int cpu;
 #endif
@@ -2436,11 +2483,10 @@ sched_add(struct thread *td, int flags)
         * Now that the thread is moving to the run-queue, set the lock
         * to the scheduler's lock.
         */
+
        thread_lock_set(td, TDQ_LOCKPTR(tdq));
        tdq_add(tdq, td, flags);
 
-       fw_notify(FW_ADMIT, (void*)&td->fw_task);
-
 #endif
        if (!(flags & SRQ_YIELDING))
                sched_setpreempt(td);
@@ -2642,6 +2688,7 @@ sched_idletd(void *dummy)
        mtx_assert(&Giant, MA_NOTOWNED);
        td = curthread;
        tdq = TDQ_SELF();
+       printf("SCHED_IDLETD\n");
        for (;;) {
 #ifdef SMP
                if (tdq_idled(tdq) == 0) {
@@ -2689,6 +2736,7 @@ sched_throw(struct thread *td)
 {
        struct thread *newtd;
        struct tdq *tdq;
+       struct fw_queues *q = cpu_queue(0);
 
        tdq = TDQ_SELF();
        if (td == NULL) {
@@ -2703,7 +2751,10 @@ sched_throw(struct thread *td)
                lock_profile_release_lock(&TDQ_LOCKPTR(tdq)->lock_object);
        }
        KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
-       newtd = choosethread();
+       fw_notify(FW_DISPATCH, NULL);
+//     newtd = choosethread();
+       newtd = (struct thread*)q->fw_current->real_task;
+       TD_SET_RUNNING(newtd);
        TDQ_LOCKPTR(tdq)->mtx_lock = (uintptr_t)newtd;
        cpu_throw(td, newtd);           /* doesn't return */
 }
similarity index 99%
rename from sys/kern/sched_ule_orig.c
rename to sys/kern/sched_ule_org.c
index 7a9b8db..34d717c 100644 (file)
@@ -2352,6 +2352,9 @@ void
 sched_add(struct thread *td, int flags)
 {
        struct tdq *tdq;
+
+       struct fw_task *new_task = (struct fw_task*)malloc(sizeof(struct fw_task), M_TEMP, M_ZERO|M_WAITOK);
+
 #ifdef SMP
        int cpu;
 #endif
@@ -2391,6 +2394,7 @@ sched_add(struct thread *td, int flags)
         */
        thread_lock_set(td, TDQ_LOCKPTR(tdq));
        tdq_add(tdq, td, flags);
+
 #endif
        if (!(flags & SRQ_YIELDING))
                sched_setpreempt(td);
@@ -2566,7 +2570,7 @@ sched_sizeof_proc(void)
 int
 sched_sizeof_thread(void)
 {
-       return (sizeof(struct thread) + sizeof(struct td_sched));
+       return (sizeof(struct thread) + sizeof(struct td_sched) + sizeof(struct fw_task));
 }
 
 #ifdef SMP
index 5c2f86a..0eb2c8c 100644 (file)
@@ -765,6 +765,7 @@ sleepq_resume_thread(struct sleepqueue *sq, struct thread *td, int pri)
         */
        if (TD_IS_SLEEPING(td)) {
                TD_CLR_SLEEPING(td);
+//             printf("sleepq_resume_thread: %p\n", td);
                return (setrunnable(td));
        }
        return (0);
index f9e0277..1f003c4 100644 (file)
@@ -222,9 +222,6 @@ struct thread {
        sigqueue_t      td_sigqueue;    /* (c) Sigs arrived, not delivered. */
 #define        td_siglist      td_sigqueue.sq_signals
        u_char          td_lend_user_pri; /* (t) Lend user pri. */
-#ifdef FW_MOD_SCHED
-       struct fw_task fw_task;
-#endif
 
 /* Cleared during fork1() */
 #define        td_startzero td_flags
@@ -320,6 +317,10 @@ struct thread {
        const char      *td_vnet_lpush; /* (k) Debugging vnet push / pop. */
        struct trapframe *td_intr_frame;/* (k) Frame of the current irq */
        struct proc *td_rfppwait_p;     /* (k) The vforked child */
+
+#ifdef FW_MOD_SCHED
+       struct fw_task *fw_tsk;
+#endif
 };
 
 struct mtx *thread_lock_block(struct thread *);