From 791fc8ed6e2888af3bd398f22562776c757cc4ac Mon Sep 17 00:00:00 2001 From: Dongxiao Xu Date: Wed, 11 Aug 2010 11:06:06 +0800 Subject: [PATCH] Netfront: Fix save/restore after enabled smart poll feature When s/r the guest, the shared ring will be set to NULL, and in this case the polling timer interrupt should stop. This fix includes the two parts: 1) Stop hrtimer when guest suspends. 2) Add check to avoid NULL pointer dereference. Thanks Ian J for reporting the problem. Signed-off-by: Dongxiao Xu --- drivers/net/xen-netfront.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 328fe40..eaea132 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1289,6 +1289,14 @@ static void xennet_disconnect_backend(struct netfront_info *info) info->rx.sring = NULL; } +static int netfront_suspend(struct xenbus_device *dev, pm_message_t state) +{ + struct netfront_info *info = dev_get_drvdata(&dev->dev); + struct hrtimer *timer = &info->smart_poll.timer; + hrtimer_cancel(timer); + return 0; +} + /** * We are reconnecting to the backend, due to a suspend/resume, or a backend * driver restart. We tear down our netif structure and recreate it, but @@ -1340,6 +1348,10 @@ static enum hrtimer_restart smart_poll_function(struct hrtimer *timer) np = netdev_priv(dev); spin_lock_irqsave(&np->tx_lock, flags); + + if (!np->rx.sring) + goto end; + np->smart_poll.counter++; if (likely(netif_carrier_ok(dev))) { @@ -1910,6 +1922,7 @@ static struct xenbus_driver netfront_driver = { .ids = netfront_ids, .probe = netfront_probe, .remove = __devexit_p(xennet_remove), + .suspend = netfront_suspend, .resume = netfront_resume, .otherend_changed = netback_changed, }; -- 1.6.3