aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-08-11 21:21:04 +0000
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-08-11 21:21:04 +0000
commite928978a4443fd107ca09bea25b155bc8a5c0ee9 (patch)
treec24efdb3456369a496653c7f931c9b54caafc97f
parent82805c47cbbc79b671793141580af343fae7b847 (diff)
downloadxen-e928978a4443fd107ca09bea25b155bc8a5c0ee9.tar.gz
xen-e928978a4443fd107ca09bea25b155bc8a5c0ee9.tar.bz2
xen-e928978a4443fd107ca09bea25b155bc8a5c0ee9.zip
bitkeeper revision 1.1159.24.1 (411a8dc04Gzs_coIAm_0Gf5NK-YpxQ)
suspend/resume now works again, though netfront contains a workaround hack for a xend issue.
-rw-r--r--linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c68
-rw-r--r--linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c27
-rw-r--r--linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c2
-rw-r--r--linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c73
4 files changed, 144 insertions, 26 deletions
diff --git a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c
index 0d5fd96968..c50d94c57d 100644
--- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c
+++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c
@@ -60,6 +60,34 @@ static int sg_operation = -1;
static unsigned long sg_next_sect;
#define DISABLE_SCATTERGATHER() (sg_operation = -1)
+
+inline void translate_req_to_pfn( blkif_request_t * xreq, blkif_request_t * req)
+{
+ int i;
+
+ *xreq=*req;
+ for ( i=0; i<req->nr_segments; i++ )
+ {
+ xreq->frame_and_sects[i] = (req->frame_and_sects[i] & ~PAGE_MASK) |
+ (machine_to_phys_mapping[req->frame_and_sects[i]>>PAGE_SHIFT]<<PAGE_SHIFT);
+ }
+ return xreq;
+}
+
+inline void translate_req_to_mfn( blkif_request_t * xreq, blkif_request_t * req)
+{
+ int i;
+
+ *xreq=*req;
+ for ( i=0; i<req->nr_segments; i++ )
+ {
+ xreq->frame_and_sects[i] = (req->frame_and_sects[i] & ~PAGE_MASK) |
+ (phys_to_machine_mapping[req->frame_and_sects[i]>>PAGE_SHIFT]<<PAGE_SHIFT);
+ }
+ return xreq;
+}
+
+
static inline void flush_requests(void)
{
DISABLE_SCATTERGATHER();
@@ -364,8 +392,8 @@ static int blkif_queue_request(unsigned long id,
DISABLE_SCATTERGATHER();
/* Update the copy of the request in the recovery ring. */
- blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod - 1)].req
- = *req;
+ translate_req_to_pfn(&blk_ring_rec->ring[
+ MASK_BLKIF_IDX(blk_ring_rec->req_prod - 1)].req, req);
return 0;
}
@@ -395,8 +423,9 @@ static int blkif_queue_request(unsigned long id,
req->frame_and_sects[0] = buffer_ma | (fsect<<3) | lsect;
req_prod++;
- /* Keep a private copy so we can reissue requests when recovering. */
- blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod)].req = *req;
+ /* Keep a private copy so we can reissue requests when recovering. */
+ translate_req_to_pfn(&blk_ring_rec->ring[
+ MASK_BLKIF_IDX(blk_ring_rec->req_prod)].req, req);
blk_ring_rec->req_prod++;
return 0;
@@ -570,9 +599,11 @@ void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
}
DISABLE_SCATTERGATHER();
- memcpy(&blk_ring->ring[MASK_BLKIF_IDX(req_prod)].req, req, sizeof(*req));
- memcpy(&blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod++)].req,
- req, sizeof(*req));
+ blk_ring->ring[MASK_BLKIF_IDX(req_prod)].req = *req;
+
+ translate_req_to_pfn(&blk_ring_rec->ring[
+ MASK_BLKIF_IDX(blk_ring_rec->req_prod++)].req,req);
+
req_prod++;
flush_requests();
@@ -660,7 +691,7 @@ static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
if ( recovery )
{
- int i;
+ int i,j;
/* Shouldn't need the io_request_lock here - the device is
* plugged and the recovery flag prevents the interrupt handler
@@ -670,18 +701,24 @@ static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
for ( i = 0;
resp_cons_rec < blk_ring_rec->req_prod;
resp_cons_rec++, i++ )
- {
- blk_ring->ring[i].req
- = blk_ring_rec->ring[MASK_BLKIF_IDX(resp_cons_rec)].req;
+ {
+ translate_req_to_mfn(&blk_ring->ring[i].req,
+ &blk_ring_rec->ring[
+ MASK_BLKIF_IDX(resp_cons_rec)].req);
}
- /* Reset the private block ring to match the new ring. */
- memcpy(blk_ring_rec, blk_ring, sizeof(*blk_ring));
+ /* Reset the private block ring to match the new ring. */
+ for( j=0; j<i; j++ )
+ {
+ translate_req_to_pfn(
+ &blk_ring_rec->ring[j].req,
+ &blk_ring->ring[j].req);
+ }
+
resp_cons_rec = 0;
/* blk_ring->req_prod will be set when we flush_requests().*/
blk_ring_rec->req_prod = req_prod = i;
-
wmb();
/* Switch off recovery mode, using a memory barrier to ensure that
@@ -806,8 +843,7 @@ void blkdev_suspend(void)
void blkdev_resume(void)
{
ctrl_msg_t cmsg;
- blkif_fe_driver_status_changed_t st;
-
+ blkif_fe_driver_status_changed_t st;
/* Send a driver-UP notification to the domain controller. */
cmsg.type = CMSG_BLKIF_FE;
diff --git a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c
index 6acd49bc06..9b740aaaa8 100644
--- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c
+++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c
@@ -1197,11 +1197,12 @@ static int shutting_down = -1;
static void __do_suspend(void)
{
+ int i,j;
/* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
extern void blkdev_suspend(void);
extern void blkdev_resume(void);
- extern void netif_resume(void);
-
+ extern void netif_suspend(void);
+ extern void netif_resume(void);
extern void time_suspend(void);
extern void time_resume(void);
@@ -1213,11 +1214,12 @@ static void __do_suspend(void)
suspend_record->nr_pfns = max_pfn; /* final number of pfns */
- //netdev_suspend();
- //blkdev_suspend();
-
__cli();
+ netif_suspend();
+
+ blkdev_suspend();
+
time_suspend();
ctrl_if_suspend();
@@ -1241,17 +1243,28 @@ static void __do_suspend(void)
memset(empty_zero_page, 0, PAGE_SIZE);
+ for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
+ {
+ pfn_to_mfn_frame_list[j] =
+ virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
+ }
+ HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
+ virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
+
+
irq_resume();
ctrl_if_resume();
time_resume();
- __sti();
-
blkdev_resume();
+
netif_resume();
+ __sti();
+
+
out:
if ( suspend_record != NULL )
free_page((unsigned long)suspend_record);
diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c
index 01447b1de8..76d23171b2 100644
--- a/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c
+++ b/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c
@@ -241,6 +241,8 @@ void netif_connect(netif_be_connect_t *connect)
netif->status = CONNECTED;
netif_get(netif);
+ netif->tx->resp_prod = netif->rx->resp_prod = 0;
+
rtnl_lock();
(void)dev_open(netif->dev);
rtnl_unlock();
diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c
index 368feadc55..a9b59505bc 100644
--- a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c
+++ b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c
@@ -546,7 +546,7 @@ static void network_connect(struct net_device *dev,
/* Step 1: Reinitialise variables. */
np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
- np->rx->event = 1;
+ np->rx->event = np->tx->event = 1;
/* Step 2: Rebuild the RX and TX ring contents.
* NB. We could just free the queued TX packets now but we hope
@@ -776,12 +776,13 @@ static int create_netdev(int handle, struct net_device **val)
* Initialize the network control interface. Set the number of network devices
* and create them.
*/
+
static void netif_driver_status_change(
netif_fe_driver_status_changed_t *status)
{
int err = 0;
int i;
-
+
netctrl.interface_n = status->nr_interfaces;
netctrl.connected_n = 0;
@@ -874,11 +875,75 @@ static int __init netif_init(void)
return err;
}
+void netif_suspend(void)
+{
+#if 1 /* XXX THIS IS TEMPORARY */
+ struct net_device *dev = NULL;
+ struct net_private *np = NULL;
+ int i;
+
+/* avoid having tx/rx stuff happen until we're ready */
+
+ for(i=0;i<netctrl.interface_n;i++)
+ {
+ char name[32];
+
+ sprintf(name,"eth%d",i);
+ dev = __dev_get_by_name(name);
+
+ if ( dev && (dev->flags & IFF_UP) )
+ {
+ np = dev->priv;
+
+ free_irq(np->irq, dev);
+ unbind_evtchn_from_irq(np->evtchn);
+ }
+ }
+#endif
+}
+
void netif_resume(void)
{
ctrl_msg_t cmsg;
- netif_fe_driver_status_changed_t st;
+ netif_fe_interface_connect_t up;
+// netif_fe_driver_status_changed_t st;
+ struct net_device *dev = NULL;
+ struct net_private *np = NULL;
+ int i;
+
+#if 1
+ /* XXX THIS IS TEMPORARY */
+
+ for(i=0;i<netctrl.interface_n;i++)
+ {
+ char name[32];
+ sprintf(name,"eth%d",i);
+ dev = __dev_get_by_name(name);
+
+ if ( dev ) // connect regardless of whether IFF_UP flag set
+ {
+ np = dev->priv;
+
+ // stop bad things from happening until we're back up
+ np->backend_state = BEST_DISCONNECTED;
+
+ cmsg.type = CMSG_NETIF_FE;
+ cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT;
+ cmsg.length = sizeof(netif_fe_interface_connect_t);
+ up.handle = np->handle;
+ up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
+ up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
+ memcpy(cmsg.msg, &up, sizeof(up));
+
+ /* Tell the controller to bring up the interface. */
+ ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
+ }
+ }
+#endif
+
+
+#if 0
/* Send a driver-UP notification to the domain controller. */
cmsg.type = CMSG_NETIF_FE;
cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
@@ -887,6 +952,8 @@ void netif_resume(void)
st.nr_interfaces = 0;
memcpy(cmsg.msg, &st, sizeof(st));
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
+#endif
+
}