Subject: mc* performance patch
To: None <port-macppc@netbsd.org>
From: Tim Kelly <hockey@dialectronics.com>
List: port-macppc
Date: 01/13/2005 12:55:01
Alright, I found the problem and turned a previously unuseable mc
interface into a 980KB/s rip roaring 0 packet loss mc interface. The
problem turned out to be pretty simple and the temporary fix was only
one line.
In if_mc.c, in mc_attach, there is the comment:
/*
* allocate memory for receive buffer and mark it non-cacheable
* XXX This should use the bus_dma interface, since the buffer
* needs to be physically contiguous. However, it seems that
* at least on my system, malloc() does allocate contiguous
* memory. If it's not, suggest reducing the number of buffers
* to 2, which will fit in one 4K page.
*/
sc->sc_rxbuf = malloc(MC_NPAGES * PAGE_SIZE, M_DEVBUF, M_WAITOK);
sc->sc_rxbuf_phys = kvtop(sc->sc_rxbuf);
memset(sc->sc_rxbuf, 0, MC_NPAGES * PAGE_SIZE);
Well, apparently on my 7300 the memory is not contiguous, or at least
it's not being written to. I examined the contents of the buffers during
transmission losses and found the upper 2 buffers to be empty,
correlating to the 50% packet loss in ping. I reduced the number of
buffers to 2 as the comment suggests and this immediately fixed the
problem.
Feedback requested from testers, as this should get committed as quickly
as others can confirm this works. Later someone can write a proper
bus_dma allocation, and I'll clean up the media type patch I have for
if_mc.c, and maybe we can close that PR.
tim
Index: if_mcvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/if_mcvar.h,v
retrieving revision 1.7
diff -d -u -r1.7 if_mcvar.h
--- if_mcvar.h 9 Apr 2003 01:54:45 -0000 1.7
+++ if_mcvar.h 13 Jan 2005 17:49:14 -0000
@@ -45,7 +45,7 @@
(sc)->sc_regh, MACE_REG(reg),(val)))
#ifndef MC_RXDMABUFS
-#define MC_RXDMABUFS 4
+#define MC_RXDMABUFS 2 /* 4 */
#endif
#if (MC_RXDMABUFS < 2)
#error Must have at least two buffers for DMA!
@@ -80,6 +80,8 @@
void (*sc_mediastatus) __P((struct mc_softc *,
struct ifmediareq *));
+ u_int sc_defaultmedia;
+
bus_space_tag_t sc_regt;
bus_space_handle_t sc_regh;