Date: Thu, 13 Oct 2005 08:13:10 -0700 From: Sean McNeil <sean@mcneil.com> To: Mike Tancsa <mike@sentex.net> Cc: freebsd-amd64@freebsd.org Subject: realtek performance (was Re: good ATI chipset results) Message-ID: <1129216390.8681.6.camel@server.mcneil.com> In-Reply-To: <6.2.3.4.0.20051013090818.07a5c9a0@64.7.153.2> References: <6.2.3.4.0.20051013090818.07a5c9a0@64.7.153.2>
next in thread | previous in thread | raw e-mail | index | archive | help
--=-bBWu23haOdgH96FR+ng9 Content-Type: text/plain Content-Transfer-Encoding: 7bit On Thu, 2005-10-13 at 09:17 -0400, Mike Tancsa wrote: > Havent really seen anyone else use this board, but I have had good > luck with it so far > > http://www.ecs.com.tw/ECSWeb/Products/ProductsDetail.aspx?DetailID=506&MenuID=90&LanID=0 > > Its a micro ATX formfactor with built in video and the onboard NIC is > a realtek. (Although its not the fastest NIC, its driver is stable > and mature-- especially compared to the headaches people seem to have > with the NVIDIA NICs.) Is this the RealTek 8169S Single-chip Gigabit Ethernet? For those interested, here are some changes I always use to increase the performance of the above NIC. With these mods, I can stream over 20 MBps video multicast and do other stuff over the network without issues. Without the changes, xmit is horrible with severe UDP packet loss. Cheers, Sean --=-bBWu23haOdgH96FR+ng9 Content-Disposition: attachment; filename=if_rlreg.h.diff Content-Type: text/x-patch; name=if_rlreg.h.diff; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit --- /sys/pci/if_rlreg.h Thu Oct 6 13:17:17 2005 +++ ./if_rlreg.h Thu Oct 6 15:01:42 2005 @@ -618,13 +618,8 @@ #define RE_FIXUP_RX 1 #endif -#define RL_TX_DESC_CNT 64 -#define RL_RX_DESC_CNT RL_TX_DESC_CNT -#define RL_RX_LIST_SZ (RL_RX_DESC_CNT * sizeof(struct rl_desc)) -#define RL_TX_LIST_SZ (RL_TX_DESC_CNT * sizeof(struct rl_desc)) #define RL_RING_ALIGN 256 #define RL_IFQ_MAXLEN 512 -#define RL_DESC_INC(x) (x = (x + 1) % RL_TX_DESC_CNT) #define RL_OWN(x) (le32toh((x)->rl_cmdstat) & RL_RDESC_STAT_OWN) #define RL_RXBYTES(x) (le32toh((x)->rl_cmdstat) & sc->rl_rxlenmask) #define RL_PKTSZ(x) ((x)/* >> 3*/) @@ -654,14 +649,15 @@ }; struct rl_list_data { - struct mbuf *rl_tx_mbuf[RL_TX_DESC_CNT]; - struct mbuf *rl_rx_mbuf[RL_TX_DESC_CNT]; + int rl_desc_count; + struct mbuf **rl_tx_mbuf; + struct mbuf **rl_rx_mbuf; int rl_tx_prodidx; int rl_rx_prodidx; int rl_tx_considx; int rl_tx_free; - bus_dmamap_t rl_tx_dmamap[RL_TX_DESC_CNT]; - bus_dmamap_t rl_rx_dmamap[RL_RX_DESC_CNT]; + bus_dmamap_t *rl_tx_dmamap; + bus_dmamap_t *rl_rx_dmamap; bus_dma_tag_t rl_mtag; /* mbuf mapping tag */ bus_dma_tag_t rl_stag; /* stats mapping tag */ bus_dmamap_t rl_smap; /* stats map */ --=-bBWu23haOdgH96FR+ng9 Content-Disposition: attachment; filename=if_re.c.diff Content-Type: text/x-patch; name=if_re.c.diff; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit --- /sys/dev/re/if_re.c Sat Oct 8 00:35:10 2005 +++ ./if_re.c Sat Oct 8 09:30:26 2005 @@ -300,6 +300,9 @@ CSR_WRITE_1(sc, RL_EECMD, \ CSR_READ_1(sc, RL_EECMD) & ~x) +#define RL_DESC_COUNT(sc) ((sc)->rl_ldata.rl_desc_count) +#define RL_DESC_INC(sc,x) (x = (x + 1) % RL_DESC_COUNT(sc)) + /* * Send a read command and address to the EEPROM, check for ACK. */ @@ -917,13 +920,13 @@ cmdstat |= RL_TDESC_CMD_SOF; else cmdstat |= RL_TDESC_CMD_OWN; - if (idx == (RL_RX_DESC_CNT - 1)) + if (idx == (RL_DESC_COUNT(ctx->sc) - 1)) cmdstat |= RL_TDESC_CMD_EOR; d->rl_cmdstat = htole32(cmdstat | ctx->rl_flags); i++; if (i == nseg) break; - RL_DESC_INC(idx); + RL_DESC_INC(ctx->sc,idx); } d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF); @@ -961,10 +964,46 @@ int nseg; int i; + sc->rl_ldata.rl_tx_mbuf = + (struct mbuf **) malloc(sizeof(struct mbuf *) * RL_DESC_COUNT(sc), + M_DEVBUF, M_NOWAIT|M_ZERO); + + if (sc->rl_ldata.rl_tx_mbuf == NULL) { + device_printf(dev, "could not allocate tx mbuf list\n"); + return (ENOMEM); + } + + sc->rl_ldata.rl_rx_mbuf = + (struct mbuf **) malloc(sizeof(struct mbuf *) * RL_DESC_COUNT(sc), + M_DEVBUF, M_NOWAIT|M_ZERO); + + if (sc->rl_ldata.rl_rx_mbuf == NULL) { + device_printf(dev, "could not allocate rx mbuf list\n"); + return (ENOMEM); + } + + sc->rl_ldata.rl_tx_dmamap = + (bus_dmamap_t *) malloc(sizeof(bus_dmamap_t) * RL_DESC_COUNT(sc), + M_DEVBUF, M_NOWAIT|M_ZERO); + + if (sc->rl_ldata.rl_tx_dmamap == NULL) { + device_printf(dev, "could not allocate tx dmamap list\n"); + return (ENOMEM); + } + + sc->rl_ldata.rl_rx_dmamap = + (bus_dmamap_t *) malloc(sizeof(bus_dmamap_t) * RL_DESC_COUNT(sc), + M_DEVBUF, M_NOWAIT|M_ZERO); + + if (sc->rl_ldata.rl_rx_dmamap == NULL) { + device_printf(dev, "could not allocate rx dmamap list\n"); + return (ENOMEM); + } + /* * Allocate map for RX mbufs. */ - nseg = 32; + nseg = RL_DESC_COUNT(sc); error = bus_dma_tag_create(sc->rl_parent_tag, ETHER_ALIGN, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES * nseg, nseg, MCLBYTES, BUS_DMA_ALLOCNOW, @@ -979,7 +1018,9 @@ */ error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, - NULL, RL_TX_LIST_SZ, 1, RL_TX_LIST_SZ, BUS_DMA_ALLOCNOW, + NULL, RL_DESC_COUNT(sc) * sizeof(struct rl_desc), 1, + RL_DESC_COUNT(sc) * sizeof(struct rl_desc), + BUS_DMA_ALLOCNOW | BUS_DMA_COHERENT, NULL, NULL, &sc->rl_ldata.rl_tx_list_tag); if (error) { device_printf(dev, "could not allocate dma tag\n"); @@ -998,12 +1039,12 @@ error = bus_dmamap_load(sc->rl_ldata.rl_tx_list_tag, sc->rl_ldata.rl_tx_list_map, sc->rl_ldata.rl_tx_list, - RL_TX_LIST_SZ, re_dma_map_addr, + RL_DESC_COUNT(sc) * sizeof(struct rl_desc), re_dma_map_addr, &sc->rl_ldata.rl_tx_list_addr, BUS_DMA_NOWAIT); /* Create DMA maps for TX buffers */ - for (i = 0; i < RL_TX_DESC_CNT; i++) { + for (i = 0; i < RL_DESC_COUNT(sc); i++) { error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0, &sc->rl_ldata.rl_tx_dmamap[i]); if (error) { @@ -1017,7 +1058,9 @@ */ error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, - NULL, RL_RX_LIST_SZ, 1, RL_RX_LIST_SZ, BUS_DMA_ALLOCNOW, + NULL, RL_DESC_COUNT(sc) * sizeof(struct rl_desc), 1, + RL_DESC_COUNT(sc) * sizeof(struct rl_desc), + BUS_DMA_ALLOCNOW | BUS_DMA_COHERENT, NULL, NULL, &sc->rl_ldata.rl_rx_list_tag); if (error) { device_printf(dev, "could not allocate dma tag\n"); @@ -1036,12 +1079,12 @@ error = bus_dmamap_load(sc->rl_ldata.rl_rx_list_tag, sc->rl_ldata.rl_rx_list_map, sc->rl_ldata.rl_rx_list, - RL_RX_LIST_SZ, re_dma_map_addr, + RL_DESC_COUNT(sc) * sizeof(struct rl_desc), re_dma_map_addr, &sc->rl_ldata.rl_rx_list_addr, BUS_DMA_NOWAIT); /* Create DMA maps for RX buffers */ - for (i = 0; i < RL_RX_DESC_CNT; i++) { + for (i = 0; i < RL_DESC_COUNT(sc); i++) { error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0, &sc->rl_ldata.rl_rx_dmamap[i]); if (error) { @@ -1122,6 +1165,8 @@ if (sc->rl_type == RL_8169) { + RL_DESC_COUNT(sc) = 1024; + /* Set RX length mask */ sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN; @@ -1141,6 +1186,8 @@ eaddr[i] = CSR_READ_1(sc, RL_IDR0 + i); } else { + RL_DESC_COUNT(sc) = 64; + /* Set RX length mask */ sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN; @@ -1163,13 +1210,13 @@ /* * Allocate the parent bus DMA tag appropriate for PCI. */ -#define RL_NSEG_NEW 32 error = bus_dma_tag_create(NULL, /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ + MAXBSIZE, /* maxsize */ + RL_DESC_COUNT(sc), /* nsegments */ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ BUS_DMA_ALLOCNOW, /* flags */ NULL, NULL, /* lockfunc, lockarg */ @@ -1340,10 +1387,10 @@ /* Destroy all the RX and TX buffer maps */ if (sc->rl_ldata.rl_mtag) { - for (i = 0; i < RL_TX_DESC_CNT; i++) + for (i = 0; i < RL_DESC_COUNT(sc); i++) bus_dmamap_destroy(sc->rl_ldata.rl_mtag, sc->rl_ldata.rl_tx_dmamap[i]); - for (i = 0; i < RL_RX_DESC_CNT; i++) + for (i = 0; i < RL_DESC_COUNT(sc); i++) bus_dmamap_destroy(sc->rl_ldata.rl_mtag, sc->rl_ldata.rl_rx_dmamap[i]); bus_dma_tag_destroy(sc->rl_ldata.rl_mtag); @@ -1363,6 +1410,18 @@ if (sc->rl_parent_tag) bus_dma_tag_destroy(sc->rl_parent_tag); + if (sc->rl_ldata.rl_rx_dmamap) + free(sc->rl_ldata.rl_rx_dmamap, M_DEVBUF); + + if (sc->rl_ldata.rl_tx_dmamap) + free(sc->rl_ldata.rl_tx_dmamap, M_DEVBUF); + + if (sc->rl_ldata.rl_rx_mbuf) + free(sc->rl_ldata.rl_rx_mbuf, M_DEVBUF); + + if (sc->rl_ldata.rl_tx_mbuf) + free(sc->rl_ldata.rl_tx_mbuf, M_DEVBUF); + mtx_destroy(&sc->rl_mtx); return (0); @@ -1452,15 +1511,16 @@ RL_LOCK_ASSERT(sc); - bzero ((char *)sc->rl_ldata.rl_tx_list, RL_TX_LIST_SZ); - bzero ((char *)&sc->rl_ldata.rl_tx_mbuf, - (RL_TX_DESC_CNT * sizeof(struct mbuf *))); + bzero ((char *)sc->rl_ldata.rl_tx_list, + RL_DESC_COUNT(sc) * sizeof(struct rl_desc)); + bzero ((char *)sc->rl_ldata.rl_tx_mbuf, + RL_DESC_COUNT(sc) * sizeof(struct mbuf *)); bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag, sc->rl_ldata.rl_tx_list_map, BUS_DMASYNC_PREWRITE); sc->rl_ldata.rl_tx_prodidx = 0; sc->rl_ldata.rl_tx_considx = 0; - sc->rl_ldata.rl_tx_free = RL_TX_DESC_CNT; + sc->rl_ldata.rl_tx_free = RL_DESC_COUNT(sc); return (0); } @@ -1471,11 +1531,12 @@ { int i; - bzero ((char *)sc->rl_ldata.rl_rx_list, RL_RX_LIST_SZ); - bzero ((char *)&sc->rl_ldata.rl_rx_mbuf, - (RL_RX_DESC_CNT * sizeof(struct mbuf *))); + bzero ((char *)sc->rl_ldata.rl_rx_list, + RL_DESC_COUNT(sc) * sizeof(struct rl_desc)); + bzero ((char *)sc->rl_ldata.rl_rx_mbuf, + RL_DESC_COUNT(sc) * sizeof(struct mbuf *)); - for (i = 0; i < RL_RX_DESC_CNT; i++) { + for (i = 0; i < RL_DESC_COUNT(sc); i++) { if (re_newbuf(sc, i, NULL) == ENOBUFS) return (ENOBUFS); } @@ -1543,7 +1604,7 @@ sc->rl_tail = m; } re_newbuf(sc, i, NULL); - RL_DESC_INC(i); + RL_DESC_INC(sc,i); continue; } @@ -1582,7 +1643,7 @@ sc->rl_head = sc->rl_tail = NULL; } re_newbuf(sc, i, m); - RL_DESC_INC(i); + RL_DESC_INC(sc,i); continue; } @@ -1598,11 +1659,11 @@ sc->rl_head = sc->rl_tail = NULL; } re_newbuf(sc, i, m); - RL_DESC_INC(i); + RL_DESC_INC(sc,i); continue; } - RL_DESC_INC(i); + RL_DESC_INC(sc,i); if (sc->rl_head != NULL) { m->m_len = total_len % RE_RX_DESC_BUFLEN; @@ -1718,7 +1779,7 @@ ifp->if_opackets++; } sc->rl_ldata.rl_tx_free++; - RL_DESC_INC(idx); + RL_DESC_INC(sc,idx); } /* No changes made to the TX ring, so no flush needed */ @@ -1735,7 +1796,7 @@ * interrupt that will cause us to re-enter this routine. * This is done in case the transmitter has gone idle. */ - if (sc->rl_ldata.rl_tx_free != RL_TX_DESC_CNT) + if (sc->rl_ldata.rl_tx_free != RL_DESC_COUNT(sc)) CSR_WRITE_4(sc, RL_TIMERCNT, 1); } @@ -1901,42 +1962,22 @@ arg.sc = sc; arg.rl_idx = *idx; arg.rl_maxsegs = sc->rl_ldata.rl_tx_free; - if (arg.rl_maxsegs > 4) - arg.rl_maxsegs -= 4; arg.rl_ring = sc->rl_ldata.rl_tx_list; map = sc->rl_ldata.rl_tx_dmamap[*idx]; + + m_new = m_defrag(*m_head, M_DONTWAIT); + if (m_new != NULL) + *m_head = m_new; + error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map, *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT); - if (error && error != EFBIG) { + if (error) { if_printf(sc->rl_ifp, "can't map mbuf (error %d)\n", error); return (ENOBUFS); } - /* Too many segments to map, coalesce into a single mbuf */ - - if (error || arg.rl_maxsegs == 0) { - m_new = m_defrag(*m_head, M_DONTWAIT); - if (m_new == NULL) - return (ENOBUFS); - else - *m_head = m_new; - - arg.sc = sc; - arg.rl_idx = *idx; - arg.rl_maxsegs = sc->rl_ldata.rl_tx_free; - arg.rl_ring = sc->rl_ldata.rl_tx_list; - - error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map, - *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT); - if (error) { - if_printf(sc->rl_ifp, "can't map mbuf (error %d)\n", - error); - return (EFBIG); - } - } - /* * Insure that the map for this transmission * is placed at the array index of the last descriptor @@ -1968,7 +2009,7 @@ sc->rl_ldata.rl_tx_list[*idx].rl_cmdstat |= htole32(RL_TDESC_CMD_OWN); - RL_DESC_INC(arg.rl_idx); + RL_DESC_INC(sc,arg.rl_idx); *idx = arg.rl_idx; return (0); @@ -2405,7 +2446,7 @@ /* Free the TX list buffers. */ - for (i = 0; i < RL_TX_DESC_CNT; i++) { + for (i = 0; i < RL_DESC_COUNT(sc); i++) { if (sc->rl_ldata.rl_tx_mbuf[i] != NULL) { bus_dmamap_unload(sc->rl_ldata.rl_mtag, sc->rl_ldata.rl_tx_dmamap[i]); @@ -2416,7 +2457,7 @@ /* Free the RX list buffers. */ - for (i = 0; i < RL_RX_DESC_CNT; i++) { + for (i = 0; i < RL_DESC_COUNT(sc); i++) { if (sc->rl_ldata.rl_rx_mbuf[i] != NULL) { bus_dmamap_unload(sc->rl_ldata.rl_mtag, sc->rl_ldata.rl_rx_dmamap[i]); --=-bBWu23haOdgH96FR+ng9--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1129216390.8681.6.camel>