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