Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/xen/xen fix panic of DOM0 in xennetback_xenbus_dest...
details: https://anonhg.NetBSD.org/src/rev/33fbf611101f
branches: trunk
changeset: 362770:33fbf611101f
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Jun 24 19:53:50 2018 +0000
description:
fix panic of DOM0 in xennetback_xenbus_destroy() on xl destroy of
DOMU with created, but non CONNECTED xennet (such as when DOMU
panics during boot); only try to disestablish the intr if it was
actually setup
while here protect xnetback_instances with mutex, and switch to use
kmem_zalloc() + KM_SLEEP / kmem_free() like xbdback_xenbus.c; add XXXSMP
to the other global variables, and at least mark them static
diffstat:
sys/arch/xen/xen/xennetback_xenbus.c | 81 +++++++++++++++++++++--------------
1 files changed, 49 insertions(+), 32 deletions(-)
diffs (185 lines):
diff -r 7854b85b6428 -r 33fbf611101f sys/arch/xen/xen/xennetback_xenbus.c
--- a/sys/arch/xen/xen/xennetback_xenbus.c Sun Jun 24 19:53:35 2018 +0000
+++ b/sys/arch/xen/xen/xennetback_xenbus.c Sun Jun 24 19:53:50 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xennetback_xenbus.c,v 1.63 2018/06/22 04:17:41 msaitoh Exp $ */
+/* $NetBSD: xennetback_xenbus.c,v 1.64 2018/06/24 19:53:50 jdolecek Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.63 2018/06/22 04:17:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.64 2018/06/24 19:53:50 jdolecek Exp $");
#include "opt_xen.h"
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
+#include <sys/kmem.h>
#include <sys/queue.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
@@ -140,9 +141,10 @@
int, int);
static void xennetback_tx_free(struct mbuf * , void *, size_t, void *);
-SLIST_HEAD(, xnetback_instance) xnetback_instances;
+static SLIST_HEAD(, xnetback_instance) xnetback_instances;
+static kmutex_t xnetback_lock;
-static struct xnetback_instance *xnetif_lookup(domid_t, uint32_t);
+static bool xnetif_lookup(domid_t, uint32_t);
static int xennetback_evthandler(void *);
static struct xenbus_backend_driver xvif_backend_driver = {
@@ -176,12 +178,13 @@
pool_cache_t xmit_pages_cachep;
/* arrays used in xennetback_ifstart(), too large to allocate on stack */
+/* XXXSMP */
static mmu_update_t xstart_mmu[NB_XMIT_PAGES_BATCH];
static multicall_entry_t xstart_mcl[NB_XMIT_PAGES_BATCH + 1];
static gnttab_transfer_t xstart_gop_transfer[NB_XMIT_PAGES_BATCH];
static gnttab_copy_t xstart_gop_copy[NB_XMIT_PAGES_BATCH];
-struct mbuf *mbufs_sent[NB_XMIT_PAGES_BATCH];
-struct _pages_pool_free {
+static struct mbuf *mbufs_sent[NB_XMIT_PAGES_BATCH];
+static struct _pages_pool_free {
vaddr_t va;
paddr_t pa;
} pages_pool_free[NB_XMIT_PAGES_BATCH];
@@ -229,6 +232,8 @@
#endif
SLIST_INIT(&xnetback_instances);
+ mutex_init(&xnetback_lock, MUTEX_DEFAULT, IPL_NONE);
+
xenbus_backend_register(&xvif_backend_driver);
}
@@ -256,14 +261,10 @@
return err;
}
- if (xnetif_lookup(domid, handle) != NULL) {
+ if (xnetif_lookup(domid, handle)) {
return EEXIST;
}
- xneti = malloc(sizeof(struct xnetback_instance), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (xneti == NULL) {
- return ENOMEM;
- }
+ xneti = kmem_zalloc(sizeof(*xneti), KM_SLEEP);
xneti->xni_domid = domid;
xneti->xni_handle = handle;
xneti->xni_status = DISCONNECTED;
@@ -317,7 +318,9 @@
if_attach(ifp);
ether_ifattach(&xneti->xni_if, xneti->xni_enaddr);
+ mutex_enter(&xnetback_lock);
SLIST_INSERT_HEAD(&xnetback_instances, xneti, next);
+ mutex_exit(&xnetback_lock);
xbusd->xbusd_otherend_changed = xennetback_frontend_changed;
@@ -371,7 +374,7 @@
abort_xbt:
xenbus_transaction_end(xbt, 1);
fail:
- free(xneti, M_DEVBUF);
+ kmem_free(xneti, sizeof(*xneti));
return err;
}
@@ -382,22 +385,24 @@
struct gnttab_unmap_grant_ref op;
int err;
-#if 0
+ aprint_verbose_ifnet(&xneti->xni_if, "disconnecting\n");
+
if (xneti->xni_status == CONNECTED) {
- return EBUSY;
- }
-#endif
- aprint_verbose_ifnet(&xneti->xni_if, "disconnecting\n");
- hypervisor_mask_event(xneti->xni_evtchn);
- intr_disestablish(xneti->xni_ih);
+ KASSERT(xneti->xni_ih);
+ hypervisor_mask_event(xneti->xni_evtchn);
+ intr_disestablish(xneti->xni_ih);
+ xneti->xni_ih = NULL;
- if (xneti->xni_softintr) {
- softint_disestablish(xneti->xni_softintr);
- xneti->xni_softintr = NULL;
+ if (xneti->xni_softintr) {
+ softint_disestablish(xneti->xni_softintr);
+ xneti->xni_softintr = NULL;
+ }
}
+ mutex_enter(&xnetback_lock);
SLIST_REMOVE(&xnetback_instances,
xneti, xnetback_instance, next);
+ mutex_exit(&xnetback_lock);
ether_ifdetach(&xneti->xni_if);
if_detach(&xneti->xni_if);
@@ -422,11 +427,17 @@
aprint_error_ifnet(&xneti->xni_if,
"unmap_grant_ref failed: %d\n", err);
}
- uvm_km_free(kernel_map, xneti->xni_tx_ring_va,
- PAGE_SIZE, UVM_KMF_VAONLY);
- uvm_km_free(kernel_map, xneti->xni_rx_ring_va,
- PAGE_SIZE, UVM_KMF_VAONLY);
- free(xneti, M_DEVBUF);
+ if (xneti->xni_tx_ring_va != 0) {
+ uvm_km_free(kernel_map, xneti->xni_tx_ring_va,
+ PAGE_SIZE, UVM_KMF_VAONLY);
+ xneti->xni_tx_ring_va = 0;
+ }
+ if (xneti->xni_rx_ring_va != 0) {
+ uvm_km_free(kernel_map, xneti->xni_rx_ring_va,
+ PAGE_SIZE, UVM_KMF_VAONLY);
+ xneti->xni_rx_ring_va = 0;
+ }
+ kmem_free(xneti, sizeof(*xneti));
return 0;
}
@@ -639,16 +650,22 @@
}
/* lookup a xneti based on domain id and interface handle */
-static struct xnetback_instance *
+static bool
xnetif_lookup(domid_t dom , uint32_t handle)
{
struct xnetback_instance *xneti;
+ bool found = false;
+ mutex_enter(&xnetback_lock);
SLIST_FOREACH(xneti, &xnetback_instances, next) {
- if (xneti->xni_domid == dom && xneti->xni_handle == handle)
- return xneti;
+ if (xneti->xni_domid == dom && xneti->xni_handle == handle) {
+ found = true;
+ break;
+ }
}
- return NULL;
+ mutex_exit(&xnetback_lock);
+
+ return found;
}
/* get a page to remplace a mbuf cluster page given to a domain */
Home |
Main Index |
Thread Index |
Old Index