Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jan 2008 09:05:42 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 132473 for review
Message-ID:  <200801040905.m0495g02067127@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=132473

Change 132473 by kmacy@pandemonium:kmacy:xen31 on 2008/01/04 09:04:42

	- pull in most recent public xen headers from hg
	- set interface version to immediately prior to addition of hyperpage
	- update grant table interface to provide runtime sized grant tables
	- add virtual network interface to build and bring it more in line with latest
	  linux version

Affected files ...

.. //depot/projects/xen31/sys/conf/files#13 edit
.. //depot/projects/xen31/sys/dev/xen/blkfront/block.h#3 edit
.. //depot/projects/xen31/sys/dev/xen/console/xencons_ring.c#5 edit
.. //depot/projects/xen31/sys/dev/xen/netfront/mbufq.h#1 add
.. //depot/projects/xen31/sys/dev/xen/netfront/netfront.c#2 edit
.. //depot/projects/xen31/sys/i386/i386/trap.c#6 edit
.. //depot/projects/xen31/sys/i386/i386/vm_machdep.c#5 edit
.. //depot/projects/xen31/sys/i386/include/cpufunc.h#6 edit
.. //depot/projects/xen31/sys/i386/include/pmap.h#8 edit
.. //depot/projects/xen31/sys/i386/include/xen/evtchn.h#5 edit
.. //depot/projects/xen31/sys/i386/include/xen/features.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/hypercall.h#5 edit
.. //depot/projects/xen31/sys/i386/include/xen/hypervisor-ifs.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/hypervisor.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-os.h#4 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/COPYING#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/acm.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/acm_ops.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-ia64.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-powerpc.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-x86/xen-x86_32.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-x86/xen-x86_64.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-x86/xen.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-x86_32.h#4 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/arch-x86_64.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/callback.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/dom0_ops.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/domctl.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/elfstructs.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/event_channel.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/features.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/foreign/Makefile#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/foreign/mkchecker.py#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/foreign/mkheader.py#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/foreign/reference.size#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/foreign/structs.py#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/grant_table.h#4 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/e820.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/hvm_info_table.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/hvm_op.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/ioreq.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/params.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/save.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/hvm/vmx_assist.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/blkif.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/console.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/fbif.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/kbdif.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/netif.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/pciif.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/protocols.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/ring.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/tpmif.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/xs_wire.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/kexec.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/libelf.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/memory.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/nmi.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/platform.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/sched.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/sched_ctl.h#2 delete
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/sysctl.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/trace.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/version.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/xen-compat.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/xen.h#5 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/xencomm.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/xenoprof.h#1 add
.. //depot/projects/xen31/sys/i386/include/xen/xenpmap.h#6 edit
.. //depot/projects/xen31/sys/i386/include/xen/xenvar.h#5 edit
.. //depot/projects/xen31/sys/i386/isa/npx.c#3 edit
.. //depot/projects/xen31/sys/i386/xen/pmap.c#11 edit
.. //depot/projects/xen31/sys/i386/xen/xen_machdep.c#12 edit
.. //depot/projects/xen31/sys/sys/cdefs.h#3 edit
.. //depot/projects/xen31/sys/xen/evtchn/evtchn_dev.c#2 edit
.. //depot/projects/xen31/sys/xen/gnttab.c#3 edit
.. //depot/projects/xen31/sys/xen/gnttab.h#2 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_xs.c#9 edit

Differences ...

==== //depot/projects/xen31/sys/conf/files#13 (text+ko) ====

@@ -2110,6 +2110,7 @@
 vm/vm_zeroidle.c		standard
 vm/vnode_pager.c		standard
 xen/gnttab.c			optional xen
+xen/features.c			optional xen
 xen/evtchn/evtchn.c		optional xen
 xen/evtchn/evtchn_dev.c		optional xen
 xen/xenbus/xenbus_client.c	optional xen
@@ -2121,6 +2122,7 @@
 dev/xen/console/console.c	optional xen
 dev/xen/console/xencons_ring.c	optional xen
 dev/xen/blkfront/blkfront.c	optional xen
+dev/xen/netfront/netfront.c	optional xen
 
 #
 gnu/fs/xfs/xfs_alloc.c		optional xfs \

==== //depot/projects/xen31/sys/dev/xen/blkfront/block.h#3 (text+ko) ====

@@ -1,5 +1,6 @@
 #ifndef __XEN_DRIVERS_BLOCK_H__
 #define __XEN_DRIVERS_BLOCK_H__
+#include <machine/xen/xen-public/io/blkif.h>
 
 struct xlbd_type_info
 {

==== //depot/projects/xen31/sys/dev/xen/console/xencons_ring.c#5 (text+ko) ====

@@ -21,6 +21,7 @@
 
 
 #include <dev/xen/console/xencons_ring.h>
+#include <machine/xen/evtchn.h>
 #include <machine/xen/xen-public/io/console.h>
 
 

==== //depot/projects/xen31/sys/dev/xen/netfront/netfront.c#2 (text+ko) ====

@@ -39,6 +39,7 @@
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#include <netinet/if_ether.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -54,20 +55,37 @@
 
 #include <machine/intr_machdep.h>
 
-#include <machine/xen-os.h>
-#include <machine/hypervisor.h>
-#include <machine/hypervisor-ifs.h>
-#include <machine/xen_intr.h>
-#include <machine/evtchn.h>
-#include <machine/xenbus.h>
-#include <machine/gnttab.h>
-#include <machine/xen-public/memory.h>
+#include <machine/xen/xen-os.h>
+#include <machine/xen/hypervisor.h>
+#include <machine/xen/hypervisor-ifs.h>
+#include <machine/xen/xen_intr.h>
+#include <machine/xen/evtchn.h>
+#include <machine/xen/xenbus.h>
+#include <xen/gnttab.h>
+#include <machine/xen/xen-public/memory.h>
+#include <dev/xen/netfront/mbufq.h>
+#include <machine/xen/features.h>
+#include <machine/xen/xen-public/io/netif.h>
+
 
 #define GRANT_INVALID_REF	0
 
 #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)
 
+#ifdef CONFIG_XEN
+static int MODPARM_rx_copy = 0;
+module_param_named(rx_copy, MODPARM_rx_copy, bool, 0);
+MODULE_PARM_DESC(rx_copy, "Copy packets from network card (rather than flip)");
+static int MODPARM_rx_flip = 0;
+module_param_named(rx_flip, MODPARM_rx_flip, bool, 0);
+MODULE_PARM_DESC(rx_flip, "Flip packets from network card (rather than copy)");
+#else
+static const int MODPARM_rx_copy = 1;
+static const int MODPARM_rx_flip = 0;
+#endif
+
+#define RX_COPY_THRESHOLD 256
 
 struct netfront_info;
 static void xn_txeof(struct netfront_info *);
@@ -89,18 +107,20 @@
 #endif
 
 static void show_device(struct netfront_info *sc);
+#ifdef notyet
 static void netfront_closing(struct xenbus_device *dev);
+#endif
 static void netif_free(struct netfront_info *info);
 static int netfront_remove(struct xenbus_device *dev);
 
 static int talk_to_backend(struct xenbus_device *dev, struct netfront_info *info);
-static int create_netdev(int handle, struct xenbus_device *dev, struct ifnet **ifp);
+static int create_netdev(struct xenbus_device *dev, struct ifnet **ifp);
 static void netif_disconnect_backend(struct netfront_info *info);
 static int setup_device(struct xenbus_device *dev, struct netfront_info *info);
 static void end_access(int ref, void *page);
 
 /* Xenolinux helper functions */
-static void network_connect(struct ifnet *ifp);
+static int network_connect(struct ifnet *ifp);
 
 static void xn_free_rx_ring(struct netfront_info *);
 
@@ -118,7 +138,7 @@
  * not the other way around.  The size must track the free index arrays.
  */
 struct xn_chain_data {
-	struct mbuf		*xn_tx_chain[NET_TX_RING_SIZE+1];
+		struct mbuf		*xn_tx_chain[NET_TX_RING_SIZE+1];
         struct mbuf		*xn_rx_chain[NET_RX_RING_SIZE+1];
 };
 
@@ -160,75 +180,67 @@
 	unsigned long	tx_compressed;
 };
 
-struct netfront_info
-{
-	struct ifnet *xn_ifp;
+struct netfront_info {
+		
+		struct ifnet *xn_ifp;
 
-	struct net_device_stats stats;
-	unsigned int tx_full;
+		struct net_device_stats stats;
+		unsigned int tx_full;
     
-	netif_tx_front_ring_t tx;
-	netif_rx_front_ring_t rx;
+		netif_tx_front_ring_t tx;
+		netif_rx_front_ring_t rx;
 
-	struct mtx   tx_lock;
-	struct mtx   rx_lock;
+		struct mtx   tx_lock;
+		struct mtx   rx_lock;
 
-	unsigned int handle;
-	unsigned int evtchn, irq;
-
-	/* What is the status of our connection to the remote backend? */
-#define BEST_CLOSED       0
-#define BEST_DISCONNECTED 1
-#define BEST_CONNECTED    2
-	unsigned int backend_state;
-
-	/* Is this interface open or closed (down or up)? */
-#define UST_CLOSED        0
-#define UST_OPEN          1
-	unsigned int user_state;
-
+		unsigned int handle;
+		unsigned int irq;
+		unsigned int copying_receiver;
+		unsigned int carrier;
+		
 	/* Receive-ring batched refills. */
 #define RX_MIN_TARGET 32
 #define RX_MAX_TARGET NET_RX_RING_SIZE
-	int rx_min_target, rx_max_target, rx_target;
+		int rx_min_target, rx_max_target, rx_target;
 
-	/*
-	 * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
-	 * array is an index into a chain of free entries.
-	 */
+		/*
+		 * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
+		 * array is an index into a chain of free entries.
+		 */
 
-	grant_ref_t gref_tx_head;
-	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; 
-	grant_ref_t gref_rx_head;
-	grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; 
+		grant_ref_t gref_tx_head;
+		grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; 
+		grant_ref_t gref_rx_head;
+		grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; 
 
-	struct xenbus_device *xbdev;
-	int tx_ring_ref;
-	int rx_ring_ref;
-	uint8_t mac[ETHER_ADDR_LEN];
-	struct xn_chain_data	xn_cdata;	/* mbufs */
+#define TX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
+		struct xenbus_device *xbdev;
+		int tx_ring_ref;
+		int rx_ring_ref;
+		uint8_t mac[ETHER_ADDR_LEN];
+		struct xn_chain_data	xn_cdata;	/* mbufs */
         unsigned short          xn_rx_free_idxs[NET_RX_RING_SIZE+1];
         unsigned short          xn_tx_free_idxs[NET_RX_RING_SIZE+1];
-	struct mbuf		*xn_rx_batch;	/* head of the batch queue */
-	struct mbuf		*xn_rx_batchtail;
-	int			xn_rx_batchlen;	/* how many queued */
-	int			xn_if_flags;
-	struct callout	        xn_stat_ch;
+		struct mbuf_head xn_rx_batch;	/* head of the batch queue */
 
+		int			xn_if_flags;
+		struct callout	        xn_stat_ch;
 };
 
+#define rx_mbufs xn_cdata.xn_rx_chain
+#define tx_mbufs xn_cdata.xn_tx_chain
 
 #define XN_LOCK_INIT(_sc, _name) \
-        mtx_init(&(_sc)->tx_lock, #_name"_tx", "network transmit lock", MTX_SPIN); \
-        mtx_init(&(_sc)->rx_lock, #_name"_rx", "network receive lock", MTX_SPIN);
-#define XN_RX_LOCK(_sc)           mtx_lock_spin(&(_sc)->rx_lock)
-#define XN_RX_UNLOCK(_sc)         mtx_unlock_spin(&(_sc)->rx_lock)
-#define XN_TX_LOCK(_sc)           mtx_lock_spin(&(_sc)->tx_lock)
-#define XN_TX_UNLOCK(_sc)         mtx_unlock_spin(&(_sc)->tx_lock)
-#define XN_LOCK(_sc)           mtx_lock_spin(&(_sc)->tx_lock); \
-                               mtx_lock_spin(&(_sc)->rx_lock); 
-#define XN_UNLOCK(_sc)         mtx_unlock_spin(&(_sc)->rx_lock); \
-                               mtx_unlock_spin(&(_sc)->tx_lock)
+        mtx_init(&(_sc)->tx_lock, #_name"_tx", "network transmit lock", MTX_DEF); \
+        mtx_init(&(_sc)->rx_lock, #_name"_rx", "network receive lock", MTX_DEF);
+#define XN_RX_LOCK(_sc)           mtx_lock(&(_sc)->rx_lock)
+#define XN_RX_UNLOCK(_sc)         mtx_unlock(&(_sc)->rx_lock)
+#define XN_TX_LOCK(_sc)           mtx_lock(&(_sc)->tx_lock)
+#define XN_TX_UNLOCK(_sc)         mtx_unlock(&(_sc)->tx_lock)
+#define XN_LOCK(_sc)           mtx_lock(&(_sc)->tx_lock); \
+                               mtx_lock(&(_sc)->rx_lock); 
+#define XN_UNLOCK(_sc)         mtx_unlock(&(_sc)->rx_lock); \
+                               mtx_unlock(&(_sc)->tx_lock)
 #define XN_LOCK_ASSERT(_sc)    mtx_assert(&(_sc)->rx_lock, MA_OWNED); \
                                mtx_assert(&(_sc)->tx_lock, MA_OWNED);
 #define XN_RX_LOCK_ASSERT(_sc)    mtx_assert(&(_sc)->rx_lock, MA_OWNED); 
@@ -236,22 +248,62 @@
 #define XN_LOCK_DESTROY(_sc)   mtx_destroy(&(_sc)->rx_lock); \
                                mtx_destroy(&(_sc)->tx_lock);
 
+#define netfront_carrier_on(netif)	((netif)->carrier = 1)
+#define netfront_carrier_off(netif)	((netif)->carrier = 0)
+#define netfront_carrier_ok(netif)	((netif)->carrier)
+
 /* Access macros for acquiring freeing slots in xn_free_{tx,rx}_idxs[]. */
-#define ADD_ID_TO_FREELIST(_list, _id)             \
-    (_list)[(_id)] = (_list)[0];                   \
-    (_list)[0]     = (_id);
-#define GET_ID_FROM_FREELIST(_list)                \
- ({ unsigned short _id = (_list)[0]; \
-    (_list)[0]  = (_list)[_id];                    \
-    (unsigned short)_id; })
-#define FREELIST_EMPTY(_list, _maxid) 		   \
-    ((_list)[0] == (_maxid+1))
+
+
+
+/*
+ * Access macros for acquiring freeing slots in tx_skbs[].
+ */
+
+static inline void
+add_id_to_freelist(struct mbuf **list, unsigned short id)
+{
+	list[id] = list[0];
+	list[0]  = (void *)(unsigned long)id;
+}
+
+static inline unsigned short
+get_id_from_freelist(struct mbuf **list)
+{
+	unsigned int id = (unsigned int)(unsigned long)list[0];
+	list[0] = list[id];
+	return (id);
+}
+
+static inline int
+xennet_rxidx(RING_IDX idx)
+{
+	return idx & (NET_RX_RING_SIZE - 1);
+}
+
+static inline struct mbuf *
+xennet_get_rx_mbuf(struct netfront_info *np,
+						RING_IDX ri)
+{
+	int i = xennet_rxidx(ri);
+	struct mbuf *m;
+
+	m = np->rx_mbufs[i];
+	np->rx_mbufs[i] = NULL;
+	return (m);
+}
+
+static inline grant_ref_t
+xennet_get_rx_ref(struct netfront_info *np, RING_IDX ri)
+{
+	int i = xennet_rxidx(ri);
+	grant_ref_t ref = np->grant_rx_ref[i];
+	np->grant_rx_ref[i] = GRANT_INVALID_REF;
+	return ref;
+}
+
 #ifdef DEBUG
-static char *be_state_name[] = {
-	[BEST_CLOSED]       = "closed",
-	[BEST_DISCONNECTED] = "disconnected",
-	[BEST_CONNECTED]    = "connected",
-};
+
 #endif
 #define IPRINTK(fmt, args...) \
     printf("[XEN] " fmt, ##args)
@@ -269,15 +321,19 @@
 	
         if (! m)
 		return 0;
-	
-	M_MOVE_PKTHDR(m, buf);
+		
+		M_MOVE_PKTHDR(m, buf);
 	
         MCLGET (m, M_DONTWAIT);
 	
         m->m_pkthdr.len = buf->m_pkthdr.len;
         m->m_len = buf->m_len;
-	m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) );
-	m->m_ext.ext_args = (vm_paddr_t *)vtophys(mtod(m,caddr_t));
+		m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) );
+	/*
+	 * XXX this will break on > 4GB
+	 * 
+	 */
+	m->m_ext.ext_args = (caddr_t *)(uintptr_t)vtophys(mtod(m,caddr_t));
 	
        	return m;
 }
@@ -294,7 +350,7 @@
 	char *s;
 	int i;
 	char *e;
-	char *macstr = xenbus_read(NULL, dev->nodename, "mac", NULL);
+	char *macstr = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
 	if (IS_ERR(macstr)) {
 		return PTR_ERR(macstr);
 	}
@@ -323,27 +379,20 @@
 	int err;
 	struct ifnet *ifp;
 	struct netfront_info *info;
-	unsigned int handle;
-	
-	err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle);
-	if (err != 1) {
-		xenbus_dev_fatal(dev, err, "reading handle");
-		return err;
-	}
 
-	err = create_netdev(handle, dev, &ifp);
+	err = create_netdev(dev, &ifp);
 	if (err) {
 		xenbus_dev_fatal(dev, err, "creating netdev");
 		return err;
 	}
 
 	info = ifp->if_softc;
-	dev->data = info;
+	dev->dev_driver_data = info;
 
 	err = talk_to_backend(dev, info);
 	if (err) {
 		free(info, M_DEVBUF);
-		dev->data = NULL;
+		dev->dev_driver_data = NULL;
 		return err;
 	}
 	
@@ -360,7 +409,7 @@
 static int 
 netfront_resume(struct xenbus_device *dev)
 {
-	struct netfront_info *info = dev->data;
+	struct netfront_info *info = dev->dev_driver_data;
 	
 	DPRINTK("%s\n", dev->nodename);
 	
@@ -374,21 +423,26 @@
 talk_to_backend(struct xenbus_device *dev, struct netfront_info *info)
 {
 	const char *message;
-	struct xenbus_transaction *xbt;
+	struct xenbus_transaction xbt;
 	int err;
-	
+
+	err = xen_net_read_mac(dev, info->mac);
+	if (err) {
+		xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
+		goto out;
+	}
+
 	/* Create shared ring, alloc event channel. */
 	err = setup_device(dev, info);
 	if (err)
 		goto out;
 	
  again:
-	xbt = xenbus_transaction_start();
-	if (IS_ERR(xbt)) {
+	err = xenbus_transaction_start(&xbt);
+	if (err) {
 		xenbus_dev_fatal(dev, err, "starting transaction");
 		goto destroy_ring;
 	}
-
 	err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
 			    info->tx_ring_ref);
 	if (err) {
@@ -402,18 +456,35 @@
 		goto abort_transaction;
 	}
 	err = xenbus_printf(xbt, dev->nodename,
-			    "event-channel", "%u", info->evtchn);
+		"event-channel", "%u", irq_to_evtchn_port(info->irq));
 	if (err) {
 		message = "writing event-channel";
 		goto abort_transaction;
 	}
+	err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u",
+			    info->copying_receiver);
+	if (err) {
+		message = "writing request-rx-copy";
+		goto abort_transaction;
+	}
 
-	err = xenbus_printf(xbt, dev->nodename,
-			    "state", "%d", XenbusStateConnected);
+	err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1);
+	if (err) {
+		message = "writing feature-rx-notify";
+		goto abort_transaction;
+	}
+	err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
+	if (err) {
+		message = "writing feature-sg";
+		goto abort_transaction;
+	}
+#ifdef HAVE_TSO
+	err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1);
 	if (err) {
-		message = "writing frontend XenbusStateConnected";
+		message = "writing feature-gso-tcpv4";
 		goto abort_transaction;
 	}
+#endif
 
 	err = xenbus_transaction_end(xbt, 0);
 	if (err) {
@@ -451,47 +522,47 @@
 	info->tx.sring = NULL;
 	info->irq = 0;
 
-	txs = (netif_tx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
+	txs = (netif_tx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
 	if (!txs) {
 		err = ENOMEM;
 		xenbus_dev_fatal(dev, err, "allocating tx ring page");
 		goto fail;
 	}
-	rxs = (netif_rx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
+	SHARED_RING_INIT(txs);
+	FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
+	err = xenbus_grant_ring(dev, virt_to_mfn(txs));
+	if (err < 0)
+		goto fail;
+	info->tx_ring_ref = err;
+
+
+	rxs = (netif_rx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
 	if (!rxs) {
 		err = ENOMEM;
 		xenbus_dev_fatal(dev, err, "allocating rx ring page");
 		goto fail;
 	}
-	memset(txs, 0, PAGE_SIZE);
-	memset(rxs, 0, PAGE_SIZE);
-	info->backend_state = BEST_DISCONNECTED;
-
-	SHARED_RING_INIT(txs);
-	FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
-
 	SHARED_RING_INIT(rxs);
 	FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
 
-	err = xenbus_grant_ring(dev, virt_to_mfn(txs));
-	if (err < 0)
-		goto fail;
-	info->tx_ring_ref = err;
-
 	err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
 	if (err < 0)
 		goto fail;
 	info->rx_ring_ref = err;
 
-	err = xenbus_alloc_evtchn(dev, &info->evtchn);
-	if (err)
-		goto fail;
-
+#if 0	
 	network_connect(ifp);
+#endif
+	err = bind_listening_port_to_irqhandler(dev->otherend_id,
+		"xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL);
 
-	info->irq = bind_evtchn_to_irqhandler(
-			  info->evtchn, "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL);
-
+	if (err <= 0) {
+		xenbus_dev_fatal(dev, err,
+				 "bind_evtchn_to_irqhandler failed");
+		goto fail;
+	}
+	info->irq = err;
+	
 	show_device(info);
 	
 	return 0;
@@ -508,26 +579,34 @@
 static void backend_changed(struct xenbus_device *dev,
 			    XenbusState backend_state)
 {
+		struct netfront_info *sc = dev->dev_driver_data;
+		
 	DPRINTK("\n");
 	
+	
 	switch (backend_state) {
 	case XenbusStateInitialising:
-	case XenbusStateInitWait:
 	case XenbusStateInitialised:
 	case XenbusStateConnected:
 	case XenbusStateUnknown:
 	case XenbusStateClosed:
-		break;
-		
+			break;
+	case XenbusStateInitWait:
+		if (dev->state != XenbusStateInitialising)
+			break;
+		if (network_connect(sc->xn_ifp) != 0)
+			break;
+		xenbus_switch_state(dev, XenbusStateConnected);
+#ifdef notyet		
+		(void)send_fake_arp(netdev);
+#endif		
+		break;	break;
 	case XenbusStateClosing:
-		netfront_closing(dev);
+			xenbus_frontend_closed(dev);
 		break;
 	}
 }
 
-
-
-
 static void
 xn_free_rx_ring(struct netfront_info *sc)
 {
@@ -564,19 +643,52 @@
 #endif
 }
 
+static inline int
+netfront_tx_slot_available(struct netfront_info *np)
+{
+	return ((np->tx.req_prod_pvt - np->tx.rsp_cons) <
+		(TX_MAX_TARGET - /* MAX_SKB_FRAGS */ 24 - 2));
+}
+static void
+netif_release_tx_bufs(struct netfront_info *np)
+{
+		struct mbuf *m;
+		int i;
+
+		for (i = 1; i <= NET_TX_RING_SIZE; i++) {
+				m = np->xn_cdata.xn_tx_chain[i];
+
+				if (m == NULL)
+						continue;
+				gnttab_grant_foreign_access_ref(
+						np->grant_tx_ref[i], np->xbdev->otherend_id, 
+							virt_to_mfn(mtod(m, vm_offset_t)),
+							GNTMAP_readonly);
+				gnttab_release_grant_reference(
+						&np->gref_tx_head, np->grant_tx_ref[i]);
+				np->grant_tx_ref[i] = GRANT_INVALID_REF;
+				add_id_to_freelist(np->tx_mbufs, i);
+				m_freem(m);
+		}
+}
+
 static void
 network_alloc_rx_buffers(struct netfront_info *sc)
 {
 	unsigned short id;
-	struct mbuf *m_new, *next;
-	int i, batch_target;
+	struct mbuf *m_new;
+	int i, batch_target, notify;
 	RING_IDX req_prod;
 	struct xen_memory_reservation reservation;
 	grant_ref_t ref;
+	int nr_flips;
+	netif_rx_request_t *req;
+	vm_offset_t vaddr;
+	unsigned long pfn;
+	
+	req_prod = sc->rx.req_prod_pvt;
 
-	req_prod = sc->rx.req_prod_pvt;
-	
-	if (unlikely(sc->backend_state != BEST_CONNECTED) )
+	if (unlikely(sc->carrier == 0))
 		return;
 	
 	/*
@@ -586,110 +698,136 @@
 	 * ourself and for other kernel subsystems.
 	 */
 	batch_target = sc->rx_target - (req_prod - sc->rx.rsp_cons);
-	for (i = sc->xn_rx_batchlen; i < batch_target; i++, sc->xn_rx_batchlen++) {
+	for (i = mbufq_len(&sc->xn_rx_batch); i < batch_target; i++) {
 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
 		if (m_new == NULL) 
-			break;
-		
-		MCLGET(m_new, M_DONTWAIT);
-		if (!(m_new->m_flags & M_EXT)) {
-			m_freem(m_new);
-			break;
+				goto no_mbuf;
+
+		m_cljget(m_new, M_DONTWAIT, MJUMPAGESIZE);
+		if ((m_new->m_flags & M_EXT) == 0) {
+				m_freem(m_new);
+
+no_mbuf:
+				if (i != 0)
+						goto refill;
+				/*
+				 * XXX set timer
+				 */
+				break;
 		}
-		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
+		m_new->m_len = m_new->m_pkthdr.len = MJUMPAGESIZE;
 		
 		/* queue the mbufs allocated */
-		if (!sc->xn_rx_batch)
-			sc->xn_rx_batch = m_new;
-		
-		if (sc->xn_rx_batchtail)
-			sc->xn_rx_batchtail->m_next = m_new;
-		sc->xn_rx_batchtail = m_new;
+		mbufq_tail(&sc->xn_rx_batch, m_new);
 	}
 	
 	/* Is the batch large enough to be worthwhile? */
-	if ( i < (sc->rx_target/2)  )
-		return;
-	
-	for (i = 0, m_new = sc->xn_rx_batch; m_new; 
-	     i++, sc->xn_rx_batchlen--, m_new = next) {
+	if (i < (sc->rx_target/2)) {
+			if (req_prod >sc->rx.sring->req_prod)
+					goto push;
+			return;
+	}
+	/* Adjust our floating fill target if we risked running out of buffers. */
+	if ( ((req_prod - sc->rx.sring->rsp_prod) < (sc->rx_target / 4)) &&
+	     ((sc->rx_target *= 2) > sc->rx_max_target) )
+		sc->rx_target = sc->rx_max_target;
 
-		next = m_new->m_next;
-		m_new->m_next = NULL;
+refill:
+	for (nr_flips = i = 0; ; i++) {
+			if ((m_new = mbufq_dequeue(&sc->xn_rx_batch)) == NULL)
+					break;
 
-		m_new->m_ext.ext_args = (vm_paddr_t *)vtophys(m_new->m_ext.ext_buf);
+			m_new->m_ext.ext_args = (vm_paddr_t *)(uintptr_t)vtophys(m_new->m_ext.ext_buf);		
+			id = xennet_rxidx(req_prod + 1);
+	
+			KASSERT(id != 0, ("alloc_rx_buffers: found free receive index of 0\n"));
+			PANIC_IF(sc->xn_cdata.xn_rx_chain[id] != NULL);
+			sc->xn_cdata.xn_rx_chain[id] = m_new;
 		
-		id = GET_ID_FROM_FREELIST(sc->xn_rx_free_idxs);
-		KASSERT(id != 0, ("alloc_rx_buffers: found free receive index of 0\n"));
-		sc->xn_cdata.xn_rx_chain[id] = m_new;
+			ref = gnttab_claim_grant_reference(&sc->gref_rx_head);
+			PANIC_IF((signed short)ref < 0);
+			sc->grant_rx_ref[id] = ref;
+			
+			vaddr = mtod(m_new, vm_offset_t);
+			pfn = vtophys(vaddr) >> PAGE_SHIFT;
+			req = RING_GET_REQUEST(&sc->rx, req_prod + i);
+
+			if (sc->copying_receiver == 0) {
+					gnttab_grant_foreign_transfer_ref(ref,
+						sc->xbdev->otherend_id,
+						pfn);
+					rx_pfn_array[nr_flips] = PFNTOMFN(pfn);
+					if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+							/* Remove this page before passing
+							 * back to Xen.
+							 */
+							set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
+							MULTI_update_va_mapping(&rx_mcl[i],
+								vaddr, 0, 0);
+					}
+					nr_flips++;
+			} else {
+					gnttab_grant_foreign_access_ref(ref,
+						sc->xbdev->otherend_id,
+						PFNTOMFN(pfn),
+						0);
+			}
+			req->id = id;
+			req->gref = ref;
 		
-		
-		RING_GET_REQUEST(&sc->rx, req_prod + i)->id = id;		
-		ref = gnttab_claim_grant_reference(&sc->gref_rx_head);
-		PANIC_IF((signed short)ref < 0);
-		sc->grant_rx_ref[id] = ref;
-		gnttab_grant_foreign_transfer_ref(ref,
-						  sc->xbdev->otherend_id);
-		RING_GET_REQUEST(&sc->rx, req_prod + i)->gref = ref;
-		
-		
-		rx_pfn_array[i] = vtomach(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT;
-		
-		/* Remove this page from pseudo phys map before passing back to Xen. */
-		xen_phys_machine[((unsigned long)m_new->m_ext.ext_args >> PAGE_SHIFT)] 
-			= INVALID_P2M_ENTRY;
-	    	
-		rx_mcl[i].op = __HYPERVISOR_update_va_mapping;
-		rx_mcl[i].args[0] = (unsigned long)mtod(m_new,vm_offset_t);
-		rx_mcl[i].args[1] = 0;
-		rx_mcl[i].args[2] = 0;
-		rx_mcl[i].args[3] = 0;
-
+			rx_pfn_array[i] = vtomach(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT;
 	} 
 	
 	KASSERT(i, ("no mbufs processed"));	/* should have returned earlier */
-	KASSERT(sc->xn_rx_batchlen == 0, ("not all mbufs processed"));
-	sc->xn_rx_batch = sc->xn_rx_batchtail = NULL;
-	
+	KASSERT(mbufq_len(&sc->xn_rx_batch) == 0, ("not all mbufs processed"));
 	/*
 	 * We may have allocated buffers which have entries outstanding
-	 in the page * update queue -- make sure we flush those first!  */
+	 * in the page * update queue -- make sure we flush those first!
+	 */
 	PT_UPDATES_FLUSH();
-	
-	/* After all PTEs have been zapped we blow away stale TLB entries. */
-	rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_LOCAL;
-	
-	/* Give away a batch of pages. */
-	rx_mcl[i].op = __HYPERVISOR_memory_op;
-	rx_mcl[i].args[0] = XENMEM_decrease_reservation;
-	rx_mcl[i].args[1] =  (unsigned long)&reservation;
-	
-	reservation.extent_start = rx_pfn_array;
-	reservation.nr_extents   = i;
-	reservation.extent_order = 0;
-	reservation.address_bits = 0;
-	reservation.domid        = DOMID_SELF;
-	
+	if (nr_flips != 0) {
 #ifdef notyet
-	/* Tell the ballon driver what is going on. */
-	balloon_update_driver_allowance(i);
+			/* Tell the ballon driver what is going on. */
+			balloon_update_driver_allowance(i);
 #endif
+			set_xen_guest_handle(reservation.extent_start, rx_pfn_array);
+			reservation.nr_extents   = i;
+			reservation.extent_order = 0;
+			reservation.address_bits = 0;
+			reservation.domid        = DOMID_SELF;
+
+			if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+
+					/* After all PTEs have been zapped, flush the TLB. */
+					rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
+						UVMF_TLB_FLUSH|UVMF_ALL;
 	
-	/* Zap PTEs and give away pages in one big multicall. */
-	(void)HYPERVISOR_multicall(rx_mcl, i+1);
+					/* Give away a batch of pages. */
+					rx_mcl[i].op = __HYPERVISOR_memory_op;
+					rx_mcl[i].args[0] = XENMEM_decrease_reservation;
+					rx_mcl[i].args[1] =  (unsigned long)&reservation;
+					/* Zap PTEs and give away pages in one big multicall. */
+					(void)HYPERVISOR_multicall(rx_mcl, i+1);
 	
-	/* Check return status of HYPERVISOR_dom_mem_op(). */
-	if (unlikely(rx_mcl[i].result != i))
-		panic("Unable to reduce memory reservation\n");
-	
+					/* Check return status of HYPERVISOR_dom_mem_op(). */
+					if (unlikely(rx_mcl[i].result != i))
+							panic("Unable to reduce memory reservation\n");
+
+			} else {
+					if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+							&reservation) != i)
+							panic("Unable to reduce memory reservation\n");
+			}
+	} else {
+			wmb();
+	}
+			
 	/* Above is a suitable barrier to ensure backend will see requests. */
 	sc->rx.req_prod_pvt = req_prod + i;
-	RING_PUSH_REQUESTS(&sc->rx);
-	
-	/* Adjust our floating fill target if we risked running out of buffers. */
-	if ( ((req_prod - sc->rx.sring->rsp_prod) < (sc->rx_target / 4)) &&
-	     ((sc->rx_target *= 2) > sc->rx_max_target) )
-		sc->rx_target = sc->rx_max_target;
+push:
+	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->rx, notify);
+	if (notify)
+			notify_remote_via_irq(sc->irq);
 }
 
 static void
@@ -704,9 +842,8 @@
 	unsigned long mfn;
 	grant_ref_t ref;
 
-
 	XN_RX_LOCK_ASSERT(np);
-	if (np->backend_state != BEST_CONNECTED)
+	if (!netfront_carrier_ok(np))
 		return;
 	
 	ifp = np->xn_ifp;
@@ -752,7 +889,7 @@
 		m = (struct mbuf *)np->xn_cdata.xn_rx_chain[rx->id];
 		if (m->m_next)
 			panic("mbuf is already part of a valid mbuf chain");
-		ADD_ID_TO_FREELIST(np->xn_rx_free_idxs, rx->id);
+		add_id_to_freelist(np->xn_cdata.xn_rx_chain, rx->id);
 		
 		m->m_data += rx->offset;/* (rx->addr & PAGE_MASK); */
 		m->m_pkthdr.len = m->m_len = rx->status;
@@ -847,7 +984,7 @@
 	
 	XN_TX_LOCK_ASSERT(np);
 	
-	if (np->backend_state != BEST_CONNECTED)
+	if (!netfront_carrier_ok(np))
 		return;
 	
 	ifp = np->xn_ifp;
@@ -878,7 +1015,7 @@
 			np->grant_tx_ref[id] = GRANT_INVALID_REF;
 			
 			np->xn_cdata.xn_tx_chain[id] = NULL;
-			ADD_ID_TO_FREELIST(np->xn_tx_free_idxs, id);
+			add_id_to_freelist(np->xn_cdata.xn_tx_chain, id);
 			m_freem(m);
 		}
 		np->tx.rsp_cons = prod;
@@ -919,7 +1056,7 @@
 
 
 	while (np->rx.rsp_cons != np->rx.sring->rsp_prod &&
-	       np->user_state == UST_OPEN && 
+		likely(netfront_carrier_ok(np)) &&
 	       ifp->if_drv_flags & IFF_DRV_RUNNING) {
 	
 		XN_RX_LOCK(np);
@@ -975,7 +1112,7 @@
 	tx_bytes = 0;
 	
 
-	if (sc->backend_state != BEST_CONNECTED)
+	if (!netfront_carrier_ok(sc))

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801040905.m0495g02067127>