bitkeeper revision 1.1159.33.1 (4120e700LNXbe5IhAOotAN5jyP0RJw)

suspend/resume fixes
This commit is contained in:
iap10@labyrinth.cl.cam.ac.uk committed 2004-08-16 16:55:28 +00:00
1 parent 9f57ca8fe5
commit 83b44e251e
6 files changed
+163 -17

No files matched your search

@@ -17,6 +17,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
#include <asm/io.h>
@@ -427,9 +428,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
*/
if ( unlikely(rx->status <= 0) )
{
/* Gate this error. We get a (valid) slew of them on suspend. */
if ( np->user_state == UST_OPEN )
printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
wmb();
np->rx->req_prod++;
@@ -470,6 +469,15 @@ static int netif_poll(struct net_device *dev, int *pbudget)
mcl->args[2] = 0;
mcl++;
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
#if 0
if (unlikely(rx_mcl[0].args[5] != 0))
printk(KERN_ALERT"Hypercall0 failed %u\n",np->rx->resp_prod);
if (unlikely(rx_mcl[1].args[5] != 0))
printk(KERN_ALERT"Hypercall1 failed %u\n",np->rx->resp_prod);
#endif
}
while ( (skb = __skb_dequeue(&rxq)) != NULL )
@@ -595,6 +603,7 @@ static void network_connect(struct net_device *dev,
printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n",
np->tx->req_prod,np->rx->req_prod);
/* Step 3: All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver
* domain a kick because we've probably just requeued some
@@ -916,6 +925,8 @@ void netif_resume(void)
struct net_private *np = NULL;
int i;
#if 1
/* XXX THIS IS TEMPORARY */
@@ -932,6 +943,9 @@ void netif_resume(void)
// stop bad things from happening until we're back up
np->backend_state = BEST_DISCONNECTED;
memset(np->tx,0,PAGE_SIZE);
memset(np->rx,0,PAGE_SIZE);
cmsg.type = CMSG_NETIF_FE;
cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT;
@@ -374,7 +374,8 @@ static inline int HYPERVISOR_dom_mem_op(unsigned int op,
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
"b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order)
"b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order),
"D" (DOMID_SELF)
: "memory" );
return ret;
+48
View File
@@ -504,6 +504,54 @@ printf("XXXXXXXXXXXXXXX pin L2\n");
xcio_info(ioctxt, "\b\b\b\b100%%\nMemory reloaded.\n");
/* Get the list of PFNs that are not in the psuedo-phys map */
{
unsigned int count, *pfntab;
int rc;
if ( xcio_read(ioctxt, &count, sizeof(count)) )
{
xcio_error(ioctxt, "Error when reading from state file");
goto out;
}
pfntab = malloc( sizeof(unsigned int) * count );
if ( !pfntab )
{
xcio_error(ioctxt, "Out of memory");
goto out;
}
if ( xcio_read(ioctxt, pfntab, sizeof(unsigned int)*count) )
{
xcio_error(ioctxt, "Error when reading pfntab from state file");
goto out;
}
for(i=0;i<count;i++)
{
unsigned long pfn = pfntab[i];
pfntab[i]=pfn_to_mfn_table[pfn];
pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap
}
if ( count>0 )
{
if ( (rc = do_dom_mem_op( xc_handle,
MEMOP_decrease_reservation,
pfntab, count, 0, dom )) <0 )
{
xcio_error(ioctxt, "Could not decrease reservation : %d",rc);
goto out;
}
else
{
printf("Decreased reservation by %d pages\n", count);
}
}
}
if ( xcio_read(ioctxt, &ctxt, sizeof(ctxt)) ||
xcio_read(ioctxt, shared_info, PAGE_SIZE) )
+35 -7
View File
@@ -463,10 +463,6 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
goto out;
}
printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n",
op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
}
/* calculate the power of 2 order of nr_pfns, e.g.
@@ -866,9 +862,41 @@ printf("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
goto out;
}
printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n",
op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
/* Send through a list of all the PFNs that were not in map at the close */
{
unsigned int i,j;
unsigned int pfntab[1024];
for ( i = 0, j = 0; i < nr_pfns; i++ )
{
if ( live_pfn_to_mfn_table[i] >= 0x80000000UL )
j++;
}
if ( xcio_write(ioctxt, &j, sizeof(unsigned int)) )
{
xcio_error(ioctxt, "Error when writing to state file (6a)");
goto out;
}
for ( i = 0, j = 0; i < nr_pfns; )
{
if ( live_pfn_to_mfn_table[i] >= 0x80000000UL )
{
pfntab[j++] = i;
}
i++;
if ( j == 1024 || i == nr_pfns )
{
if ( xcio_write(ioctxt, &pfntab, sizeof(unsigned long)*j) )
{
xcio_error(ioctxt, "Error when writing to state file (6b)");
goto out;
}
j = 0;
}
}
}
/* Map the suspend-record MFN to pin it. The page must be owned by
domid for this to succeed. */
+36
View File
@@ -127,6 +127,42 @@ static inline int do_multicall_op(int xc_handle,
out1: return ret;
}
static inline int do_dom_mem_op(int xc_handle,
unsigned int memop,
unsigned int *extent_list,
unsigned int nr_extents,
unsigned int extent_order,
domid_t domid)
{
privcmd_hypercall_t hypercall;
long ret = -EINVAL;
hypercall.op = __HYPERVISOR_dom_mem_op;
hypercall.arg[0] = (unsigned long)memop;
hypercall.arg[1] = (unsigned long)extent_list;
hypercall.arg[2] = (unsigned long)nr_extents;
hypercall.arg[3] = (unsigned long)extent_order;
hypercall.arg[4] = (unsigned long)domid;
if ( mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0 )
{
PERROR("Could not lock memory for Xen hypercall");
goto out1;
}
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
{
fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
" rebuild the user-space tool set?\n",ret,errno);
goto out2;
}
out2: (void)munlock(extent_list, nr_extents*sizeof(unsigned long));
out1: return ret;
}
/*
* PFN mapping.
*/
+25 -6
View File
@@ -92,13 +92,32 @@ static long free_dom_mem(struct domain *d,
long do_dom_mem_op(unsigned int op,
unsigned long *extent_list,
unsigned long nr_extents,
unsigned int extent_order)
unsigned int extent_order,
domid_t domid)
{
if ( op == MEMOP_increase_reservation )
return alloc_dom_mem(current, extent_list, nr_extents, extent_order);
struct domain *d;
long rc = -ENOSYS;
if ( op == MEMOP_decrease_reservation )
return free_dom_mem(current, extent_list, nr_extents, extent_order);
if (domid == DOMID_SELF)
d = current;
else
d = find_domain_by_id(domid);
return -ENOSYS;
if (d==NULL)
return -ESRCH;
switch( op )
{
case MEMOP_increase_reservation:
rc = alloc_dom_mem(d, extent_list, nr_extents, extent_order);
break;
case MEMOP_decrease_reservation:
rc = free_dom_mem(d, extent_list, nr_extents, extent_order);
break;
}
if (domid!=DOMID_SELF)
put_domain(d);
return rc;
}
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.