Module Name: src
Committed By: martin
Date: Sun Jul 15 10:54:03 UTC 2018
Modified Files:
src/sys/arch/xen/xen [netbsd-8]: xennetback_xenbus.c
Log Message:
Pull up following revision(s) (requested by jdolecek in ticket #909):
sys/arch/xen/xen/xennetback_xenbus.c: revision 1.64 (patch)
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
To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.58.8.1 src/sys/arch/xen/xen/xennetback_xenbus.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/xen/xen/xennetback_xenbus.c
diff -u src/sys/arch/xen/xen/xennetback_xenbus.c:1.58 src/sys/arch/xen/xen/xennetback_xenbus.c:1.58.8.1
--- src/sys/arch/xen/xen/xennetback_xenbus.c:1.58 Thu Dec 15 09:28:04 2016
+++ src/sys/arch/xen/xen/xennetback_xenbus.c Sun Jul 15 10:54:03 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: xennetback_xenbus.c,v 1.58 2016/12/15 09:28:04 ozaki-r Exp $ */
+/* $NetBSD: xennetback_xenbus.c,v 1.58.8.1 2018/07/15 10:54:03 martin Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.58 2016/12/15 09:28:04 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.58.8.1 2018/07/15 10:54:03 martin Exp $");
#include "opt_xen.h"
@@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: xennetback_x
#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 @@ static inline void xennetback_tx_respons
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_cache;
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 @@ xvifattach(int n)
#endif
SLIST_INIT(&xnetback_instances);
+ mutex_init(&xnetback_lock, MUTEX_DEFAULT, IPL_NONE);
+
xenbus_backend_register(&xvif_backend_driver);
}
@@ -256,14 +261,10 @@ xennetback_xenbus_create(struct xenbus_d
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 @@ xennetback_xenbus_create(struct xenbus_d
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 @@ xennetback_xenbus_create(struct xenbus_d
abort_xbt:
xenbus_transaction_end(xbt, 1);
fail:
- free(xneti, M_DEVBUF);
+ kmem_free(xneti, sizeof(*xneti));
return err;
}
@@ -382,21 +385,22 @@ xennetback_xenbus_destroy(void *arg)
struct gnttab_unmap_grant_ref op;
int err;
-#if 0
- if (xneti->xni_status == CONNECTED) {
- return EBUSY;
- }
-#endif
aprint_verbose_ifnet(&xneti->xni_if, "disconnecting\n");
- hypervisor_mask_event(xneti->xni_evtchn);
- event_remove_handler(xneti->xni_evtchn, xennetback_evthandler, xneti);
- if (xneti->xni_softintr) {
- softint_disestablish(xneti->xni_softintr);
- xneti->xni_softintr = NULL;
+
+ if (xneti->xni_status == CONNECTED) {
+ hypervisor_mask_event(xneti->xni_evtchn);
+ event_remove_handler(xneti->xni_evtchn, xennetback_evthandler,
+ xneti);
+ 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);
@@ -421,11 +425,17 @@ xennetback_xenbus_destroy(void *arg)
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;
}
@@ -636,16 +646,22 @@ xennetback_frontend_changed(void *arg, X
}
/* 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;
}