Re: Potential re(4) / netbsd-4 / i386 problem?
Hi, I've been seeing panics on a netbsd-4/i386 machine which appears to be related to the reception of oversized frames: re0: discarding oversize frame (len=8813) I've narrowed down the problem here to a specific change. Basically with netbsd-4 branch I see the failure, but if I revert only the file: ./src/sys/dev/mii/rgephy.c to netbsd-4-0-1-RELEASE the problem goes away. Looking at the difference between the 2 revisions I would guess the most likely cause is the difference in register writes in rgephy_reset? Unfortunately for my purposes one of the two motherboard types I have exhibiting the problem has an RTL8111C which (without the netbsd-4 changes) fails to detect the media automatically (forcing it to 1000baseT has it sync at 100baseTX for some reason). Are there any changes I could make to the netbsd-4 rgephy.c to find a fix for this?(netbsd-5 has the same problem by the way) Thanks, Brad # cd /usr/src/sys/dev/mii # cvs diff -u -r netbsd-4-0-1-RELEASE -r netbsd-4 rgephy.c Index: rgephy.c === RCS file: /cvsroot/src/sys/dev/mii/rgephy.c,v retrieving revision 1.15 retrieving revision 1.15.2.1 diff -u -r1.15 -r1.15.2.1 --- rgephy.c29 Nov 2006 13:57:59 -1.15 +++ rgephy.c18 Aug 2009 09:46:50 -1.15.2.1 @@ -1,4 +1,4 @@ -/*$NetBSD: rgephy.c,v 1.15 2006/11/29 13:57:59 tsutsui Exp $*/ +/*$NetBSD: rgephy.c,v 1.15.2.1 2009/08/18 09:46:50 bouyer Exp $*/ /* * Copyright (c) 2003 @@ -33,7 +33,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.15 2006/11/29 13:57:59 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.15.2.1 2009/08/18 09:46:50 bouyer Exp $"); /* @@ -61,7 +61,12 @@ static intrgephy_match(struct device *, struct cfdata *, void *); static voidrgephy_attach(struct device *, struct device *, void *); -CFATTACH_DECL(rgephy, sizeof(struct mii_softc), +struct rgephy_softc { +struct mii_softc mii_sc; +int mii_revision; +}; + +CFATTACH_DECL(rgephy, sizeof(struct rgephy_softc), rgephy_match, rgephy_attach, mii_phy_detach, mii_phy_activate); @@ -72,8 +77,6 @@ static voidrgephy_loop(struct mii_softc *); static voidrgephy_load_dspcode(struct mii_softc *); -static intrgephy_mii_model; - static const struct mii_phy_funcs rgephy_funcs = { rgephy_service, rgephy_status, rgephy_reset, }; @@ -103,19 +106,26 @@ static void rgephy_attach(struct device *parent, struct device *self, void *aux) { -struct mii_softc *sc = device_private(self); +struct rgephy_softc *rsc = device_private(self); +struct mii_softc *sc = &rsc->mii_sc; struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; const struct mii_phydesc *mpd; int rev; const char *sep = ""; +rsc = device_private(self); +sc = &rsc->mii_sc; +ma = aux; +mii = ma->mii_data; + rev = MII_REV(ma->mii_id2); mpd = mii_phy_match(ma, rgephys); aprint_naive(": Media interface\n"); aprint_normal(": %s, rev. %d\n", mpd->mpd_name, rev); -sc->mii_mpd_model = rev;/* XXX miivar.h comment vs usage? */ +rsc->mii_revision = rev; + sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_pdata = mii; @@ -124,23 +134,14 @@ sc->mii_funcs = &rgephy_funcs; -/* Don't do isolate on this PHY. */ -sc->mii_flags |= MIIF_NOISOLATE; - #defineADD(m, c)ifmedia_add(&mii->mii_media, (m), (c), NULL) #definePRINT(n)aprint_normal("%s%s", sep, (n)); sep = ", " -#if 0 -ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), -BMCR_ISO); -#endif #ifdef __FreeBSD__ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), BMCR_LOOP|BMCR_S100); #endif -rgephy_mii_model = MII_MODEL(ma->mii_id2); - sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; sc->mii_capabilities &= ~BMSR_ANEG; @@ -149,19 +150,11 @@ * media explicitly. Why? */ aprint_normal("%s: ", sc->mii_dev.dv_xname); -#ifdef __FreeBSD__ -mii_phy_add_media(sc); -ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), -RGEPHY_BMCR_FDX); -PRINT(", 1000baseTX"); -ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0); -PRINT("1000baseTX-FDX"); -#else if (sc->mii_capabilities & BMSR_EXTSTAT) { sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); } mii_phy_add_media(sc); -#endif + /* rtl8169S does not report auto-sense; add manually. */ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), MII_NMEDIA); sep =", "; @@ -177,9 +170,12 @@ static int rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { +struct rgephy_softc *rsc; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg, speed, gig, anar; +rsc = (struct rgephy_softc *)sc; + switch (cmd) { case MII_POLLSTAT: /* @@ -254,7 +25
Re: xmd(4) (Re: XIP)
hi, > On Thu, Oct 28, 2010 at 05:31:45AM +, YAMAMOTO Takashi wrote: >> hi, >> >> > Here's the reason why I've written xmd_machdep.c: >> > >> > xmd(4) is a read-only RAM-based disk driver capable of XIP. The >> > main purpose is to test XIP functionality. xmd(4) can be implemented >> > on any platforms that supports VM in theory. xmd(4) may be also >> > useful for other cases where md(4) is used, but users want to save >> > memory. md(4) allocates memory for its storage, and copies pages >> > from or to page cache. >> > >> > xmd(4) allocates a static, read-only array and provides it as a >> > backing store. When it's used as XIP, it registers the array as >> > a physical device page segment. From VM's POV, the registered >> > region is seen like a ROM in a device connected over some buses. >> > >> > The procedure to register an array as a physical segment is somewhat >> > strange. The registered array resides in kernel's read-only data >> > section. Kernel already maps its static region (text, rodata, >> > data, bss, ...) at boot time. xmd(4) "re-defines" part of it as >> > a physical device segment, like a ROM connected via another bus. >> > >> > As far as the backing store array resides in main memory, you'll >> > end up with some way to convert kernel VA back to physical address. >> > There is no alternative to achieve the goal in MI way, or xmd.c is >> > sprinkled like mem.c. >> >> why can't you use pmap_extract? > > Because looking up a paddr_t doesn't help alone. > > The driver needs to allocate a physical segment object (struct > vm_physseg) and per-page objects (struct vm_page), so that its > region can be mapped to user address. This is done by calling > bus_space_physload_device() or xmd_machdep_physload(), which in > turn call uvm_page_physload_device(). > > This is what happens during a fault onto xmd: > > - User opens a cdev (/dev/XXX), then calls mmap() with its fd > - User touch a mapped address > - Fault is triggered, fault handler looks up user's map and map > entry > - uvm_fault() -> udv_fault() -> cdev_mmap() -> xmd_mmap() > - xmd_mmap() returns a "paddr_t" > - udv_fault() enters the paddr_t to pmap_enter() > - pmap_enter looks up a vm_physseg from a paddr_t > - pmap_enter looks up a vm_page from a vm_physseg > - pmap_enter looks up a vm_page_md from a vm_page > : > > This is redundant. The problem is we use "paddr_t" as a cookie > to identify a page in a segment, overriding its original meaning, > physical address. What pmap_enter needs is an ID. Looking up a > physical address from an ID is easy. The reverse is not. > > After these observations, I have concluded that any appearance of > "paddr_t" in any MI code (sys/uvm, sys/kern, sys/dev) is a wrong > approach. I don't see how pmap_extract() helps this situation? because you seem saying that there is no MI way to "convert kernel VA back to physical address", i suggested pmap_extract. i guess i don't understand your situation. :-) YAMAMOTO Takashi > > Masao > >> >> YAMAMOTO Takashi >> >> > >> > Masao > > -- > Masao Uebayashi / Tombi Inc. / Tel: +81-90-9141-4635
Re: xmd(4) (Re: XIP)
On Thu, Oct 28, 2010 at 05:31:45AM +, YAMAMOTO Takashi wrote: > hi, > > > Here's the reason why I've written xmd_machdep.c: > > > > xmd(4) is a read-only RAM-based disk driver capable of XIP. The > > main purpose is to test XIP functionality. xmd(4) can be implemented > > on any platforms that supports VM in theory. xmd(4) may be also > > useful for other cases where md(4) is used, but users want to save > > memory. md(4) allocates memory for its storage, and copies pages > > from or to page cache. > > > > xmd(4) allocates a static, read-only array and provides it as a > > backing store. When it's used as XIP, it registers the array as > > a physical device page segment. From VM's POV, the registered > > region is seen like a ROM in a device connected over some buses. > > > > The procedure to register an array as a physical segment is somewhat > > strange. The registered array resides in kernel's read-only data > > section. Kernel already maps its static region (text, rodata, > > data, bss, ...) at boot time. xmd(4) "re-defines" part of it as > > a physical device segment, like a ROM connected via another bus. > > > > As far as the backing store array resides in main memory, you'll > > end up with some way to convert kernel VA back to physical address. > > There is no alternative to achieve the goal in MI way, or xmd.c is > > sprinkled like mem.c. > > why can't you use pmap_extract? Because looking up a paddr_t doesn't help alone. The driver needs to allocate a physical segment object (struct vm_physseg) and per-page objects (struct vm_page), so that its region can be mapped to user address. This is done by calling bus_space_physload_device() or xmd_machdep_physload(), which in turn call uvm_page_physload_device(). This is what happens during a fault onto xmd: - User opens a cdev (/dev/XXX), then calls mmap() with its fd - User touch a mapped address - Fault is triggered, fault handler looks up user's map and map entry - uvm_fault() -> udv_fault() -> cdev_mmap() -> xmd_mmap() - xmd_mmap() returns a "paddr_t" - udv_fault() enters the paddr_t to pmap_enter() - pmap_enter looks up a vm_physseg from a paddr_t - pmap_enter looks up a vm_page from a vm_physseg - pmap_enter looks up a vm_page_md from a vm_page : This is redundant. The problem is we use "paddr_t" as a cookie to identify a page in a segment, overriding its original meaning, physical address. What pmap_enter needs is an ID. Looking up a physical address from an ID is easy. The reverse is not. After these observations, I have concluded that any appearance of "paddr_t" in any MI code (sys/uvm, sys/kern, sys/dev) is a wrong approach. I don't see how pmap_extract() helps this situation? Masao > > YAMAMOTO Takashi > > > > > Masao -- Masao Uebayashi / Tombi Inc. / Tel: +81-90-9141-4635