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