Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Jan 2008 07:55:13 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 132561 for review
Message-ID:  <200801050755.m057tDt9026476@repoman.freebsd.org>

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

Change 132561 by kmacy@pandemonium:kmacy:xen31 on 2008/01/05 07:54:19

	fix sleeping with lock held issue by making port lock a separate sx lock
	(needed for xenbus interaction)

Affected files ...

.. //depot/projects/xen31/sys/dev/xen/netfront/netfront.c#3 edit

Differences ...

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

@@ -24,6 +24,7 @@
 #include <sys/kernel.h>
 #include <sys/socket.h>
 #include <sys/queue.h>
+#include <sys/sx.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -192,6 +193,7 @@
 
 		struct mtx   tx_lock;
 		struct mtx   rx_lock;
+		struct sx    sc_lock;
 
 		unsigned int handle;
 		unsigned int irq;
@@ -219,8 +221,6 @@
 		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_head xn_rx_batch;	/* head of the batch queue */
 
 		int			xn_if_flags;
@@ -232,21 +232,24 @@
 
 #define XN_LOCK_INIT(_sc, _name) \
         mtx_init(&(_sc)->tx_lock, #_name"_tx", "network transmit lock", MTX_DEF); \
-        mtx_init(&(_sc)->rx_lock, #_name"_rx", "network receive lock", MTX_DEF);
+        mtx_init(&(_sc)->rx_lock, #_name"_rx", "network receive lock", MTX_DEF);  \
+        sx_init(&(_sc)->sc_lock, #_name"_rx")
+
 #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_LOCK(_sc)           sx_xlock(&(_sc)->sc_lock); 
+#define XN_UNLOCK(_sc)         sx_xunlock(&(_sc)->sc_lock); 
+
+#define XN_LOCK_ASSERT(_sc)    sx_assert(&(_sc)->sc_lock, SX_LOCKED); 
 #define XN_RX_LOCK_ASSERT(_sc)    mtx_assert(&(_sc)->rx_lock, MA_OWNED); 
 #define XN_TX_LOCK_ASSERT(_sc)    mtx_assert(&(_sc)->tx_lock, MA_OWNED); 
 #define XN_LOCK_DESTROY(_sc)   mtx_destroy(&(_sc)->rx_lock); \
-                               mtx_destroy(&(_sc)->tx_lock);
+                               mtx_destroy(&(_sc)->tx_lock); \
+                               sx_destroy(&(_sc)->sc_lock);
 
 #define netfront_carrier_on(netif)	((netif)->carrier = 1)
 #define netfront_carrier_off(netif)	((netif)->carrier = 0)
@@ -323,9 +326,8 @@
 		return 0;
 		
 		M_MOVE_PKTHDR(m, buf);
-	
-        MCLGET (m, M_DONTWAIT);
-	
+
+		m_cljget(m, M_DONTWAIT, MJUMPAGESIZE);
         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) );
@@ -380,6 +382,8 @@
 	struct ifnet *ifp;
 	struct netfront_info *info;
 
+	printf("netfront_probe() \n");
+	
 	err = create_netdev(dev, &ifp);
 	if (err) {
 		xenbus_dev_fatal(dev, err, "creating netdev");
@@ -389,12 +393,6 @@
 	info = ifp->if_softc;
 	dev->dev_driver_data = info;
 
-	err = talk_to_backend(dev, info);
-	if (err) {
-		free(info, M_DEVBUF);
-		dev->dev_driver_data = NULL;
-		return err;
-	}
 	
 	return 0;
 }
@@ -414,7 +412,7 @@
 	DPRINTK("%s\n", dev->nodename);
 	
 	netif_disconnect_backend(info);
-	return talk_to_backend(dev, info);
+	return (0);
 }
 
 
@@ -467,12 +465,16 @@
 		message = "writing request-rx-copy";
 		goto abort_transaction;
 	}
-
 	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-no-csum-offload", "%d", 1);
+	if (err) {
+		message = "writing feature-no-csum-offload";
+		goto abort_transaction;
+	}
 	err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
 	if (err) {
 		message = "writing feature-sg";
@@ -535,7 +537,6 @@
 		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;
@@ -572,18 +573,17 @@
 	return err;
 }
 
-
 /**
  * Callback received when the backend's state changes.
  */
-static void backend_changed(struct xenbus_device *dev,
+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 XenbusStateInitialised:
@@ -658,7 +658,7 @@
 		for (i = 1; i <= NET_TX_RING_SIZE; i++) {
 				m = np->xn_cdata.xn_tx_chain[i];
 
-				if (m == NULL)
+				if (((unsigned long)m) < KERNBASE)
 						continue;
 				gnttab_grant_foreign_access_ref(
 						np->grant_tx_ref[i], np->xbdev->otherend_id, 
@@ -738,9 +738,8 @@
 					break;
 
 			m_new->m_ext.ext_args = (vm_paddr_t *)(uintptr_t)vtophys(m_new->m_ext.ext_buf);		
-			id = xennet_rxidx(req_prod + 1);
+			id = xennet_rxidx(req_prod + i);
 	
-			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;
 		
@@ -1165,7 +1164,9 @@
 	if (notify)
 		notify_remote_via_irq(sc->irq);
 
+	XN_TX_LOCK(sc);
 	xn_txeof(sc);
+	XN_TX_UNLOCK(sc);
 
 	if (RING_FULL(&sc->tx)) {
 		sc->tx_full = 1;
@@ -1357,6 +1358,8 @@
 	netif_rx_request_t *req;
 	unsigned int feature_rx_copy, feature_rx_flip;
 
+	printf("network_connect\n");
+	
 	np = ifp->if_softc;
 	err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
 			   "feature-rx-copy", "%u", &feature_rx_copy);
@@ -1375,10 +1378,11 @@
 	np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) ||
 				(MODPARM_rx_flip && !feature_rx_flip));
 
-	
 	XN_LOCK(np);
-
 	/* Recovery procedure: */
+	err = talk_to_backend(np->xbdev, np);
+	if (err) 
+			return (err);
 	
 	/* Step 1: Reinitialise variables. */
 	netif_release_tx_bufs(np);
@@ -1418,7 +1422,9 @@
 	 */
 	netfront_carrier_on(np);
 	notify_remote_via_irq(np->irq);
+	XN_TX_LOCK(np);
 	xn_txeof(np);
+	XN_TX_UNLOCK(np);
 	network_alloc_rx_buffers(np);
 	XN_UNLOCK(np);
 
@@ -1458,7 +1464,10 @@
 	int err;
 	struct ifnet *ifp;
 
-	np = (struct netfront_info *)malloc(sizeof(struct netfront_info), M_DEVBUF, M_WAITOK);
+	np = (struct netfront_info *)malloc(sizeof(struct netfront_info), M_DEVBUF, M_NOWAIT);
+	if (np == NULL)
+			return (ENOMEM);
+	
 	memset(np, 0, sizeof(struct netfront_info));
 	
 	np->xbdev         = dev;
@@ -1470,22 +1479,22 @@
 	
 	/* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
 	for (i = 0; i <= NET_TX_RING_SIZE; i++) {
-		np->xn_tx_free_idxs[i] = (i+1);
-		np->grant_tx_ref[i] = GRANT_INVALID_REF;		
+			np->tx_mbufs[i] = (void *) ((unsigned long) i+1);
+			np->grant_tx_ref[i] = GRANT_INVALID_REF;	
 	}
 	for (i = 0; i <= NET_RX_RING_SIZE; i++) {
-		np->xn_rx_free_idxs[i] = (i+1);
-		np->grant_rx_ref[i] = GRANT_INVALID_REF;
+			np->rx_mbufs[i] = NULL;
+			np->grant_rx_ref[i] = GRANT_INVALID_REF;
 	}
 	/* A grant for every tx ring slot */
-	if (gnttab_alloc_grant_references(NET_TX_RING_SIZE,
+	if (gnttab_alloc_grant_references(TX_MAX_TARGET,
 					  &np->gref_tx_head) < 0) {
 		printf("#### netfront can't alloc tx grant refs\n");
 		err = ENOMEM;
 		goto exit;
 	}
 	/* A grant for every rx ring slot */
-	if (gnttab_alloc_grant_references(NET_RX_RING_SIZE,
+	if (gnttab_alloc_grant_references(RX_MAX_TARGET,
 					  &np->gref_rx_head) < 0) {
 		printf("#### netfront can't alloc rx grant refs\n");
 		gnttab_free_grant_references(np->gref_tx_head);
@@ -1624,14 +1633,15 @@
 static void
 netif_init(void *unused)
 {
-	if (xen_start_info->flags & SIF_INITDOMAIN)
-		return;
+		if (!is_running_on_xen())
+				return;
+		
+		if (is_initial_xendomain())
+				return;
 
-	IPRINTK("Initialising virtual ethernet driver.\n");
+		IPRINTK("Initialising virtual ethernet driver.\n");
 
-	xenbus_register_frontend(&netfront);
-
-    
+		xenbus_register_frontend(&netfront);
 }
 
 SYSINIT(xennetif, SI_SUB_PSEUDO, SI_ORDER_ANY, netif_init, NULL)



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