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>