? arch/amd64/compile/XEN3_DOMU
Index: arch/xen/xen/if_xennet_xenbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/if_xennet_xenbus.c,v
retrieving revision 1.41
diff -u -r1.41 if_xennet_xenbus.c
--- arch/xen/xen/if_xennet_xenbus.c	5 Apr 2010 07:19:32 -0000	1.41
+++ arch/xen/xen/if_xennet_xenbus.c	13 Apr 2010 09:51:07 -0000
@@ -195,6 +195,7 @@
 	int sc_free_rxreql; /* number of free receive request struct */
 
 	int sc_backend_status; /* our status with backend */
+        int sc_rx_copy;
 #define BEST_CLOSED		0
 #define BEST_DISCONNECTED	1
 #define BEST_CONNECTED		2
@@ -263,7 +264,7 @@
 	int s;
 	extern int ifqmaxlen; /* XXX */
 #ifdef XENNET_DEBUG
-	char **dir;
+ 	char **dir;
 	int dir_n = 0;
 	char id_str[20];
 #endif
@@ -356,7 +357,11 @@
 	ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
 	ifp->if_timer = 0;
 	ifp->if_snd.ifq_maxlen = max(ifqmaxlen, NET_TX_RING_SIZE * 2);
+#if 0
+	ifp->if_capabilities = 0;
+#else
 	ifp->if_capabilities = IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
+#endif
 	IFQ_SET_READY(&ifp->if_snd);
 	if_attach(ifp);
 	ether_ifattach(ifp, sc->sc_enaddr);
@@ -434,6 +439,7 @@
 	struct xennet_xenbus_softc *sc = p;
 	struct xenbus_transaction *xbt;
 	int error;
+	unsigned long rx_copy = 0;
 	netif_tx_sring_t *tx_ring;
 	netif_rx_sring_t *rx_ring;
 	paddr_t ma;
@@ -472,6 +478,16 @@
 	event_set_handler(sc->sc_evtchn, &xennet_handler, sc,
 	    IPL_NET, device_xname(sc->sc_dev));
 
+	if (0 != xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend, "feature-rx-copy", &rx_copy, 10)) {
+		rx_copy = 0;
+	}
+
+	if (rx_copy != 0) {
+		sc->sc_rx_copy = 1;
+	} else {
+		sc->sc_rx_copy = 0;
+	}
+
 again:
 	xbt = xenbus_transaction_start();
 	if (xbt == NULL)
@@ -489,6 +505,32 @@
 		goto abort_transaction;
 	}
 	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
+		"request-rx-copy", "%u", (unsigned int) sc->sc_rx_copy);
+	if (error) {
+		errmsg = "writing request-rx-copy";
+		goto abort_transaction;
+	}
+#if 0
+	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
+	    "feature-sg", "%u", 1);
+	if (error) {
+		errmsg = "writing feature-sg";
+		goto abort_transaction;
+	}
+	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
+	    "feature-gso-tcpv4", "%u", 1);
+	if (error) {
+		errmsg = "writing feature-gso-tcpv4";
+		goto abort_transaction;
+	}
+	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
+	    "feature-sg", "%u", 1);
+	if (error) {
+		errmsg = "writing feature-sg";
+		goto abort_transaction;
+	}
+#endif
+	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
 	    "feature-rx-notify", "%u", 1);
 	if (error) {
 		errmsg = "writing feature-rx-notify";
@@ -569,45 +611,59 @@
 		KASSERT(req == &sc->sc_rxreqs[req->rxreq_id]);
 		RING_GET_REQUEST(&sc->sc_rx_ring, req_prod + i)->id =
 		    req->rxreq_id;
-		if (xengnt_grant_transfer(sc->sc_xbusd->xbusd_otherend_id,
+
+		if (sc->sc_rx_copy) {
+		  if (xengnt_grant_access(sc->sc_xbusd->xbusd_otherend_id,
+					xpmap_ptom_masked(req->rxreq_pa),
+					0,
+					&req->rxreq_gntref) != 0) {
+			break;
+		  }
+		} else {
+		  if (xengnt_grant_transfer(sc->sc_xbusd->xbusd_otherend_id,
 		    &req->rxreq_gntref) != 0) {
 			break;
+		  }
 		}
+
 		RING_GET_REQUEST(&sc->sc_rx_ring, req_prod + i)->gref =
 		    req->rxreq_gntref;
 
 		SLIST_REMOVE_HEAD(&sc->sc_rxreq_head, rxreq_next);
 		sc->sc_free_rxreql--;
 
-		/* unmap the page */
-		MULTI_update_va_mapping(&rx_mcl[i], req->rxreq_va, 0, 0);
-		/*
-		 * Remove this page from pseudo phys map before
-		 * passing back to Xen.
-		 */
-		pfn = (req->rxreq_pa - XPMAP_OFFSET) >> PAGE_SHIFT;
-		xennet_pages[i] = xpmap_phys_to_machine_mapping[pfn];
-		xpmap_phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
+		if (!sc->sc_rx_copy) {
+		  /* unmap the page */
+		  MULTI_update_va_mapping(&rx_mcl[i], req->rxreq_va, 0, 0);
+		  /*
+		   * Remove this page from pseudo phys map before
+		   * passing back to Xen.
+		   */
+		  pfn = (req->rxreq_pa - XPMAP_OFFSET) >> PAGE_SHIFT;
+		  xennet_pages[i] = xpmap_phys_to_machine_mapping[pfn];
+		  xpmap_phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
+		}
 	}
 	if (i == 0) {
 		splx(s1);
 		return;
 	}
-	/* also make sure to flush all TLB entries */
-	rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-	/*
-	 * We may have allocated buffers which have entries
-	 * outstanding in the page update queue -- make sure we flush
-	 * those first!
-	 */
-	s2 = splvm();
-	xpq_flush_queue();
-	splx(s2);
-	/* now decrease reservation */
-	xenguest_handle(reservation.extent_start) = xennet_pages;
-	reservation.nr_extents = i;
-	reservation.extent_order = 0;
-	reservation.address_bits = 0;
+	if (!sc->sc_rx_copy) {
+	  /* also make sure to flush all TLB entries */
+	  rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+	  /*
+	   * We may have allocated buffers which have entries
+	   * outstanding in the page update queue -- make sure we flush
+	   * those first!
+	   */
+	  s2 = splvm();
+	  xpq_flush_queue();
+	  splx(s2);
+	  /* now decrease reservation */
+	  xenguest_handle(reservation.extent_start) = xennet_pages;
+	  reservation.nr_extents = i;
+	  reservation.extent_order = 0;
+	  reservation.address_bits = 0;
 	reservation.domid = DOMID_SELF;
 	rx_mcl[i].op = __HYPERVISOR_memory_op;
 	rx_mcl[i].args[0] = XENMEM_decrease_reservation;
@@ -616,9 +672,9 @@
 	if (__predict_false(rx_mcl[i].result != i)) {
 		panic("xennet_alloc_rx_buffer: XENMEM_decrease_reservation");
 	}
+	}
 	sc->sc_rx_ring.req_prod_pvt = req_prod + i;
 	RING_PUSH_REQUESTS(&sc->sc_rx_ring);
-
 	splx(s1);
 	return;
 }
@@ -658,9 +714,13 @@
 			SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq,
 			    rxreq_next);
 			sc->sc_free_rxreql++;
-			ma = xengnt_revoke_transfer(rxreq->rxreq_gntref);
-			rxreq->rxreq_gntref = GRANT_INVALID_REF;
-			if (ma == 0) {
+			if (sc->sc_rx_copy) {
+			  xengnt_revoke_access(rxreq->rxreq_gntref);
+			  rxreq->rxreq_gntref = GRANT_INVALID_REF;
+			} else {
+			  ma = xengnt_revoke_transfer(rxreq->rxreq_gntref);
+			  rxreq->rxreq_gntref = GRANT_INVALID_REF;
+			  if (ma == 0) {
 				u_long pfn;
 				struct xen_memory_reservation xenres;
 				/*
@@ -696,6 +756,7 @@
 			mcl[1].args[2] = 0;
 			mcl[1].args[3] = DOMID_SELF;
 			HYPERVISOR_multicall(mcl, 2);
+			}
 		}
 
 	}
@@ -826,8 +887,12 @@
 		req = &sc->sc_rxreqs[rx->id];
 		KASSERT(req->rxreq_gntref != GRANT_INVALID_REF);
 		KASSERT(req->rxreq_id == rx->id);
-		ma = xengnt_revoke_transfer(req->rxreq_gntref);
-		if (ma == 0) {
+		if (sc->sc_rx_copy) {
+		  xengnt_revoke_access(req->rxreq_gntref);
+		  ma = 0;
+		} else {
+		  ma = xengnt_revoke_transfer(req->rxreq_gntref);
+		  if (ma == 0) {
 			DPRINTFN(XEDB_EVENT, ("xennet_handler ma == 0\n"));
 			/*
 			 * the remote could't send us a packet.
@@ -843,11 +908,12 @@
 			sc->sc_rx_ring.req_prod_pvt++;
 			RING_PUSH_REQUESTS(&sc->sc_rx_ring);
 			continue;
+		  }
 		}
 		req->rxreq_gntref = GRANT_INVALID_REF;
-
 		pa = req->rxreq_pa;
 		va = req->rxreq_va;
+		if (!sc->sc_rx_copy) {
 		/* remap the page */
 		mmu[0].ptr = (ma << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
 		mmu[0].val = ((pa - XPMAP_OFFSET) >> PAGE_SHIFT);
@@ -861,6 +927,7 @@
 		mcl[1].args[2] = 0;
 		mcl[1].args[3] = DOMID_SELF;
 		HYPERVISOR_multicall(mcl, 2);
+		}
 		pktp = (void *)(va + rx->offset);
 #ifdef XENNET_DEBUG_DUMP
 		xennet_hex_dump(pktp, rx->status, "r", rx->id);
@@ -1031,7 +1098,11 @@
 		    (M_CSUM_TCPv4 | M_CSUM_UDPv4)) != 0) {
 			txflags = NETTXF_csum_blank;
 		} else {
+#if 0
+			txflags = NETTXF_data_validated;
+#else
 			txflags = 0;
+#endif
 		}
 
 		if (m->m_pkthdr.len != m->m_len ||
@@ -1276,7 +1347,10 @@
 {
 	size_t i, j;
 
-	printf("pkt %p len %d/%x type %s id %d\n", pkt, len, len, type, id);
+
+	if (len > 4096)
+	  len = 4096;
+	printf("pkt %p len %d/%x type %s id %d\n", pkt, (int)len, (unsigned int)len, type, id);
 	printf("00000000  ");
 	for(i=0; i<len; i++) {
 		printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i]));
