svn commit: r225729 - in user/attilio/vmcontention: contrib/top libexec/rtld-elf share/mk sys/dev/usb sys/dev/xen/blkfront sys/dev/xen/control sys/dev/xen/netfront sys/net sys/netinet6 sys/ufs/ffs ...

Attilio Rao attilio at FreeBSD.org
Thu Sep 22 12:53:28 UTC 2011


Author: attilio
Date: Thu Sep 22 12:53:27 2011
New Revision: 225729
URL: http://svn.freebsd.org/changeset/base/225729

Log:
  MFC

Modified:
  user/attilio/vmcontention/libexec/rtld-elf/map_object.c
  user/attilio/vmcontention/sys/dev/usb/usb_transfer.c
  user/attilio/vmcontention/sys/dev/xen/blkfront/blkfront.c
  user/attilio/vmcontention/sys/dev/xen/blkfront/block.h
  user/attilio/vmcontention/sys/dev/xen/control/control.c
  user/attilio/vmcontention/sys/dev/xen/netfront/netfront.c
  user/attilio/vmcontention/sys/net/if_llatbl.h
  user/attilio/vmcontention/sys/net/radix.h
  user/attilio/vmcontention/sys/net/route.h
  user/attilio/vmcontention/sys/netinet6/in6.h
  user/attilio/vmcontention/sys/ufs/ffs/ffs_softdep.c
  user/attilio/vmcontention/sys/xen/xenbus/xenbusb.c
  user/attilio/vmcontention/sys/xen/xenbus/xenbusb_back.c
  user/attilio/vmcontention/sys/xen/xenbus/xenbusb_front.c
  user/attilio/vmcontention/sys/xen/xenstore/xenstore.c
Directory Properties:
  user/attilio/vmcontention/   (props changed)
  user/attilio/vmcontention/cddl/contrib/opensolaris/   (props changed)
  user/attilio/vmcontention/contrib/bind9/   (props changed)
  user/attilio/vmcontention/contrib/binutils/   (props changed)
  user/attilio/vmcontention/contrib/bzip2/   (props changed)
  user/attilio/vmcontention/contrib/compiler-rt/   (props changed)
  user/attilio/vmcontention/contrib/dialog/   (props changed)
  user/attilio/vmcontention/contrib/ee/   (props changed)
  user/attilio/vmcontention/contrib/expat/   (props changed)
  user/attilio/vmcontention/contrib/file/   (props changed)
  user/attilio/vmcontention/contrib/gcc/   (props changed)
  user/attilio/vmcontention/contrib/gdb/   (props changed)
  user/attilio/vmcontention/contrib/gdtoa/   (props changed)
  user/attilio/vmcontention/contrib/gnu-sort/   (props changed)
  user/attilio/vmcontention/contrib/groff/   (props changed)
  user/attilio/vmcontention/contrib/less/   (props changed)
  user/attilio/vmcontention/contrib/libpcap/   (props changed)
  user/attilio/vmcontention/contrib/libstdc++/   (props changed)
  user/attilio/vmcontention/contrib/llvm/   (props changed)
  user/attilio/vmcontention/contrib/llvm/tools/clang/   (props changed)
  user/attilio/vmcontention/contrib/ncurses/   (props changed)
  user/attilio/vmcontention/contrib/netcat/   (props changed)
  user/attilio/vmcontention/contrib/ntp/   (props changed)
  user/attilio/vmcontention/contrib/one-true-awk/   (props changed)
  user/attilio/vmcontention/contrib/openbsm/   (props changed)
  user/attilio/vmcontention/contrib/openpam/   (props changed)
  user/attilio/vmcontention/contrib/openresolv/   (props changed)
  user/attilio/vmcontention/contrib/pf/   (props changed)
  user/attilio/vmcontention/contrib/sendmail/   (props changed)
  user/attilio/vmcontention/contrib/tcpdump/   (props changed)
  user/attilio/vmcontention/contrib/tcsh/   (props changed)
  user/attilio/vmcontention/contrib/tnftp/   (props changed)
  user/attilio/vmcontention/contrib/top/   (props changed)
  user/attilio/vmcontention/contrib/top/install-sh   (props changed)
  user/attilio/vmcontention/contrib/tzcode/stdtime/   (props changed)
  user/attilio/vmcontention/contrib/tzcode/zic/   (props changed)
  user/attilio/vmcontention/contrib/tzdata/   (props changed)
  user/attilio/vmcontention/contrib/wpa/   (props changed)
  user/attilio/vmcontention/contrib/xz/   (props changed)
  user/attilio/vmcontention/crypto/openssh/   (props changed)
  user/attilio/vmcontention/crypto/openssl/   (props changed)
  user/attilio/vmcontention/gnu/lib/   (props changed)
  user/attilio/vmcontention/gnu/usr.bin/binutils/   (props changed)
  user/attilio/vmcontention/gnu/usr.bin/cc/cc_tools/   (props changed)
  user/attilio/vmcontention/gnu/usr.bin/gdb/   (props changed)
  user/attilio/vmcontention/lib/libc/   (props changed)
  user/attilio/vmcontention/lib/libc/stdtime/   (props changed)
  user/attilio/vmcontention/lib/libutil/   (props changed)
  user/attilio/vmcontention/lib/libz/   (props changed)
  user/attilio/vmcontention/sbin/   (props changed)
  user/attilio/vmcontention/sbin/ipfw/   (props changed)
  user/attilio/vmcontention/share/mk/bsd.arch.inc.mk   (props changed)
  user/attilio/vmcontention/share/zoneinfo/   (props changed)
  user/attilio/vmcontention/sys/   (props changed)
  user/attilio/vmcontention/sys/amd64/include/xen/   (props changed)
  user/attilio/vmcontention/sys/boot/   (props changed)
  user/attilio/vmcontention/sys/boot/i386/efi/   (props changed)
  user/attilio/vmcontention/sys/boot/ia64/efi/   (props changed)
  user/attilio/vmcontention/sys/boot/ia64/ski/   (props changed)
  user/attilio/vmcontention/sys/boot/powerpc/boot1.chrp/   (props changed)
  user/attilio/vmcontention/sys/boot/powerpc/ofw/   (props changed)
  user/attilio/vmcontention/sys/cddl/contrib/opensolaris/   (props changed)
  user/attilio/vmcontention/sys/conf/   (props changed)
  user/attilio/vmcontention/sys/contrib/dev/acpica/   (props changed)
  user/attilio/vmcontention/sys/contrib/octeon-sdk/   (props changed)
  user/attilio/vmcontention/sys/contrib/pf/   (props changed)
  user/attilio/vmcontention/sys/contrib/x86emu/   (props changed)
  user/attilio/vmcontention/usr.bin/calendar/   (props changed)
  user/attilio/vmcontention/usr.bin/csup/   (props changed)
  user/attilio/vmcontention/usr.bin/procstat/   (props changed)
  user/attilio/vmcontention/usr.sbin/ndiscvt/   (props changed)
  user/attilio/vmcontention/usr.sbin/rtadvctl/   (props changed)
  user/attilio/vmcontention/usr.sbin/rtadvd/   (props changed)
  user/attilio/vmcontention/usr.sbin/rtsold/   (props changed)
  user/attilio/vmcontention/usr.sbin/zic/   (props changed)

Modified: user/attilio/vmcontention/libexec/rtld-elf/map_object.c
==============================================================================
--- user/attilio/vmcontention/libexec/rtld-elf/map_object.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/libexec/rtld-elf/map_object.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -215,8 +215,9 @@ map_object(int fd, const char *path, con
 	    bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz);
 	    bss_addr = mapbase +  (bss_vaddr - base_vaddr);
 	    if (bss_vlimit > bss_vaddr) {	/* There is something to do */
-		if (mprotect(bss_addr, bss_vlimit - bss_vaddr, data_prot) == -1) {
-		    _rtld_error("%s: mprotect of bss failed: %s", path,
+		if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot,
+		    data_flags | MAP_ANON, -1, 0) == (caddr_t)-1) {
+		    _rtld_error("%s: mmap of bss failed: %s", path,
 			strerror(errno));
 		    return NULL;
 		}

Modified: user/attilio/vmcontention/sys/dev/usb/usb_transfer.c
==============================================================================
--- user/attilio/vmcontention/sys/dev/usb/usb_transfer.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/dev/usb/usb_transfer.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -2417,8 +2417,9 @@ usbd_transfer_start_cb(void *arg)
 #if USB_HAVE_PF
 	usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT);
 #endif
-	/* start the transfer */
-	(ep->methods->start) (xfer);
+	/* start USB transfer, if no error */
+	if (xfer->error == 0)
+		(ep->methods->start) (xfer);
 
 	xfer->flags_int.can_cancel_immed = 1;
 
@@ -2597,8 +2598,9 @@ usbd_pipe_start(struct usb_xfer_queue *p
 #if USB_HAVE_PF
 	usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT);
 #endif
-	/* start USB transfer */
-	(ep->methods->start) (xfer);
+	/* start USB transfer, if no error */
+	if (xfer->error == 0)
+		(ep->methods->start) (xfer);
 
 	xfer->flags_int.can_cancel_immed = 1;
 

Modified: user/attilio/vmcontention/sys/dev/xen/blkfront/blkfront.c
==============================================================================
--- user/attilio/vmcontention/sys/dev/xen/blkfront/blkfront.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/dev/xen/blkfront/blkfront.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -77,11 +77,8 @@ static int blkfront_detach(device_t);
 static int setup_blkring(struct xb_softc *);
 static void blkif_int(void *);
 static void blkfront_initialize(struct xb_softc *);
-#if 0
-static void blkif_recover(struct xb_softc *);
-#endif
 static int blkif_completion(struct xb_command *);
-static void blkif_free(struct xb_softc *, int);
+static void blkif_free(struct xb_softc *);
 static void blkif_queue_cb(void *, bus_dma_segment_t *, int, int);
 
 MALLOC_DEFINE(M_XENBLOCKFRONT, "xbd", "Xen Block Front driver data");
@@ -452,9 +449,6 @@ blkfront_attach(device_t dev)
 	sc->vdevice = vdevice;
 	sc->connected = BLKIF_STATE_DISCONNECTED;
 
-	/* Front end dir is a number, which is used as the id. */
-	sc->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
-
 	/* Wait for backend device to publish its protocol capabilities. */
 	xenbus_set_state(dev, XenbusStateInitialising);
 
@@ -465,29 +459,40 @@ static int
 blkfront_suspend(device_t dev)
 {
 	struct xb_softc *sc = device_get_softc(dev);
+	int retval;
+	int saved_state;
 
 	/* Prevent new requests being issued until we fix things up. */
 	mtx_lock(&sc->xb_io_lock);
+	saved_state = sc->connected;
 	sc->connected = BLKIF_STATE_SUSPENDED;
+
+	/* Wait for outstanding I/O to drain. */
+	retval = 0;
+	while (TAILQ_EMPTY(&sc->cm_busy) == 0) {
+		if (msleep(&sc->cm_busy, &sc->xb_io_lock,
+			   PRIBIO, "blkf_susp", 30 * hz) == EWOULDBLOCK) {
+			retval = EBUSY;
+			break;
+		}
+	}
 	mtx_unlock(&sc->xb_io_lock);
 
-	return (0);
+	if (retval != 0)
+		sc->connected = saved_state;
+
+	return (retval);
 }
 
 static int
 blkfront_resume(device_t dev)
 {
-#if 0
 	struct xb_softc *sc = device_get_softc(dev);
 
 	DPRINTK("blkfront_resume: %s\n", xenbus_get_node(dev));
 
-/* XXX This can't work!!! */
-	blkif_free(sc, 1);
+	blkif_free(sc);
 	blkfront_initialize(sc);
-	if (sc->connected == BLKIF_STATE_SUSPENDED)
-		blkif_recover(sc);
-#endif
 	return (0);
 }
 
@@ -499,8 +504,10 @@ blkfront_initialize(struct xb_softc *sc)
 	int error;
 	int i;
 
-	if (xenbus_get_state(sc->xb_dev) != XenbusStateInitialising)
-                return;
+	if (xenbus_get_state(sc->xb_dev) != XenbusStateInitialising) {
+		/* Initialization has already been performed. */
+		return;
+	}
 
 	/*
 	 * Protocol defaults valid even if negotiation for a
@@ -593,8 +600,10 @@ blkfront_initialize(struct xb_softc *sc)
 	sc->shadow = malloc(sizeof(*sc->shadow) * sc->max_requests,
 			    M_XENBLOCKFRONT, M_NOWAIT|M_ZERO);
 	if (sc->shadow == NULL) {
+		bus_dma_tag_destroy(sc->xb_io_dmat);
 		xenbus_dev_fatal(sc->xb_dev, error,
 				 "Cannot allocate request structures\n");
+		return;
 	}
 
 	for (i = 0; i < sc->max_requests; i++) {
@@ -755,10 +764,10 @@ blkfront_backend_changed(device_t dev, X
 		break;
 
 	case XenbusStateInitWait:
+	case XenbusStateInitialised:
 		blkfront_initialize(sc);
 		break;
 
-	case XenbusStateInitialised:
 	case XenbusStateConnected:
 		blkfront_initialize(sc);
 		blkfront_connect(sc);
@@ -775,7 +784,7 @@ blkfront_backend_changed(device_t dev, X
 }
 
 /* 
-** Invoked when the backend is finally 'ready' (and has told produced 
+** Invoked when the backend is finally 'ready' (and has published
 ** the details about the physical device - #sectors, size, etc). 
 */
 static void 
@@ -809,13 +818,15 @@ blkfront_connect(struct xb_softc *sc)
 	if (!err || feature_barrier)
 		sc->xb_flags |= XB_BARRIER;
 
-	device_printf(dev, "%juMB <%s> at %s",
-	    (uintmax_t) sectors / (1048576 / sector_size),
-	    device_get_desc(dev),
-	    xenbus_get_node(dev));
-	bus_print_child_footer(device_get_parent(dev), dev);
+	if (sc->xb_disk == NULL) {
+		device_printf(dev, "%juMB <%s> at %s",
+		    (uintmax_t) sectors / (1048576 / sector_size),
+		    device_get_desc(dev),
+		    xenbus_get_node(dev));
+		bus_print_child_footer(device_get_parent(dev), dev);
 
-	xlvbd_add(sc, sectors, sc->vdevice, binfo, sector_size);
+		xlvbd_add(sc, sectors, sc->vdevice, binfo, sector_size);
+	}
 
 	(void)xenbus_set_state(dev, XenbusStateConnected); 
 
@@ -825,7 +836,6 @@ blkfront_connect(struct xb_softc *sc)
 	xb_startio(sc);
 	sc->xb_flags |= XB_READY;
 	mtx_unlock(&sc->xb_io_lock);
-	
 }
 
 /**
@@ -859,7 +869,7 @@ blkfront_detach(device_t dev)
 
 	DPRINTK("blkfront_remove: %s removed\n", xenbus_get_node(dev));
 
-	blkif_free(sc, 0);
+	blkif_free(sc);
 	mtx_destroy(&sc->xb_io_lock);
 
 	return 0;
@@ -1140,6 +1150,9 @@ xb_startio(struct xb_softc *sc)
 
 	mtx_assert(&sc->xb_io_lock, MA_OWNED);
 
+	if (sc->connected != BLKIF_STATE_CONNECTED)
+		return;
+
 	while (RING_FREE_REQUESTS(&sc->ring) >= sc->max_request_blocks) {
 		if (sc->xb_flags & XB_FROZEN)
 			break;
@@ -1174,7 +1187,7 @@ blkif_int(void *xsc)
 
 	mtx_lock(&sc->xb_io_lock);
 
-	if (unlikely(sc->connected != BLKIF_STATE_CONNECTED)) {
+	if (unlikely(sc->connected == BLKIF_STATE_DISCONNECTED)) {
 		mtx_unlock(&sc->xb_io_lock);
 		return;
 	}
@@ -1232,19 +1245,21 @@ blkif_int(void *xsc)
 
 	xb_startio(sc);
 
+	if (unlikely(sc->connected == BLKIF_STATE_SUSPENDED))
+		wakeup(&sc->cm_busy);
+
 	mtx_unlock(&sc->xb_io_lock);
 }
 
 static void 
-blkif_free(struct xb_softc *sc, int suspend)
+blkif_free(struct xb_softc *sc)
 {
 	uint8_t *sring_page_ptr;
 	int i;
 	
 	/* Prevent new requests being issued until we fix things up. */
 	mtx_lock(&sc->xb_io_lock);
-	sc->connected = suspend ? 
-		BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; 
+	sc->connected = BLKIF_STATE_DISCONNECTED; 
 	mtx_unlock(&sc->xb_io_lock);
 
 	/* Free resources associated with old device channel. */
@@ -1276,6 +1291,12 @@ blkif_free(struct xb_softc *sc, int susp
 		}
 		free(sc->shadow, M_XENBLOCKFRONT);
 		sc->shadow = NULL;
+
+		bus_dma_tag_destroy(sc->xb_io_dmat);
+		
+		xb_initq_free(sc);
+		xb_initq_ready(sc);
+		xb_initq_complete(sc);
 	}
 		
 	if (sc->irq) {
@@ -1292,21 +1313,6 @@ blkif_completion(struct xb_command *s)
 	return (BLKIF_SEGS_TO_BLOCKS(s->nseg));
 }
 
-#if 0
-static void 
-blkif_recover(struct xb_softc *sc)
-{
-	/*
-	 * XXX The whole concept of not quiescing and completing all i/o
-	 * during suspend, and then hoping to recover and replay the
-	 * resulting abandoned I/O during resume, is laughable.  At best,
-	 * it invalidates the i/o ordering rules required by just about
-	 * every filesystem, and at worst it'll corrupt data.  The code
-	 * has been removed until further notice.
-	 */
-}
-#endif
-
 /* ** Driver registration ** */
 static device_method_t blkfront_methods[] = { 
 	/* Device interface */ 

Modified: user/attilio/vmcontention/sys/dev/xen/blkfront/block.h
==============================================================================
--- user/attilio/vmcontention/sys/dev/xen/blkfront/block.h	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/dev/xen/blkfront/block.h	Thu Sep 22 12:53:27 2011	(r225729)
@@ -142,7 +142,6 @@ struct xb_softc {
 #define XB_READY	(1 << 2)	/* Is ready */
 #define XB_FROZEN	(1 << 3)	/* Waiting for resources */
 	int			vdevice;
-	blkif_vdev_t		handle;
 	int			connected;
 	u_int			ring_pages;
 	uint32_t		max_requests;

Modified: user/attilio/vmcontention/sys/dev/xen/control/control.c
==============================================================================
--- user/attilio/vmcontention/sys/dev/xen/control/control.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/dev/xen/control/control.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/reboot.h>
 #include <sys/rman.h>
+#include <sys/sched.h>
 #include <sys/taskqueue.h>
 #include <sys/types.h>
 #include <sys/vnode.h>
@@ -201,6 +202,8 @@ xctrl_suspend()
 	int i, j, k, fpp;
 	unsigned long max_pfn, start_info_mfn;
 
+	EVENTHANDLER_INVOKE(power_suspend);
+
 #ifdef SMP
 	struct thread *td;
 	cpuset_t map;
@@ -221,7 +224,13 @@ xctrl_suspend()
 		stop_cpus(map);
 #endif
 
+	/*
+	 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
+	 * drivers need this.
+	 */
+	mtx_lock(&Giant);
 	if (DEVICE_SUSPEND(root_bus) != 0) {
+		mtx_unlock(&Giant);
 		printf("xen_suspend: device_suspend failed\n");
 #ifdef SMP
 		if (!CPU_EMPTY(&map))
@@ -229,6 +238,7 @@ xctrl_suspend()
 #endif
 		return;
 	}
+	mtx_unlock(&Giant);
 
 	local_irq_disable();
 
@@ -283,11 +293,14 @@ xctrl_suspend()
 		vcpu_prepare(i);
 
 #endif
+
 	/* 
 	 * Only resume xenbus /after/ we've prepared our VCPUs; otherwise
 	 * the VCPU hotplug callback can race with our vcpu_prepare
 	 */
+	mtx_lock(&Giant);
 	DEVICE_RESUME(root_bus);
+	mtx_unlock(&Giant);
 
 #ifdef SMP
 	thread_lock(curthread);
@@ -296,6 +309,7 @@ xctrl_suspend()
 	if (!CPU_EMPTY(&map))
 		restart_cpus(map);
 #endif
+	EVENTHANDLER_INVOKE(power_resume);
 }
 
 static void
@@ -322,39 +336,47 @@ xctrl_suspend()
 {
 	int suspend_cancelled;
 
+	EVENTHANDLER_INVOKE(power_suspend);
+
+	/*
+	 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
+	 * drivers need this.
+	 */
+	mtx_lock(&Giant);
 	if (DEVICE_SUSPEND(root_bus)) {
+		mtx_unlock(&Giant);
 		printf("xen_suspend: device_suspend failed\n");
 		return;
 	}
-
-	/*
-	 * Make sure we don't change cpus or switch to some other
-	 * thread. for the duration.
-	 */
-	critical_enter();
+	mtx_unlock(&Giant);
 
 	/*
 	 * Prevent any races with evtchn_interrupt() handler.
 	 */
-	irq_suspend();
 	disable_intr();
+	irq_suspend();
 
 	suspend_cancelled = HYPERVISOR_suspend(0);
-	if (!suspend_cancelled)
+	if (suspend_cancelled)
+		irq_resume();
+	else
 		xenpci_resume();
 
 	/*
 	 * Re-enable interrupts and put the scheduler back to normal.
 	 */
 	enable_intr();
-	critical_exit();
 
 	/*
 	 * FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or
 	 * similar.
 	 */
+	mtx_lock(&Giant);
 	if (!suspend_cancelled)
 		DEVICE_RESUME(root_bus);
+	mtx_unlock(&Giant);
+
+	EVENTHANDLER_INVOKE(power_resume);
 }
 #endif
 

Modified: user/attilio/vmcontention/sys/dev/xen/netfront/netfront.c
==============================================================================
--- user/attilio/vmcontention/sys/dev/xen/netfront/netfront.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/dev/xen/netfront/netfront.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -92,7 +92,8 @@ __FBSDID("$FreeBSD$");
 
 #include "xenbus_if.h"
 
-#define XN_CSUM_FEATURES	(CSUM_TCP | CSUM_UDP | CSUM_TSO)
+/* Features supported by all backends.  TSO and LRO can be negotiated */
+#define XN_CSUM_FEATURES	(CSUM_TCP | CSUM_UDP)
 
 #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
@@ -159,6 +160,8 @@ static int  xn_ioctl(struct ifnet *, u_l
 static void xn_ifinit_locked(struct netfront_info *);
 static void xn_ifinit(void *);
 static void xn_stop(struct netfront_info *);
+static void xn_query_features(struct netfront_info *np);
+static int  xn_configure_features(struct netfront_info *np);
 #ifdef notyet
 static void xn_watchdog(struct ifnet *);
 #endif
@@ -174,7 +177,7 @@ static int talk_to_backend(device_t dev,
 static int create_netdev(device_t dev);
 static void netif_disconnect_backend(struct netfront_info *info);
 static int setup_device(device_t dev, struct netfront_info *info);
-static void end_access(int ref, void *page);
+static void free_ring(int *ref, void *ring_ptr_ref);
 
 static int  xn_ifmedia_upd(struct ifnet *ifp);
 static void xn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
@@ -261,6 +264,7 @@ struct netfront_info {
 	u_int irq;
 	u_int copying_receiver;
 	u_int carrier;
+	u_int maxfrags;
 		
 	/* Receive-ring batched refills. */
 #define RX_MIN_TARGET 32
@@ -405,11 +409,33 @@ xen_net_read_mac(device_t dev, uint8_t m
 {
 	int error, i;
 	char *s, *e, *macstr;
+	const char *path;
 
-	error = xs_read(XST_NIL, xenbus_get_node(dev), "mac", NULL,
-	    (void **) &macstr);
-	if (error)
+	path = xenbus_get_node(dev);
+	error = xs_read(XST_NIL, path, "mac", NULL, (void **) &macstr);
+	if (error == ENOENT) {
+		/*
+		 * Deal with missing mac XenStore nodes on devices with
+		 * HVM emulation (the 'ioemu' configuration attribute)
+		 * enabled.
+		 *
+		 * The HVM emulator may execute in a stub device model
+		 * domain which lacks the permission, only given to Dom0,
+		 * to update the guest's XenStore tree.  For this reason,
+		 * the HVM emulator doesn't even attempt to write the
+		 * front-side mac node, even when operating in Dom0.
+		 * However, there should always be a mac listed in the
+		 * backend tree.  Fallback to this version if our query
+		 * of the front side XenStore location doesn't find
+		 * anything.
+		 */
+		path = xenbus_get_otherend_path(dev);
+		error = xs_read(XST_NIL, path, "mac", NULL, (void **) &macstr);
+	}
+	if (error != 0) {
+		xenbus_dev_fatal(dev, error, "parsing %s/mac", path);
 		return (error);
+	}
 
 	s = macstr;
 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
@@ -450,7 +476,7 @@ netfront_attach(device_t dev)
 	err = create_netdev(dev);
 	if (err) {
 		xenbus_dev_fatal(dev, err, "creating netdev");
-		return err;
+		return (err);
 	}
 
 #if __FreeBSD_version >= 700000
@@ -460,9 +486,21 @@ netfront_attach(device_t dev)
 	    &xn_enable_lro, 0, "Large Receive Offload");
 #endif
 
-	return 0;
+	return (0);
 }
 
+static int
+netfront_suspend(device_t dev)
+{
+	struct netfront_info *info = device_get_softc(dev);
+
+	XN_RX_LOCK(info);
+	XN_TX_LOCK(info);
+	netfront_carrier_off(info);
+	XN_TX_UNLOCK(info);
+	XN_RX_UNLOCK(info);
+	return (0);
+}
 
 /**
  * We are reconnecting to the backend, due to a suspend/resume, or a backend
@@ -749,10 +787,7 @@ netif_release_tx_bufs(struct netfront_in
 		 */
 		if (((uintptr_t)m) <= NET_TX_RING_SIZE)
 			continue;
-		gnttab_grant_foreign_access_ref(np->grant_tx_ref[i],
-		    xenbus_get_otherend_id(np->xbdev),
-		    virt_to_mfn(mtod(m, vm_offset_t)),
-		    GNTMAP_readonly);
+		gnttab_end_foreign_access_ref(np->grant_tx_ref[i]);
 		gnttab_release_grant_reference(&np->gref_tx_head,
 		    np->grant_tx_ref[i]);
 		np->grant_tx_ref[i] = GRANT_REF_INVALID;
@@ -761,7 +796,7 @@ netif_release_tx_bufs(struct netfront_in
 		if (np->xn_cdata.xn_tx_chain_cnt < 0) {
 			panic("netif_release_tx_bufs: tx_chain_cnt must be >= 0");
 		}
-		m_freem(m);
+		m_free(m);
 	}
 }
 
@@ -1494,7 +1529,7 @@ xn_assemble_tx_request(struct netfront_i
 	 * deal with nfrags > MAX_TX_REQ_FRAGS, which is a quirk of
 	 * the Linux network stack.
 	 */
-	if (nfrags > MAX_TX_REQ_FRAGS) {
+	if (nfrags > sc->maxfrags) {
 		m = m_defrag(m_head, M_DONTWAIT);
 		if (!m) {
 			/*
@@ -1911,6 +1946,8 @@ network_connect(struct netfront_info *np
 		return (error);
 	
 	/* Step 1: Reinitialise variables. */
+	xn_query_features(np);
+	xn_configure_features(np);
 	netif_release_tx_bufs(np);
 
 	/* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
@@ -1978,6 +2015,67 @@ show_device(struct netfront_info *sc)
 #endif
 }
 
+static void
+xn_query_features(struct netfront_info *np)
+{
+	int val;
+
+	device_printf(np->xbdev, "backend features:");
+
+	if (xs_scanf(XST_NIL, xenbus_get_otherend_path(np->xbdev),
+		"feature-sg", NULL, "%d", &val) < 0)
+		val = 0;
+
+	np->maxfrags = 1;
+	if (val) {
+		np->maxfrags = MAX_TX_REQ_FRAGS;
+		printf(" feature-sg");
+	}
+
+	if (xs_scanf(XST_NIL, xenbus_get_otherend_path(np->xbdev),
+		"feature-gso-tcpv4", NULL, "%d", &val) < 0)
+		val = 0;
+
+	np->xn_ifp->if_capabilities &= ~(IFCAP_TSO4|IFCAP_LRO);
+	if (val) {
+		np->xn_ifp->if_capabilities |= IFCAP_TSO4|IFCAP_LRO;
+		printf(" feature-gso-tcp4");
+	}
+
+	printf("\n");
+}
+
+static int
+xn_configure_features(struct netfront_info *np)
+{
+	int err;
+
+	err = 0;
+#if __FreeBSD_version >= 700000
+	if ((np->xn_ifp->if_capenable & IFCAP_LRO) != 0)
+		tcp_lro_free(&np->xn_lro);
+#endif
+    	np->xn_ifp->if_capenable =
+	    np->xn_ifp->if_capabilities & ~(IFCAP_LRO|IFCAP_TSO4);
+	np->xn_ifp->if_hwassist &= ~CSUM_TSO;
+#if __FreeBSD_version >= 700000
+	if (xn_enable_lro && (np->xn_ifp->if_capabilities & IFCAP_LRO) != 0) {
+		err = tcp_lro_init(&np->xn_lro);
+		if (err) {
+			device_printf(np->xbdev, "LRO initialization failed\n");
+		} else {
+			np->xn_lro.ifp = np->xn_ifp;
+			np->xn_ifp->if_capenable |= IFCAP_LRO;
+		}
+	}
+	if ((np->xn_ifp->if_capabilities & IFCAP_TSO4) != 0) {
+		np->xn_ifp->if_capenable |= IFCAP_TSO4;
+		np->xn_ifp->if_hwassist |= CSUM_TSO;
+	}
+#endif
+	return (err);
+}
+
 /** Create a network device.
  * @param handle device handle
  */
@@ -2002,7 +2100,7 @@ create_netdev(device_t dev)
 	np->rx_target     = RX_MIN_TARGET;
 	np->rx_min_target = RX_MIN_TARGET;
 	np->rx_max_target = RX_MAX_TARGET;
-	
+
 	/* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
 	for (i = 0; i <= NET_TX_RING_SIZE; i++) {
 		np->tx_mbufs[i] = (void *) ((u_long) i+1);
@@ -2032,11 +2130,8 @@ create_netdev(device_t dev)
 	}
 	
 	err = xen_net_read_mac(dev, np->mac);
-	if (err) {
-		xenbus_dev_fatal(dev, err, "parsing %s/mac",
-		    xenbus_get_node(dev));
+	if (err)
 		goto out;
-	}
 	
 	/* Set up ifnet structure */
 	ifp = np->xn_ifp = if_alloc(IFT_ETHER);
@@ -2055,19 +2150,6 @@ create_netdev(device_t dev)
 	
     	ifp->if_hwassist = XN_CSUM_FEATURES;
     	ifp->if_capabilities = IFCAP_HWCSUM;
-#if __FreeBSD_version >= 700000
-	ifp->if_capabilities |= IFCAP_TSO4;
-	if (xn_enable_lro) {
-		int err = tcp_lro_init(&np->xn_lro);
-		if (err) {
-			device_printf(dev, "LRO initialization failed\n");
-			goto exit;
-		}
-		np->xn_lro.ifp = ifp;
-		ifp->if_capabilities |= IFCAP_LRO;
-	}
-#endif
-    	ifp->if_capenable = ifp->if_capabilities;
 	
     	ether_ifattach(ifp, np->mac);
     	callout_init(&np->xn_stat_ch, CALLOUT_MPSAFE);
@@ -2078,8 +2160,7 @@ create_netdev(device_t dev)
 exit:
 	gnttab_free_grant_references(np->gref_tx_head);
 out:
-	panic("do something smart");
-
+	return (err);
 }
 
 /**
@@ -2133,12 +2214,8 @@ netif_disconnect_backend(struct netfront
 	XN_TX_UNLOCK(info);
 	XN_RX_UNLOCK(info);
 
-	end_access(info->tx_ring_ref, info->tx.sring);
-	end_access(info->rx_ring_ref, info->rx.sring);
-	info->tx_ring_ref = GRANT_REF_INVALID;
-	info->rx_ring_ref = GRANT_REF_INVALID;
-	info->tx.sring = NULL;
-	info->rx.sring = NULL;
+	free_ring(&info->tx_ring_ref, &info->tx.sring);
+	free_ring(&info->rx_ring_ref, &info->rx.sring);
 
 	if (info->irq)
 		unbind_from_irqhandler(info->irq);
@@ -2146,12 +2223,17 @@ netif_disconnect_backend(struct netfront
 	info->irq = 0;
 }
 
-
 static void
-end_access(int ref, void *page)
+free_ring(int *ref, void *ring_ptr_ref)
 {
-	if (ref != GRANT_REF_INVALID)
-		gnttab_end_foreign_access(ref, page);
+	void **ring_ptr_ptr = ring_ptr_ref;
+
+	if (*ref != GRANT_REF_INVALID) {
+		/* This API frees the associated storage. */
+		gnttab_end_foreign_access(*ref, *ring_ptr_ptr);
+		*ref = GRANT_REF_INVALID;
+	}
+	*ring_ptr_ptr = NULL;
 }
 
 static int
@@ -2174,7 +2256,7 @@ static device_method_t netfront_methods[
 	DEVMETHOD(device_attach,        netfront_attach), 
 	DEVMETHOD(device_detach,        netfront_detach), 
 	DEVMETHOD(device_shutdown,      bus_generic_shutdown), 
-	DEVMETHOD(device_suspend,       bus_generic_suspend), 
+	DEVMETHOD(device_suspend,       netfront_suspend), 
 	DEVMETHOD(device_resume,        netfront_resume), 
  
 	/* Xenbus interface */

Modified: user/attilio/vmcontention/sys/net/if_llatbl.h
==============================================================================
--- user/attilio/vmcontention/sys/net/if_llatbl.h	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/net/if_llatbl.h	Thu Sep 22 12:53:27 2011	(r225729)
@@ -59,6 +59,7 @@ struct llentry {
 	struct rwlock		 lle_lock;
 	struct lltable		 *lle_tbl;
 	struct llentries	 *lle_head;
+	void			(*lle_free)(struct lltable *, struct llentry *);
 	struct mbuf		 *la_hold;
 	int     		 la_numheld;  /* # of packets currently held */
 	time_t			 la_expire;

Modified: user/attilio/vmcontention/sys/net/radix.h
==============================================================================
--- user/attilio/vmcontention/sys/net/radix.h	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/net/radix.h	Thu Sep 22 12:53:27 2011	(r225729)
@@ -105,6 +105,8 @@ typedef int walktree_f_t(struct radix_no
 
 struct radix_node_head {
 	struct	radix_node *rnh_treetop;
+	u_int	rnh_gen;		/* generation counter */
+	int	rnh_multipath;		/* multipath capable ? */
 	int	rnh_addrsize;		/* permit, but not require fixed keys */
 	int	rnh_pktsize;		/* permit, but not require fixed keys */
 	struct	radix_node *(*rnh_addaddr)	/* add based on sockaddr */
@@ -131,8 +133,6 @@ struct radix_node_head {
 	void	(*rnh_close)	/* do something when the last ref drops */
 		(struct radix_node *rn, struct radix_node_head *head);
 	struct	radix_node rnh_nodes[3];	/* empty tree for common case */
-	int	rnh_multipath;			/* multipath capable ? */
-	u_int	rnh_spare;			/* route caching */
 #ifdef _KERNEL
 	struct	rwlock rnh_lock;		/* locks entire radix tree */
 #endif

Modified: user/attilio/vmcontention/sys/net/route.h
==============================================================================
--- user/attilio/vmcontention/sys/net/route.h	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/net/route.h	Thu Sep 22 12:53:27 2011	(r225729)
@@ -49,9 +49,13 @@
 struct route {
 	struct	rtentry *ro_rt;
 	struct	llentry *ro_lle;
+	struct	in_ifaddr *ro_ia;
+	int		ro_flags;
 	struct	sockaddr ro_dst;
 };
 
+#define RT_CACHING_CONTEXT	0x1
+
 /*
  * These numbers are used by reliable protocols for determining
  * retransmission behavior and are included in the routing structure.

Modified: user/attilio/vmcontention/sys/netinet6/in6.h
==============================================================================
--- user/attilio/vmcontention/sys/netinet6/in6.h	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/netinet6/in6.h	Thu Sep 22 12:53:27 2011	(r225729)
@@ -376,6 +376,8 @@ extern const struct in6_addr in6addr_lin
 struct route_in6 {
 	struct	rtentry *ro_rt;
 	struct	llentry *ro_lle;
+	struct	in6_addr *ro_ia6;
+	int		ro_flags;
 	struct	sockaddr_in6 ro_dst;
 };
 #endif

Modified: user/attilio/vmcontention/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- user/attilio/vmcontention/sys/ufs/ffs/ffs_softdep.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/ufs/ffs/ffs_softdep.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -12648,7 +12648,7 @@ retry:
 				MNT_ILOCK(mp);
 				continue;
 			}
-			(void) ffs_syncvnode(lvp, MNT_WAIT);
+			(void) ffs_syncvnode(lvp, MNT_NOWAIT);
 			vput(lvp);
 			MNT_ILOCK(mp);
 		}

Modified: user/attilio/vmcontention/sys/xen/xenbus/xenbusb.c
==============================================================================
--- user/attilio/vmcontention/sys/xen/xenbus/xenbusb.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/xen/xenbus/xenbusb.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -773,7 +773,7 @@ xenbusb_resume(device_t dev)
 			ivars = device_get_ivars(kids[i]);
 
 			xs_unregister_watch(&ivars->xd_otherend_watch);
-			ivars->xd_state = XenbusStateInitialising;
+			xenbus_set_state(kids[i], XenbusStateInitialising);
 
 			/*
 			 * Find the new backend details and
@@ -783,16 +783,16 @@ xenbusb_resume(device_t dev)
 			if (error)
 				return (error);
 
-			DEVICE_RESUME(kids[i]);
-
 			statepath = malloc(ivars->xd_otherend_path_len
 			    + strlen("/state") + 1, M_XENBUS, M_WAITOK);
 			sprintf(statepath, "%s/state", ivars->xd_otherend_path);
 
 			free(ivars->xd_otherend_watch.node, M_XENBUS);
 			ivars->xd_otherend_watch.node = statepath;
-			xs_register_watch(&ivars->xd_otherend_watch);
 
+			DEVICE_RESUME(kids[i]);
+
+			xs_register_watch(&ivars->xd_otherend_watch);
 #if 0
 			/*
 			 * Can't do this yet since we are running in

Modified: user/attilio/vmcontention/sys/xen/xenbus/xenbusb_back.c
==============================================================================
--- user/attilio/vmcontention/sys/xen/xenbus/xenbusb_back.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/xen/xenbus/xenbusb_back.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -292,7 +292,7 @@ static device_method_t xenbusb_back_meth
 	DEVMETHOD(device_detach,        bus_generic_detach), 
 	DEVMETHOD(device_shutdown,      bus_generic_shutdown), 
 	DEVMETHOD(device_suspend,       bus_generic_suspend), 
-	DEVMETHOD(device_resume,        bus_generic_resume), 
+	DEVMETHOD(device_resume,        xenbusb_resume), 
  
 	/* Bus Interface */ 
 	DEVMETHOD(bus_print_child,      xenbusb_print_child),

Modified: user/attilio/vmcontention/sys/xen/xenbus/xenbusb_front.c
==============================================================================
--- user/attilio/vmcontention/sys/xen/xenbus/xenbusb_front.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/xen/xenbus/xenbusb_front.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -171,7 +171,7 @@ static device_method_t xenbusb_front_met
 	DEVMETHOD(device_detach,        bus_generic_detach), 
 	DEVMETHOD(device_shutdown,      bus_generic_shutdown), 
 	DEVMETHOD(device_suspend,       bus_generic_suspend), 
-	DEVMETHOD(device_resume,        bus_generic_resume), 
+	DEVMETHOD(device_resume,        xenbusb_resume), 
  
 	/* Bus Interface */ 
 	DEVMETHOD(bus_print_child,      xenbusb_print_child),

Modified: user/attilio/vmcontention/sys/xen/xenstore/xenstore.c
==============================================================================
--- user/attilio/vmcontention/sys/xen/xenstore/xenstore.c	Thu Sep 22 11:07:11 2011	(r225728)
+++ user/attilio/vmcontention/sys/xen/xenstore/xenstore.c	Thu Sep 22 12:53:27 2011	(r225729)
@@ -721,8 +721,8 @@ xs_reply_filter(uint32_t request_msg_typ
 	/*
 	 * The count of transactions drops if we attempted
 	 * to end a transaction (even if that attempt fails
-	 * in error), we receive a transaction end acknowledgement
-	 * or if our attempt to begin a transactionfails.
+	 * in error), we receive a transaction end acknowledgement,
+	 * or if our attempt to begin a transaction fails.
 	 */
 	if (request_msg_type == XS_TRANSACTION_END
 	 || (request_reply_error == 0 && reply_msg_type == XS_TRANSACTION_END)
@@ -1194,8 +1194,14 @@ xs_attach(device_t dev)
  * all transactions and individual requests have completed.
  */
 static int
-xs_suspend(device_t dev __unused)
+xs_suspend(device_t dev)
 {
+	int error;
+
+	/* Suspend child Xen devices. */
+	error = bus_generic_suspend(dev);
+	if (error != 0)
+		return (error);
 
 	sx_xlock(&xs.suspend_mutex);
 	sx_xlock(&xs.request_mutex);
@@ -1227,6 +1233,9 @@ xs_resume(device_t dev __unused)
 
 	sx_xunlock(&xs.suspend_mutex);
 
+	/* Resume child Xen devices. */
+	bus_generic_resume(dev);
+
 	return (0);
 }
 


More information about the svn-src-user mailing list