aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth D. Merry <ken@FreeBSD.org>2010-06-11 19:17:36 +0000
committerKenneth D. Merry <ken@FreeBSD.org>2010-06-11 19:17:36 +0000
commit7c049a853c0b5ef5554810d9066a819b875216cd (patch)
treec58c21acda8497df3cc0cb595ec5e7a199c995f7
parentad7a11c94c49f4c1c826179831d91f8eca12f94c (diff)
Notes
-rw-r--r--sys/amd64/include/xen/xenfunc.h31
-rw-r--r--sys/amd64/include/xen/xenvar.h26
-rw-r--r--sys/dev/cxgb/sys/mvec.h42
-rw-r--r--sys/dev/cxgb/sys/uipc_mvec.c44
-rw-r--r--sys/dev/xen/netfront/netfront.c756
-rw-r--r--sys/i386/include/xen/xenfunc.h29
-rw-r--r--sys/i386/include/xen/xenvar.h27
-rw-r--r--sys/kern/subr_bufring.c45
-rw-r--r--sys/sys/buf_ring.h42
9 files changed, 566 insertions, 476 deletions
diff --git a/sys/amd64/include/xen/xenfunc.h b/sys/amd64/include/xen/xenfunc.h
index b3a6672576cb..d03d4f685e24 100644
--- a/sys/amd64/include/xen/xenfunc.h
+++ b/sys/amd64/include/xen/xenfunc.h
@@ -1,6 +1,5 @@
-/*
- *
- * Copyright (c) 2004,2005 Kip Macy
+/*-
+ * Copyright (c) 2004, 2005 Kip Macy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,22 +10,22 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
-
#ifndef _XEN_XENFUNC_H_
#define _XEN_XENFUNC_H_
diff --git a/sys/amd64/include/xen/xenvar.h b/sys/amd64/include/xen/xenvar.h
index 1433b76871ec..d9dbc5d9186a 100644
--- a/sys/amd64/include/xen/xenvar.h
+++ b/sys/amd64/include/xen/xenvar.h
@@ -1,29 +1,27 @@
-/*
+/*-
* Copyright (c) 2008 Kip Macy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
* $FreeBSD$
*/
diff --git a/sys/dev/cxgb/sys/mvec.h b/sys/dev/cxgb/sys/mvec.h
index ed38dca34445..9db27ddf75d4 100644
--- a/sys/dev/cxgb/sys/mvec.h
+++ b/sys/dev/cxgb/sys/mvec.h
@@ -1,33 +1,31 @@
-/**************************************************************************
- *
- * Copyright (c) 2007,2009 Kip Macy kmacy@freebsd.org
+/*-
+ * Copyright (c) 2007, 2009 Kip Macy <kmacy@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. The name of Kip Macy nor the names of other
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
* $FreeBSD$
*
- ***************************************************************************/
+ */
#ifndef _MVEC_H_
#define _MVEC_H_
diff --git a/sys/dev/cxgb/sys/uipc_mvec.c b/sys/dev/cxgb/sys/uipc_mvec.c
index 4e494ebfc152..f52daa681b13 100644
--- a/sys/dev/cxgb/sys/uipc_mvec.c
+++ b/sys/dev/cxgb/sys/uipc_mvec.c
@@ -1,32 +1,28 @@
-/**************************************************************************
- *
- * Copyright (c) 2007-2008, Kip Macy kmacy@freebsd.org
+/*-
+ * Copyright (c) 2007-2008 Kip Macy <kmacy@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. The name of Kip Macy nor the names of other
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- *
- ***************************************************************************/
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index 571ecd0e3c0a..a6fd9ea28866 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -1,19 +1,27 @@
-/*
- *
+/*-
* Copyright (c) 2004-2006 Kip Macy
* All rights reserved.
*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
@@ -116,7 +124,16 @@ static const int MODPARM_rx_copy = 1;
static const int MODPARM_rx_flip = 0;
#endif
-#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
+/**
+ * \brief The maximum allowed data fragments in a single transmit
+ * request.
+ *
+ * This limit is imposed by the backend driver. We assume here that
+ * we are dealing with a Linux driver domain and have set our limit
+ * to mirror the Linux MAX_SKB_FRAGS constant.
+ */
+#define MAX_TX_REQ_FRAGS (65536 / PAGE_SIZE + 2)
+
#define RX_COPY_THRESHOLD 256
#define net_ratelimit() 0
@@ -132,6 +149,9 @@ static void xn_tick_locked(struct netfront_info *);
static void xn_tick(void *);
static void xn_intr(void *);
+static inline int xn_count_frags(struct mbuf *m);
+static int xn_assemble_tx_request(struct netfront_info *sc,
+ struct mbuf *m_head);
static void xn_start_locked(struct ifnet *);
static void xn_start(struct ifnet *);
static int xn_ioctl(struct ifnet *, u_long, caddr_t);
@@ -155,6 +175,9 @@ static void netif_disconnect_backend(struct netfront_info *info);
static int setup_device(device_t dev, struct netfront_info *info);
static void end_access(int ref, void *page);
+static int xn_ifmedia_upd(struct ifnet *ifp);
+static void xn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
+
/* Xenolinux helper functions */
int network_connect(struct netfront_info *);
@@ -163,8 +186,8 @@ static void xn_free_rx_ring(struct netfront_info *);
static void xn_free_tx_ring(struct netfront_info *);
static int xennet_get_responses(struct netfront_info *np,
- struct netfront_rx_info *rinfo, RING_IDX rp, struct mbuf **list,
- int *pages_flipped_p);
+ struct netfront_rx_info *rinfo, RING_IDX rp, RING_IDX *cons,
+ struct mbuf **list, int *pages_flipped_p);
#define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT)
@@ -176,11 +199,12 @@ static int xennet_get_responses(struct netfront_info *np,
* 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];
- int xn_tx_chain_cnt;
- struct mbuf *xn_rx_chain[NET_RX_RING_SIZE+1];
+ struct mbuf *xn_tx_chain[NET_TX_RING_SIZE+1];
+ int xn_tx_chain_cnt;
+ struct mbuf *xn_rx_chain[NET_RX_RING_SIZE+1];
};
+#define NUM_ELEMENTS(x) (sizeof(x)/sizeof(*x))
struct net_device_stats
{
@@ -230,7 +254,7 @@ struct netfront_info {
struct mtx tx_lock;
struct mtx rx_lock;
- struct sx sc_lock;
+ struct mtx sc_lock;
u_int handle;
u_int irq;
@@ -240,32 +264,29 @@ struct netfront_info {
/* 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;
-
- /*
- * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
- * array is an index into a chain of free entries.
- */
+ int rx_min_target;
+ int rx_max_target;
+ int rx_target;
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];
-#define TX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
- device_t xbdev;
- int tx_ring_ref;
- int rx_ring_ref;
- uint8_t mac[ETHER_ADDR_LEN];
+ device_t xbdev;
+ int tx_ring_ref;
+ int rx_ring_ref;
+ uint8_t mac[ETHER_ADDR_LEN];
struct xn_chain_data xn_cdata; /* mbufs */
- struct mbuf_head xn_rx_batch; /* head of the batch queue */
+ struct mbuf_head xn_rx_batch; /* head of the batch queue */
int xn_if_flags;
struct callout xn_stat_ch;
- u_long rx_pfn_array[NET_RX_RING_SIZE];
- multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
- mmu_update_t rx_mmu[NET_RX_RING_SIZE];
+ u_long rx_pfn_array[NET_RX_RING_SIZE];
+ multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
+ mmu_update_t rx_mmu[NET_RX_RING_SIZE];
+ struct ifmedia sc_media;
};
#define rx_mbufs xn_cdata.xn_rx_chain
@@ -274,7 +295,7 @@ struct netfront_info {
#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); \
- sx_init(&(_sc)->sc_lock, #_name"_rx")
+ mtx_init(&(_sc)->sc_lock, #_name"_sc", "netfront softc lock", MTX_DEF)
#define XN_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_lock)
#define XN_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_lock)
@@ -282,15 +303,15 @@ struct netfront_info {
#define XN_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_lock)
#define XN_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_lock)
-#define XN_LOCK(_sc) sx_xlock(&(_sc)->sc_lock);
-#define XN_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_lock);
+#define XN_LOCK(_sc) mtx_lock(&(_sc)->sc_lock);
+#define XN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock);
-#define XN_LOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_lock, SX_LOCKED);
+#define XN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_lock, MA_OWNED);
#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); \
- sx_destroy(&(_sc)->sc_lock);
+ mtx_destroy(&(_sc)->sc_lock);
struct netfront_rx_info {
struct netif_rx_response rx;
@@ -310,18 +331,22 @@ struct netfront_rx_info {
*/
static inline void
-add_id_to_freelist(struct mbuf **list, unsigned short id)
+add_id_to_freelist(struct mbuf **list, uintptr_t id)
{
- KASSERT(id != 0, ("add_id_to_freelist: the head item (0) must always be free."));
+ KASSERT(id != 0,
+ ("%s: the head item (0) must always be free.", __func__));
list[id] = list[0];
- list[0] = (void *)(u_long)id;
+ list[0] = (struct mbuf *)id;
}
static inline unsigned short
get_id_from_freelist(struct mbuf **list)
{
- u_int id = (u_int)(u_long)list[0];
- KASSERT(id != 0, ("get_id_from_freelist: the head item (0) must always remain free."));
+ uintptr_t id;
+
+ id = (uintptr_t)list[0];
+ KASSERT(id != 0,
+ ("%s: the head item (0) must always remain free.", __func__));
list[0] = list[id];
return (id);
}
@@ -333,8 +358,7 @@ xennet_rxidx(RING_IDX idx)
}
static inline struct mbuf *
-xennet_get_rx_mbuf(struct netfront_info *np,
- RING_IDX ri)
+xennet_get_rx_mbuf(struct netfront_info *np, RING_IDX ri)
{
int i = xennet_rxidx(ri);
struct mbuf *m;
@@ -355,9 +379,13 @@ xennet_get_rx_ref(struct netfront_info *np, RING_IDX ri)
#define IPRINTK(fmt, args...) \
printf("[XEN] " fmt, ##args)
+#ifdef INVARIANTS
#define WPRINTK(fmt, args...) \
printf("[XEN] " fmt, ##args)
-#if 0
+#else
+#define WPRINTK(fmt, args...)
+#endif
+#ifdef DEBUG
#define DPRINTK(fmt, args...) \
printf("[XEN] %s: " fmt, __func__, ##args)
#else
@@ -477,25 +505,25 @@ talk_to_backend(device_t dev, struct netfront_info *info)
goto destroy_ring;
}
err = xenbus_printf(xbt, node, "tx-ring-ref","%u",
- info->tx_ring_ref);
+ info->tx_ring_ref);
if (err) {
message = "writing tx ring-ref";
goto abort_transaction;
}
err = xenbus_printf(xbt, node, "rx-ring-ref","%u",
- info->rx_ring_ref);
+ info->rx_ring_ref);
if (err) {
message = "writing rx ring-ref";
goto abort_transaction;
}
err = xenbus_printf(xbt, node,
- "event-channel", "%u", irq_to_evtchn_port(info->irq));
+ "event-channel", "%u", irq_to_evtchn_port(info->irq));
if (err) {
message = "writing event-channel";
goto abort_transaction;
}
err = xenbus_printf(xbt, node, "request-rx-copy", "%u",
- info->copying_receiver);
+ info->copying_receiver);
if (err) {
message = "writing request-rx-copy";
goto abort_transaction;
@@ -656,9 +684,9 @@ xn_free_rx_ring(struct netfront_info *sc)
int i;
for (i = 0; i < NET_RX_RING_SIZE; i++) {
- if (sc->xn_cdata.xn_rx_chain[i] != NULL) {
- m_freem(sc->xn_cdata.xn_rx_chain[i]);
- sc->xn_cdata.xn_rx_chain[i] = NULL;
+ if (sc->xn_cdata.rx_mbufs[i] != NULL) {
+ m_freem(sc->rx_mbufs[i]);
+ sc->rx_mbufs[i] = NULL;
}
}
@@ -675,8 +703,8 @@ xn_free_tx_ring(struct netfront_info *sc)
int i;
for (i = 0; i < NET_TX_RING_SIZE; i++) {
- if (sc->xn_cdata.xn_tx_chain[i] != NULL) {
- m_freem(sc->xn_cdata.xn_tx_chain[i]);
+ if (sc->tx_mbufs[i] != NULL) {
+ m_freem(sc->tx_mbufs[i]);
sc->xn_cdata.xn_tx_chain[i] = NULL;
}
}
@@ -685,39 +713,36 @@ xn_free_tx_ring(struct netfront_info *sc)
#endif
}
-/*
- * Do some brief math on the number of descriptors available to
- * determine how many slots are available.
- *
- * Firstly - wouldn't something with RING_FREE_REQUESTS() be more applicable?
- * Secondly - MAX_SKB_FRAGS is a Linux construct which may not apply here.
- * Thirdly - it isn't used here anyway; the magic constant '24' is possibly
- * wrong?
- * The "2" is presumably to ensure there are also enough slots available for
- * the ring entries used for "options" (eg, the TSO entry before a packet
- * is queued); I'm not sure why its 2 and not 1. Perhaps to make sure there's
- * a "free" node in the tx mbuf list (node 0) to represent the freelist?
+/**
+ * \brief Verify that there is sufficient space in the Tx ring
+ * buffer for a maximally sized request to be enqueued.
*
- * This only figures out whether any xenbus ring descriptors are available;
- * it doesn't at all reflect how many tx mbuf ring descriptors are also
- * available.
+ * A transmit request requires a transmit descriptor for each packet
+ * fragment, plus up to 2 entries for "options" (e.g. TSO).
*/
static inline int
-netfront_tx_slot_available(struct netfront_info *np)
+xn_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));
+ return (RING_FREE_REQUESTS(&np->tx) > (MAX_TX_REQ_FRAGS + 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];
+ struct mbuf *m;
+
+ m = np->tx_mbufs[i];
- if (((u_long)m) < KERNBASE)
+ /*
+ * We assume that no kernel addresses are
+ * less than NET_TX_RING_SIZE. Any entry
+ * in the table that is below this number
+ * must be an index from free-list tracking.
+ */
+ if (((uintptr_t)m) <= NET_TX_RING_SIZE)
continue;
gnttab_grant_foreign_access_ref(np->grant_tx_ref[i],
xenbus_get_otherend_id(np->xbdev),
@@ -756,19 +781,25 @@ network_alloc_rx_buffers(struct netfront_info *sc)
return;
/*
- * Allocate skbuffs greedily, even though we batch updates to the
+ * Allocate mbufs greedily, even though we batch updates to the
* receive ring. This creates a less bursty demand on the memory
- * allocator, so should reduce the chance of failed allocation
+ * allocator, and so should reduce the chance of failed allocation
* requests both for ourself and for other kernel subsystems.
+ *
+ * Here we attempt to maintain rx_target buffers in flight, counting
+ * buffers that we have yet to process in the receive ring.
*/
batch_target = sc->rx_target - (req_prod - sc->rx.rsp_cons);
for (i = mbufq_len(&sc->xn_rx_batch); i < batch_target; i++) {
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL)
+ if (m_new == NULL) {
+ printf("%s: MGETHDR failed\n", __func__);
goto no_mbuf;
+ }
m_cljget(m_new, M_DONTWAIT, MJUMPAGESIZE);
if ((m_new->m_flags & M_EXT) == 0) {
+ printf("%s: m_cljget failed\n", __func__);
m_freem(m_new);
no_mbuf:
@@ -785,16 +816,29 @@ no_mbuf:
mbufq_tail(&sc->xn_rx_batch, m_new);
}
- /* Is the batch large enough to be worthwhile? */
+ /*
+ * If we've allocated at least half of our target number of entries,
+ * submit them to the backend - we have enough to make the overhead
+ * of submission worthwhile. Otherwise wait for more mbufs and
+ * request entries to become available.
+ */
if (i < (sc->rx_target/2)) {
if (req_prod >sc->rx.sring->req_prod)
goto push;
return;
}
- /* Adjust 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;
+
+ /*
+ * Double floating fill target if we risked having the backend
+ * run out of empty buffers for receive traffic. We define "running
+ * low" as having less than a fourth of our target buffers free
+ * at the time we refilled the queue.
+ */
+ if ((req_prod - sc->rx.sring->rsp_prod) < (sc->rx_target / 4)) {
+ sc->rx_target *= 2;
+ if (sc->rx_target > sc->rx_max_target)
+ sc->rx_target = sc->rx_max_target;
+ }
refill:
for (nr_flips = i = 0; ; i++) {
@@ -806,9 +850,8 @@ refill:
id = xennet_rxidx(req_prod + i);
- KASSERT(sc->xn_cdata.xn_rx_chain[id] == NULL,
- ("non-NULL xm_rx_chain"));
- sc->xn_cdata.xn_rx_chain[id] = m_new;
+ KASSERT(sc->rx_mbufs[id] == NULL, ("non-NULL xm_rx_chain"));
+ sc->rx_mbufs[id] = m_new;
ref = gnttab_claim_grant_reference(&sc->gref_rx_head);
KASSERT((short)ref >= 0, ("negative ref"));
@@ -932,14 +975,13 @@ xn_rxeof(struct netfront_info *np)
memset(extras, 0, sizeof(rinfo.extras));
m = NULL;
- err = xennet_get_responses(np, &rinfo, rp, &m,
+ err = xennet_get_responses(np, &rinfo, rp, &i, &m,
&pages_flipped);
if (unlikely(err)) {
if (m)
mbufq_tail(&errq, m);
np->stats.rx_errors++;
- i = np->rx.rsp_cons;
continue;
}
@@ -961,7 +1003,7 @@ xn_rxeof(struct netfront_info *np)
np->stats.rx_bytes += m->m_pkthdr.len;
mbufq_tail(&rxq, m);
- np->rx.rsp_cons = ++i;
+ np->rx.rsp_cons = i;
}
if (pages_flipped) {
@@ -1056,7 +1098,6 @@ xn_txeof(struct netfront_info *np)
return;
ifp = np->xn_ifp;
- ifp->if_timer = 0;
do {
prod = np->tx.sring->rsp_prod;
@@ -1067,9 +1108,16 @@ xn_txeof(struct netfront_info *np)
if (txr->status == NETIF_RSP_NULL)
continue;
+ if (txr->status != NETIF_RSP_OKAY) {
+ printf("%s: WARNING: response is %d!\n",
+ __func__, txr->status);
+ }
id = txr->id;
- m = np->xn_cdata.xn_tx_chain[id];
+ m = np->tx_mbufs[id];
KASSERT(m != NULL, ("mbuf not found in xn_tx_chain"));
+ KASSERT((uintptr_t)m > NET_TX_RING_SIZE,
+ ("mbuf already on the free list, but we're "
+ "trying to free it again!"));
M_ASSERTVALID(m);
/*
@@ -1080,10 +1128,8 @@ xn_txeof(struct netfront_info *np)
ifp->if_opackets++;
if (unlikely(gnttab_query_foreign_access(
np->grant_tx_ref[id]) != 0)) {
- printf("network_tx_buf_gc: warning "
- "-- grant still in use by backend "
- "domain.\n");
- goto out;
+ panic("grant id %u still in use by the backend",
+ id);
}
gnttab_end_foreign_access_ref(
np->grant_tx_ref[id]);
@@ -1091,12 +1137,9 @@ xn_txeof(struct netfront_info *np)
&np->gref_tx_head, np->grant_tx_ref[id]);
np->grant_tx_ref[id] = GRANT_INVALID_REF;
- np->xn_cdata.xn_tx_chain[id] = NULL;
- add_id_to_freelist(np->xn_cdata.xn_tx_chain, id);
+ np->tx_mbufs[id] = NULL;
+ add_id_to_freelist(np->tx_mbufs, id);
np->xn_cdata.xn_tx_chain_cnt--;
- if (np->xn_cdata.xn_tx_chain_cnt < 0) {
- panic("netif_release_tx_bufs: tx_chain_cnt must be >= 0");
- }
m_free(m);
/* Only mark the queue active if we've freed up at least one slot to try */
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
@@ -1118,7 +1161,6 @@ xn_txeof(struct netfront_info *np)
mb();
} while (prod != np->tx.sring->rsp_prod);
- out:
if (np->tx_full &&
((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE)) {
np->tx_full = 0;
@@ -1142,7 +1184,7 @@ xn_intr(void *xsc)
ifp->if_drv_flags & IFF_DRV_RUNNING))
return;
#endif
- if (np->tx.rsp_cons != np->tx.sring->rsp_prod) {
+ if (RING_HAS_UNCONSUMED_RESPONSES(&np->tx)) {
XN_TX_LOCK(np);
xn_txeof(np);
XN_TX_UNLOCK(np);
@@ -1174,10 +1216,9 @@ xennet_move_rx_slot(struct netfront_info *np, struct mbuf *m,
static int
xennet_get_extras(struct netfront_info *np,
- struct netif_extra_info *extras, RING_IDX rp)
+ struct netif_extra_info *extras, RING_IDX rp, RING_IDX *cons)
{
struct netif_extra_info *extra;
- RING_IDX cons = np->rx.rsp_cons;
int err = 0;
@@ -1185,17 +1226,17 @@ xennet_get_extras(struct netfront_info *np,
struct mbuf *m;
grant_ref_t ref;
- if (unlikely(cons + 1 == rp)) {
+ if (unlikely(*cons + 1 == rp)) {
#if 0
if (net_ratelimit())
WPRINTK("Missing extra info\n");
#endif
- err = -EINVAL;
+ err = EINVAL;
break;
}
extra = (struct netif_extra_info *)
- RING_GET_RESPONSE(&np->rx, ++cons);
+ RING_GET_RESPONSE(&np->rx, ++(*cons));
if (unlikely(!extra->type ||
extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
@@ -1204,23 +1245,22 @@ xennet_get_extras(struct netfront_info *np,
WPRINTK("Invalid extra type: %d\n",
extra->type);
#endif
- err = -EINVAL;
+ err = EINVAL;
} else {
memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
}
- m = xennet_get_rx_mbuf(np, cons);
- ref = xennet_get_rx_ref(np, cons);
+ m = xennet_get_rx_mbuf(np, *cons);
+ ref = xennet_get_rx_ref(np, *cons);
xennet_move_rx_slot(np, m, ref);
} while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
- np->rx.rsp_cons = cons;
return err;
}
static int
xennet_get_responses(struct netfront_info *np,
- struct netfront_rx_info *rinfo, RING_IDX rp,
+ struct netfront_rx_info *rinfo, RING_IDX rp, RING_IDX *cons,
struct mbuf **list,
int *pages_flipped_p)
{
@@ -1229,45 +1269,48 @@ xennet_get_responses(struct netfront_info *np,
struct multicall_entry *mcl;
struct netif_rx_response *rx = &rinfo->rx;
struct netif_extra_info *extras = rinfo->extras;
- RING_IDX cons = np->rx.rsp_cons;
struct mbuf *m, *m0, *m_prev;
- grant_ref_t ref = xennet_get_rx_ref(np, cons);
- int max = 5 /* MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD) */;
+ grant_ref_t ref = xennet_get_rx_ref(np, *cons);
+ RING_IDX ref_cons = *cons;
+ int max = 5 /* MAX_TX_REQ_FRAGS + (rx->status <= RX_COPY_THRESHOLD) */;
int frags = 1;
int err = 0;
u_long ret;
- m0 = m = m_prev = xennet_get_rx_mbuf(np, cons);
+ m0 = m = m_prev = xennet_get_rx_mbuf(np, *cons);
if (rx->flags & NETRXF_extra_info) {
- err = xennet_get_extras(np, extras, rp);
- cons = np->rx.rsp_cons;
+ err = xennet_get_extras(np, extras, rp, cons);
}
if (m0 != NULL) {
- m0->m_pkthdr.len = 0;
- m0->m_next = NULL;
+ m0->m_pkthdr.len = 0;
+ m0->m_next = NULL;
}
for (;;) {
u_long mfn;
#if 0
- printf("rx->status=%hd rx->offset=%hu frags=%u\n",
+ DPRINTK("rx->status=%hd rx->offset=%hu frags=%u\n",
rx->status, rx->offset, frags);
#endif
if (unlikely(rx->status < 0 ||
rx->offset + rx->status > PAGE_SIZE)) {
+
#if 0
if (net_ratelimit())
WPRINTK("rx->offset: %x, size: %u\n",
rx->offset, rx->status);
#endif
xennet_move_rx_slot(np, m, ref);
- err = -EINVAL;
- goto next;
+ if (m0 == m)
+ m0 = NULL;
+ m = NULL;
+ err = EINVAL;
+ goto next_skip_queue;
}
/*
@@ -1276,11 +1319,12 @@ xennet_get_responses(struct netfront_info *np,
* situation to the system controller to reboot the backed.
*/
if (ref == GRANT_INVALID_REF) {
+
#if 0
if (net_ratelimit())
WPRINTK("Bad rx response id %d.\n", rx->id);
#endif
- err = -EINVAL;
+ err = EINVAL;
goto next;
}
@@ -1289,12 +1333,10 @@ xennet_get_responses(struct netfront_info *np,
* headroom, ...
*/
if (!(mfn = gnttab_end_foreign_transfer_ref(ref))) {
- if (net_ratelimit())
- WPRINTK("Unfulfilled rx req "
- "(id=%d, st=%d).\n",
- rx->id, rx->status);
+ WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n",
+ rx->id, rx->status);
xennet_move_rx_slot(np, m, ref);
- err = -ENOMEM;
+ err = ENOMEM;
goto next;
}
@@ -1332,23 +1374,43 @@ next:
m->m_data += rx->offset;
m0->m_pkthdr.len += rx->status;
+next_skip_queue:
if (!(rx->flags & NETRXF_more_data))
break;
- if (cons + frags == rp) {
+ if (*cons + frags == rp) {
if (net_ratelimit())
WPRINTK("Need more frags\n");
- err = -ENOENT;
+ err = ENOENT;
+ printf("%s: cons %u frags %u rp %u, not enough frags\n",
+ __func__, *cons, frags, rp);
break;
}
+ /*
+ * Note that m can be NULL, if rx->status < 0 or if
+ * rx->offset + rx->status > PAGE_SIZE above.
+ */
m_prev = m;
- rx = RING_GET_RESPONSE(&np->rx, cons + frags);
- m = xennet_get_rx_mbuf(np, cons + frags);
+ rx = RING_GET_RESPONSE(&np->rx, *cons + frags);
+ m = xennet_get_rx_mbuf(np, *cons + frags);
- m_prev->m_next = m;
+ /*
+ * m_prev == NULL can happen if rx->status < 0 or if
+ * rx->offset + * rx->status > PAGE_SIZE above.
+ */
+ if (m_prev != NULL)
+ m_prev->m_next = m;
+
+ /*
+ * m0 can be NULL if rx->status < 0 or if * rx->offset +
+ * rx->status > PAGE_SIZE above.
+ */
+ if (m0 == NULL)
+ m0 = m;
m->m_next = NULL;
- ref = xennet_get_rx_ref(np, cons + frags);
+ ref = xennet_get_rx_ref(np, *cons + frags);
+ ref_cons = *cons + frags;
frags++;
}
*list = m0;
@@ -1356,11 +1418,12 @@ next:
if (unlikely(frags > max)) {
if (net_ratelimit())
WPRINTK("Too many frags\n");
- err = -E2BIG;
+ printf("%s: too many frags %d > max %d\n", __func__, frags,
+ max);
+ err = E2BIG;
}
- if (unlikely(err))
- np->rx.rsp_cons = cons + frags;
+ *cons += frags;
*pages_flipped_p = pages_flipped;
@@ -1389,209 +1452,228 @@ xn_tick(void *xsc)
XN_RX_UNLOCK(sc);
}
-static void
-xn_start_locked(struct ifnet *ifp)
+
+/**
+ * \brief Count the number of fragments in an mbuf chain.
+ *
+ * Surprisingly, there isn't an M* macro for this.
+ */
+static inline int
+xn_count_frags(struct mbuf *m)
{
- int otherend_id;
- unsigned short id;
- struct mbuf *m_head, *m;
- struct netfront_info *sc;
- netif_tx_request_t *tx;
+ int nfrags;
+
+ for (nfrags = 0; m != NULL; m = m->m_next)
+ nfrags++;
+
+ return (nfrags);
+}
+
+/**
+ * Given an mbuf chain, make sure we have enough room and then push
+ * it onto the transmit ring.
+ */
+static int
+xn_assemble_tx_request(struct netfront_info *sc, struct mbuf *m_head)
+{
+ struct ifnet *ifp;
+ struct mbuf *m;
+ u_int nfrags;
netif_extra_info_t *extra;
- RING_IDX i;
- grant_ref_t ref;
- u_long mfn, tx_bytes;
- int notify, nfrags;
+ int otherend_id;
- sc = ifp->if_softc;
- otherend_id = xenbus_get_otherend_id(sc->xbdev);
- tx_bytes = 0;
+ ifp = sc->xn_ifp;
- if (!netfront_carrier_ok(sc))
- return;
-
- for (i = sc->tx.req_prod_pvt; TRUE; i++) {
- IF_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
-
- /*
- * netfront_tx_slot_available() tries to do some math to
- * ensure that there'll be enough xenbus ring slots available
- * for the maximum number of packet fragments (and a couple more
- * for what I guess are TSO and other ring entry items.)
- */
- if (!netfront_tx_slot_available(sc)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ /**
+ * Defragment the mbuf if necessary.
+ */
+ nfrags = xn_count_frags(m_head);
- /*
- * Defragment the mbuf if necessary.
- */
- for (m = m_head, nfrags = 0; m; m = m->m_next)
- nfrags++;
- if (nfrags > MAX_SKB_FRAGS) {
- m = m_defrag(m_head, M_DONTWAIT);
- if (!m) {
- m_freem(m_head);
- break;
- }
- m_head = m;
+ /*
+ * Check to see whether this request is longer than netback
+ * can handle, and try to defrag it.
+ */
+ /**
+ * It is a bit lame, but the netback driver in Linux can't
+ * deal with nfrags > MAX_TX_REQ_FRAGS, which is a quirk of
+ * the Linux network stack.
+ */
+ if (nfrags > MAX_TX_REQ_FRAGS) {
+ m = m_defrag(m_head, M_DONTWAIT);
+ if (!m) {
+ /*
+ * Defrag failed, so free the mbuf and
+ * therefore drop the packet.
+ */
+ m_freem(m_head);
+ return (EMSGSIZE);
}
+ m_head = m;
+ }
- /* Determine how many fragments now exist */
- for (m = m_head, nfrags = 0; m; m = m->m_next)
- nfrags++;
+ /* Determine how many fragments now exist */
+ nfrags = xn_count_frags(m_head);
- /*
- * Don't attempt to queue this packet if there aren't
- * enough free entries in the chain.
- *
- * There isn't a 1:1 correspondance between the mbuf TX ring
- * and the xenbus TX ring.
- * xn_txeof() may need to be called to free up some slots.
- *
- * It is quite possible that this can be later eliminated if
- * it turns out that partial * packets can be pushed into
- * the ringbuffer, with fragments pushed in when further slots
- * free up.
- *
- * It is also quite possible that the driver will lock up
- * if the TX queue fills up with no RX traffic, and
- * the mbuf ring is exhausted. The queue may need
- * a swift kick to continue.
- */
+ /*
+ * Check to see whether the defragmented packet has too many
+ * segments for the Linux netback driver.
+ */
+ /**
+ * The FreeBSD TCP stack, with TSO enabled, can produce a chain
+ * of mbufs longer than Linux can handle. Make sure we don't
+ * pass a too-long chain over to the other side by dropping the
+ * packet. It doesn't look like there is currently a way to
+ * tell the TCP stack to generate a shorter chain of packets.
+ */
+ if (nfrags > MAX_TX_REQ_FRAGS) {
+ m_freem(m_head);
+ return (EMSGSIZE);
+ }
- /*
- * It is not +1 like the allocation because we need to keep
- * slot [0] free for the freelist head
- */
- if (sc->xn_cdata.xn_tx_chain_cnt + nfrags >= NET_TX_RING_SIZE) {
- printf("xn_start_locked: xn_tx_chain_cnt (%d) + nfrags %d >= NET_TX_RING_SIZE (%d); must be full!\n",
- (int) sc->xn_cdata.xn_tx_chain_cnt,
- (int) nfrags, (int) NET_TX_RING_SIZE);
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ /*
+ * This check should be redundant. We've already verified that we
+ * have enough slots in the ring to handle a packet of maximum
+ * size, and that our packet is less than the maximum size. Keep
+ * it in here as an assert for now just to make certain that
+ * xn_tx_chain_cnt is accurate.
+ */
+ KASSERT((sc->xn_cdata.xn_tx_chain_cnt + nfrags) <= NET_TX_RING_SIZE,
+ ("%s: xn_tx_chain_cnt (%d) + nfrags (%d) > NET_TX_RING_SIZE "
+ "(%d)!", __func__, (int) sc->xn_cdata.xn_tx_chain_cnt,
+ (int) nfrags, (int) NET_TX_RING_SIZE));
- /*
- * Make sure there's actually space available in the
- * Xen TX ring for this. Overcompensate for the possibility
- * of having a TCP offload fragment just in case for now
- * (the +1) rather than adding logic to accurately calculate
- * the required size.
- */
- if (RING_FREE_REQUESTS(&sc->tx) < (nfrags + 1)) {
- printf("xn_start_locked: free ring slots (%d) < (nfrags + 1) (%d); must be full!\n",
- (int) RING_FREE_REQUESTS(&sc->tx),
- (int) (nfrags + 1));
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ /*
+ * Start packing the mbufs in this chain into
+ * the fragment pointers. Stop when we run out
+ * of fragments or hit the end of the mbuf chain.
+ */
+ m = m_head;
+ extra = NULL;
+ otherend_id = xenbus_get_otherend_id(sc->xbdev);
+ for (m = m_head; m; m = m->m_next) {
+ netif_tx_request_t *tx;
+ uintptr_t id;
+ grant_ref_t ref;
+ u_long mfn; /* XXX Wrong type? */
- /*
- * Start packing the mbufs in this chain into
- * the fragment pointers. Stop when we run out
- * of fragments or hit the end of the mbuf chain.
- */
- m = m_head;
- extra = NULL;
- for (m = m_head; m; m = m->m_next) {
- tx = RING_GET_REQUEST(&sc->tx, i);
- id = get_id_from_freelist(sc->xn_cdata.xn_tx_chain);
- if (id == 0)
- panic("xn_start_locked: was allocated the freelist head!\n");
- sc->xn_cdata.xn_tx_chain_cnt++;
- if (sc->xn_cdata.xn_tx_chain_cnt >= NET_TX_RING_SIZE+1)
- panic("xn_start_locked: tx_chain_cnt must be < NET_TX_RING_SIZE+1\n");
- sc->xn_cdata.xn_tx_chain[id] = m;
- tx->id = id;
- ref = gnttab_claim_grant_reference(&sc->gref_tx_head);
- KASSERT((short)ref >= 0, ("Negative ref"));
- mfn = virt_to_mfn(mtod(m, vm_offset_t));
- gnttab_grant_foreign_access_ref(ref, otherend_id,
- mfn, GNTMAP_readonly);
- tx->gref = sc->grant_tx_ref[id] = ref;
- tx->offset = mtod(m, vm_offset_t) & (PAGE_SIZE - 1);
- tx->flags = 0;
- if (m == m_head) {
- /*
- * The first fragment has the entire packet
- * size, subsequent fragments have just the
- * fragment size. The backend works out the
- * true size of the first fragment by
- * subtracting the sizes of the other
- * fragments.
- */
- tx->size = m->m_pkthdr.len;
+ tx = RING_GET_REQUEST(&sc->tx, sc->tx.req_prod_pvt);
+ id = get_id_from_freelist(sc->tx_mbufs);
+ if (id == 0)
+ panic("xn_start_locked: was allocated the freelist head!\n");
+ sc->xn_cdata.xn_tx_chain_cnt++;
+ if (sc->xn_cdata.xn_tx_chain_cnt > NET_TX_RING_SIZE)
+ panic("xn_start_locked: tx_chain_cnt must be <= NET_TX_RING_SIZE\n");
+ sc->tx_mbufs[id] = m;
+ tx->id = id;
+ ref = gnttab_claim_grant_reference(&sc->gref_tx_head);
+ KASSERT((short)ref >= 0, ("Negative ref"));
+ mfn = virt_to_mfn(mtod(m, vm_offset_t));
+ gnttab_grant_foreign_access_ref(ref, otherend_id,
+ mfn, GNTMAP_readonly);
+ tx->gref = sc->grant_tx_ref[id] = ref;
+ tx->offset = mtod(m, vm_offset_t) & (PAGE_SIZE - 1);
+ tx->flags = 0;
+ if (m == m_head) {
+ /*
+ * The first fragment has the entire packet
+ * size, subsequent fragments have just the
+ * fragment size. The backend works out the
+ * true size of the first fragment by
+ * subtracting the sizes of the other
+ * fragments.
+ */
+ tx->size = m->m_pkthdr.len;
- /*
- * The first fragment contains the
- * checksum flags and is optionally
- * followed by extra data for TSO etc.
- */
- if (m->m_pkthdr.csum_flags
- & CSUM_DELAY_DATA) {
- tx->flags |= (NETTXF_csum_blank
- | NETTXF_data_validated);
- }
+ /*
+ * The first fragment contains the checksum flags
+ * and is optionally followed by extra data for
+ * TSO etc.
+ */
+ /**
+ * CSUM_TSO requires checksum offloading.
+ * Some versions of FreeBSD fail to
+ * set CSUM_TCP in the CSUM_TSO case,
+ * so we have to test for CSUM_TSO
+ * explicitly.
+ */
+ if (m->m_pkthdr.csum_flags
+ & (CSUM_DELAY_DATA | CSUM_TSO)) {
+ tx->flags |= (NETTXF_csum_blank
+ | NETTXF_data_validated);
+ }
#if __FreeBSD_version >= 700000
- if (m->m_pkthdr.csum_flags & CSUM_TSO) {
- struct netif_extra_info *gso =
- (struct netif_extra_info *)
- RING_GET_REQUEST(&sc->tx, ++i);
+ if (m->m_pkthdr.csum_flags & CSUM_TSO) {
+ struct netif_extra_info *gso =
+ (struct netif_extra_info *)
+ RING_GET_REQUEST(&sc->tx,
+ ++sc->tx.req_prod_pvt);
- if (extra)
- extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
- else
- tx->flags |= NETTXF_extra_info;
+ tx->flags |= NETTXF_extra_info;
- gso->u.gso.size = m->m_pkthdr.tso_segsz;
- gso->u.gso.type =
- XEN_NETIF_GSO_TYPE_TCPV4;
- gso->u.gso.pad = 0;
- gso->u.gso.features = 0;
+ gso->u.gso.size = m->m_pkthdr.tso_segsz;
+ gso->u.gso.type =
+ XEN_NETIF_GSO_TYPE_TCPV4;
+ gso->u.gso.pad = 0;
+ gso->u.gso.features = 0;
- gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
- gso->flags = 0;
- extra = gso;
- }
-#endif
- } else {
- tx->size = m->m_len;
- }
- if (m->m_next) {
- tx->flags |= NETTXF_more_data;
- i++;
+ gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
+ gso->flags = 0;
}
+#endif
+ } else {
+ tx->size = m->m_len;
}
+ if (m->m_next)
+ tx->flags |= NETTXF_more_data;
+
+ sc->tx.req_prod_pvt++;
+ }
+ BPF_MTAP(ifp, m_head);
- BPF_MTAP(ifp, m_head);
+ sc->stats.tx_bytes += m_head->m_pkthdr.len;
+ sc->stats.tx_packets++;
- sc->stats.tx_bytes += m_head->m_pkthdr.len;
- sc->stats.tx_packets++;
+ return (0);
+}
+
+static void
+xn_start_locked(struct ifnet *ifp)
+{
+ struct netfront_info *sc;
+ struct mbuf *m_head;
+ int notify;
+
+ sc = ifp->if_softc;
+
+ if (!netfront_carrier_ok(sc))
+ return;
+
+ /*
+ * While we have enough transmit slots available for at least one
+ * maximum-sized packet, pull mbufs off the queue and put them on
+ * the transmit ring.
+ */
+ while (xn_tx_slot_available(sc)) {
+ IF_DEQUEUE(&ifp->if_snd, m_head);
+ if (m_head == NULL)
+ break;
+
+ if (xn_assemble_tx_request(sc, m_head) != 0)
+ break;
}
- sc->tx.req_prod_pvt = i;
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->tx, notify);
if (notify)
notify_remote_via_irq(sc->irq);
- xn_txeof(sc);
-
if (RING_FULL(&sc->tx)) {
sc->tx_full = 1;
#if 0
netif_stop_queue(dev);
#endif
}
+}
- return;
-}
static void
xn_start(struct ifnet *ifp)
@@ -1623,6 +1705,7 @@ xn_ifinit_locked(struct netfront_info *sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ if_link_state_change(ifp, LINK_STATE_UP);
callout_reset(&sc->xn_stat_ch, hz, xn_tick, sc);
@@ -1762,7 +1845,7 @@ xn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/* FALLTHROUGH */
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
- error = EINVAL;
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
break;
default:
error = ether_ioctl(ifp, cmd, data);
@@ -1786,6 +1869,7 @@ xn_stop(struct netfront_info *sc)
xn_free_tx_ring(sc);
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ if_link_state_change(ifp, LINK_STATE_DOWN);
}
/* START of Xenolinux helper functions adapted to FreeBSD */
@@ -1814,7 +1898,6 @@ network_connect(struct netfront_info *np)
np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) ||
(MODPARM_rx_flip && !feature_rx_flip));
- XN_LOCK(np);
/* Recovery procedure: */
error = talk_to_backend(np->xbdev, np);
if (error)
@@ -1833,6 +1916,7 @@ network_connect(struct netfront_info *np)
m = np->rx_mbufs[requeue_idx] = xennet_get_rx_mbuf(np, i);
ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i);
+
req = RING_GET_REQUEST(&np->rx, requeue_idx);
pfn = vtophys(mtod(m, vm_offset_t)) >> PAGE_SHIFT;
@@ -1864,7 +1948,6 @@ network_connect(struct netfront_info *np)
xn_txeof(np);
XN_TX_UNLOCK(np);
network_alloc_rx_buffers(np);
- XN_UNLOCK(np);
return (0);
}
@@ -1904,6 +1987,11 @@ create_netdev(device_t dev)
np->xbdev = dev;
XN_LOCK_INIT(np, xennetif);
+
+ ifmedia_init(&np->sc_media, 0, xn_ifmedia_upd, xn_ifmedia_sts);
+ ifmedia_add(&np->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
+ ifmedia_set(&np->sc_media, IFM_ETHER|IFM_MANUAL);
+
np->rx_target = RX_MIN_TARGET;
np->rx_min_target = RX_MIN_TARGET;
np->rx_max_target = RX_MAX_TARGET;
@@ -1913,21 +2001,24 @@ create_netdev(device_t dev)
np->tx_mbufs[i] = (void *) ((u_long) i+1);
np->grant_tx_ref[i] = GRANT_INVALID_REF;
}
+ np->tx_mbufs[NET_TX_RING_SIZE] = (void *)0;
+
for (i = 0; i <= NET_RX_RING_SIZE; i++) {
+
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(TX_MAX_TARGET,
- &np->gref_tx_head) < 0) {
- printf("#### netfront can't alloc tx grant refs\n");
+ if (gnttab_alloc_grant_references(NET_TX_RING_SIZE,
+ &np->gref_tx_head) != 0) {
+ IPRINTK("#### netfront can't alloc tx grant refs\n");
err = ENOMEM;
goto exit;
}
/* A grant for every rx ring slot */
if (gnttab_alloc_grant_references(RX_MAX_TARGET,
- &np->gref_rx_head) < 0) {
- printf("#### netfront can't alloc rx grant refs\n");
+ &np->gref_rx_head) != 0) {
+ WPRINTK("#### netfront can't alloc rx grant refs\n");
gnttab_free_grant_references(np->gref_tx_head);
err = ENOMEM;
goto exit;
@@ -1991,7 +2082,8 @@ out:
* acknowledgement.
*/
#if 0
-static void netfront_closing(device_t dev)
+static void
+netfront_closing(device_t dev)
{
#if 0
struct netfront_info *info = dev->dev_driver_data;
@@ -2004,7 +2096,8 @@ static void netfront_closing(device_t dev)
}
#endif
-static int netfront_detach(device_t dev)
+static int
+netfront_detach(device_t dev)
{
struct netfront_info *info = device_get_softc(dev);
@@ -2015,8 +2108,8 @@ static int netfront_detach(device_t dev)
return 0;
}
-
-static void netif_free(struct netfront_info *info)
+static void
+netif_free(struct netfront_info *info)
{
netif_disconnect_backend(info);
#if 0
@@ -2024,7 +2117,8 @@ static void netif_free(struct netfront_info *info)
#endif
}
-static void netif_disconnect_backend(struct netfront_info *info)
+static void
+netif_disconnect_backend(struct netfront_info *info)
{
XN_RX_LOCK(info);
XN_TX_LOCK(info);
@@ -2046,12 +2140,26 @@ static void netif_disconnect_backend(struct netfront_info *info)
}
-static void end_access(int ref, void *page)
+static void
+end_access(int ref, void *page)
{
if (ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(ref, page);
}
+static int
+xn_ifmedia_upd(struct ifnet *ifp)
+{
+ return (0);
+}
+
+static void
+xn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ ifmr->ifm_status = IFM_AVALID|IFM_ACTIVE;
+ ifmr->ifm_active = IFM_ETHER|IFM_MANUAL;
+}
+
/* ** Driver registration ** */
static device_method_t netfront_methods[] = {
/* Device interface */
diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h
index 2851709cb955..47f04057aa68 100644
--- a/sys/i386/include/xen/xenfunc.h
+++ b/sys/i386/include/xen/xenfunc.h
@@ -1,6 +1,5 @@
-/*
- *
- * Copyright (c) 2004,2005 Kip Macy
+/*-
+ * Copyright (c) 2004, 2005 Kip Macy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,24 +10,22 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
* $FreeBSD$
*/
-
#ifndef _XEN_XENFUNC_H_
#define _XEN_XENFUNC_H_
diff --git a/sys/i386/include/xen/xenvar.h b/sys/i386/include/xen/xenvar.h
index cefbb058c1c5..1110f8506ae0 100644
--- a/sys/i386/include/xen/xenvar.h
+++ b/sys/i386/include/xen/xenvar.h
@@ -1,32 +1,31 @@
-/*
+/*-
* Copyright (c) 2008 Kip Macy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
* $FreeBSD$
*/
+
#ifndef XENVAR_H_
#define XENVAR_H_
#define XBOOTUP 0x1
diff --git a/sys/kern/subr_bufring.c b/sys/kern/subr_bufring.c
index 63938eaca444..4cd39292622c 100644
--- a/sys/kern/subr_bufring.c
+++ b/sys/kern/subr_bufring.c
@@ -1,32 +1,29 @@
-/**************************************************************************
- *
- * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org
+/*-
+ * Copyright (c) 2007, 2008 Kip Macy <kmacy@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. The name of Kip Macy nor the names of other
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- *
- ***************************************************************************/
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/sys/sys/buf_ring.h b/sys/sys/buf_ring.h
index efa667de1896..57e42e5c1890 100644
--- a/sys/sys/buf_ring.h
+++ b/sys/sys/buf_ring.h
@@ -1,33 +1,31 @@
-/**************************************************************************
- *
- * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+/*-
+ * Copyright (c) 2007-2009 Kip Macy <kmacy@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * 2. The name of Kip Macy nor the names of other
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
* $FreeBSD$
*
- ***************************************************************************/
+ */
#ifndef _SYS_BUF_RING_H_
#define _SYS_BUF_RING_H_