Sun Mar 6 18:52:07 2016 UTC ()
Pull up following revision(s) (requested by bouyer in ticket #1125):
	sys/arch/xen/xen/if_xennet_xenbus.c: revision 1.67
In xennet_xenbus_detach(), remove the event handler early (just after
xennet_stop()) so that we don't get events while slepping (e.g.
in softint_disestablish()) when some structures have already been
freed.
Problem reported and patch tested by Rohan Desai.


(martin)
diff -r1.63 -r1.63.2.1 src/sys/arch/xen/xen/if_xennet_xenbus.c

cvs diff -r1.63 -r1.63.2.1 src/sys/arch/xen/xen/if_xennet_xenbus.c (expand / switch to unified diff)

--- src/sys/arch/xen/xen/if_xennet_xenbus.c 2014/08/10 16:44:35 1.63
+++ src/sys/arch/xen/xen/if_xennet_xenbus.c 2016/03/06 18:52:06 1.63.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_xennet_xenbus.c,v 1.63 2014/08/10 16:44:35 tls Exp $ */ 1/* $NetBSD: if_xennet_xenbus.c,v 1.63.2.1 2016/03/06 18:52:06 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Manuel Bouyer. 4 * Copyright (c) 2006 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -75,27 +75,27 @@ @@ -75,27 +75,27 @@
75 * Purpose is to process the packets received from the outside. RX buffers 75 * Purpose is to process the packets received from the outside. RX buffers
76 * are pre-allocated through xennet_alloc_rx_buffer(), during xennet autoconf 76 * are pre-allocated through xennet_alloc_rx_buffer(), during xennet autoconf
77 * attach. During pre-allocation, frontend pushes requests in the I/O ring, in 77 * attach. During pre-allocation, frontend pushes requests in the I/O ring, in
78 * preparation for incoming packets from backend. 78 * preparation for incoming packets from backend.
79 * When RX packets need to be processed, backend takes the requests previously 79 * When RX packets need to be processed, backend takes the requests previously
80 * offered by frontend and pushes the associated responses inside the I/O ring. 80 * offered by frontend and pushes the associated responses inside the I/O ring.
81 * When done, it notifies frontend through an event notification, which will 81 * When done, it notifies frontend through an event notification, which will
82 * asynchronously call xennet_handler() in frontend. 82 * asynchronously call xennet_handler() in frontend.
83 * xennet_handler() processes the responses, generates the associated mbuf, and 83 * xennet_handler() processes the responses, generates the associated mbuf, and
84 * passes it to the MI layer for further processing. 84 * passes it to the MI layer for further processing.
85 */ 85 */
86 86
87#include <sys/cdefs.h> 87#include <sys/cdefs.h>
88__KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.63 2014/08/10 16:44:35 tls Exp $"); 88__KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.63.2.1 2016/03/06 18:52:06 martin Exp $");
89 89
90#include "opt_xen.h" 90#include "opt_xen.h"
91#include "opt_nfs_boot.h" 91#include "opt_nfs_boot.h"
92 92
93#include <sys/param.h> 93#include <sys/param.h>
94#include <sys/device.h> 94#include <sys/device.h>
95#include <sys/conf.h> 95#include <sys/conf.h>
96#include <sys/kernel.h> 96#include <sys/kernel.h>
97#include <sys/proc.h> 97#include <sys/proc.h>
98#include <sys/systm.h> 98#include <sys/systm.h>
99#include <sys/intr.h> 99#include <sys/intr.h>
100#include <sys/rnd.h> 100#include <sys/rnd.h>
101 101
@@ -411,26 +411,27 @@ xennet_xenbus_attach(device_t parent, de @@ -411,26 +411,27 @@ xennet_xenbus_attach(device_t parent, de
411} 411}
412 412
413static int 413static int
414xennet_xenbus_detach(device_t self, int flags) 414xennet_xenbus_detach(device_t self, int flags)
415{ 415{
416 struct xennet_xenbus_softc *sc = device_private(self); 416 struct xennet_xenbus_softc *sc = device_private(self);
417 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 417 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
418 int s0, s1; 418 int s0, s1;
419 RING_IDX i; 419 RING_IDX i;
420 420
421 DPRINTF(("%s: xennet_xenbus_detach\n", device_xname(self))); 421 DPRINTF(("%s: xennet_xenbus_detach\n", device_xname(self)));
422 s0 = splnet(); 422 s0 = splnet();
423 xennet_stop(ifp, 1); 423 xennet_stop(ifp, 1);
 424 event_remove_handler(sc->sc_evtchn, &xennet_handler, sc);
424 /* wait for pending TX to complete, and collect pending RX packets */ 425 /* wait for pending TX to complete, and collect pending RX packets */
425 xennet_handler(sc); 426 xennet_handler(sc);
426 while (sc->sc_tx_ring.sring->rsp_prod != sc->sc_tx_ring.rsp_cons) { 427 while (sc->sc_tx_ring.sring->rsp_prod != sc->sc_tx_ring.rsp_cons) {
427 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_detach", hz/2); 428 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_detach", hz/2);
428 xennet_handler(sc); 429 xennet_handler(sc);
429 } 430 }
430 xennet_free_rx_buffer(sc); 431 xennet_free_rx_buffer(sc);
431 432
432 s1 = splvm(); 433 s1 = splvm();
433 for (i = 0; i < NET_RX_RING_SIZE; i++) { 434 for (i = 0; i < NET_RX_RING_SIZE; i++) {
434 struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i]; 435 struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i];
435 uvm_km_free(kernel_map, rxreq->rxreq_va, PAGE_SIZE, 436 uvm_km_free(kernel_map, rxreq->rxreq_va, PAGE_SIZE,
436 UVM_KMF_WIRED); 437 UVM_KMF_WIRED);
@@ -446,27 +447,26 @@ xennet_xenbus_detach(device_t self, int  @@ -446,27 +447,26 @@ xennet_xenbus_detach(device_t self, int
446 while (xengnt_status(sc->sc_tx_ring_gntref)) { 447 while (xengnt_status(sc->sc_tx_ring_gntref)) {
447 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_txref", hz/2); 448 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_txref", hz/2);
448 } 449 }
449 xengnt_revoke_access(sc->sc_tx_ring_gntref); 450 xengnt_revoke_access(sc->sc_tx_ring_gntref);
450 uvm_km_free(kernel_map, (vaddr_t)sc->sc_tx_ring.sring, PAGE_SIZE, 451 uvm_km_free(kernel_map, (vaddr_t)sc->sc_tx_ring.sring, PAGE_SIZE,
451 UVM_KMF_WIRED); 452 UVM_KMF_WIRED);
452 while (xengnt_status(sc->sc_rx_ring_gntref)) { 453 while (xengnt_status(sc->sc_rx_ring_gntref)) {
453 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_rxref", hz/2); 454 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_rxref", hz/2);
454 } 455 }
455 xengnt_revoke_access(sc->sc_rx_ring_gntref); 456 xengnt_revoke_access(sc->sc_rx_ring_gntref);
456 uvm_km_free(kernel_map, (vaddr_t)sc->sc_rx_ring.sring, PAGE_SIZE, 457 uvm_km_free(kernel_map, (vaddr_t)sc->sc_rx_ring.sring, PAGE_SIZE,
457 UVM_KMF_WIRED); 458 UVM_KMF_WIRED);
458 softint_disestablish(sc->sc_softintr); 459 softint_disestablish(sc->sc_softintr);
459 event_remove_handler(sc->sc_evtchn, &xennet_handler, sc); 
460 splx(s0); 460 splx(s0);
461 461
462 pmf_device_deregister(self); 462 pmf_device_deregister(self);
463 463
464 DPRINTF(("%s: xennet_xenbus_detach done\n", device_xname(self))); 464 DPRINTF(("%s: xennet_xenbus_detach done\n", device_xname(self)));
465 return 0; 465 return 0;
466} 466}
467 467
468static bool 468static bool
469xennet_xenbus_resume(device_t dev, const pmf_qual_t *qual) 469xennet_xenbus_resume(device_t dev, const pmf_qual_t *qual)
470{ 470{
471 struct xennet_xenbus_softc *sc = device_private(dev); 471 struct xennet_xenbus_softc *sc = device_private(dev);
472 int error; 472 int error;