WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH 1/1] Xen ARINC 653 Scheduler

To: Kathy Hadley <Kathy.Hadley@xxxxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH 1/1] Xen ARINC 653 Scheduler
From: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
Date: Tue, 4 May 2010 10:54:06 -0500
Cc: Keir.Fraser@xxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Tue, 04 May 2010 08:55:07 -0700
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:sender:received :in-reply-to:references:date:x-google-sender-auth:message-id:subject :from:to:cc:content-type; bh=tAKMAv/39dzYmz8bG0oS4WbTiRcPODEg4/tIlfJSPRI=; b=AwfSIeTL449/55MfyVUmuai5G396Rr/H0ERx87C8/nHjDwNYxabz/dG8le5kLevkyi x8e9xtdMP4YS6jpu0DqXUr5CGmJxYmIoZLZJhzOwtmxmVll66KwmGwBbEwemIpL4dog6 WOx2gO27mVS9cSeWD1hp+ZZ1aXynIyqMxo4xQ=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; b=h3edUNpM40DVfs2D7+fZrBk4XN4mjtTt5edtYktltALdgKTYJS7Tn+AqVMGEoQpsZ1 f3C5CEwYO15yPWMX037P1t21PVHWMWpVF4TRyYq9Yz2cKMS4nnDcekUc8152HOcJMey3 ucfvQEWAyTLmio1RfGWxVuRtPe9cFMzsz+9XA=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <D3E384327F5C6D48AADCEA84160B7D73012C9F48@xxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <D3E384327F5C6D48AADCEA84160B7D73012C9F48@xxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Kathy, thanks for your work on this.  Unfortunately, with the new cpupools feature, your actual scheduler will need a little more modification before it can be merged into -unstable.  Cpu pools carves up the cpus into several "pools", each of which has independent schedulers.  This means that schedulers need to make pointers to per-pool "global" structures, rather than having global static structures.  It should be a fairly straightforward transformation; you can see example transformations done on the credit and sedf schedulers.  Let us know if you need any help.

 -George

On Fri, Apr 16, 2010 at 9:18 AM, Kathy Hadley <Kathy.Hadley@xxxxxxxxxxxxxxx> wrote:

This patch adds an ARINC 653 scheduler to Xen.  This is a modification of an earlier patch ([Xen-devel] [PATCH 1/1] Xen ARINC653 scheduler).  In particular, it has been modified to use the new .adjust_global callback function, which was added in “[Xen-devel] [PATCH 1/1] Add .adjust_global callback”.

 

Thanks and regards,

 

 

cid:image001.jpg@01CAD7E0.50E45D70

Kathy Hadley
DornerWorks, Ltd.
Embedded Systems Engineering

3445 Lake Eastbrook Blvd SE
Grand Rapids, MI  49546

Direct: 616.389.6127

Tel:      616.245.8369

Fax:     616.245.8372

 

Kathy.Hadley@xxxxxxxxxxxxxxx

www.DornerWorks.com

cid:image002.jpg@01CAD7E0.50E45D70

Honored as one of the 2010 “Michigan 50 Companies to Watch”

 

diff -rupN a/tools/libxc/Makefile b/tools/libxc/Makefile

--- a/tools/libxc/Makefile            2010-04-13 10:49:37.573793000 -0400

+++ b/tools/libxc/Makefile         2010-04-14 17:49:26.952638000 -0400

@@ -17,6 +17,7 @@ CTRL_SRCS-y       += xc_physdev.c

 CTRL_SRCS-y       += xc_private.c

 CTRL_SRCS-y       += xc_sedf.c

 CTRL_SRCS-y       += xc_csched.c

+CTRL_SRCS-y       += xc_arinc653.c

 CTRL_SRCS-y       += xc_tbuf.c

 CTRL_SRCS-y       += xc_pm.c

 CTRL_SRCS-y       += xc_cpu_hotplug.c

diff -rupN a/tools/libxc/xc_arinc653.c b/tools/libxc/xc_arinc653.c

--- a/tools/libxc/xc_arinc653.c     1969-12-31 19:00:00.000000000 -0500

+++ b/tools/libxc/xc_arinc653.c 2010-04-14 17:49:26.952638000 -0400

@@ -0,0 +1,28 @@

+/****************************************************************************

+ * (C) 2010 - DornerWorks, Ltd <DornerWorks.com>

+ ****************************************************************************

+ *

+ *        File: xc_arinc653.c

+ *      Author: Josh Holtrop <DornerWorks.com>

+ *

+ * Description: XC Interface to the ARINC 653 scheduler

+ *

+ */

+

+#include "xc_private.h"

+

+int

+xc_sched_arinc653_sched_set(

+    int xc_handle,

+    xen_domctl_sched_arinc653_schedule_t * sched)

+{

+    DECLARE_DOMCTL;

+

+    domctl.cmd = XEN_DOMCTL_scheduler_op;

+    domctl.domain = (domid_t) 0;

+    domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_ARINC653;

+    domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_put_global_info;

+    set_xen_guest_handle(domctl.u.scheduler_op.u.arinc653.schedule, sched);

+

+    return do_domctl(xc_handle, &domctl);

+}

diff -rupN a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h

--- a/tools/libxc/xenctrl.h            2010-04-13 10:49:37.573793000 -0400

+++ b/tools/libxc/xenctrl.h         2010-04-14 17:49:26.952638000 -0400

@@ -476,6 +476,16 @@ int xc_sched_credit_domain_get(int xc_ha

                                struct xen_domctl_sched_credit *sdom);

 

 /**

+ * This function sets the global ARINC 653 schedule.

+ *

+ * @parm xc_handle a handle to an open hypervisor interface

+ * @parm sched a pointer to the new ARINC 653 schedule

+ * return 0 on success

+ */

+int xc_sched_arinc653_sched_set(int xc_handle,

+                                xen_domctl_sched_arinc653_schedule_t * sched);

+

+/**

  * This function sends a trigger to a domain.

  *

  * @parm xc_handle a handle to an open hypervisor interface

diff -rupN a/xen/common/Makefile b/xen/common/Makefile

--- a/xen/common/Makefile         2010-04-13 10:49:37.573793000 -0400

+++ b/xen/common/Makefile     2010-04-13 13:00:31.651749000 -0400

@@ -14,6 +14,7 @@ obj-y += page_alloc.o

 obj-y += rangeset.o

 obj-y += sched_credit.o

 obj-y += sched_sedf.o

+obj-y += sched_arinc653.o

 obj-y += schedule.o

 obj-y += shutdown.o

 obj-y += softirq.o

diff -rupN a/xen/common/sched_arinc653.c b/xen/common/sched_arinc653.c

--- a/xen/common/sched_arinc653.c       1969-12-31 19:00:00.000000000 -0500

+++ b/xen/common/sched_arinc653.c    2010-04-14 18:13:26.163404000 -0400

@@ -0,0 +1,590 @@

+/*

+ * File: sched_arinc653.c

+ * Copyright (c) 2010, DornerWorks, Ltd. <DornerWorks.com>

+ *

+ * Description:

+ *   This file provides an ARINC653-compatible scheduling algorithm

+ *   for use in Xen.

+ *

+ * This program is free software; you can redistribute it and/or modify it

+ * under the terms of the GNU General Public License as published by the Free

+ * software Foundation; either version 2 of the License, or (at your option)

+ * any later version.

+ *

+ * This program is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

+ * See the GNU General Public License for more details.

+ */

+

+

+/**************************************************************************

+ * Includes                                                               *

+ *************************************************************************/

+#include <xen/lib.h>

+#include <xen/sched.h>

+#include <xen/sched-if.h>

+#include <xen/timer.h>

+#include <xen/softirq.h>

+#include <xen/time.h>

+#include <xen/errno.h>

+#include <xen/list.h>

+#include <public/domctl.h>          /* ARINC653_MAX_DOMAINS_PER_SCHEDULE */

+#include <xen/guest_access.h>

+

+

+/**************************************************************************

+ * Private Macros                                                         *

+ **************************************************************************/

+

+/**

+ * Retrieve the idle VCPU for a given physical CPU

+ */

+#define IDLETASK(cpu)  ((struct vcpu *) per_cpu(schedule_data, (cpu)).idle)

+

+/**

+ * Return a pointer to the ARINC 653-specific scheduler data information

+ * associated with the given VCPU (vc)

+ */

+#define AVCPU(vc) ((arinc653_vcpu_t *)(vc)->sched_priv)

+

+/**************************************************************************

+ * Private Type Definitions                                               *

+ **************************************************************************/

+

+/**

+ * The sched_entry_t structure holds a single entry of the

+ * ARINC 653 schedule.

+ */

+typedef struct sched_entry_s

+{

+    /* dom_handle holds the handle ("UUID") for the domain that this

+     * schedule entry refers to. */

+    xen_domain_handle_t dom_handle;

+    /* vcpu_id holds the VCPU number for the VCPU that this schedule

+     * entry refers to. */

+    int                 vcpu_id;

+    /* runtime holds the number of nanoseconds that the VCPU for this

+     * schedule entry should be allowed to run per major frame. */

+    s_time_t            runtime;

+    /* vc holds a pointer to the Xen VCPU structure */

+    struct vcpu *       vc;

+} sched_entry_t;

+

+/**

+ * The arinc653_vcpu_t structure holds ARINC 653-scheduler-specific

+ * information for all non-idle VCPUs

+ */

+typedef struct arinc653_vcpu_s

+{

+    /* vc points to Xen's struct vcpu so we can get to it from an

+     * arinc653_vcpu_t pointer. */

+    struct vcpu *       vc;

+    /* awake holds whether the VCPU has been woken with vcpu_wake() */

+    bool_t              awake;

+    /* list holds the linked list information for the list this VCPU

+     * is stored in */

+    struct list_head    list;

+} arinc653_vcpu_t;

+

+

+/**************************************************************************

+ * Global Data                                                            *

+ **************************************************************************/

+

+/**

+ * This array holds the active ARINC 653 schedule.

+ *

+ * When the system tries to start a new VCPU, this schedule is scanned

+ * to look for a matching (handle, VCPU #) pair. If both the handle ("UUID")

+ * and VCPU number match, then the VCPU is allowed to run. Its run time

+ * (per major frame) is given in the third entry of the schedule.

+ */

+static sched_entry_t arinc653_schedule[ARINC653_MAX_DOMAINS_PER_SCHEDULE] = {

+    { "", 0, MILLISECS(10), NULL }

+};

+

+/**

+ * This variable holds the number of entries that are valid in

+ * the arinc653_schedule table.

+ *

+ * This is not necessarily the same as the number of domains in the

+ * schedule. A domain could be listed multiple times within the schedule,

+ * or a domain with multiple VCPUs could have a different

+ * schedule entry for each VCPU.

+ *

+ * A value of 1 means that only 1 domain (Dom0) will initially be started.

+ */

+static int num_schedule_entries = 1;

+

+/**

+ * arinc653_major_frame holds the major frame time for the ARINC 653 schedule.

+ */

+static s_time_t arinc653_major_frame = MILLISECS(10);

+

+/**

+ * next_major_frame holds the time that the next major frame starts

+ */

+static s_time_t next_major_frame = 0;

+

+/**

+ * vcpu_list holds pointers to all Xen VCPU structures for iterating through

+ */

+static LIST_HEAD(vcpu_list);

+

+/**************************************************************************

+ * Scheduler functions                                                    *

+ **************************************************************************/

+

+/**

+ * This function compares two domain handles.

+ *

+ * @param h1        Pointer to handle 1

+ * @param h2        Pointer to handle 2

+ *

+ * @return          <ul>

+ *                  <li> <0:  handle 1 is less than handle 2

+ *                  <li>  0:  handle 1 is equal to handle 2

+ *                  <li> >0:  handle 1 is greater than handle 2

+ *                  </ul>

+ */

+static int dom_handle_cmp(const xen_domain_handle_t h1,

+                          const xen_domain_handle_t h2)

+{

+    return memcmp(h1, h2, sizeof(xen_domain_handle_t));

+} /* end dom_handle_cmp */

+

+/**

+ * This function searches the vcpu list to find a VCPU that matches

+ * the domain handle and VCPU ID specified.

+ *

+ * @param handle    Pointer to handler

+ * @param vcpu_id   VCPU ID

+ *

+ * @return          <ul>

+ *                  <li> Pointer to the matching VCPU if one is found

+ *                  <li> NULL otherwise

+ *                  </ul>

+ */

+static struct vcpu * find_vcpu(xen_domain_handle_t handle, int vcpu_id)

+{

+    arinc653_vcpu_t * avcpu; /* loop index variable */

+    struct vcpu * vc = NULL;

+

+    /* loop through the vcpu_list looking for the specified VCPU */

+    list_for_each_entry(avcpu, &vcpu_list, list)

+    {

+        /* If the handles & VCPU IDs match, we've found a matching VCPU */

+        if ((dom_handle_cmp(avcpu->vc->domain->handle, handle) == 0)

+             && (vcpu_id == avcpu->vc->vcpu_id))

+        {

+            vc = avcpu->vc;

+            /*

+             * "break" statement used instead of loop control variable because

+             * the macro used for this loop does not support using loop control

+             * variables

+             */

+            break;

+        }

+    }

+

+    return vc;

+} /* end find_vcpu */

+

+/**

+ * This function updates the pointer to the Xen VCPU structure for each entry in

+ * the ARINC 653 schedule.

+ *

+ * @param           <None>

+ * @return          <None>

+ */

+static void update_schedule_vcpus(void)

+{

+    /* Loop through the number of entries in the schedule */

+    for (int i = 0; i < num_schedule_entries; i++)

+    {

+        /* Update the pointer to the Xen VCPU structure for the current entry */

+        arinc653_schedule[i].vc =

+            find_vcpu(arinc653_schedule[i].dom_handle,

+                      arinc653_schedule[i].vcpu_id);

+    }

+} /* end update_schedule_vcpus */

+

+/**

+ * This function is called by the arinc653_adjust_global scheduler

+ * callback function in response to a domain control hypercall with

+ * a scheduler operation.

+ *

+ * The parameter schedule is set to be the address of a local variable from

+ * within arinc653_adjust_global(), so it is guaranteed to not be NULL.

+ *

+ * @param schedule  Pointer to the new ARINC 653 schedule.

+ *

+ * @return          <ul>

+ *                  <li> 0 = success

+ *                  <li> !0 = error

+ *                  </ul>

+ */

+static int arinc653_sched_set(xen_domctl_sched_arinc653_schedule_t * schedule)

+{

+    int ret = 0;

+    s_time_t total_runtime = 0;

+    bool_t found_dom0 = 0;

+    const static xen_domain_handle_t dom0_handle = {0};

+

+    /* check for valid major frame and number of schedule entries */

+    if ( (schedule->major_frame <= 0)

+      || (schedule->num_sched_entries < 1)

+      || (schedule->num_sched_entries > ARINC653_MAX_DOMAINS_PER_SCHEDULE) )

+    {

+        ret = -EINVAL;

+    }

+

+    if (ret == 0)

+    {

+        for (int i = 0; i < schedule->num_sched_entries; i++)

+        {

+            /*

+             * look for domain 0 handle - every schedule must contain

+             * some time for domain 0 to run

+             */

+            if (dom_handle_cmp(schedule->sched_entries[i].dom_handle,

+                               dom0_handle) == 0)

+            {

+                found_dom0 = 1;

+            }

+

+            /* check for a valid VCPU ID and run time */

+            if ( (schedule->sched_entries[i].vcpu_id < 0)

+              || (schedule->sched_entries[i].runtime <= 0) )

+            {

+                ret = -EINVAL;

+            }

+            else

+            {

+                /* Add this entry's run time to total run time */

+                total_runtime += schedule->sched_entries[i].runtime;

+            }

+        } /* end loop through schedule entries */

+    }

+

+    if (ret == 0)

+    {

+        /* error if the schedule doesn't contain a slot for domain 0 */

+        if (found_dom0 == 0)

+        {

+            ret = -EINVAL;

+        }

+    }

+

+    if (ret == 0)

+    {

+        /*

+         * error if the major frame is not large enough to run all entries

+         * as indicated by comparing the total run time to the major frame

+         * length

+         */

+        if (total_runtime > schedule->major_frame)

+        {

+            ret = -EINVAL;

+        }

+    }

+

+    if (ret == 0)

+    {

+        /* copy the new schedule into place */

+        num_schedule_entries = schedule->num_sched_entries;

+        arinc653_major_frame = schedule->major_frame;

+        for (int i = 0; i < num_schedule_entries; i++)

+        {

+            memcpy(arinc653_schedule[i].dom_handle,

+                   schedule->sched_entries[i].dom_handle,

+                   sizeof(arinc653_schedule[i].dom_handle));

+            arinc653_schedule[i].vcpu_id = schedule->sched_entries[i].vcpu_id;

+            arinc653_schedule[i].runtime = schedule->sched_entries[i].runtime;

+        }

+        update_schedule_vcpus();

+

+        /*

+         * The newly-installed schedule takes effect immediately.

+         * We do not even wait for the current major frame to expire.

+         *

+         * Signal a new major frame to begin. The next major frame

+         * is set up by the do_schedule callback function when it

+         * is next invoked.

+         */

+        next_major_frame = NOW();

+    }

+

+    return ret;

+} /* end arinc653_sched_set */

+

+/**

+ * Xen scheduler callback function to adjust global scheduling parameters

+ *

+ * @param op    Pointer to the domain control scheduler operation structure

+ *

+ * @return          <ul>

+ *                  <li> 0 for success

+ *                  <li> !0 if there is an error

+ *                  </ul>

+ */

+static int arinc653_adjust_global(struct xen_domctl_scheduler_op * op)

+{

+    int ret = -1;

+    xen_domctl_sched_arinc653_schedule_t new_sched;

+

+    if (op->cmd == XEN_DOMCTL_SCHEDOP_put_global_info)

+    {

+        if (copy_from_guest(&new_sched, op->u.arinc653.schedule, 1) != 0)

+        {

+            ret = -EFAULT;

+        }

+        else

+        {

+            ret = arinc653_sched_set(&new_sched);

+        }

+    }

+

+    return ret;

+} /* end arinc653_adjust_global */

+

+/**

+ * Xen scheduler callback function to initialize a virtual CPU (VCPU).

+ *

+ * @param v         Pointer to the VCPU structure

+ *

+ * @return          <ul>

+ *                  <li> 0 if the VCPU is allowed to run

+ *                  <li> !0 if there is an error

+ *                  </ul>

+ */

+static int arinc653_init_vcpu(struct vcpu * v)

+{

+    int ret = -1;

+

+    if (is_idle_vcpu(v))

+    {

+        /*

+         * The idle VCPU is created by Xen to run when no domains

+         * are runnable or require CPU time.

+         * It is similar to an "idle task" or "halt loop" process

+         * in an operating system.

+         * We do not track any scheduler information for the idle VCPU.

+         */

+        v->sched_priv = NULL;

+        ret = 0;

+    }

+    else

+    {

+        /*

+         * Allocate memory for the ARINC 653-specific scheduler data information

+         * associated with the given VCPU (vc).

+         */

+        v->sched_priv = xmalloc(arinc653_vcpu_t);

+        if (AVCPU(v) != NULL)

+        {

+            /*

+             * Initialize our ARINC 653 scheduler-specific information

+             * for the VCPU.

+             * The VCPU starts "asleep."

+             * When Xen is ready for the VCPU to run, it will call

+             * the vcpu_wake scheduler callback function and our

+             * scheduler will mark the VCPU awake.

+             */

+            AVCPU(v)->vc = v;

+            AVCPU(v)->awake = 0;

+            list_add(&AVCPU(v)->list, &vcpu_list);

+            ret = 0;

+            update_schedule_vcpus();

+        }

+    }

+

+    return ret;

+} /* end arinc653_init_vcpu */

+

+/**

+ * Xen scheduler callback function to remove a VCPU

+ *

+ * @param v         Pointer to the VCPU structure to remove

+ *

+ * @return          <None>

+ */

+static void arinc653_destroy_vcpu(struct vcpu * v)

+{

+    if (AVCPU(v) != NULL)

+    {

+        /* remove the VCPU from whichever list it is on */

+        list_del(&AVCPU(v)->list);

+        /* free the arinc653_vcpu structure */

+        xfree(AVCPU(v));

+        update_schedule_vcpus();

+    }

+} /* end arinc653_destroy_vcpu */

+

+/**

+ * Xen scheduler callback function to select a VCPU to run.

+ * This is the main scheduler routine.

+ *

+ * @param t         Current time

+ *

+ * @return          Time slice and address of the VCPU structure for the chosen

+ *                  domain

+ */

+static struct task_slice arinc653_do_schedule(s_time_t t)

+{

+    struct task_slice ret;                      /* hold the chosen domain */

+    struct vcpu * new_task = NULL;

+    static int sched_index = 0;

+    static s_time_t last_major_frame;

+    static s_time_t last_switch_time;

+    static s_time_t next_switch_time;

+

+    if (t >= next_major_frame)

+    {

+        /* time to enter a new major frame

+         * the first time this function is called, this will be true */

+        sched_index = 0;

+        last_major_frame = last_switch_time = t;

+        next_major_frame = t + arinc653_major_frame;

+    }

+    else if (t >= next_switch_time)

+    {

+        /* time to switch to the next domain in this major frame */

+        sched_index++;

+        last_switch_time = next_switch_time;

+    }

+

+    /*

+     * If there are more domains to run in the current major frame, set

+     * next_switch_time equal to the last switch time + this domain's run time.

+     * Otherwise, set next_switch_time equal to the start of the next major

+     * frame.

+     */

+    next_switch_time = (sched_index < num_schedule_entries)

+                     ? last_switch_time + arinc653_schedule[sched_index].runtime

+                     : next_major_frame;

+

+    /*

+     * If there are more domains to run in the current major frame, set

+     * new_task equal to the address of next domain's VCPU structure.

+     * Otherwise, set new_task equal to the address of the idle task's VCPU

+     * structure.

+     */

+    new_task = (sched_index < num_schedule_entries)

+                   ? arinc653_schedule[sched_index].vc

+                   : IDLETASK(0);

+

+    /* Check to see if the new task can be run (awake & runnable). */

+    if (!((new_task != NULL)

+            && AVCPU(new_task)->awake

+            && vcpu_runnable(new_task)) )

+    {

+        new_task = IDLETASK(0);

+    }

+    BUG_ON(new_task == NULL);

+

+    /*

+     * Check to make sure we did not miss a major frame.

+     * This is a good test for robust partitioning.

+     */

+    BUG_ON(t >= next_major_frame);

+

+    /*

+     * Return the amount of time the next domain has to run and the address

+     * of the selected task's VCPU structure.

+     */

+    ret.time = next_switch_time - t;

+    ret.task = new_task;

+

+    BUG_ON(ret.time <= 0);

+

+    return ret;

+} /* end arinc653_do_schedule */

+

+/**

+ * Xen scheduler callback function to select a CPU for the VCPU to run on

+ *

+ * @param v         Pointer to the VCPU structure for the current domain

+ *

+ * @return          Number of selected physical CPU

+ */

+static int arinc653_pick_cpu(struct vcpu * v)

+{

+    /* this implementation only supports one physical CPU */

+    return 0;

+} /* end arinc653_pick_cpu */

+

+/**

+ * Xen scheduler callback function to wake up a VCPU

+ *

+ * @param vc        Pointer to the VCPU structure for the current domain

+ *

+ * @return          <None>

+ */

+static void arinc653_vcpu_wake(struct vcpu * vc)

+{

+    /* boolean flag to indicate first run */

+    static bool_t dont_raise_softirq = 0;

+

+    if (AVCPU(vc) != NULL)  /* check that this is a VCPU we are tracking */

+    {

+        AVCPU(vc)->awake = 1;

+    }

+

+    /* the first time the vcpu_wake function is called, we should raise

+     * a softirq to invoke the do_scheduler callback */

+    if (!dont_raise_softirq)

+    {

+        cpu_raise_softirq(vc->processor, SCHEDULE_SOFTIRQ);

+        dont_raise_softirq = 1;

+    }

+} /* end arinc653_vcpu_wake */

+

+/**

+ * Xen scheduler callback function to sleep a VCPU

+ *

+ * @param vc        Pointer to the VCPU structure for the current domain

+ *

+ * @return          <None>

+ */

+static void arinc653_vcpu_sleep(struct vcpu * vc)

+{

+    if (AVCPU(vc) != NULL)  /* check that this is a VCPU we are tracking */

+    {

+        AVCPU(vc)->awake = 0;

+    }

+

+    /* if the VCPU being put to sleep is the same one that is currently

+     * running, raise a softirq to invoke the scheduler to switch domains */

+    if (per_cpu(schedule_data, vc->processor).curr == vc)

+    {

+        cpu_raise_softirq(vc->processor, SCHEDULE_SOFTIRQ);

+    }

+} /* end arinc653_vcpu_sleep */

+

+/**

+ * This structure defines our scheduler for Xen.

+ * The entries tell Xen where to find our scheduler-specific

+ * callback functions.

+ * The symbol must be visible to the rest of Xen at link time.

+ */

+struct scheduler sched_arinc653_def = {

+    .name           = "ARINC 653 Scheduler",

+    .opt_name       = "arinc653",

+    .sched_id       = XEN_SCHEDULER_ARINC653,

+

+    .init_domain    = NULL,

+    .destroy_domain = NULL,

+

+    .init_vcpu      = arinc653_init_vcpu,

+    .destroy_vcpu   = arinc653_destroy_vcpu,

+

+    .do_schedule    = arinc653_do_schedule,

+    .pick_cpu       = arinc653_pick_cpu,

+    .dump_cpu_state = NULL,

+    .sleep          = arinc653_vcpu_sleep,

+    .wake           = arinc653_vcpu_wake,

+    .adjust         = NULL,

+    .adjust_global  = arinc653_adjust_global,

+};

diff -rupN a/xen/common/schedule.c b/xen/common/schedule.c

--- a/xen/common/schedule.c     2010-04-14 10:57:11.262796000 -0400

+++ b/xen/common/schedule.c  2010-04-14 16:40:21.543608000 -0400

@@ -7,7 +7,8 @@

  *        File: common/schedule.c

  *      Author: Rolf Neugebauer & Keir Fraser

  *              Updated for generic API by Mark Williamson

- *

+ *              ARINC653 scheduler added by DornerWorks <DornerWorks.com>

+ *

  * Description: Generic CPU scheduling code

  *              implements support functionality for the Xen scheduler API.

  *

@@ -56,9 +57,11 @@ DEFINE_PER_CPU(struct schedule_data, sch

 

 extern const struct scheduler sched_sedf_def;

 extern const struct scheduler sched_credit_def;

+extern const struct scheduler sched_arinc653_def;

 static const struct scheduler *__initdata schedulers[] = {

     &sched_sedf_def,

     &sched_credit_def,

+    &sched_arinc653_def,

     NULL

 };

 

diff -rupN a/xen/include/public/domctl.h b/xen/include/public/domctl.h

--- a/xen/include/public/domctl.h 2010-04-14 10:57:11.262796000 -0400

+++ b/xen/include/public/domctl.h         2010-04-14 16:40:21.543608000 -0400

@@ -23,6 +23,8 @@

  *

  * Copyright (c) 2002-2003, B Dragovic

  * Copyright (c) 2002-2006, K Fraser

+ *

+ * ARINC653 Scheduler type added by DornerWorks <DornerWorks.com>.

  */

 

 #ifndef __XEN_PUBLIC_DOMCTL_H__

@@ -303,11 +305,43 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_v

 /* Scheduler types. */

 #define XEN_SCHEDULER_SEDF     4

 #define XEN_SCHEDULER_CREDIT   5

+#define XEN_SCHEDULER_ARINC653 6

+

 /* Set or get info? */

 #define XEN_DOMCTL_SCHEDOP_putinfo 0

 #define XEN_DOMCTL_SCHEDOP_getinfo 1

 #define XEN_DOMCTL_SCHEDOP_put_global_info 2

 #define XEN_DOMCTL_SCHEDOP_get_global_info 3

+

+/*

+ * This structure is used to pass a new ARINC653 schedule from a

+ * privileged domain (ie dom0) to Xen.

+ */

+#define ARINC653_MAX_DOMAINS_PER_SCHEDULE   64

+struct xen_domctl_sched_arinc653_schedule {

+    /* major_frame holds the time for the new schedule's major frame

+     * in nanoseconds. */

+    int64_t     major_frame;

+    /* num_sched_entries holds how many of the entries in the

+     * sched_entries[] array are valid. */

+    uint8_t     num_sched_entries;

+    /* The sched_entries array holds the actual schedule entries. */

+    struct {

+        /* dom_handle must match a domain's UUID */

+        xen_domain_handle_t dom_handle;

+        /* If a domain has multiple VCPUs, vcpu_id specifies which one

+         * this schedule entry applies to. It should be set to 0 if

+         * there is only one VCPU for the domain. */

+        int                 vcpu_id;

+        /* runtime specifies the amount of time that should be allocated

+         * to this VCPU per major frame. It is specified in nanoseconds */

+        int64_t             runtime;

+    } sched_entries[ARINC653_MAX_DOMAINS_PER_SCHEDULE];

+};

+typedef struct xen_domctl_sched_arinc653_schedule

+    xen_domctl_sched_arinc653_schedule_t;

+DEFINE_XEN_GUEST_HANDLE(xen_domctl_sched_arinc653_schedule_t);

+

 struct xen_domctl_scheduler_op {

     uint32_t sched_id;  /* XEN_SCHEDULER_* */

     uint32_t cmd;       /* XEN_DOMCTL_SCHEDOP_* */

@@ -323,6 +357,9 @@ struct xen_domctl_scheduler_op {

             uint16_t weight;

             uint16_t cap;

         } credit;

+        struct xen_domctl_sched_arinc653 {

+            XEN_GUEST_HANDLE(xen_domctl_sched_arinc653_schedule_t) schedule;

+        } arinc653;

     } u;

 };

 typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;

 

 

 

 

 


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • Re: [Xen-devel] [PATCH 1/1] Xen ARINC 653 Scheduler, George Dunlap <=