Use MCLGET() instead of local list of buffers. Garbage-collect
struct xennet_txbuf usage.
This commit is contained in:
parent
acad751169
commit
4f6680c241
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_xennetvar.h,v 1.7 2005/06/06 11:51:02 yamt Exp $ */
|
||||
/* $NetBSD: if_xennetvar.h,v 1.8 2005/09/11 13:20:00 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
@ -49,15 +49,6 @@ union xennet_bufarray {
|
||||
int xb_next;
|
||||
};
|
||||
|
||||
struct xennet_txbuf {
|
||||
SLIST_ENTRY(xennet_txbuf) xt_next;
|
||||
struct xennet_softc *xt_sc;
|
||||
paddr_t xt_pa;
|
||||
u_char xt_buf[0];
|
||||
};
|
||||
#define TXBUF_PER_PAGE 2
|
||||
#define TXBUF_BUFSIZE (PAGE_SIZE / TXBUF_PER_PAGE) - sizeof(struct xennet_txbuf)
|
||||
|
||||
struct xennet_softc {
|
||||
struct device sc_dev; /* base device glue */
|
||||
struct ethercom sc_ethercom; /* Ethernet common part */
|
||||
@ -92,8 +83,6 @@ struct xennet_softc {
|
||||
union xennet_bufarray sc_tx_bufa[NETIF_TX_RING_SIZE];
|
||||
union xennet_bufarray sc_rx_bufa[NETIF_RX_RING_SIZE];
|
||||
|
||||
SLIST_HEAD(, xennet_txbuf) sc_tx_bufs;
|
||||
|
||||
#if NRND > 0
|
||||
rndsource_element_t sc_rnd_source;
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_xennet.c,v 1.32 2005/09/11 11:44:52 bouyer Exp $ */
|
||||
/* $NetBSD: if_xennet.c,v 1.33 2005/09/11 13:20:00 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_xennet.c,v 1.32 2005/09/11 11:44:52 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_xennet.c,v 1.33 2005/09/11 13:20:00 bouyer Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_nfs_boot.h"
|
||||
@ -128,12 +128,10 @@ static void xennet_ctrlif_rx(ctrl_msg_t *, unsigned long);
|
||||
static int xennet_driver_count_connected(void);
|
||||
static void xennet_driver_status_change(netif_fe_driver_status_t *);
|
||||
static void xennet_interface_status_change(netif_fe_interface_status_t *);
|
||||
static void xennet_tx_mbuf_free(struct mbuf *, caddr_t, size_t, void *);
|
||||
static void xennet_rx_mbuf_free(struct mbuf *, caddr_t, size_t, void *);
|
||||
static int xen_network_handler(void *);
|
||||
static void network_tx_buf_gc(struct xennet_softc *);
|
||||
static void network_alloc_rx_buffers(struct xennet_softc *);
|
||||
static void network_alloc_tx_buffers(struct xennet_softc *);
|
||||
int xennet_init(struct ifnet *);
|
||||
void xennet_stop(struct ifnet *, int);
|
||||
void xennet_reset(struct xennet_softc *);
|
||||
@ -499,10 +497,8 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
|
||||
sc->sc_rx_resp_cons = sc->sc_tx_resp_cons = /* sc->sc_tx_full = */ 0;
|
||||
sc->sc_rx->event = sc->sc_tx->event = 1;
|
||||
|
||||
/* Step 2: Rebuild the RX and TX ring contents. */
|
||||
/* Step 2: Rebuild the RX ring contents. */
|
||||
network_alloc_rx_buffers(sc);
|
||||
SLIST_INIT(&sc->sc_tx_bufs);
|
||||
network_alloc_tx_buffers(sc);
|
||||
|
||||
/* Step 3: All public and private state should now be
|
||||
* sane. Get ready to start sending and receiving
|
||||
@ -546,20 +542,6 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
|
||||
DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change()\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
xennet_tx_mbuf_free(struct mbuf *m, caddr_t buf, size_t size, void *arg)
|
||||
{
|
||||
struct xennet_txbuf *txbuf = (struct xennet_txbuf *)arg;
|
||||
|
||||
DPRINTFN(XEDB_MBUF, ("xennet_tx_mbuf_free %p pa %p\n", txbuf,
|
||||
(void *)txbuf->xt_pa));
|
||||
SLIST_INSERT_HEAD(&txbuf->xt_sc->sc_tx_bufs, txbuf, xt_next);
|
||||
|
||||
if (m != NULL) {
|
||||
pool_cache_put(&mbpool_cache, m);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xennet_rx_push_buffer(struct xennet_softc *sc, int id)
|
||||
{
|
||||
@ -950,38 +932,6 @@ network_alloc_rx_buffers(struct xennet_softc *sc)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
network_alloc_tx_buffers(struct xennet_softc *sc)
|
||||
{
|
||||
vaddr_t txpages, va;
|
||||
struct vm_page *pg;
|
||||
struct xennet_txbuf *txbuf;
|
||||
int i;
|
||||
|
||||
txpages = uvm_km_alloc(kernel_map,
|
||||
(TX_ENTRIES / TXBUF_PER_PAGE) * PAGE_SIZE, PAGE_SIZE,
|
||||
UVM_KMF_VAONLY);
|
||||
for (va = txpages;
|
||||
va < txpages + (TX_ENTRIES / TXBUF_PER_PAGE) * PAGE_SIZE;
|
||||
va += PAGE_SIZE) {
|
||||
pg = uvm_pagealloc(NULL, 0, NULL, 0);
|
||||
if (pg == NULL)
|
||||
panic("network_alloc_tx_buffers: no pages");
|
||||
pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
|
||||
VM_PROT_READ | VM_PROT_WRITE);
|
||||
|
||||
for (i = 0; i < TXBUF_PER_PAGE; i++) {
|
||||
txbuf = (struct xennet_txbuf *)
|
||||
(va + i * (PAGE_SIZE / TXBUF_PER_PAGE));
|
||||
txbuf->xt_sc = sc;
|
||||
txbuf->xt_pa = VM_PAGE_TO_PHYS(pg) +
|
||||
i * (PAGE_SIZE / TXBUF_PER_PAGE) +
|
||||
sizeof(struct xennet_txbuf);
|
||||
SLIST_INSERT_HEAD(&sc->sc_tx_bufs, txbuf, xt_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called at splnet.
|
||||
*/
|
||||
@ -990,7 +940,6 @@ xennet_start(struct ifnet *ifp)
|
||||
{
|
||||
struct xennet_softc *sc = ifp->if_softc;
|
||||
struct mbuf *m, *new_m;
|
||||
struct xennet_txbuf *txbuf;
|
||||
netif_tx_request_t *txreq;
|
||||
NETIF_RING_IDX idx;
|
||||
paddr_t pa;
|
||||
@ -1021,10 +970,12 @@ xennet_start(struct ifnet *ifp)
|
||||
|
||||
switch (m->m_flags & (M_EXT|M_EXT_CLUSTER)) {
|
||||
case M_EXT|M_EXT_CLUSTER:
|
||||
KASSERT(m->m_ext.ext_paddr != M_PADDR_INVALID);
|
||||
pa = m->m_ext.ext_paddr +
|
||||
(m->m_data - m->m_ext.ext_buf);
|
||||
break;
|
||||
case 0:
|
||||
KASSERT(m->m_paddr != M_PADDR_INVALID);
|
||||
pa = m->m_paddr + M_BUFOFFSET(m) +
|
||||
(m->m_data - M_BUFADDR(m));
|
||||
break;
|
||||
@ -1038,34 +989,28 @@ xennet_start(struct ifnet *ifp)
|
||||
|
||||
if (m->m_pkthdr.len != m->m_len ||
|
||||
(pa ^ (pa + m->m_pkthdr.len)) & PG_FRAME) {
|
||||
txbuf = SLIST_FIRST(&sc->sc_tx_bufs);
|
||||
if (txbuf == NULL) {
|
||||
// printf("xennet: no tx bufs\n");
|
||||
break;
|
||||
}
|
||||
|
||||
MGETHDR(new_m, M_DONTWAIT, MT_DATA);
|
||||
if (new_m == NULL) {
|
||||
printf("xennet: no mbuf\n");
|
||||
break;
|
||||
}
|
||||
|
||||
SLIST_REMOVE_HEAD(&sc->sc_tx_bufs, xt_next);
|
||||
MCLGET(new_m, M_DONTWAIT);
|
||||
if ((new_m->m_flags & M_EXT) == 0) {
|
||||
printf("xennet: no mbuf cluster\n");
|
||||
m_freem(new_m);
|
||||
break;
|
||||
}
|
||||
IFQ_DEQUEUE(&ifp->if_snd, m);
|
||||
|
||||
KASSERT(m->m_flags & M_PKTHDR);
|
||||
M_COPY_PKTHDR(new_m, m);
|
||||
m_copydata(m, 0, m->m_pkthdr.len, txbuf->xt_buf);
|
||||
MEXTADD(new_m, txbuf->xt_buf, m->m_pkthdr.len,
|
||||
M_DEVBUF, xennet_tx_mbuf_free, txbuf);
|
||||
new_m->m_ext.ext_paddr = txbuf->xt_pa;
|
||||
m_copydata(m, 0, m->m_pkthdr.len, mtod(new_m, caddr_t));
|
||||
new_m->m_len = new_m->m_pkthdr.len = m->m_pkthdr.len;
|
||||
|
||||
m_freem(m);
|
||||
m = new_m;
|
||||
|
||||
pa = m->m_ext.ext_paddr +
|
||||
(m->m_data - m->m_ext.ext_buf);
|
||||
KASSERT(m->m_ext.ext_paddr != M_PADDR_INVALID);
|
||||
KASSERT(m->m_data == m->m_ext.ext_buf);
|
||||
pa = m->m_ext.ext_paddr;
|
||||
} else
|
||||
IFQ_DEQUEUE(&ifp->if_snd, m);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user