PERFORCE change 132473 for review
Kip Macy
kmacy at FreeBSD.org
Fri Jan 4 01:05:43 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=132473
Change 132473 by kmacy at 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) <<<
More information about the p4-projects
mailing list