aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEduardo Otubo <otubo@redhat.com>2017-11-23 09:18:35 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-27 14:21:58 -0500
commit5b5971df3bc2775107ddad164018a8a8db633b81 (patch)
treedca1b7578a39cd189f67e2feba7d49d54ade1adc
parentd3fe1e0185cffabc9b6f73f246a5552b46af7131 (diff)
xen-netfront: remove warning when unloading module
v2: * Replace busy wait with wait_event()/wake_up_all() * Cannot garantee that at the time xennet_remove is called, the xen_netback state will not be XenbusStateClosed, so added a condition for that * There's a small chance for the xen_netback state is XenbusStateUnknown by the time the xen_netfront switches to Closed, so added a condition for that. When unloading module xen_netfront from guest, dmesg would output warning messages like below: [ 105.236836] xen:grant_table: WARNING: g.e. 0x903 still in use! [ 105.236839] deferring g.e. 0x903 (pfn 0x35805) This problem relies on netfront and netback being out of sync. By the time netfront revokes the g.e.'s netback didn't have enough time to free all of them, hence displaying the warnings on dmesg. The trick here is to make netfront to wait until netback frees all the g.e.'s and only then continue to cleanup for the module removal, and this is done by manipulating both device states. Signed-off-by: Eduardo Otubo <otubo@redhat.com> Acked-by: Juergen Gross <jgross@suse.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/xen-netfront.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 8b8689c6d887..391432e2725d 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -87,6 +87,8 @@ struct netfront_cb {
87/* IRQ name is queue name with "-tx" or "-rx" appended */ 87/* IRQ name is queue name with "-tx" or "-rx" appended */
88#define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) 88#define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)
89 89
90static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
91
90struct netfront_stats { 92struct netfront_stats {
91 u64 packets; 93 u64 packets;
92 u64 bytes; 94 u64 bytes;
@@ -2021,10 +2023,12 @@ static void netback_changed(struct xenbus_device *dev,
2021 break; 2023 break;
2022 2024
2023 case XenbusStateClosed: 2025 case XenbusStateClosed:
2026 wake_up_all(&module_unload_q);
2024 if (dev->state == XenbusStateClosed) 2027 if (dev->state == XenbusStateClosed)
2025 break; 2028 break;
2026 /* Missed the backend's CLOSING state -- fallthrough */ 2029 /* Missed the backend's CLOSING state -- fallthrough */
2027 case XenbusStateClosing: 2030 case XenbusStateClosing:
2031 wake_up_all(&module_unload_q);
2028 xenbus_frontend_closed(dev); 2032 xenbus_frontend_closed(dev);
2029 break; 2033 break;
2030 } 2034 }
@@ -2130,6 +2134,20 @@ static int xennet_remove(struct xenbus_device *dev)
2130 2134
2131 dev_dbg(&dev->dev, "%s\n", dev->nodename); 2135 dev_dbg(&dev->dev, "%s\n", dev->nodename);
2132 2136
2137 if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) {
2138 xenbus_switch_state(dev, XenbusStateClosing);
2139 wait_event(module_unload_q,
2140 xenbus_read_driver_state(dev->otherend) ==
2141 XenbusStateClosing);
2142
2143 xenbus_switch_state(dev, XenbusStateClosed);
2144 wait_event(module_unload_q,
2145 xenbus_read_driver_state(dev->otherend) ==
2146 XenbusStateClosed ||
2147 xenbus_read_driver_state(dev->otherend) ==
2148 XenbusStateUnknown);
2149 }
2150
2133 xennet_disconnect_backend(info); 2151 xennet_disconnect_backend(info);
2134 2152
2135 unregister_netdev(info->netdev); 2153 unregister_netdev(info->netdev);