bitkeeper revision 1.1159.1.172 (41542610ZBPAMBCg2f-D1VTZ8pdChw)

Merge xenbk@gandalf:/var/bk/xeno-unstable.bk
into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-09-24 13:43:30 +00:00
commit 5e782a40bc
14 files changed
+301 -188

No files matched your search

+1
View File
@@ -13,6 +13,7 @@ cl349@freefall.cl.cam.ac.uk
cl349@labyrinth.cl.cam.ac.uk
djm@kirby.fc.hp.com
gm281@boulderdash.cl.cam.ac.uk
gm281@tetrapod.cl.cam.ac.uk
iap10@freefall.cl.cam.ac.uk
iap10@labyrinth.cl.cam.ac.uk
iap10@nidd.cl.cam.ac.uk
@@ -17,6 +17,8 @@ comment 'Xen'
bool 'Support for privileged operations (domain 0)' CONFIG_XEN_PRIVILEGED_GUEST
bool 'Device-driver domain (physical device access)' CONFIG_XEN_PHYSDEV_ACCESS
bool 'Scrub memory before freeing it to Xen' CONFIG_XEN_SCRUB_PAGES
bool 'Network-device frontend driver' CONFIG_XEN_NETDEV_FRONTEND
bool 'Block-device frontend driver' CONFIG_XEN_BLKDEV_FRONTEND
endmenu
# The IBM S/390 patch needs this.
define_bool CONFIG_NO_IDLE_HZ y
@@ -13,6 +13,8 @@ CONFIG_UID16=y
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_PHYSDEV_ACCESS=y
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_NETDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_NO_IDLE_HZ=y
CONFIG_FOREIGN_PAGES=y
@@ -1,5 +1,5 @@
#
# Automatically generated make config: don't edit
# Automatically generated by make menuconfig: don't edit
#
CONFIG_XEN=y
CONFIG_X86=y
@@ -17,6 +17,8 @@ CONFIG_UID16=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_NETDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_NO_IDLE_HZ=y
# CONFIG_FOREIGN_PAGES is not set
CONFIG_NETDEVICES=y
@@ -156,10 +158,6 @@ CONFIG_IP_NF_TARGET_ULOG=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
@@ -192,20 +190,12 @@ CONFIG_IP_NF_TARGET_ULOG=y
# SCSI support
#
CONFIG_SCSI=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
@@ -317,10 +307,6 @@ CONFIG_PSMOUSE=y
# CONFIG_INPUT_EMU10K1 is not set
# CONFIG_INPUT_SERIO is not set
# CONFIG_INPUT_SERPORT is not set
#
# Joysticks
#
# CONFIG_INPUT_ANALOG is not set
# CONFIG_INPUT_A3D is not set
# CONFIG_INPUT_ADI is not set
@@ -1,8 +1,8 @@
O_TARGET := drv.o
subdir-y += frontend
obj-y += frontend/drv.o
subdir-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend/drv.o
subdir-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend
obj-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend/drv.o
@@ -1,8 +1,8 @@
O_TARGET := drv.o
subdir-y += frontend
obj-y += frontend/drv.o
subdir-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend/drv.o
subdir-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend
obj-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend/drv.o
@@ -13,6 +13,7 @@
#include "common.h"
static void netif_page_release(struct page *page);
static void netif_skb_release(struct sk_buff *skb);
static void make_tx_response(netif_t *netif,
u16 id,
s8 st);
@@ -40,7 +41,8 @@ static unsigned char rx_notify[NR_EVENT_CHANNELS];
static unsigned long mmap_vstart;
#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
#define PKT_PROT_LEN (ETH_HLEN + 20)
#define PKT_MIN_LEN (ETH_HLEN + 20)
#define PKT_PROT_LEN 64
static struct {
netif_tx_request_t req;
@@ -385,6 +387,7 @@ static void net_tx_action(unsigned long unused)
NETIF_RING_IDX i;
multicall_entry_t *mcl;
PEND_RING_IDX dc, dp;
unsigned int data_len;
if ( (dc = dealloc_cons) == (dp = dealloc_prod) )
goto skip_dealloc;
@@ -497,7 +500,7 @@ static void net_tx_action(unsigned long unused)
netif_schedule_work(netif);
if ( unlikely(txreq.size <= PKT_PROT_LEN) ||
if ( unlikely(txreq.size <= PKT_MIN_LEN) ||
unlikely(txreq.size > ETH_FRAME_LEN) )
{
DPRINTK("Bad packet size: %d\n", txreq.size);
@@ -519,7 +522,9 @@ static void net_tx_action(unsigned long unused)
pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
if ( unlikely((skb = alloc_skb(PKT_PROT_LEN+16, GFP_ATOMIC)) == NULL) )
data_len = txreq.size > PKT_PROT_LEN ? PKT_PROT_LEN : txreq.size;
if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) )
{
DPRINTK("Can't allocate a skb in start_xmit.\n");
make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
@@ -578,19 +583,28 @@ static void net_tx_action(unsigned long unused)
phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT);
__skb_put(skb, PKT_PROT_LEN);
data_len = txreq.size > PKT_PROT_LEN ? PKT_PROT_LEN : txreq.size;
__skb_put(skb, data_len);
memcpy(skb->data,
(void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)),
PKT_PROT_LEN);
data_len);
/* Append the packet payload as a fragment. */
skb_shinfo(skb)->frags[0].page =
virt_to_page(MMAP_VADDR(pending_idx));
skb_shinfo(skb)->frags[0].size = txreq.size - PKT_PROT_LEN;
skb_shinfo(skb)->frags[0].page_offset =
(txreq.addr + PKT_PROT_LEN) & ~PAGE_MASK;
skb_shinfo(skb)->nr_frags = 1;
skb->data_len = txreq.size - PKT_PROT_LEN;
if (data_len < txreq.size) {
/* Append the packet payload as a fragment. */
skb_shinfo(skb)->frags[0].page =
virt_to_page(MMAP_VADDR(pending_idx));
skb_shinfo(skb)->frags[0].size = txreq.size - data_len;
skb_shinfo(skb)->frags[0].page_offset =
(txreq.addr + data_len) & ~PAGE_MASK;
skb_shinfo(skb)->nr_frags = 1;
} else {
skb_shinfo(skb)->frags[0].page =
virt_to_page(MMAP_VADDR(pending_idx));
skb->destructor = netif_skb_release;
}
skb->data_len = txreq.size - data_len;
skb->len += skb->data_len;
skb->dev = netif->dev;
@@ -606,13 +620,9 @@ static void net_tx_action(unsigned long unused)
}
}
static void netif_page_release(struct page *page)
static void netif_idx_release(u16 pending_idx)
{
unsigned long flags;
u16 pending_idx = page - virt_to_page(mmap_vstart);
/* Ready for next use. */
set_page_count(page, 1);
spin_lock_irqsave(&dealloc_lock, flags);
dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
@@ -621,6 +631,24 @@ static void netif_page_release(struct page *page)
tasklet_schedule(&net_tx_tasklet);
}
static void netif_page_release(struct page *page)
{
u16 pending_idx = page - virt_to_page(mmap_vstart);
/* Ready for next use. */
set_page_count(page, 1);
netif_idx_release(pending_idx);
}
static void netif_skb_release(struct sk_buff *skb)
{
struct page *page = skb_shinfo(skb)->frags[0].page;
u16 pending_idx = page - virt_to_page(mmap_vstart);
netif_idx_release(pending_idx);
}
#if 0
long flush_bufs_for_netif(netif_t *netif)
{
@@ -249,16 +249,14 @@ static int vif_wake(struct net_device *dev)
{
struct sk_buff *skb;
u32 src_ip, dst_ip;
unsigned char dst_hw[ETH_ALEN];
memset(dst_hw, 0xff, ETH_ALEN);
dst_ip = INADDR_BROADCAST;
src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK);
skb = arp_create(ARPOP_REQUEST, ETH_P_ARP,
skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
dst_ip, dev, src_ip,
dst_hw, dev->dev_addr, NULL);
/*dst_hw*/ NULL, /*src_hw*/ NULL,
/*target_hw*/ dev->dev_addr);
if ( skb == NULL )
return -ENOMEM;
+2 -2
View File
@@ -223,12 +223,12 @@ void arch_do_createdomain(struct domain *d)
virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
machine_to_phys_mapping[virt_to_phys(d->shared_info) >>
PAGE_SHIFT] = 0x80000000UL; /* debug */
PAGE_SHIFT] = INVALID_P2M_ENTRY;
d->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
memset(d->mm.perdomain_pt, 0, PAGE_SIZE);
machine_to_phys_mapping[virt_to_phys(d->mm.perdomain_pt) >>
PAGE_SHIFT] = 0x0fffdeadUL; /* debug */
PAGE_SHIFT] = INVALID_P2M_ENTRY;
}
int arch_final_setup_guestos(struct domain *d, full_execution_context_t *c)
+6
View File
@@ -1802,6 +1802,12 @@ static __init int ptwr_init(void)
(void *)alloc_xenheap_page();
ptwr_info[i].ptinfo[PTWR_PT_INACTIVE].page =
(void *)alloc_xenheap_page();
machine_to_phys_mapping[virt_to_phys(
ptwr_info[i].ptinfo[PTWR_PT_ACTIVE].page)>>PAGE_SHIFT] =
INVALID_P2M_ENTRY;
machine_to_phys_mapping[virt_to_phys(
ptwr_info[i].ptinfo[PTWR_PT_INACTIVE].page)>>PAGE_SHIFT] =
INVALID_P2M_ENTRY;
}
return 0;
+15 -7
View File
@@ -200,8 +200,6 @@ int shadow_mode_enable( struct domain *p, unsigned int mode )
struct shadow_status **fptr;
int i;
m->shadow_mode = mode;
// allocate hashtable
m->shadow_ht = xmalloc(shadow_ht_buckets *
sizeof(struct shadow_status));
@@ -241,16 +239,25 @@ int shadow_mode_enable( struct domain *p, unsigned int mode )
if( m->shadow_dirty_bitmap == NULL )
{
m->shadow_dirty_bitmap_size = 0;
BUG();
goto nomem;
}
memset(m->shadow_dirty_bitmap,0,m->shadow_dirty_bitmap_size/8);
}
m->shadow_mode = mode;
// call shadow_mk_pagetable
__shadow_mk_pagetable( m );
return 0;
nomem:
if( m->shadow_ht ) {
xfree( m->shadow_ht ); m->shadow_ht = NULL; };
if( m->shadow_ht_extras ) {
xfree( m->shadow_ht_extras ); m->shadow_ht_extras = NULL; };
return -ENOMEM;
}
@@ -285,7 +292,10 @@ void __shadow_mode_disable(struct domain *d)
}
// free the hashtable itself
xfree( &m->shadow_ht[0] );
xfree( m->shadow_ht );
m->shadow_ht = NULL;
m->shadow_ht_extras = NULL;
}
static int shadow_mode_table_op(struct domain *d,
@@ -314,8 +324,6 @@ static int shadow_mode_table_op(struct domain *d,
switch(op)
{
case DOM0_SHADOW_CONTROL_OP_FLUSH:
// XXX THIS IS VERY DANGEROUS : MUST ENSURE THE PTs ARE NOT IN USE ON
// OTHER CPU -- fix when we get sched sync pause.
__free_shadow_table( m );
break;
@@ -452,12 +460,12 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc)
else if ( cmd == DOM0_SHADOW_CONTROL_OP_ENABLE_TEST )
{
shadow_mode_disable(d);
shadow_mode_enable(d, SHM_test);
rc = shadow_mode_enable(d, SHM_test);
}
else if ( cmd == DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY )
{
shadow_mode_disable(d);
shadow_mode_enable(d, SHM_logdirty);
rc = shadow_mode_enable(d, SHM_logdirty);
}
else if ( shadow_mode(d) &&
(cmd >= DOM0_SHADOW_CONTROL_OP_FLUSH) &&
+213 -135
View File
@@ -23,26 +23,17 @@
#include <hypervisor-ifs/sched_ctl.h>
#include <xen/trace.h>
/*
* KAF -- Atropos is broken by the new scheduler interfaces.
* It'll need fixing to get rid of use of ATROPOS_TASK__*
*/
#ifdef KAF_KILLED
#define ATROPOS_TASK_UNBLOCKED 16
#define ATROPOS_TASK_WAIT 32
#define Activation_Reason_Allocated 1
#define Activation_Reason_Preempted 2
#define Activation_Reason_Extra 3
#define ATROPOS_TASK_BLOCKED 48
/* Atropos-specific per-domain data */
struct at_dom_info
{
/* MAW Xen additions */
struct domain *owner; /* the domain this data belongs to */
struct list_head run_list; /* runqueue */
struct list_head waitq; /* wait queue */
int reason; /* reason domain was last scheduled */
/* (what remains of) the original fields */
@@ -57,26 +48,59 @@ struct at_dom_info
s_time_t latency; /* Unblocking latency */
int xtratime; /* Prepared to accept extra time? */
int state; /* Keeps Atropos domain state */
};
/* Atropos-specific per-CPU data */
struct at_cpu_info
{
spinlock_t runq_lock;
struct list_head runq; /* run queue */
spinlock_t waitq_lock;
struct list_head waitq; /* wait queue*/
};
#define DOM_INFO(_p) ((struct at_dom_info *)((_p)->sched_priv))
#define CPU_INFO(_c) ((struct at_cpu_info *)((_c).sched_priv))
#define WAITQ(cpu) (&CPU_INFO(schedule_data[cpu])->waitq)
#define RUNQ(cpu) (&schedule_data[cpu].runqueue)
#define CPU_INFO(_c) ((struct at_cpu_info *)((schedule_data[_c]).sched_priv))
#define WAITQ(cpu) (&CPU_INFO(cpu)->waitq)
#define RUNQ(cpu) (&CPU_INFO(cpu)->runq)
#define RUNLIST(_d) (&DOM_INFO(_d)->run_list)
#define BESTEFFORT_QUANTUM MILLISECS(5)
static void at_dump_cpu_state(int cpu);
/* SLAB cache for struct at_dom_info objects */
static xmem_cache_t *dom_info_cache;
/*
* Wrappers for run-queue management. Must be called with the run_lock
* held.
*/
static inline void __add_to_runqueue_head(struct domain *d)
{
list_add(RUNLIST(d), RUNQ(d->processor));
}
static inline void __add_to_runqueue_tail(struct domain *d)
{
list_add_tail(RUNLIST(d), RUNQ(d->processor));
}
static inline void __del_from_runqueue(struct domain *d)
{
struct list_head *runlist = RUNLIST(d);
list_del(runlist);
runlist->next = NULL;
}
static inline int __task_on_runqueue(struct domain *d)
{
return (RUNLIST(d))->next != NULL;
}
/** calculate the length of a linked list */
static int q_len(struct list_head *q)
@@ -114,15 +138,17 @@ static inline struct domain *waitq_el(struct list_head *l)
static void requeue(struct domain *sdom)
{
struct at_dom_info *inf = DOM_INFO(sdom);
struct list_head *prev = WAITQ(sdom->processor);
struct list_head *prev;
struct list_head *next;
if(sdom->state == ATROPOS_TASK_WAIT ||
sdom->state == ATROPOS_TASK_UNBLOCKED )
{
/* insert into ordered wait queue */
if(!domain_runnable(sdom)) return;
if(inf->state == ATROPOS_TASK_WAIT ||
inf->state == ATROPOS_TASK_UNBLOCKED)
{
prev = WAITQ(sdom->processor);
list_for_each(next, WAITQ(sdom->processor))
{
struct at_dom_info *i =
@@ -144,16 +170,17 @@ static void requeue(struct domain *sdom)
else if ( domain_runnable(sdom) )
{
/* insert into ordered run queue */
prev = RUNQ(sdom->processor);
list_for_each(next, RUNQ(sdom->processor))
{
struct domain *p = list_entry(next, struct domain,
struct at_dom_info *p = list_entry(next, struct at_dom_info,
run_list);
if( DOM_INFO(p)->deadline > inf->deadline || is_idle_task(p) )
if( p->deadline > inf->deadline || is_idle_task(p->owner) )
{
__list_add(&sdom->run_list, prev, next);
__list_add(&inf->run_list, prev, next);
break;
}
@@ -161,12 +188,27 @@ static void requeue(struct domain *sdom)
}
if ( next == RUNQ(sdom->processor) )
list_add_tail(&sdom->run_list, RUNQ(sdom->processor));
list_add_tail(&inf->run_list, RUNQ(sdom->processor));
}
/* silently ignore tasks in other states like BLOCKED, DYING, STOPPED, etc
* - they shouldn't be on any queue */
}
/** at_alloc_task - allocate private info for a task */
static int at_alloc_task(struct domain *p)
{
ASSERT(p != NULL);
p->sched_priv = xmem_cache_alloc(dom_info_cache);
if( p->sched_priv == NULL )
return -1;
return 0;
}
/* prepare a task to be added to scheduling */
static void at_add_task(struct domain *p)
{
@@ -199,14 +241,15 @@ static void at_add_task(struct domain *p)
DOM_INFO(p)->slice = MILLISECS(10);
DOM_INFO(p)->latency = SECONDS(10);
DOM_INFO(p)->xtratime = 1;
DOM_INFO(p)->deadline = now + SECONDS(10);
DOM_INFO(p)->deadline = now;
// DOM_INFO(p)->deadline = now + SECONDS(10);
DOM_INFO(p)->prevddln = 0;
}
INIT_LIST_HEAD(&(DOM_INFO(p)->run_list));
INIT_LIST_HEAD(&(DOM_INFO(p)->waitq));
}
/**
* dequeue - remove a domain from any queues it is on.
* @sdom: the task to remove
@@ -214,19 +257,16 @@ static void at_add_task(struct domain *p)
static void dequeue(struct domain *sdom)
{
struct at_dom_info *inf = DOM_INFO(sdom);
ASSERT(sdom->domain != IDLE_DOMAIN_ID);
/* just delete it from all the queues! */
list_del(&inf->waitq);
INIT_LIST_HEAD(&inf->waitq);
if(__task_on_runqueue(sdom))
__del_from_runqueue(sdom);
sdom->run_list.next = NULL;
sdom->run_list.prev = NULL;
}
@@ -254,44 +294,64 @@ static void unblock(struct domain *sdom)
{
s_time_t time = NOW();
struct at_dom_info *inf = DOM_INFO(sdom);
dequeue(sdom);
/* We distinguish two cases... short and long blocks */
if ( inf->deadline < time )
{
/* Long blocking case */
/* The sdom has passed its deadline since it was blocked.
Give it its new deadline based on the latency value. */
inf->prevddln = time;
/* The sdom has passed its deadline since it was blocked.
Give it its new deadline based on the latency value. */
inf->prevddln = time;
/* Scale the scheduling parameters as requested by the latency hint. */
inf->deadline = time + inf->latency;
inf->deadline = time + inf->latency;
inf->slice = inf->nat_slice / ( inf->nat_period / inf->latency );
inf->period = inf->latency;
inf->remain = inf->slice;
inf->remain = inf->slice;
}
else
else
{
/* Short blocking case */
/* We leave REMAIN intact, but put this domain on the WAIT
queue marked as recently unblocked. It will be given
priority over other domains on the wait queue until while
REMAIN>0 in a generous attempt to help it make up for its
own foolishness. */
if(inf->remain > 0)
sdom->state = ATROPOS_TASK_UNBLOCKED;
/* We leave REMAIN intact, but put this domain on the WAIT
queue marked as recently unblocked. It will be given
priority over other domains on the wait queue until while
REMAIN>0 in a generous attempt to help it make up for its
own foolishness. */
if(inf->remain > 0)
inf->state = ATROPOS_TASK_UNBLOCKED;
else
sdom->state = ATROPOS_TASK_WAIT;
inf->state = ATROPOS_TASK_WAIT;
}
requeue(sdom);
}
static int at_init_idle_task(struct domain *p)
{
if(at_alloc_task(p) < 0) return -1;
at_add_task(p);
dequeue(p);
requeue(p);
return 0;
}
static void block(struct domain* sdom)
{
DOM_INFO(sdom)->state = ATROPOS_TASK_BLOCKED;
dequeue(sdom);
requeue(sdom);
}
/**
* ATROPOS - main scheduler function
*/
@@ -301,13 +361,13 @@ task_slice_t ksched_scheduler(s_time_t time)
s_time_t newtime;
s_time_t ranfor; /* How long the domain ran */
struct domain *sdom; /* tmp. scheduling domain */
int reason; /* reason for reschedule */
int cpu = cur_sdom->processor; /* current CPU */
struct at_dom_info *cur_info;
static unsigned long waitq_rrobin = 0;
int i;
task_slice_t ret;
cur_info = DOM_INFO(cur_sdom);
ASSERT( cur_sdom != NULL);
@@ -333,36 +393,35 @@ task_slice_t ksched_scheduler(s_time_t time)
dequeue(cur_sdom);
if ( domain_runnable(cur_sdom) ||
(cur_sdom->state == ATROPOS_TASK_UNBLOCKED) )
(cur_info->state == ATROPOS_TASK_UNBLOCKED) )
{
/* In this block, we are doing accounting for an sdom which has
been running in contracted time. Note that this could now happen
even if the domain is on the wait queue (i.e. if it blocked) */
/* In this block, we are doing accounting for an sdom which has
been running in contracted time. Note that this could now happen
even if the domain is on the wait queue (i.e. if it blocked) */
/* Deduct guaranteed time from the domain */
cur_info->remain -= ranfor;
/* Deduct guaranteed time from the domain */
cur_info->remain -= ranfor;
/* If guaranteed time has run out... */
if ( cur_info->remain <= 0 )
/* If guaranteed time has run out... */
if ( cur_info->remain <= 0 )
{
/* Move domain to correct position in WAIT queue */
/* Move domain to correct position in WAIT queue */
/* XXX sdom_unblocked doesn't need this since it is
already in the correct place. */
cur_sdom->state = ATROPOS_TASK_WAIT;
}
cur_info->state = ATROPOS_TASK_WAIT;
}
}
requeue(cur_sdom);
deschedule_done:
deschedule_done:
/*****************************
*
* We have now successfully descheduled the current sdom.
* The next task is the allocate CPU time to any sdom it is due to.
*
****************************/
****************************/
cur_sdom = NULL;
/*****************************
@@ -371,13 +430,14 @@ task_slice_t ksched_scheduler(s_time_t time)
* period deadline. If necessary, move them to run queue.
*
****************************/
while(!list_empty(WAITQ(cpu)) &&
DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time ) {
struct at_dom_info *inf = DOM_INFO(sdom);
DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time )
{
struct at_dom_info *inf = DOM_INFO(sdom);
dequeue(sdom);
if ( inf->period != inf->nat_period )
{
/* This domain has had its parameters adjusted as a result of
@@ -392,22 +452,22 @@ task_slice_t ksched_scheduler(s_time_t time)
}
}
/* Domain begins a new period and receives a slice of CPU
* If this domain has been blocking then throw away the
* rest of it's remain - it can't be trusted */
if (inf->remain > 0)
inf->remain = inf->slice;
else
inf->remain += inf->slice;
/* Domain begins a new period and receives a slice of CPU
* If this domain has been blocking then throw away the
* rest of it's remain - it can't be trusted */
if (inf->remain > 0)
inf->remain = inf->slice;
else
inf->remain += inf->slice;
inf->prevddln = inf->deadline;
inf->deadline += inf->period;
inf->prevddln = inf->deadline;
inf->deadline += inf->period;
if ( inf->remain <= 0 )
sdom->state = ATROPOS_TASK_WAIT;
inf->state = ATROPOS_TASK_WAIT;
/* Place on the appropriate queue */
requeue(sdom);
/* Place on the appropriate queue */
requeue(sdom);
}
/*****************************
@@ -421,13 +481,11 @@ task_slice_t ksched_scheduler(s_time_t time)
****************************/
/* we guarantee there's always something on the runqueue */
cur_sdom = list_entry(RUNQ(cpu)->next,
struct domain, run_list);
cur_info = list_entry(RUNQ(cpu)->next,
struct at_dom_info, run_list);
cur_info = DOM_INFO(cur_sdom);
cur_sdom = cur_info->owner;
newtime = time + cur_info->remain;
reason = (cur_info->prevddln > cur_sdom->lastschd) ?
Activation_Reason_Allocated : Activation_Reason_Preempted;
/* MAW - the idle domain is always on the run queue. We run from the
* runqueue if it's NOT the idle domain or if there's nothing on the wait
@@ -436,12 +494,13 @@ task_slice_t ksched_scheduler(s_time_t time)
{
struct list_head *item;
/* Try running a domain on the WAIT queue - this part of the
scheduler isn't particularly efficient but then again, we
don't have any guaranteed domains to worry about. */
/* Try running a domain on the WAIT queue - this part of the
scheduler isn't particularly efficient but then again, we
don't have any guaranteed domains to worry about. */
/* See if there are any unblocked domains on the WAIT
queue who we can give preferential treatment to. */
/* See if there are any unblocked domains on the WAIT
queue who we can give preferential treatment to. */
list_for_each(item, WAITQ(cpu))
{
struct at_dom_info *inf =
@@ -449,23 +508,24 @@ task_slice_t ksched_scheduler(s_time_t time)
sdom = inf->owner;
if (sdom->state == ATROPOS_TASK_UNBLOCKED) {
cur_sdom = sdom;
cur_info = inf;
newtime = time + inf->remain;
reason = Activation_Reason_Preempted;
goto found;
if (inf->state == ATROPOS_TASK_UNBLOCKED)
{
cur_sdom = sdom;
cur_info = inf;
newtime = time + inf->remain;
goto found;
}
}
}
/* init values needed to approximate round-robin for slack time */
i = 0;
if ( waitq_rrobin >= q_len(WAITQ(cpu)))
waitq_rrobin = 0;
/* Last chance: pick a domain on the wait queue with the XTRA
flag set. The NEXT_OPTM field is used to cheaply achieve
an approximation of round-robin order */
/* Last chance: pick a domain on the wait queue with the XTRA
flag set. The NEXT_OPTM field is used to cheaply achieve
an approximation of round-robin order */
list_for_each(item, WAITQ(cpu))
{
struct at_dom_info *inf =
@@ -473,11 +533,11 @@ task_slice_t ksched_scheduler(s_time_t time)
sdom = inf->owner;
if (inf->xtratime && i >= waitq_rrobin) {
if (inf->xtratime && i >= waitq_rrobin)
{
cur_sdom = sdom;
cur_info = inf;
newtime = time + BESTEFFORT_QUANTUM;
reason = Activation_Reason_Extra;
waitq_rrobin = i + 1; /* set this value ready for next */
goto found;
}
@@ -502,7 +562,7 @@ task_slice_t ksched_scheduler(s_time_t time)
/* exhausted its time, cut short the time allocation */
if (!list_empty(WAITQ(cpu)))
{
newtime = MIN(newtime,
newtime = MIN(newtime,
DOM_INFO(waitq_el(WAITQ(cpu)->next))->deadline);
}
@@ -512,9 +572,6 @@ task_slice_t ksched_scheduler(s_time_t time)
ret.task = cur_sdom;
ret.time = newtime - time;
cur_sdom->min_slice = newtime - time;
DOM_INFO(cur_sdom)->reason = reason;
TRACE_1D(0, cur_sdom->domain);
return ret;
@@ -531,8 +588,10 @@ static int at_init_scheduler()
schedule_data[i].sched_priv = xmalloc(sizeof(struct at_cpu_info));
if ( schedule_data[i].sched_priv == NULL )
return -1;
WAITQ(i)->next = WAITQ(i);
WAITQ(i)->prev = WAITQ(i);
INIT_LIST_HEAD(WAITQ(i));
INIT_LIST_HEAD(RUNQ(i));
spin_lock_init(&CPU_INFO(i)->runq_lock);
spin_lock_init(&CPU_INFO(i)->waitq_lock);
}
dom_info_cache = xmem_cache_create("Atropos dom info",
@@ -542,13 +601,6 @@ static int at_init_scheduler()
return 0;
}
/* dump relevant per-cpu state for a run queue dump */
static void at_dump_cpu_state(int cpu)
{
printk("Waitq len: %d Runq len: %d ",
q_len(WAITQ(cpu)),
q_len(RUNQ(cpu)));
}
/* print relevant per-domain info for a run queue dump */
static void at_dump_runq_el(struct domain *p)
@@ -558,6 +610,51 @@ static void at_dump_runq_el(struct domain *p)
}
/* dump relevant per-cpu state for a run queue dump */
static void at_dump_cpu_state(int cpu)
{
struct list_head *list, *queue;
int loop = 0;
struct at_dom_info *d_inf;
struct domain *d;
queue = RUNQ(cpu);
printk("\nRUNQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
(unsigned long) queue->next, (unsigned long) queue->prev);
list_for_each ( list, queue )
{
d_inf = list_entry(list, struct at_dom_info, run_list);
d = d_inf->owner;
printk("%3d: %d has=%c ", loop++, d->domain,
test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
at_dump_runq_el(d);
printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
printk(" l: %lx n: %lx p: %lx\n",
(unsigned long)list, (unsigned long)list->next,
(unsigned long)list->prev);
}
queue = WAITQ(cpu);
printk("\nWAITQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
(unsigned long) queue->next, (unsigned long) queue->prev);
list_for_each ( list, queue )
{
d_inf = list_entry(list, struct at_dom_info, waitq);
d = d_inf->owner;
printk("%3d: %d has=%c ", loop++, d->domain,
test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
at_dump_runq_el(d);
printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
printk(" l: %lx n: %lx p: %lx\n",
(unsigned long)list, (unsigned long)list->next,
(unsigned long)list->prev);
}
}
/* set or fetch domain scheduling parameters */
static int at_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
{
@@ -585,22 +682,6 @@ static int at_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
return 0;
}
/** at_alloc_task - allocate private info for a task */
static int at_alloc_task(struct domain *p)
{
ASSERT(p != NULL);
p->sched_priv = xmem_cache_alloc(dom_info_cache);
if( p->sched_priv == NULL )
return -1;
memset(p->sched_priv, 0, sizeof(struct at_dom_info));
return 0;
}
/* free memory associated with a task */
static void at_free_task(struct domain *p)
{
@@ -627,23 +708,20 @@ static int at_prn_state(int state)
return ret;
}
#endif /* KAF_KILLED */
struct scheduler sched_atropos_def = {
.name = "Atropos Soft Real Time Scheduler",
.opt_name = "atropos",
.sched_id = SCHED_ATROPOS,
#ifdef KAF_KILLED
.init_scheduler = at_init_scheduler,
.init_idle_task = at_init_idle_task,
.alloc_task = at_alloc_task,
.add_task = at_add_task,
.free_task = at_free_task,
.wake_up = unblock,
.wake = unblock,
.sleep = block,
.do_schedule = ksched_scheduler,
.adjdom = at_adjdom,
.dump_cpu_state = at_dump_cpu_state,
.dump_runq_el = at_dump_runq_el,
.prn_state = at_prn_state,
#endif /* KAF_KILLED */
};
+2
View File
@@ -321,6 +321,8 @@ static cache_sizes_t cache_sizes[] = {
{ 4096, NULL},
{ 8192, NULL},
{ 16384, NULL},
{ 32768, NULL},
{ 65536, NULL},
{ 0, NULL}
};
+2
View File
@@ -116,6 +116,8 @@ struct pfn_info
spin_unlock(&(_dom)->page_alloc_lock); \
} while ( 0 )
#define INVALID_P2M_ENTRY (~0UL)
extern struct pfn_info *frame_table;
extern unsigned long frame_table_size;
extern unsigned long max_page;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.